「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战」
阅读这篇文章之前,建议先阅读和这篇文章关联的内容。
1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解)
2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干货)
4. BAT面试必问细节:关于Netty中的ByteBuf详解
5. 通过大量实战案例分解Netty中是如何解决拆包黏包问题的?
6. 基于Netty实现自定义消息通信协议(协议设计及解析应用实战)
8. 手把手教你基于Netty实现一个基础的RPC框架(通俗易懂)
在本篇文章中,我们继续围绕Netty手写实现RPC基础篇进行优化,主要引入几个点
- 集成spring,实现注解驱动配置
- 集成zookeeper,实现服务注册
- 增加负载均衡实现
源代码,加「跟着Mic学架构」微信号,回复『rpc』获取。
增加注解驱动
主要涉及到的修改模块
- netty-rpc-protocol
- netty-rpc-provider
netty-rpc-protocol
当前模块主要修改的类如下。
图7-1
下面针对netty-rpc-protocol模块的修改如下
增加注解驱动
这个注解的作用是用来指定某些服务为远程服务
1 | java复制代码@Target(ElementType.TYPE)// Target说明了Annotation所修饰的对象范围, TYPE:用于描述类、接口(包括注解类型) 或enum声明 |
SpringRpcProviderBean
这个类主要用来在启动NettyServer,以及保存bean的映射关系
1 | java复制代码@Slf4j |
Mediator
主要管理bean以及调用
BeanMethod
1 | java复制代码@Data |
Mediator
负责持有发布bean的管理,以及bean的反射调用
1 | java复制代码public class Mediator { |
RpcServerProperties
定义配置属性
1 | java复制代码@Data |
RpcProviderAutoConfiguration
定义自动配置类
1 | java复制代码@Configuration |
修改RpcServerHandler
修改调用方式,直接使用Mediator的调用即可。
1 | java复制代码public class RpcServerHandler extends SimpleChannelInboundHandler<RpcProtocol<RpcRequest>> { |
netty-rpc-provider
这个模块中主要修改两个部分
- application.properties
- NettyRpcProviderMain
NettyRpcProviderMain
1 | java复制代码@ComponentScan(basePackages = {"com.example.spring.annotation","com.example.spring.service","com.example.service"}) |
application.properties
增加一个配置属性。
1 | java复制代码gp.rpc.servicePort=20880 |
UserServiceImpl
把当前服务发布出去。
1 | java复制代码@GpRemoteService //表示将当前服务发布成远程服务 |
修改客户端的注解驱动
客户端同样也需要通过注解的方式来引用服务,这样就能够彻底的屏蔽掉远程通信的细节内容,代码结构如图7-2所示
图7-2
增加客户端注解
在netty-rpc-protocol模块的annotation目录下创建下面这个注解。
1 | java复制代码@Retention(RetentionPolicy.RUNTIME) |
SpringRpcReferenceBean
定义工厂Bean,用来构建远程通信的代理
1 | java复制代码public class SpringRpcReferenceBean implements FactoryBean<Object> { |
SpringRpcReferencePostProcessor
用来实现远程Bean的动态代理注入:
- BeanClassLoaderAware: 获取Bean的类装载器
- BeanFactoryPostProcessor:在spring容器加载了bean的定义文件之后,在bean实例化之前执行
- ApplicationContextAware: 获取上下文对象ApplicationContenxt
1 | java复制代码@Slf4j |
需要在RpcConstant常量中增加一个INIT_METHOD_NAME属性
1 | java复制代码public class RpcConstant { |
RpcClientProperties
1 | java复制代码@Data |
RpcRefernceAutoConfiguration
1 | java复制代码@Configuration |
netty-rpc-consumer
修改netty-rpc-consumer模块
- 把该模块变成一个spring boot项目
- 增加web依赖
- 添加测试类
图7-3 netty-rpc-consumer模块
引入jar包依赖
1 | xml复制代码<dependency> |
HelloController
1 | java复制代码@RestController |
NettyConsumerMain
1 | java复制代码@ComponentScan(basePackages = {"com.example.spring.annotation","com.example.controller","com.example.spring.reference"}) |
application.properties
1 | properties复制代码gp.serviceAddress=192.168.1.102 |
访问测试
- 启动Netty-Rpc-Server
- 启动Netty-Rpc-Consumer
如果启动过程没有任何问题,则可以访问HelloController来测试远程服务的访问。
引入注册中心
创建一个netty-rpc-registry模块,代码结构如图7-4所示。
引入相关依赖
1 | xml复制代码<dependency> |
IRegistryService
1 | java复制代码public interface IRegistryService { |
ServiceInfo
1 | java复制代码@Data |
ZookeeperRegistryService
1 | java复制代码@Slf4j |
引入负载均衡算法
由于服务端发现服务时可能有多个,所以需要用到负载均衡算法来实现
ILoadBalance
1 | java复制代码public interface ILoadBalance<T> { |
AbstractLoadBalance
1 | java复制代码public abstract class AbstractLoadBanalce implements ILoadBalance<ServiceInstance<ServiceInfo>> { |
RandomLoadBalance
1 | java复制代码public class RandomLoadBalance extends AbstractLoadBanalce { |
RegistryType
1 | java复制代码public enum RegistryType { |
RegistryFactory
1 | java复制代码public class RegistryFactory { |
修改服务端增加服务注册
修改netty-rpc-protocol模块,加入注册中心的支持
SpringRpcProviderBean
按照下面case标注部分,表示要修改的内容
1 | java复制代码@Slf4j |
RpcServerProperties
修改RpcServerProperties,增加注册中心的配置
1 | java复制代码@Data |
RpcProviderAutoConfiguration
增加注册中心的注入。
1 | java复制代码@Configuration |
application.properties
修改netty-rpc-provider中的application.properties。
1 | properties复制代码gp.rpc.servicePort=20880 |
修改客户端,增加服务发现
客户端需要修改的地方较多,下面这些修改的代码,都是netty-rpc-protocol模块中的类。
RpcClientProperties
增加注册中心类型和注册中心地址的选项
1 | java复制代码@Data |
修改NettyClient
原本是静态地址,现在修改成了从注册中心获取地址
1 | java复制代码@Slf4j |
修改RpcInvokerProxy
将静态ip和地址,修改成IRegistryService
1 | java复制代码@Slf4j |
SpringRpcReferenceBean
修改引用bean,增加注册中心配置
1 | java复制代码public class SpringRpcReferenceBean implements FactoryBean<Object> { |
SpringRpcReferencePostProcessor
1 | java复制代码@Slf4j |
RpcRefernceAutoConfiguration
1 | java复制代码@Configuration |
application.properties
修改netty-rpc-consumer模块中的配置
1 | properties复制代码gp.serviceAddress=192.168.1.102 |
负载均衡的测试
增加一个服务端的启动类,并且修改端口。然后客户端不需要重启的情况下刷新浏览器,即可看到负载均衡的效果。
图7-5
需要源码的同学,请关注公众号[跟着Mic学架构],回复关键字[rpc],即可获得
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
Mic带你学架构
!
如果本篇文章对您有帮助,还请帮忙点个关注和赞,您的坚持是我不断创作的动力。欢迎关注同名微信公众号获取更多技术干货!
本文转载自: 掘金