RPC开发2_全局配置加载

RPC开发2_全局配置加载
琴生一、需求分析
在 RPC 框架运行的过程中,会涉及到很多的配置信息,比如注册中心的地址、序列化方式、网络服务器端口号等等。
之前的简易版 RPC 项目中,我们是在程序里硬编码了这些配置,不利于维护。
而且 RPC 框架是需要被其他项目作为服务提供者或者服务消费者引入的,我们应当允许引入框架的项目通过编写配置文件来 自定义配置。并且一般情况下,服务提供者和服务消费者需要编写相同的 RPC 配置。
因此,我们需要一套全局配置加载功能。能够让 RPC 框架轻松地从配置文件中读取配置,并且维护一个全局配置对象,便于框架快速获取到一致的配置。
二、设计方案
配置项
首先我们梳理需要的配置项,刚开始就一切从简,只提供以下几个配置项即可:
- name 名称
- version 版本号
- serverHost 服务器主机名
- serverPort 服务器端口号
后续随着框架功能的扩展,我们会不断地新增配置项,还可以适当地对配置项进行分组。
比如以下是一些常见的 RPC 框架配置项,仅做了解:
- 注册中心地址:服务提供者和服务消费者都需要指定注册中心的地址,以便进行服务的注册和发现。
- 服务接口:服务提供者需要指定提供的服务接口,而服务消费者需要指定要调用的服务接口。
- 序列化方式:服务提供者和服务消费者都需要指定序列化方式,以便在网络中传输数据时进行序列化和反序列化。
- 网络通信协议:服务提供者和服务消费者都需要选择合适的网络通信协议,比如 TCP、HTTP 等。
- 超时设置:服务提供者和服务消费者都需要设置超时时间,以便在调用服务时进行超时处理。
- 负载均衡策略:服务消费者需要指定负载均衡策略,以决定调用哪个服务提供者实例。
- 服务端线程模型:服务提供者需要指定服务端线程模型,以决定如何处理客户端请求。
作为参考可以了解 Dubbo RPC 框架的配置项,包括应用配置、注册中心配置、服务配置等。
参考 Dubbo:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/
读取配置文件
如何读取配置文件呢?可以使用 Java 的 Properties 类自行编写,但更推荐使用一些第三方工具库,比如 Hutool 的 Setting 模块,可以直接读取指定名称的配置文件中的部分配置信息,并且转换成 Java 对象,非常方便。
参考官方文档:https://doc.hutool.cn/pages/Props/。
一般情况下,我们读取的配置文件名称为 application.properties
,还可以通过指定文件名称后缀的方式来区分多环境,比如 application-prod.properties
表示生产环境、 application-test.properties
表示测试环境。
三、开发实现
1、项目初始化
2、配置加载
1)在 config 包下新建配置类 RpcConfig
,用于保存配置信息。
可以给属性指定一些默认值,完整代码如下:
1 | /** |
2)在 utils 包下新建工具类 ConfigUtils
,作用是读取配置文件并返回配置对象,可以简化调用。
工具类应当尽量通用,和业务不强绑定,提高使用的灵活性。比如支持外层传入要读取的配置内容前缀、支持传入环境等。
1 | /** |
之后,调用 ConfigUtils
的静态方法就能读取配置了。
3)在 constant 包中新建 RpcConstant
接口,用于存储 RPC 框架相关的常量。
比如默认配置文件的加载前缀为 rpc
:
1 | package com.yupi.yurpc.constant; |
可以读取到类似下面的配置:
1 | rpc.name=yurpc |
3、维护全局配置对象
RPC 框架中需要维护一个全局的配置对象。在引入 RPC 框架的项目启动时,从配置文件中读取配置并创建对象实例,之后就可以集中地从这个对象中获取配置信息,而不用每次加载配置时再重新读取配置、并创建新的对象,减少了性能开销。
使用设计模式中的 单例模式,就能够很轻松地实现这个需求了。
一般情况下,我们会使用 holder 来维护全局配置对象实例。在我们的项目中,可以换一个更优雅的命名,使用 RpcApplication
类作为 RPC 项目的启动入口、并且维护项目全局用到的变量。
完整代码如下:
1 | /** |
上述代码其实就是 双检锁单例模式
的经典实现,支持在获取配置时才调用 init 方法实现懒加载。
为了便于扩展,还支持自己传入配置对象;如果不传入,则默认调用前面写好的 ConfigUtils 来加载配置。
以后 RPC 框架内只需要写一行代码,就能正确加载到配置:
1 | RpcConfig rpc = RpcApplication.getRpcConfig(); |