分布式服务框架 XXL-RPC
一、简介
1.1 概述
XXL-RPC 是一个分布式服务框架,提供稳定高性能的RPC远程服务调用功能。拥有”高性能、分布式、注册中心、负载均衡、服务治理”等特性。现已开放源代码,开箱即用。
1.2 特性
- 1、快速接入:接入步骤非常简洁,两分钟即可上手;
- 2、服务透明:系统完整的封装了底层通信细节,开发时调用远程服务就像调用本地服务,在提供远程调用能力时不损失本地调用的语义简洁性;
- 3、多调用方案:支持 SYNC、ONEWAY、FUTURE、CALLBACK 等方案;
- 4、多通讯方案:支持 TCP 和 HTTP 两种通讯方式进行服务调用;
- 5、多序列化方案:支持 HESSIAN、HESSIAN1 等方案;
- 6、负载均衡/软负载:提供丰富的负载均衡策略,包括:轮询、随机、LRU、LFU、一致性HASH等;
- 7、注册中心:可选组件,支持服务注册并动态发现(内置“轻量级注册中心 / 服务管心”(推荐)、“Local注册中心”等);可选择不启用,直接指定服务提供方机器地址通讯;
- 8、服务治理:提供服务治理中心,可在线管理注册的服务信息,如服务锁定、禁用等;
- 9、服务监控:可在线监控服务调用统计信息以及服务健康状况等(计划中);
- 10、容错:服务提供方集群注册时,某个服务节点不可用时将会自动摘除,同时消费方将会移除失效节点将流量分发到其余节点,提高系统容错能力。
- 11、
解决1+1问题:传统分布式通讯一般通过nginx或f5做集群服务的流量负载均衡,每次请求在到达目标服务机器之前都需要经过负载均衡机器,即1+1,
这将会把流量放大一倍。而XXL-RPC将会从消费方直达服务提供方,每次请求直达目标机器,从而可以避免上述问题; - 12、高兼容性:得益于优良的兼容性与模块化设计,不限制外部框架;除 spring/springboot 环境之外,理论上支持运行在任何Java代码中,甚至main方法直接启动运行;
- 13、泛化调用:服务调用方不依赖服务方提供的API;
1.3 背景
RPC(Remote Procedure Call Protocol,远程过程调用),调用远程服务就像调用本地服务,在提供远程调用能力时不损失本地调用的语义简洁性;
一般公司,尤其是大型互联网公司内部系统由上千上万个服务组成,不同的服务部署在不同机器,跑在不同的JVM上,此时需要解决两个问题:
- 1、如果我需要依赖别人的服务,但是别人的服务在远程机器上,我该如何调用?
- 2、如果其他团队需要使用我的服务,我该怎样发布自己的服务供他人调用?
“XXL-RPC”可以高效的解决这个问题:
- 1、如何调用:只需要知晓远程服务的stub和地址,即可方便的调用远程服务,同时调用透明化,就像调用本地服务一样简单;
- 2、如何发布:只需要提供自己服务的stub和地址,别人即可方便的调用我的服务,在开启注册中心的情况下服务动态发现,只需要提供服务的stub即可;
1.4 下载
源码仓库地址
源码仓库地址 | Release Download |
---|---|
https://github.com/xuxueli/xxl-rpc | Download |
https://gitee.com/xuxueli0323/xxl-rpc | Download |
1.5 环境
- Maven3+
- Jdk1.7+
- Tomcat7+
二、快速入门( springboot版本 + 轻量级注册中心 )
2.1 准备工作
解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下:
源码目录介绍: - /doc - /xxl-rpc-admin :轻量级服务(注册)中心,可选模块; - /xxl-rpc-core :核心依赖; - /xxl-rpc-samples :示例项目; - /xxl-rpc-sample-frameless :无框架版本示例; - /xxl-rpc-sample-springboot :springboot版本示例; - /xxl-rpc-sample-springboot-api :公共API接口 - /xxl-rpc-sample-springboot-client :服务消费方 invoker 调用示例; - /xxl-rpc-sample-springboot-server :服务提供方 provider 示例;
2.2 搭建部署 “服务(注册)中心”
推荐使用 “xxl-rpc-admin” 作为轻量级服务(注册)中心。非常轻量级,一分钟可完成部署工作。
注册中心为可选模块,可以不使用注册中心,也可以选型其他注册中心。
2.2.1 初始化“服务(注册)中心数据库”
请下载项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可。数据库初始化SQL脚本”位置为:
/xxl-rpc/doc/db/tables_xxl_rpc.sql
服务(注册)中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;如果mysql做主从,集群节点务必强制走主库;
2.2.2 配置部署“服务(注册)中心”
服务(注册)中心项目:xxl-rpc-admin 作用:一个轻量级分布式服务(注册)中心,拥有"轻量级、秒级注册上线、多环境、跨语言、跨机房"等特性。现已开放源代码,开箱即用。
步骤一:配置项目:
配置文件地址:
/xxl-rpc/xxl-rpc-admin/src/main/resources/application.properties
配置内容说明:
### 数据库配置 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_rpc?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai ### 服务注册数据磁盘同步目录 xxl.rpc.registry.data.filepath=/data/applogs/xxl-rpc/registrydata ### xxl-rpc, access token xxl.rpc.registry.accessToken= ### 登陆信息配置 xxl.rpc.registry.login.username=admin xxl.rpc.registry.login.password=123456
步骤二:部署项目:
如果已经正确进行上述配置,可将项目编译打包部署。
访问地址:http://localhost:8080/xxl-rpc-admin (该地址接入方项目将会使用到,作为注册地址),登录后运行界面如下图所示
至此“服务注册中心”项目已经部署成功。
步骤三:服务注册中心集群(可选):
服务注册中心支持集群部署,提升消息系统容灾和可用性。
集群部署时,几点要求和建议:
- DB配置保持一致;
- 登陆账号配置保持一致;
- 建议:推荐通过nginx为集群做负载均衡,分配域名。访问、客户端使用等操作均通过该域名进行。
其他:Docker 镜像方式搭建消息中心:
- 下载镜像
// Docker地址:https://hub.docker.com/r/xuxueli/xxl-rpc-admin/ docker pull xuxueli/xxl-rpc-admin
- 创建容器并运行
docker run -p 8080:8080 -v /tmp:/data/applogs --name xxl-rpc-admin -d xuxueli/xxl-rpc-admin /** * 如需自定义 mysql 等配置,可通过 "PARAMS" 指定,参数格式 RAMS="--key=value --key2=value2" ; * 配置项参考文件:/xxl-rpc/xxl-rpc-admin/src/main/resources/application.properties */ docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_rpc?Unicode=true&characterEncoding=UTF-8" -p 8080:8080 -v /tmp:/data/applogs --name xxl-rpc-admin -d xuxueli/xxl-rpc-admin
2.3 项目中使用XXL-RPC
以示例项目 “xxl-rpc-sample-springboot” 为例讲解;
2.3.1 开发“服务API”
开发RPC服务的 “接口 / interface” 和 “数据模型 / DTO”;
可参考如下代码: com.xxl.rpc.sample.api.DemoService com.xxl.rpc.sample.api.dto.UserDTO
2.3.2 配置开发“服务提供方”
- 1、配置 “maven依赖”:
需引入:XXL-RPC核心依赖 + 公共API接口依赖
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-rpc-core</artifactId> <version>${parent.version}</version> </dependency>
- 2、配置“服务提供方 ProviderFactory”
// 参考代码位置:com.xxl.rpc.sample.server.conf.XxlRpcProviderConfig @Bean public XxlRpcSpringProviderFactory xxlRpcSpringProviderFactory() { XxlRpcSpringProviderFactory providerFactory = new XxlRpcSpringProviderFactory(); providerFactory.setServer(NettyServer.class); providerFactory.setSerializer(HessianSerializer.class); providerFactory.setCorePoolSize(-1); providerFactory.setMaxPoolSize(-1); providerFactory.setIp(null); providerFactory.setPort(port); providerFactory.setAccessToken(null); providerFactory.setServiceRegistry(XxlRegistryServiceRegistry.class); providerFactory.setServiceRegistryParam(new HashMap<String, String>() {{ put(XxlRegistryServiceRegistry.XXL_REGISTRY_ADDRESS, address); put(XxlRegistryServiceRegistry.ENV, env); }}); logger.info(">>>>>>>>>>> xxl-rpc provider config init finish."); return providerFactory; }
ProviderFactory 参数 | 说明 |
---|---|
setServer | 服务通讯方案,可选范围:NettyServer(默认)、NettyHttpServer ; |
setSerializer | 序列化方案,可选范围: HessianSerializer(默认)、Hessian1Serializer ; |
setCorePoolSize | 业务线程池core大小 |
setMaxPoolSize | 业务线程是max大小 |
ip | 服务方IP,为空自动获取机器IP,支持手动指定 |
port | 服务方端口,默认 7080 |
accessToken | 服务鉴权Token,非空时生效; |
setServiceRegistry | 服务注册中心,可选范围:XxlRegistryServiceRegistry.class、LocalServiceRegistry.class;支持灵活自由扩展; |
setServiceRegistryParam | 服务注册中心启动参数,参数说明可参考各注册中心实现的 start() 的方法注释; |
- 3、开发“服务实现类”
实现 “服务API” 的接口,开发业务逻辑代码;
可参考如下代码: com.xxl.rpc.sample.api.DemoService 注意: 1、添加 “@Service” 注解:被Spring容器扫描识别为SpringBean; 2、添加 “@XxlRpcService” 注解:被 “XXL-RPC” 的 ProviderFactory 扫描识别,进行Provider服务注册,如果开启注册中心同时也会进行注册中心服务注册;
XxlRpcService 注解参数 | 说明 |
---|---|
version | 服务版本,默认空;可据此区分同一个“服务API” 的不同版本; |
2.3.3 配置开发“服务消费方”
- 1、配置 “maven依赖”:
需引入:XXL-RPC核心依赖 + 公共API接口依赖
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-rpc-core</artifactId> <version>${parent.version}</version> </dependency>
- 2、配置“服务消费方 InvokerFactory”
// 参考代码位置:com.xxl.rpc.sample.client.conf.XxlRpcInvokerConfig @Bean public XxlRpcSpringInvokerFactory xxlJobExecutor() { XxlRpcSpringInvokerFactory invokerFactory = new XxlRpcSpringInvokerFactory(); invokerFactory.setServiceRegistryClass(XxlRegistryServiceRegistry.class); invokerFactory.setServiceRegistryParam(new HashMap<String, String>(){{ put(XxlRegistryServiceRegistry.XXL_REGISTRY_ADDRESS, address); put(XxlRegistryServiceRegistry.ENV, env); }}); logger.info(">>>>>>>>>>> xxl-rpc invoker config init finish."); return invokerFactory; }
InvokerFactory 参数 | 说明 |
---|---|
serviceRegistryClass | 服务注册中心,可选范围:XxlRegistryServiceRegistry.class、LocalServiceRegistry.class;支持灵活自由扩展; |
serviceRegistryParam | 服务注册中心启动参数,参数说明可参考各注册中心实现的 start() 的方法注释; |
- 3、注入并实用远程服务
// 参考代码位置:com.xxl.rpc.sample.client.controller.IndexController @XxlRpcReference private DemoService demoService; …… UserDTO user = demoService.sayHi(name); ……
“@XxlRpcReference” 注解参数 | 说明 |
---|---|
client | 服务通讯方案,可选范围:NettyClient(默认)、NettyHttpClient ; |
serializer | 序列化方案,可选范围: HESSIAN(默认)、HESSIAN1; |
callType | 请求类型,可选范围:SYNC(默认)、ONEWAY、FUTURE、CALLBACK; |
loadBalance | 负载均衡类型,可选范围:ROUND(默认)、RANDOM、LRU、LFU、CONSISTENT_HASH; |
version | 服务版本,默认空;可据此区分同一个“服务API” 的不同版本; |
timeout | 服务超时时间,单位毫秒; |
address | 服务远程地址,ip:port 格式;选填;非空时将会优先实用该服务地址,为空时会从注册中心服务地址发现; |
accessToken | 服务鉴权Token,非空时生效; |
2.3.4 测试
// 参考代码位置:com.xxl.rpc.sample.client.controller.IndexController
代码中将上面配置的消费方 invoker 远程服务注入到测试 Controller 中使用,调用该服务,查看看是否正常。
如果正常,说明该接口项目通过XXL-RPC从 client 项目调用了 server 项目中的服务,夸JVM进行了一次RPC通讯。
访问该Controller地址即可进行测试:http://127.0.0.1:8081/?name=jack
三、快速入门( frameless 无框架版本 )
得益于优良的兼容性与模块化设计,不限制外部框架;除 spring/springboot 环境之外,理论上支持运行在任何Java代码中,甚至main方法直接启动运行;
以示例项目 “xxl-rpc-sample-frameless” 为例讲解;该示例项目以直连IP方式进行演示,也可以选择接入注册中心方式使用。
3.1 API方式创建“服务提供者”:
// 参考代码位置:com.xxl.rpc.sample.server.XxlRpcServerApplication // init XxlRpcProviderFactory providerFactory = new XxlRpcProviderFactory(); providerFactory.setServer(NettyServer.class); providerFactory.setSerializer(HessianSerializer.class); providerFactory.setCorePoolSize(-1); providerFactory.setMaxPoolSize(-1); providerFactory.setIp(null); providerFactory.setPort(7080); providerFactory.setAccessToken(null); providerFactory.setServiceRegistry(null); providerFactory.setServiceRegistryParam(null); // add services providerFactory.addService(DemoService.class.getName(), null, new DemoServiceImpl()); // start providerFactory.start(); while (!Thread.currentThread().isInterrupted()) { TimeUnit.HOURS.sleep(1); } // stop providerFactory.stop();
3.2 API方式创建“服务消费者”:
// 参考代码位置:com.xxl.rpc.sample.client.XxlRpcClientAplication // init client XxlRpcReferenceBean referenceBean = new XxlRpcReferenceBean(); referenceBean.setClient(NettyClient.class); referenceBean.setSerializer(HessianSerializer.class); referenceBean.setCallType(CallType.SYNC); referenceBean.setLoadBalance(LoadBalance.ROUND); referenceBean.setIface(DemoService.class); referenceBean.setVersion(null); referenceBean.setTimeout(500); referenceBean.setAddress("127.0.0.1:7080"); referenceBean.setAccessToken(null); referenceBean.setInvokeCallback(null); referenceBean.setInvokerFactory(null); DemoService demoService = (DemoService) referenceBean.getObject(); // test UserDTO userDTO = demoService.sayHi("[SYNC]jack"); System.out.println(userDTO);
四、系统设计
4.1 系统架构图
4.2 核心思想
提供稳定高性能的RPC远程服务调用功能,简化分布式服务通讯开发。
4.3 角色构成
- 1、provider:服务提供方;
- 2、invoker:服务消费方;
- 3、serializer: 序列化模块;
- 4、remoting:服务通讯模块;
- 5、registry:服务注册中心;
- 6、admin:服务治理、监控中心:管理服务节点信息,统计服务调用次数、QPS和健康情况;(非必选,暂未整理发布…)
4.4 RPC工作原理剖析
概念:
- 1、serialization:序列化,通讯数据需要经过序列化,从而支持在网络中传输;
- 2、deserialization:反序列化,服务接受到序列化的请求数据,需要序列化为底层原始数据;
- 3、stub:体现在XXL-RPC为服务的api接口;
- 4、skeleton:体现在XXL-RPC为服务的实现api接口的具体服务;
- 5、proxy:根据远程服务的stub生成的代理服务,对开发人员透明;
- 6、provider:远程服务的提供方;
- 7、consumer:远程服务的消费方;
RPC通讯,可大致划分为四个步骤,可参考上图进行理解:(XXL-RPC提供了多种调用方案,此处以 “SYNC” 方案为例讲解;)
- 1、consumer发起请求:consumer会根据远程服务的stub实例化远程服务的代理服务,在发起请求时,代理服务会封装本次请求相关
底层数据,如服务iface、methos、params等等,然后将数据经过serialization之后发送给provider; - 2、provider接收请求:provider接收到请求数据,首先会deserialization获取原始请求数据,然后根据stub匹配目标服务并调用;
- 3、provider响应请求:provider在调用目标服务后,封装服务返回数据并进行serialization,然后把数据传输给consumer;
- 4、consumer接收响应:consumer接受到相应数据后,首先会deserialization获取原始数据,然后根据stub生成调用返回结果,返回给请求调用处。结束。
4.5 TCP通讯模型
consumer和provider采用NIO方式通讯,其中TCP通讯方案可选NETTY具体选型,高吞吐高并发;但是仅仅依靠单个TCP连接进
行数据传输存在瓶颈和风险,因此XXL-RPC在consumer端自身实现了内部连接池,consumer和provider之间为了一个连接池,当尽
情底层通讯是会取出一条TCP连接进行通讯(可参考上图)。
4.6 sync-over-async
XXL-RPC采用NIO进行底层通讯,但是NIO是异步通讯模型,调用线程并不会阻塞获取调用结果,因此,XXL-RPC实现了在异步通讯模型上的同步调用,即“sync-over-async”,实现原理如下,可参考上图进行理解:
- 1、每次请求会生成一个唯一的RequestId和一个RpcResponse,托管到请求池中。
- 2、调度线程,执行RpcResponse的get方法阻塞获取本次请求结果;
- 3、然后,底层通过NIO方式发起调用,provider异步响应请求结果,然后根据RequestId寻找到本次调用的RpcResponse,设置响应结果后唤醒调度线程。
- 4、调度线程被唤醒,返回异步响应的请求数据。
4.7 注册中心
XXL-RPC的注册中心,是可选组件,支持服务注册并动态发现;
可选择不启用,直接指定服务提供方机器地址通讯;
选择启用时,内置可选方案:“XXL-RPC-ADMIN 轻量级服务注册中心”(推荐)、“ZK注册中心”、“Local注册中心”等;
a、XXL-RPC-ADMIN 轻量级服务注册中心(推荐)
推荐使用内置的 “XXL-RPC-ADMIN” 作为注册中心。非常轻量级,一分钟可完成部署工作。
更易于集群部署、横向扩展,搭建与学习成本更低,推荐采用该方式;
b、ZK注册中心
内置“ZK注册中心”,可选组件,结构图如下:
原理:
XXL-RPC中每个服务在zookeeper中对应一个节点,如图”iface
name”节点,该服务的每一个provider机器对应”iface
name”节点下的一个子节点,如图中”192.168.0.1:9999”、”192.168.0.2:9999”
和”192.168.0.3:9999”,子节点类型为zookeeper的EPHMERAL类型,该类型节点有个特点,当机器和zookeeper集群
断掉连接后节点将会被移除。consumer底层可以从zookeeper获取到可提供服务的provider集群地址列表,从而可以向其中一个机器发起
RPC调用。
4.8 在线服务目录
服务提供方新增 “/services” 服务目录功能,可查看在线服务列表;暂时仅针对NETTY_HTTP通讯方案,浏览器访问地址 “{端口地址}/services” 即可。
4.9 如何切换“通讯方案”选型
XXL-
RPC提供多中通讯方案:支持 TCP 和 HTTP 两种通讯方式进行服务调用;其中 TCP 提供可选方案 NETTY ,HTTP 提供可选方案
NETTY_HTTP (新版本移除了Mina和Jetty通讯方案,主推Netty;如果有需要可以参考旧版本;);
如果需要切换XXL-RPC“通讯方案”,只需要执行以下两个步骤即可:
- a、引入通讯依赖包,排除掉其他方案依赖,各方案依赖如下:
- NETTY:依赖 netty-all ;
- NETTY_HTTP:依赖 netty-all ;
- b、修改通讯枚举,需要同时在“服务方”与“消费方”两端一同修改,通讯枚举属性代码位置如下:
- 服务工厂 “XxlRpcSpringProviderFactory.netType” :可参考springboot示例组件初始化代码;
- 服务引用注解 “XxlRpcReference.netType” | 服务Bean对象 “XxlRpcReferenceBean.netType” :可参考springboot示例组件初始化代码;
4.10 如何切换“注册中心”选型
XXL-RPC的注册中心,是一个可选组件,不强制依赖;支持服务注册并动态发现;
可选择不启用,直接指定服务提供方机器地址通讯;
选择启用时,原生提供多种开箱即用的注册中心可选方案,包括:“XXL-RPC原生轻量级注册中心”、“ZK注册中心”、“Local注册中心”等;
如果需要切换XXL-RPC“注册中心”,只需要执行以下两个步骤即可:
- a、引入注册注册中心依赖包,排除掉其他方案依赖,各方案依赖如下:
- XXL-RPC原生轻量级注册中心:轻量级、无第三方依赖;
- ZK注册中心:依赖 zookeeper
- Local注册中心:轻量级、零依赖;
- b、修改注册中心配置,需要同时在“服务方”与“消费方”两端一同修改,代码位置如下:
- XxlRpcSpringProviderFactory.serviceRegistryClass:注册中心实现类,可
选:XxlRegistryServiceRegistry.class、LocalServiceRegistry.class、
ZkServiceRegistry.class - XxlRpcSpringProviderFactory.serviceRegistryParam:注册中心启动参数,各种注册中心启动参数不同,可参考其 start 方案了解;
- XxlRpcSpringProviderFactory.serviceRegistryClass:注册中心实现类,可
4.11 泛化调用
XXL-RPC 提供 “泛化调用” 支持,服务调用方不依赖服务方提供的API;泛化调用通常用于框架集成,比如 “网关平台、跨语言调用、测试平台” 等;
开启 “泛化调用” 时服务方不需要做任何调整,仅需要调用方初始化一个泛化调用服务Reference (”XxlRpcGenericService”) 即可。
“XxlRpcGenericService#invoke” 请求参数 | 说明 |
---|---|
String iface | 服务接口类名 |
String version | 服务版本 |
String method | 服务方法 |
String[] parameterTypes | 服务方法形参-类型,如 “int、java.lang.Integer、java.util.List、java.util.Map …” |
Object[] args | 服务方法形参-数据 |
// 服务Reference初始化-注解方式示例 @XxlRpcReference private XxlRpcGenericService genericService; // 服务Reference初始化-API方式示例 XxlRpcGenericService genericService = (XxlRpcGenericService) new XxlRpcReferenceBean(……).getObject(); // 调用方示例 Object result = genericService.invoke( "com.xxl.rpc.sample.server.service.Demo2Service", null, "sum", new String[]{"int", "int"}, new Object[]{1, 2} ); // 服务方示例 public class Demo2ServiceImpl implements Demo2Service { @Override public int sum(int a, int b) { return a + b; } }
五、分布式服务(注册)中心详解
5.1 概述
XXL-RPC-ADMIN(原XXL-REGISTRY) 是一个轻量级分布式服务注册中心,拥有”轻量级、秒级注册上线、多环境、跨语言、跨机房”等特性。现已开放源代码,开箱即用。
5.2 特性
- 1、轻量级:基于DB与磁盘文件,只需要提供一个DB实例即可,无第三方依赖;
- 2、实时性:借助内部广播机制,新服务上线、下线,可以在1s内推送给客户端;
- 3、数据同步:注册中心会定期全量同步数据至磁盘文件,清理无效服务,确保服务数据实时可用;
- 4、性能:服务发现时仅读磁盘文件,性能非常高;服务注册、摘除时通过磁盘文件校验,防止重复注册操作;
- 5、扩展性:可方便、快速的横向扩展,只需保证服务注册中心配置一致即可,可借助负载均衡组件如Nginx快速集群部署;
- 6、多状态:服务内置三种状态:
- 正常状态=支持动态注册、发现,服务注册信息实时更新;
- 锁定状态=人工维护注册信息,服务注册信息固定不变;
- 禁用状态=禁止使用,服务注册信息固定为空;
- 7、跨语言:注册中心提供HTTP接口(RESTFUL 格式)供客户端实用,语言无关,通用性更强;
- 8、兼容性:项目立项之初是为XXL-RPC量身设计,但是不限于XXL-RPC使用。兼容支持任何服务框架服务注册实用,如dubbo、springboot等;
- 9、跨机房:得益于服务注册中心集群关系对等特性,集群各节点提供幂等的配置服务;因此,异地跨机房部署时,只需要请求本机房服务注册中心即可,实现异地多活;
- 10、容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现 “服务注册中心” 产品开箱即用;
- 11、访问令牌(accessToken):为提升系统安全性,注册中心和客户端进行安全性校验,双方AccessToken匹配才允许通讯;
5.3 “服务(注册)中心 xxl-rpc-admin” 快速入门
可参考章节:2.2 搭建部署 “服务(注册)中心”
5.4 接入 “服务注册中心” 示例
a、Java语言项目接入示例
XXL-RPC默认将 “XXL-RPC-ADMIN” 作为原生注册中心。其他Java服务框架。
其他Java服务框架,如dubbo、springboot等,建议参考 XXL-RPC 提供的实例项目;
b、非Java语言项目接入;
非Java语言项目,可以借助提供的 RESTFUL 格式API接口实现服务注册与发现功能。
5.5 注册中心 RESTful API
服务注册中心为支持服务注册与发现功能,提供的 RESTful 格式API接口如下:
5.5.1、服务注册 & 续约 API
说明:新服务注册上线1s内广播通知接入方;需要接入方循环续约,否则服务将会过期(三倍于注册中心心跳时间)下线;
地址格式:{服务注册中心跟地址}/registry 请求参数说明: 1、accessToken:请求令牌; 2、biz:业务标识 2、env:环境标识 3、registryDataList:服务注册信息 请求数据格式如下,放置在 RequestBody 中,JSON格式: { "accessToken" : "xx", "biz" : "xx", "env" : "xx", "registryDataList" : [{ "key" : "service01", "value" : "address01" }] }
5.5.2、服务摘除 API
说明:新服务摘除下线1s内广播通知接入方;
地址格式:{服务注册中心跟地址}/remove 请求参数说明: 1、accessToken:请求令牌; 2、biz:业务标识 2、env:环境标识 3、registryDataList:服务注册信息 请求数据格式如下,放置在 RequestBody 中,JSON格式: { "accessToken" : "xx", "biz" : "xx", "env" : "xx", "registryDataList" : [{ "key" : "service01", "value" : "address01" }] }
5.5.3、服务发现 API
说明:查询在线服务地址列表;
地址格式:{服务注册中心跟地址}/discovery 请求参数说明: 1、accessToken:请求令牌; 2、biz:业务标识 2、env:环境标识 3、keys:服务注册Key列表 请求数据格式如下,放置在 RequestBody 中,JSON格式: { "accessToken" : "xx", "biz" : "xx", "env" : "xx", "keys" : [ "service01", "service02" ] }
5.5.4、服务监控 API
说明:long-polling 接口,主动阻塞一段时间(三倍于注册中心心跳时间);直至阻塞超时或服务注册信息变动时响应;
地址格式:{服务注册中心跟地址}/monitor 请求参数说明: 1、accessToken:请求令牌; 2、biz:业务标识 2、env:环境标识 3、keys:服务注册Key列表 请求数据格式如下,放置在 RequestBody 中,JSON格式: { "accessToken" : "xx", "biz" : "xx", "env" : "xx", "keys" : [ "service01", "service02" ] }
5.6 服务中心系统设计
5.6.1 系统架构图
5.6.2 原理解析
内部通过广播机制,集群节点实时同步服务注册信息,确保一致。客户端借助 long pollong 实时感知服务注册信息,简洁、高效;
5.6.3 跨机房(异地多活)
得益于服务注册中心集群关系对等特性,集群各节点提供幂等的服务注册服务;因此,异地跨机房部署时,只需要请求本机房服务注册中心即可,实现异地多活;
举个例子:比如机房A、B 内分别部署服务注册中心集群节点。即机房A部署 a1、a2 两个服务注册中心服务节点,机房B部署 b1、b2 两个服务注册中心服务节点;
那么各机房内应用只需要请求本机房内部署的服务注册中心节点即可,不需要跨机房调用。即机房A内业务应用请求 a1、a2 获取配置、机房B内业务应用 b1、b2 获取配置。
这种跨机房部署方式实现了配置服务的 “异地多活”,拥有以下几点好处:
- 1、注册服务响应更快:注册请求本机房内搞定;
- 2、注册服务更稳定:注册请求不需要跨机房,不需要考虑复杂的网络情况,更加稳定;
- 2、容灾性:即使一个机房内服务注册中心全部宕机,仅会影响到本机房内应用加载服务,其他机房不会受到影响。
5.6.4 一致性
类似 Raft 方案,更轻量级、稳定;
- Raft:Leader统一处理变更操作请求,一致性协议的作用具化为保证节点间操作日志副本(log replication)一致,以term作为逻辑时钟(logical clock)保证时序,节点运行相同状态机(state machine)得到一致结果。
- 本项目:
- Leader(统一处理分发变更请求):DB消息表(仅变更时产生消息,消息量较小,而且消息轮训存在间隔,因此消息表压力不会太大;);
- state machine(顺序操作日志副本并保证结果一直):顺序消费消息,保证本地数据一致,并通过周期全量同步进一步保证一致性;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: ES6 知识点
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论