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:2181SPI 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的更多相关文章

  1. 从零开始实现简单 RPC 框架 2:扩展利器 SPI

    RPC 框架有很多可扩展的地方,如:序列化类型.压缩类型.负载均衡类型.注册中心类型等等. 假设框架提供的注册中心只有zookeeper,但是使用者想用Eureka,修改框架以支持使用者的需求显然不是 ...

  2. 从零开始实现简单 RPC 框架 5:网络通信之序列化

    我们在接下来会开始讲网络通信相关的内容了.既然是网络通信,那必然会涉及到序列化的相关技术. 下面是 ccx-rpc 序列化器的接口定义. /** * 序列化器 */ public interface ...

  3. 从零开始实现简单 RPC 框架 6:网络通信之 Netty

    网络通信的开发,就涉及到一些开发框架:Java NIO.Netty.Mina 等等. 理论上来说,类似于序列化器,可以为其定义一套统一的接口,让不同类型的框架实现,事实上,Dubbo 就是这么干的. ...

  4. 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)

    当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...

  5. 从零开始实现简单 RPC 框架 4:注册中心

    RPC 中服务消费端(Consumer) 需要请求服务提供方(Provider)的接口,必须要知道 Provider 的地址才能请求到. 那么,Consumer 要从哪里获取 Provider 的地址 ...

  6. 从零开始实现简单 RPC 框架 9:网络通信之心跳与重连机制

    一.心跳 什么是心跳 在 TPC 中,客户端和服务端建立连接之后,需要定期发送数据包,来通知对方自己还在线,以确保 TPC 连接的有效性.如果一个连接长时间没有心跳,需要及时断开,否则服务端会维护很多 ...

  7. 从零开始实现简单 RPC 框架 8:网络通信之 Request-Response 模型

    Netty 在服务端与客户端的网络通信中,使用的是异步双向通信(双工)的方式,即客户端和服务端可以相互主动发请求给对方,发消息后不会同步等响应.这样就会有一下问题: 如何识别消息是请求还是响应? 请求 ...

  8. RPC笔记之初探RPC:DIY简单RPC框架

    一.什么是RPC RPC(Remote Procedure Call)即远程过程调用,简单的说就是在A机器上去调用B机器上的某个方法,在分布式系统中极其常用. rpc原理其实很简单,比较容易理解,在r ...

  9. Java实现简单RPC框架(转)

    一.RPC简介 RPC,全称Remote Procedure Call, 即远程过程调用,它是一个计算机通信协议.它允许像本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).H ...

随机推荐

  1. IDA,IDA PRO 产品介绍

    IDA理念这是我们在开发产品时竭尽全力遵循的理念--在此过程中,我们相信我们将开发出能够为您带来所需的可靠性.便利性和易用性的软件.没有什么能打败人脑因为我们知道一秒钟的洞察力仍然胜过百年的处理时间, ...

  2. gitlab部署及汉化

    目录 Git 简介 部署 1. 配置yum源(推荐) 2. 安装 配置GitLab 1.加载配置 2.修改git默认访问端口 gitlab.rb unicorn.rb gitlab-http.conf ...

  3. 盘点linux操作系统中的10条性能调优命令,一文搞懂Linux系统调优

    原文链接:猛戳这里 性能调优一直是运维工程师最重要的工作之一,如果您所在的生产环境中遇到了系统响应速度慢,硬盘IO吞吐量异常,数据处理速度低于预期值的情况,又或者如CPU.内存.硬盘.网络等系统资源长 ...

  4. 「CF1208G」 Polygons

    「CF1208G」 Polygons 似乎我校神犇在很久以前和我提过这题? 首先有一点显而易见:这 \(k\) 个多边形肯定至少有一个公共的顶点.假设我们将此点定义为起点. 那么对于一个正 \(n\) ...

  5. Ubuntu中Docker的安装与使用

    Ubuntu中安装Docker 更新ubuntu的apt源索引 sudo apt-get update 2.安装包允许apt通过HTTPS使用仓库 sudo apt-get install \ apt ...

  6. python 操作word

    pip install python.docx from docx import DocumentDoc = Document() 解释:from 从 docx这个文件中,导入一个叫Document的 ...

  7. ORB-SLAM3论文阅读:ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual-Inertial and Multi-Map SLAM

    简介 ORB-SLAM3是第一个能在单目.双目.RGBD鱼眼相机和针孔相机模型下运行视觉.视觉-惯导以及多地图SLAM的系统.其贡献主要包括两方面:提出了完全依赖于最大后验估计的紧耦合视觉-惯导SLA ...

  8. Linux服务器相关性能的命令

    Linux服务器相关性能的命令 一.查看服务器性能信息的相关命令 1.cpu信息查看 cpu分为物理cpu和逻辑cpu 物理cpu:实际物理服务器插槽上cpu的个数,可以通过physical id不重 ...

  9. PAT甲级:1064 Complete Binary Search Tree (30分)

    PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...

  10. odoo源码学习之任务中的阶段字段stage_id

    # 案例0004针对form表单 class Task(models.Model): _name = "project.task" _description = "对于项 ...