菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
228
0

dubbo 框架

原创
05/13 14:22
阅读数 76594

2.1 dubbo  

  Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提
供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和

发现。

  Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案、 服
务治理方案。
官网:http://dubbo.apache.org/zh-cn/

快速开始文档地址:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html

面向接口代理:调用接口的方法,在 A 服务器调用 B 服务器的方法,由 dubbo 实现对 B 的
调用,无需关心实现的细节,就像 MyBatis 访问 Dao 的接口,可以操作数据库一样。不用关
心 Dao 接口方法的实现。这样开发是方便,舒服的。

 

2.2 基本架构

架构图:

provider:提供者,供应商,提供程序

consumer:消费者

subscribe:订阅

notify:通知

invoke:调用,呼叫

  服务提供者( (Provider) ):暴露服务的服务提供方,服务提供者在启动时,向注册中心注
册自己提供的服务。
  服务消费者( (Consumer ): 调用远程服务的服务消费方,服务消费者在启动时,向注册
中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一
台提供者进行调用,如果调用失败,再选另一台调用。
  注册中心( (Registry) ):注册中心返回服务提供者地址列表给消费者,如果有变更,注册
中心将基于长连接推送变更数据给消费者
  监控中心( (Monitor) ):服务消费者和提供者,在内存中累计调用次数和调用时间,定时
每分钟发送一次统计数据到监控中心

 

调用关系说明:
⚫ 服务容器负责启动,加载,运行服务提供者。
⚫ 服务提供者在启动时,向注册中心注册自己提供的服务。
⚫ 服务消费者在启动时,向注册中心订阅自己所需的服务。
⚫ 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送
变更数据给消费者。
⚫ 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如
果调用失败,再选另一台调用。

⚫  服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数
据到监控中心。

 

2.3 dubbo  支持的协议

  支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。
dubbo 官方推荐使用 dubbo 协议。dubbo 协议默认端口 20880
使用 dubbo 协议,spring 配置文件加入:
<dubbo:protocol name="dubbo" port="20880" />

 

2.4  电商平台需求

  某电商平台系统需求,用户浏览商品;选择商品下订单,订单系统需要获取用户信息中
的送货地址;向支付系统请求完成付款。

 

2.5直连方式 dubbo

  点对点的直连项目:消费者直接访问服务提供者,没有注册中心。消费者必须指定服务
提供者的访问地址(url)。
消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。

 

2.5.1 实现目标

 

2.5.2 实现方式

以 JavaSE 为例,服务提供者,服务消费者都是 JavaSE 项目

(1) 创建服务提供者: 订单服务

A 、 建 新建 java project

项目名称: link-orderservice-provider
设置 version 为 1.0.0

B 、 maven pom.xml

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.16.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.2</version>
</dependency>

 

在<build>中加入 plugin

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
        <source>1.8</source>
        <target>1.8</target>
        </configuration>
    </plugin>
</plugins>                

C 、  创建 订单实体 类:Order

package com.bjpowernode.domain;

import java.io.Serializable;

public class Order implements Serializable {

    private String id;
    private String goodName;
    private float price;
    private  int amount;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getGoodName() {
        return goodName;
    }

    public void setGoodName(String goodName) {
        this.goodName = goodName;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id='" + id + '\'' +
                ", goodName='" + goodName + '\'' +
                ", price=" + price +
                ", amount=" + amount +
                '}';
    }
}

D 、  新建 订单 服务接口:OrderService

package com.bjpowernode.service;

import com.bjpowernode.domain.Order;

public interface OrderService {
    public Order createOrder(Integer userId,String goodName,float price,int amount);
}

E 、  新建接口的实现类:OrderServiceImpl

package com.bjpowernode.service.impl;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.OrderService;

import java.util.UUID;

public class OrderServiceImpl implements OrderService {
    public Order createOrder(Integer userId, String goodName, float price, int amount) {
        Order order=new Order();
        order.setAmount(amount);
        order.setGoodName(goodName);
        order.setId(UUID.randomUUID().toString().replace("-",""));
        order.setPrice(price);
        System.out.println("创建订单"+order);
        return order;
    }
}

F 、 建 创建 dubbo 

orderservce-provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--声明dubbo服务名称-->
    <dubbo:application name="link-orderservice-provider"/>

    <!--声明访问dubbo服务的协议-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--声明服务的接口暴露服务-->
    <dubbo:service interface="com.bjpowernode.service.OrderService"
                   ref="orderService" registry="N/A"/>

    <!--声明接口的实现类对象-->
    <bean id="orderService" class="com.bjpowernode.service.impl.OrderServiceImpl"/>

</beans>

G 、  测试配置 文件

package com.bjpowernode;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class OrderProviderApplication {
    public static void main(String[] args) throws IOException {
        String config="orderservice-provider.xml";
        ApplicationContext context=new ClassPathXmlApplicationContext(config);
        //调用容器的启动方法。
        ((ClassPathXmlApplicationContext) context).start();

        System.in.read();
    }
}

H 、 地 安装本地 jar 到 到 maven 

  服务接口中的方法要给消费者使用,消费者项目需要知道接口名称和接口中的方法名称、参
数等。这些信息服务提供者才知道。需要把接口的 class 文件打包为 jar .
  服务接口项目的类文件打包为 jar, 安装到 maven 仓库,仓库中的提供者 jar 可以被消费者
使用。
使用 idea 的 maven 窗口执行 install

(2 )  创建服务消费者: 商品网站

A 、 建 新建 java project

项目名称: link-main-web

B 、 maven pom.xml

<dependency>
    <groupId>com.bjpowernode</groupId>
    <artifactId>link-orderservice-provider</artifactId>
    <version>1.0.0</version>
</dependency>

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency>

<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency>

<build>加入 maven 编译插件

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>            

C 、  创建 购买商品 接口

package com.bjpowernode.service;

import com.bjpowernode.domain.Order;

public interface ShopService {
  //用户id,商品名称,价格,数量
public Order buyGoods(Integer userId,String goodName,float price,int amount); }

D 、  创建 购买接口和实现类

package com.bjpowernode.service.impl;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.OrderService;
import com.bjpowernode.service.ShopService;
import com.sun.org.apache.xpath.internal.operations.Or;

public class ShopServiceImpl implements ShopService {
  //使用远程服务接口
private OrderService orderService; public void setOrderService(OrderService orderService) { this.orderService = orderService; } @Override public Order buyGoods(Integer userId, String goodName, float price, int amount) { System.out.println("buyGoods访问服务提供的方法"); System.out.println("代理:"+orderService.getClass().getName());       
      
      //调用远程方法,创建订单 Order order
= orderService.createOrder(userId,goodName,price,amount); return order; } }

 

E 、 创建 dubbo 配置文件

shop-consume.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--声明dubbo的服务名称
       name:dubbo的服务名称,自定义的字符串,可以使用项目的名称。
           服务的名称最好是唯一值,dubbo框架内部用来区分服务的。
   -->
    <dubbo:application name="link-main-web" />

    <!--声明要使用的远程接口(服务提供者)
      id:dubbo创建的接口的实现类对象的名称(动态代理)
      interface:远程的接口全限定名称(服务提供者中的接口)
      registry:表示是否使用注册中心, 不使用赋值为"N/A"
      url:访问服务提供者的地址,直连方式中,地址是固定的。
        http://localhost:8080/myweb
        dubbo://localhost:20880

   -->
    <dubbo:reference id="remoteOrderService" interface="com.bjpowernode.service.OrderService"
    registry="N/A" url="dubbo://localhost:20880">

    </dubbo:reference>

    <!--声明自定义的业务对象-->
    <bean id="shopService" class="com.bjpowernode.service.impl.ShopServiceImpl">
        <property name="orderService" ref="remoteOrderService"></property>
    </bean>


</beans>

 

F 、 执行消费者

package com.bjpowernode;

import com.bjpowernode.domain.Order;
import com.bjpowernode.service.ShopService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumeApplication {
    public static void main(String[] args) {
        String config = "main-consume.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(config);
        ShopService shopService = (ShopService) context.getBean("shopService");
        Order order = shopService.buyGoods(1, "thinkpad", 5999, 1);
        System.out.println(order);
    }
}

 

2.6 dubbo  服务化最佳实践

2.6.1 分包

  建议将服务接口、服务模型、服务异常等均放在公共包中。

2.6.2  粒度

  服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否
则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
  服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。

不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会
给后期维护带来不便。

 

2.6.3 版本

每个接口都应定义版本号,为后续不兼容升级提供可能,如: <dubbo:service

interface="com.xxx.XxxService" version="1.0" />。
建议使用两位版本号,要变更服务版本。先升级一半提供者为新版本,再将消费者全部
升为新版本,然后将剩下的一半提供者升为新版本。

2.7  改造 dubbo 项目

  抽象分散在多个项目中的公共接口,实体类,异常,工具类到一个项目中,在其他项目
如服务提供者,消费者共用公共的资源。

2.7.1 实现目标

用户访问电商网站浏览商品—选择商品购买
用户访问电商网站—查看用户信息(收件人地址)

 

 

 

 

 

2.8 dubbo  常用标签

Dubbo 中常用标签。分为三个类别:公用标签,服务提供者标签,服务消费者标签

2.8.1 公用标签

<dubbo:application/><dubbo:registry/>

 

A、配置应用信息

<dubbo:application name=”服务的名称”/>

B、 、 配置注册中心

<dubbo:registry address=”ip:port” protocol=”协议”/>

2.8.2 服务提供者标签

配置暴露的服务

<dubbo:service interface=”服务接口名” ref=”服务实现对象 bean”>

2.8.3 服务消费者

配置服务消费者引用远程服务

<dubbo:reference id=”服务引用 bean 的 id” interface=”服务接口名”/>

 

发表评论

0/200
228 点赞
0 评论
收藏