• Dubbo(二)Dubbo和ZooKeeper的协同工作原理


    Dubbo和ZooKeeper是如何协同工作的?

    文章目录

    Dubbo

    • 通过RPC的方式实现服务调用

    • 通过简单实现理解原理:

      Client和Server共用一个接口,将接口打成一个jar包,在客户端和服务端引入这个jar包,Client端面向接口写调用,Server端面向接口写实现,中间的网络通信交给Dubbo框架去实现。

    以下是黄字叙述内容:“点对点RPC”的实现细节

    1.服务提供者-配置

    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    加载Spring配置

    public class Provider {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
            context.start();
            System.in.read(); // 按任意键退出
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.服务消费者-配置

    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    加载Spring配置,并调用远程服务

    public class Consumer {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
            context.start();
            // 获取远程服务代理
            DemoService userService = (DemoService)context.getBean("userService");
            // 执行远程方法
            String hello = userService.sayHello("world");
            // Hello world
            System.out.println( hello );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    负载均衡

    以上就是典型的点对点的服务调用,假如在未指定zookeeper注册中心时,Client和Server端的配置文件部分如下

    
    
    
    • 1
    • 2

    此时,若我们为了高可用,可以:

    • 配置多个服务提供者;
    • consumer.xml中配置多个服务调用者,在标签的url属性中加入多个地址,中间用分号隔开即可配置负载均衡策略在consumer.xml的dubbo:reference标签中增加loadbalance属性即可,属性值可以为如下四种:

    1. 随机 + 权重(random)

    1. 计算服务Provider的总权重,并维护一个前缀和数组;
    2. 基于第一步的结果,在0~总权重 之间生成一个随机数;
    3. 随机数得到一个权重,遍历前缀和数组,找到第一个比随机权重大的位置,即可确定选择的服务Provider;
    4. 如果所有服务提供者节点都没有分配权重,或者分配的权重都一样,那么就采用随机的选择一个服务提供者节点;

    2.轮询 + 权重(roundrobin)

    1. 计算服务提供者的总权重。
    2. 每个服务提供者除了始终不变的固定权重以外,需要记录服务提供者当前权重。
    3. 每次请求,更新所有的服务提供者的当前权重,当前权重 = 当前权重 + 固定权重。
    4. 从上一步得到的结果中,选择一个当前权重最大的服务提供者用于处理请求,如果存在多个,那么就看遍历的过程中先遇到哪个服务提供者就是哪一个。并且,选中的权重最大的服务提供者更新其当前权重 = 当前权重 - 总权重

    3.最少连接(leastactive)

    1. Client存在一个计数器,记录当前通过某个Server提供者的请求还未完成的总数;
    2. 选择计数最少的那个用于处理当前请求, 将计数器+1;
    3. 如果存在多个相同的计数,那么使用随机+权重的方式选取;
    4. 否则从多个最少的服务提供者当中随机的选择一个处理当前请求;

    4.一致性Hash(ConsistentHash)

    一致性Hash,相同参数的请求总是发到同一提供者;

    consumer.xml中生成接口的远程代理如下:

    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    现在整体架构如下图(假设consumer为订单服务,provider为用户服务)

    图解Dubbo和ZooKeeper是如何协同工作的?

    此时会有什么问题?

    1. 当服务器增加服务节点时,需要修改配置文件;
    2. 当其中一个服务Provider宕机时,consumer不能及时感知到,还会往宕机的服务发送请求;

    这是后就需要引入zookeeper注册中心了!

    ZooKeeper注册中心

    zookeeper注册中心实现注册的大致流程如下图:

    图解Dubbo和ZooKeeper是如何协同工作的?

    对照上图来看Dubbo官网上的Dubbo框架图,是不是觉得和上图很类似?zookeeper是被选来作为Dubbo框架中的注册中心。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pwYKV8qn-1650879464231)(https://dubbo.apache.org/imgs/architecture.png)]

    节点

    角色说明

    Provider

    暴露服务的服务提供方

    Consumer

    调用远程服务的服务消费方

    Register

    服务注册与发现的注册中心

    Monitor

    统计服务的调用次数和调用时间的监控中心

    Container

    服务运行容器

    调用关系说明

    • Container负责启动(上面的容器为Spring容器),加载,运行服务提供者;
    • 服务提供者在启动时,向注册中心注册自己提供的服务;
    • 服务消费者在启动时,向注册中心订阅自己所需的服务;
    • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者;
    • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选择一台提供者进行调用,如果调用失败,再选另一个台调用;
    • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

    回归之前的问题,如要使用注册中心,只需要将provider.xml和consumer.xml恢复为如下:

    
    
    
    • 1
    • 2

    如果zookeeper是一个集群,则多个地址之间逗号分隔即可:

    
    
    • 1

    将consumer.xml中配置的直连的方式去掉

    
    
    
    
    • 1
    • 2
    • 3

    启动上述服务后,我们观察在zookeeper的根节点多了一个dubbo节点,如下图(树状存储)

    图解Dubbo和ZooKeeper是如何协同工作的?

    最后一个节点中192.168.1.104是我的内网地址,绿色代表临时节点,而其他节点是持久节点,这样,当服务宕机时,这个节点就会自动消失,不在提供服务,服务消费者也不会载请求。若部署多个Service,则Provider下面会有好几个节点,一个节点保存一个Service的服务地址。

  • 相关阅读:
    七月论文审稿GPT第4.5版:通过15K条paper-review数据微调Llama2 70B(含各种坑)
    AD教程 (十八)导入常见报错解决办法(unkonw pin及绿色报错等)
    程序猿的中秋原来可以这样过
    Spring Boot文档阅读笔记-Scheduling Tasks
    Matlab|模拟电动汽车的充放电【充电顺序,波动发电,电池缓冲】
    【PyTorch】PyTorch中张量(Tensor)统计操作
    HUAWEI华为MateBook X Pro 2021款 i7 集显(MACHD-WFE9Q)原装出厂Win10系统20H2
    Sulfo CY3-NH2生物分析和检测方法2183440-43-7星戈瑞
    【踩坑记录】Elasticsearch查询:circuit_breaking_exception异常解决方案
    .Net Core后端架构实战【1-项目分层框架设计】
  • 原文地址:https://blog.csdn.net/m0_67391683/article/details/126327818