从零开始实现简单 RPC 框架 3:配置总线 URL
URL 的定义
URL 对于大部分程序猿来说都是很熟悉的,其全称是 Uniform Resource Locator (统一资源定位器)。它是互联网的统一资源定位标志,也就是指网络地址。
一个标准的 URL 格式可以包含如下的几个部分:
protocol://username:password@host:port/path?key1=value1&key2=value2
- protocol:协议,例如 http 协议
- username/password:用户名/密码
- host/port:主机/端口
- path:请求路径
- parameters:参数键值对
为什么使用 URL
在 ccx-rpc 中,URL 可以理解为配置总线。所有扩展点参数都包含 URL 参数,URL 作为上下文信息贯穿整个扩展点设计体系。
在没有 URL 之前,参数传递有时候是字符串类型,有时候是 Map 类型,又有时候是对象:
doSomething(String param1, String param2);
doSomething2(Map<String,String> params);
doSomething3(Parameters params);
使用 URL 一致性模型:
doSomething(URL url);
doSomething2(URL url);
doSomething3(URL url);
使用 URL 统一配置模型的好处:
- 形成代码规范,多作者编写和读者都能以同一种标准编写/阅读代码,提供效率。
- 可扩展性强,URL 相当于参数的集合(
key1=value1&key2=value2),当我们在扩展代码时,可以将新的参数追加到 URL 中,不需要改变出入参。
ccx-rpc 中的应用
1. SPI 适配扩展
SPI 的适配方法,使用 @Adaptive 注解标注,同时参数必须包含 URL。在生成扩展类的时候,加载器会从 URL 中提取 @Adaptive 注解配置的参数对应的值。
以注册中心扩展类工厂为例:
@SPI
public interface RegistryFactory {
/**
* 获取注册中心
*
* @param url 注册中心的配置,例如注册中心的地址。会自动根据协议获取注册中心实例
* @return 如果协议类型跟注册中心匹配上了,返回对应的配置中心实例
*/
@Adaptive("protocol")
Registry getRegistry(URL url);
}
public static void main(String[] args) {
// 获取适配扩展
RegistryFactory zkRegistryFactory = ExtensionLoader.getLoader(RegistryFactory.class).getAdaptiveExtension();
URL url = URLParser.toURL("zk://localhost:2181");
// 适配扩展自动从 ur 中解析出扩展名,然后返回对应的扩展类
Registry registry = zkRegistryFactory.getRegistry(url);
}
URL 是 zk://localhost:2181, SPI Adaptive 会自动从 URL 中获取协议类型 zk,然后从 Registry 的实现类中找到对应的 ZkRegistry。
2. 暴露服务
服务提供方想注册中心注册服务的时候,是通过 URL 注册。其格式大致如下:
zk://192.168.10.11:1234/com.ccx.rpc.core.test.registry.ZkRegistryTest?methods=test1
注册中心接口中的注册方法:
public interface Registry {
/**
* 向注册中心注册服务
*
* @param url 注册者的信息
*/
void register(URL url);
zk 拿到 URL 之后,从中解析出接口 com.ccx.rpc.core.test.registry.ZkRegistryTest,为其创建一个节点,下面再放提供者的信息。
3. 引用服务
服务引用方,从注册中心拿到的服务信息就是提供方注册的信息。
zk://192.168.10.11:1234/com.ccx.rpc.core.test.registry.ZkRegistryTest?methods=test1
然后引用方从 URL 中解析出服务的地址:192.168.10.11:1234,接着就可以通过地址直连服务提供方了。
public interface Registry {
/**
* 查找注册的服务
*
* @param condition 查询条件
* @return 符合查询条件的所有注册者
*/
List<URL> lookup(URL condition);
}
总结
URL 在 ccx-rpc 中发挥了配置总线的作用,其应用也不仅仅只是上面提到的。
统一配置模型类似于契约,在开发中,沟通是一件很麻烦的事情,统一模型可以省去很多沟通成本,这就是 URL 统一配置模型存在的意义。
从零开始实现简单 RPC 框架 3:配置总线 URL的更多相关文章
- 从零开始实现简单 RPC 框架 2:扩展利器 SPI
RPC 框架有很多可扩展的地方,如:序列化类型.压缩类型.负载均衡类型.注册中心类型等等. 假设框架提供的注册中心只有zookeeper,但是使用者想用Eureka,修改框架以支持使用者的需求显然不是 ...
- 从零开始实现简单 RPC 框架 5:网络通信之序列化
我们在接下来会开始讲网络通信相关的内容了.既然是网络通信,那必然会涉及到序列化的相关技术. 下面是 ccx-rpc 序列化器的接口定义. /** * 序列化器 */ public interface ...
- 从零开始实现简单 RPC 框架 6:网络通信之 Netty
网络通信的开发,就涉及到一些开发框架:Java NIO.Netty.Mina 等等. 理论上来说,类似于序列化器,可以为其定义一套统一的接口,让不同类型的框架实现,事实上,Dubbo 就是这么干的. ...
- 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)
当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...
- 从零开始实现简单 RPC 框架 4:注册中心
RPC 中服务消费端(Consumer) 需要请求服务提供方(Provider)的接口,必须要知道 Provider 的地址才能请求到. 那么,Consumer 要从哪里获取 Provider 的地址 ...
- 从零开始实现简单 RPC 框架 9:网络通信之心跳与重连机制
一.心跳 什么是心跳 在 TPC 中,客户端和服务端建立连接之后,需要定期发送数据包,来通知对方自己还在线,以确保 TPC 连接的有效性.如果一个连接长时间没有心跳,需要及时断开,否则服务端会维护很多 ...
- 从零开始实现简单 RPC 框架 8:网络通信之 Request-Response 模型
Netty 在服务端与客户端的网络通信中,使用的是异步双向通信(双工)的方式,即客户端和服务端可以相互主动发请求给对方,发消息后不会同步等响应.这样就会有一下问题: 如何识别消息是请求还是响应? 请求 ...
- RPC笔记之初探RPC:DIY简单RPC框架
一.什么是RPC RPC(Remote Procedure Call)即远程过程调用,简单的说就是在A机器上去调用B机器上的某个方法,在分布式系统中极其常用. rpc原理其实很简单,比较容易理解,在r ...
- Java实现简单RPC框架(转)
一.RPC简介 RPC,全称Remote Procedure Call, 即远程过程调用,它是一个计算机通信协议.它允许像本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).H ...
随机推荐
- shell 中的for循环
第一类:数字性循环 #!/bin/bash for((i=1;i<=10;i++)); do echo $(expr $i \* 3 + 1); done #!/bin/bash for i i ...
- 文末送书四本 | 这篇Java反射机制太经典!不看后悔!
先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经 ...
- gitlab用户,组,项目权限管控
前言:gitlab上的权限管控是非常重要的,尤其是很多研发人员开发一个项目.这个是我总结的权限管控. 1.这个是创建项目时开放权限设置 2.这个创建用户设置的权限 3.用户权限,5种类型用户是 ...
- RSTP_PA协商过程
P/A协商的基本需求: P:①DP端口,②discarding A:①P2P链路 所有交换机的stp mode改为rstp,确保sw2的g0/0/3为AP,sw3的g0/0/3为DP 把sw3的g0/ ...
- dev c++处理汉字
工具--编译选项--编译器 在连接器命令行加入以下命令 -static-libgcc -finput-charset=GBK -fexec-charset=GBK 有些处理汉字的程序运行正常,但E ...
- Java基础00-基础语法3
1. 注释 1.1 注释概述 1.2 注释分类 1.3 示例 2. 关键字 2.1 关键字概述 2.2 关键字的特点 3. 常量 3.1 常量的概述 3.2 常量分类 以上常量除了空常量都是可以直接输 ...
- 【算法学习笔记】概率与期望DP
本文学习自 Sengxian 学长的博客 之前也在CF上写了一些概率DP的题并做过总结 建议阅读完本文再去接着阅读这篇文章:Here 前言 单纯只用到概率的题并不是很多,从现有的 OI/ACM 比赛中 ...
- ES6 模版字符串及常用的es6扩展方法
1.ES6 模版字符串es6 模版字符串主要用于简化字符串的拼接 <script type="text/javascript"> let obj={name:'rdb' ...
- 前端开发入门到进阶第三集【js和jquery的执行时间与页面加载的关系】
https://blog.csdn.net/u014179029/article/details/81603561 [原文链接]:https://www.cnblogs.com/eric-qin/p/ ...
- P4774-屠龙勇士-扩展中国剩余定理
屠龙勇士 很久很久以前,巨龙突然出现,带来了灾难带走公主又消失不见.王国十分危险,世间谁最勇敢,一位英雄出现-- 学习于该大佬博客 那么你就是这位英雄,不过不同的是,你面对的是一群巨龙,虽然巨龙都不会 ...