Dubbo(开源分布式服务框架)

    科技2024-12-01  14

    Dubbo(开源分布式服务框架)

    Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。

    Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

    分布式系统

    分布式系统时若干独立计算机的聚合,这些计算机对用户来说就像是单个相关系统。

    主要核心部件

    Remoting: 网络通信框架,实现了 sync-over-async 和

    ​ request-response 消息机制. RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能 Registry: 服务目录框架用于服务的注册和服务事件发布和订阅

    工作原理

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

    调用关系说明

    服务容器负责启动,加载,运行服务提供者。

    服务提供者在启动时,向注册中心注册自己提供的服务。

    服务消费者在启动时,向注册中心订阅自己所需的服务。

    注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

    服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

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

    特点

    连通性

    注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

    健壮性

    监控中心宕掉不影响使用,只是丢失部分采样数据数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务注册中心对等集群,任意一台宕掉后,将自动切换到另一台注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯服务提供者无状态,任意一台宕掉后,不影响使用服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

    伸缩性

    注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

    升级性

    当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力。

    实践

    Zookeeper环境搭建

    官网下载zookeeper安装包

    解压后,配置配置文件

    dataDir=…/data 临时数据存放在根目录的data文件夹下

    clientPort=2181 端口为2181

    # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=../data # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature #autopurge.purgeInterval=1

    启动zkServer.cmd和zkCli.cmd测试是否成功

    安装监控中心

    到dubbo的github上找到Dubbo Admin下载

    解压检查配置zookeeper的地址后,打包dubbo-admin

    运行打包好的jar包

    访问localhost:7001

    编写程序测试

    抽离bean和interface

    创建服务提供者

    pom

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>gmalldubbo</artifactId> <groupId>com.tom</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user-service-provider</artifactId> <dependencies> <dependency> <groupId>com.tom</groupId> <artifactId>gmall-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> <scope>compile</scope> </dependency> <!--引入dubbo--> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!--注册中心zookeeper,引入操作zookeeper的客户端--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies> </project>

    UserServiceImpl

    模拟服务

    public class UserServiceImpl implements UserService { public List<UserAddress> getUserAddressList(String userId) { UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y"); UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N"); return Arrays.asList(address1,address2); } }

    provider.xml

    配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" > <!--1.指定当前服务/应用的名字--> <dubbo:application name="user-service-provider"/> <!--2.指定注册中心位置--> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <!--3.指定通信规则(通信协议,通信端口)--> <dubbo:protocol name="dubbo" port="20880"/> <!--4.暴露服务--> <dubbo:service interface="com.tom.gmall.service.UserService" ref="userServiceImpl"/> <!--服务的实现--> <bean id="userServiceImpl" class="com.tom.gmall.service.impl.UserServiceImpl"/> </beans>

    main

    启动服务提供方的方法

    public class MainApplication { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml"); ioc.start(); System.in.read(); } }

    运行main方法

    创建服务消费者

    pom

    参考provider的pom

    OrderServiceImpl

    模拟调用UserService

    @Service public class OrderServiceImpl implements OrderService { @Autowired UserService userService; public void initOrder(String userId) { //1.查询用户的收货地址 System.out.println("用户id:"+ userId); List<UserAddress> userAddressList = userService.getUserAddressList(userId); for (UserAddress userAddress : userAddressList) { System.out.println(userAddress.getUserAddress()); } } }

    consumer.xml

    配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.tom.gmall.service.impl"/> <dubbo:application name="order-service-consumer"/> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <!--声明需要调用远程服务的接口--> <dubbo:reference interface="com.tom.gmall.service.UserService" id="userService"/> </beans>

    main

    启动服务消费者方法

    public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml"); OrderService orderService = applicationContext.getBean(OrderService.class); orderService.initOrder("1"); System.out.println("调用完成"); System.in.read(); }

    运行截图(先启动服务提供者的main方法)

    监控中心Simple Monitor

    打包解压dubbo-monitor-simple

    修改配置文件

    dubbo.container=log4j,spring,registry,jetty-monitor dubbo.application.name=simple-monitor dubbo.application.owner=dubbo #配置注册中心地址和端口 #dubbo.registry.address=multicast://224.5.6.7:1234 dubbo.registry.address=zookeeper://127.0.0.1:2181 #dubbo.registry.address=redis://127.0.0.1:6379 #dubbo.registry.address=dubbo://127.0.0.1:9090 dubbo.protocol.port=7070 dubbo.jetty.port=8081 dubbo.jetty.directory=${user.home}/monitor dubbo.charts.directory=${user.home}/monitor/charts dubbo.statistics.directory=${user.home}/monitor/statistics dubbo.log4j.file=logs/dubbo-monitor-simple.log dubbo.log4j.level=WARN

    启动监控中心

    启动成功

    配置服务提供者和服务消费者的监控中心

    <!--监控中心,自动发现--> <dubbo:monitor protocol="registry"/> <!-- <dubbo:monitor address="127.0.0.1:7070"/> -->

    浏览器访问

    整合SpringBoot

    注解

    服务提供者

    导入dubbo-spring-boot-starter

    配置文件参考provider.xml

    暴露服务

    ​ 1.@Service注解,注意是dubbo的Service注解。

    ​ 2.主程序中添加**@EnableDubbo**注解,开启基于注解的dubbo功能

    服务消费者

    导入dubbo-spring-boot-starter

    配置文件参考consumer.xml

    引用服务

    ​ 1.@Reference注解,注册中心引用远程服务。

    ​ 2.主程序中添加**@EnableDubbo**注解。

    三种方式整合SpringBoot

    导入dubbo-starter,在application.properties配置属性,使用@Service【暴露服务】使用@Reference【引用】保留dubbo.xml配置文件,使用@ImportResource导入dubbo的配置文件使用注解API的方式,将每一个组件手动创建到容器中。

    其他常用配置

    启动时检查、超时、重试次数、多版本、本地存根等参考官方文档

    学习记录用,若有错误望海涵

    Processed: 0.011, SQL: 8