天天看点

Dubbo入门

Dubbo

Dubbo介绍

Dubbo是轻量级,高性能的RPC框架,并不是一个微服务的全面解决方案,由Java语言开发。

RPC的介绍

  • RPC: 远程过程调用
  • 在早期单机时代:IPC:单机里各个进程间的相互通信

    到了网络时代:把IPC扩展到网络上,就叫做了RPC。也就是通过socket、IO通信和传输

  • 调用其他机器上的程序和调用本地程序一样方便

常见的RPC框架:Dubbo、Montan(新浪,轻量级)、Thrift(Facebook,可以跨语言)

HTTP和RPC对比:

  • HTTP和RPC都是用来通信的。但是HTTP有许多规定:请求头组成、传输的要求等,效率较低。RPC效率较高,减少资源消耗。
  • 传输效率: RPC方式可以自己进行定制,HTTP包含了许多无用的信息,导致效率低
  • 性能消耗,主要是在于序列化和反序列化的耗时。 RPC采用二进制高效的传输,HTTP多采用JSON的格式进行传输,JSON转为具体的对象比较耗时。
  • 负载均衡:Dubbo在调用时发现如果有多个服务方可以进行负载均衡,采用随机 、轮询等方式

    HTTP可能会借助外部的组件。如nginx进行负载均衡,自身对这个能力比较欠缺。

Dubbo工作原理

Dubbo入门

角色

  • Provider:服务的服务提供者
  • Consumer:调用远程服务的消费者
  • Container:服务运行的容器
  • Registry:服务注册和发现的注册中心
  • Minitor:统计服务调用次数和时间的监控中心

调用关系

  • 0:服务器容器负责启动、加载、运行服务提供者。
  • 1:服务提供者在启动后就可以向注册中心暴露服务。
  • 2:服务消费者在启动后就可以向注册中心订阅想要的服务。
  • 3:注册中心向服务消费者返回服务调用列表。
  • 4:服务消费者基于负载均衡算法调用服务提供者的服务,这个服务提供者有可能是一个服务提供者列表,调用那个服务提供者就是根据负载均衡来调用了。
  • 5:服务提供者和服务消费者定时将保存在内存中的服务调用次数和服务调用时间推送给监控。

Dubbo支持的通信协议

Dubbo入门

1)Dubbo协议

dubbo://ip:端口

单一长连接,NIO异步通信,基于hessian作为序列化协议,适用传输数据量很小(每次请求在100kb以内),但是并发量很高

Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况

2)RMI协议

RMI协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式

走java二进制序列化,多个短连接,适合消费者和提供者数量差不多,适用于文件的传输,一般较少用

3)Hessian协议

Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现

走Hessian序列化协议,多个短连接,适用于提供者数量比消费者数量还多,适用于文件的传输,一般较少用

4)Http协议

采用Spring的HttpInvoker实现

走json序列化

5)webservice

基于CXF的frontend-simple和transports-http实现

走SOAP文本序列化

dubbo支持的序列化协议

所以dubbo实际基于不同的通信协议,支持hessian、java二进制序列化、json、SOAP文本序列化多种序列化协议。但是hessian是其默认的序列化协议。

Dubbo本地存根(Stub)

  • 类似于Dubbo的静态代理
  • Dubbo会在客户端生成一个代理,处理部分业务
  • Stub必须有可传入的Proxy的构造函数

流程:

Dubbo入门

简单的调用

  • 引入依赖

父pom文件

<dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-bom</artifactId>
        <version>${dubbo.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>${dubbo.version}</version>
        <exclusions>
          <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
          </exclusion>
          <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
          </exclusion>
          <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
          </exclusion>
        </exclusions>
      </dependency>      

producer和concumer的 pom文件

<dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo</artifactId>
    </dependency>
    <!-- Zookeeper dependencies -->
    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-dependencies-zookeeper</artifactId>
      <version>${dubbo.version}</version>
      <type>pom</type>
      <exclusions>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
      </exclusions>
    </dependency>      
  • Dubbo和Zookeeper的简单配置

    concumer的properties配置文件

demo.service.version=1.0.0
#dubbo协议
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
#dubbo注册zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.registry.file=${user.home}/dubbo-cache/dubbo.cache      

producer的properties配置文件在此基础上还要加上一个Dubbo包扫描的配置

dubbo.scan.base-packages=com.liu.producer.service.impl      
  • 业务中producer的service实现类加@Service(version = "${demo.service.version}"),注意是Dubbo的service注解
  • 业务中producer的service实现类注入依赖时加 @Reference(version = "${demo.service.version}")
@Reference(version = "${demo.service.version}")
    CourseListService courseListService;