• Dubbo实现RPC


    Apache Dubbo

    认识dubbo

    一款rpc框架,用于解决微服务架构下服务治理和通信问题。

    服务治理:服务发现、负载均衡、流量调度)

    RPC:远程调用的一种技术概念,封装寻址和网络通信的细节,实现像本地方法调用一样的模式。

    一次RPC调用过程:

    consumer 网络通信 producer 请求对象序列化、编码 解码、反序列化 调用本地服务处理请求 处理结果序列化、编码 响应对象解码、反序列化 consumer 网络通信 producer
    实现RPC 的关键
    1. 代理

    2. 序列化与反序列化:对象无法在网络中传输,需要转成二进制数据,此为序列化

    3. 编码和解码

    4. 网络通信:IO

    RPC通信协议

    三种协议形式

    • 固定长度形式:每次读取固定长度解析

    • 特殊字符隔断形式:根据特殊字符来判断读取协议单元结束

    • header + body 形式:先解析头部,根据头部得到 body 的长度再解析 body

    dubbo采用的是header + body 形式的协议,同时使用特殊字符,解决网络粘包问题

    dubbo支持协议
    • dubbo 协议 (默认)

      • 连接个数:单连接
      • 连接方式:长连接
      • 传输协议:TCP
      • 传输方式:NIO 异步传输
      • 序列化:Hessian 二进制序列化
      • 适用范围:传入传出参数数据包较小(建议小于 100 K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。
      • 适用场景:常规远程服务方法调用
    • rmi 协议

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

      • 连接个数:多连接
      • 连接方式:短连接
      • 传输协议:TCP
      • 传输方式:同步传输
      • 序列化:Java 标准二进制序列化
      • 适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。
      • 适用场景:常规远程服务方法调用,与原生RMI服务互操作
    • hessian 协议

      • 连接个数:多连接
      • 连接方式:短连接
      • 传输协议:HTTP
      • 传输方式:同步传输
      • 序列化:Hessian二进制序列化
      • 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
      • 适用场景:页面传输,文件传输,或与原生hessian服务互操作
    • gRPC协议

    • http 协议

      基于 HTTP 表单的远程调用协议

      • 连接个数:多连接
      • 连接方式:短连接
      • 传输协议:HTTP
      • 传输方式:同步传输
      • 序列化:表单序列化
      • 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
      • 适用场景:需同时给应用程序和浏览器 JS 使用的服务
    • webservice 协议

      • 连接个数:多连接
      • 连接方式:短连接
      • 传输协议:HTTP
      • 传输方式:同步传输
      • 序列化:SOAP 文本序列化
      • 适用场景:系统集成,跨语言调用
    • thrift 协议

      适用于 SOA 标准 RPC 框架

    • memcached 协议

    • redis 协议

    • rest 协议

      基于标准的 Java REST API - JAX-RS 2.0Java API for RESTful Web Services 的简写)实现的 REST 调用支持

    经典架构图

    在这里插入图片描述

    节点角色说明
    Provider暴露服务的服务提供方
    Consumer调用远程服务的服务消费方
    Registry服务注册与发现的注册中心
    Monitor统计服务的调用次数和调用时间的监控中心
    Container服务运行容器
    相关组件
    • 注册中心

    使用zookeeper(或Nacos)作为注册中心,协调consumerproducer之间地址的注册与发现

    • 配置中心

    使用zookeeper(或Nacos)作为配置中心

    存储dubbo启动阶段的全局配置,保证配置的跨环境共享与全局一致性

    负责服务治理规则(路由规则、动态配置)的存储与推送

    • 元数据中心

    使用zookeeper(或Nacos)作为元数据中心

    接收producer上报的服务接口元数据,为admin等控制台提供运维能力

    代码示例

    1.准备zookeeper,配置中心,dubbo需要与zookeeper搭配使用

    2.创建聚合工程 springboot 项目

    (1)父pom依赖

    <modules>
            <module>dubbo-producermodule>
            <module>dubbo-consumermodule>
        modules>
    <properties>
            <spring-boot.version>2.1.4.RELEASEspring-boot.version>
            <dubbo.version>3.0.7dubbo.version>
        properties>
    <dependencyManagement>
       <dependencies>
               <dependency>
                   <groupId>org.springframework.bootgroupId>
                   <artifactId>spring-boot-dependenciesartifactId>
                   <version>${spring-boot.version}version>
                   <type>pomtype>
                   <scope>importscope>
               dependency>
    
               <dependency>
                   <groupId>org.apache.dubbogroupId>
                   <artifactId>dubbo-bomartifactId>
                   <version>${dubbo.version}version>
                   <type>pomtype>
                   <scope>importscope>
               dependency>
    
               <dependency>
                   <groupId>org.apache.dubbogroupId>
                   <artifactId>dubbo-dependencies-zookeeperartifactId>
                   <version>${dubbo.version}version>
                   <type>pomtype>
               dependency>
    
       dependencies>
    dependencyManagement>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.创建子模块producer module

    (1)pom依赖

    <dependencies>
            
            <dependency>
                <groupId>org.apache.dubbogroupId>
                <artifactId>dubboartifactId>
            dependency>
            <dependency>
                <groupId>org.apache.dubbogroupId>
                <artifactId>dubbo-dependencies-zookeeperartifactId>
                <type>pomtype>
            dependency>
    
            
            <dependency>
                <groupId>org.apache.dubbogroupId>
                <artifactId>dubbo-spring-boot-starterartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starterartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-autoconfigureartifactId>
            dependency>
    
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    (2)配置

    server.port=9090
    dubbo.application.name=dubbo-producer
    
    dubbo.protocol.name=dubbo
    dubbo.protocol.id=-1
    
    dubbo.registry.id=zk-registry
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    
    dubbo.config-center.address=zookeeper://127.0.0.1:2181
    dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (3)定义服务接口

    public interface DemoService {
        String sayHello(String name);
    }
    
    • 1
    • 2
    • 3

    (4)实现接口具体方法

    实现类需要加@DubboService注解

    @DubboService
    public class DemoServiceImpl implements DemoService {
        @Override
        public String sayHello(String name) {
            System.out.println("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
            return "Hello " + name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (5)主程序类

    使用@EnableDubbo注解

    @EnableDubbo
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    public class DubboProducerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DubboProducerApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.创建子模块consumer module

    (1)pom依赖

    <dependencies>
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubboartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-dependencies-zookeeperartifactId>
            <type>pomtype>
        dependency>
    
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
        dependency>
    
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-autoconfigureartifactId>
        dependency>
    
        
        <dependency>
            <groupId>com.examplegroupId>
            <artifactId>dubbo-producerartifactId>
            <version>0.0.1-SNAPSHOTversion>
            <scope>compilescope>
        dependency>
    
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    (2)配置

    server.port=9091
    dubbo.application.name=dubbo-consumer
    
    dubbo.protocol.name=dubbo
    dubbo.protocol.id=-1
    
    dubbo.registry.id=zk-registry
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    
    dubbo.config-center.address=zookeeper://127.0.0.1:2181
    dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (3)引用远程服务接口

    使用@DubboReference注解,引用远程服务接口

    @RestController
    @RequestMapping("/consumer")
    @Slf4j
    public class TestController {
        @DubboReference
        private DemoService demoService;
    
        @RequestMapping("/user/{id}")
        public String getProduceService() {
            demoService.sayHello("I am consumer");
            return "get producer back success";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    (4)主程序类

    使用@EnableDubbo注解

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    @EnableDubbo
    public class DubboConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DubboConsumerApplication.class, args);
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.测试

    请求接口http://localhost:9091/consumer/user/1,返回:

    在这里插入图片描述

    与此同时,服务端打印请求日志

    Hello I am consumer, request from consumer: /ip:61544
    
    • 1
  • 相关阅读:
    计算机毕业论文选题Python毕业设计基于Python实现的职业推荐系统[包运行成功]
    如何给16进制的色值设置透明度
    写一个简易的spring包含ioc和aop功能
    当客户说价格高时我会这样做
    API安全实战
    SpringMVC获得请求数据类型
    详解KubeEdge EdgeMesh v1.15 边缘CNI特性
    2020年初全国行政区划矢量数据
    分享几个Linux几个有趣且实用的命令
    【ceph】ceph集群的节点机器重启,导致磁盘的lvm消失,如何恢复呢~~满满的都是干货
  • 原文地址:https://blog.csdn.net/Wang_Dong_Liang/article/details/127804457