首先写这个RPC的目的是让自己有一定造轮子的能力,虽然说工作大部分时间是拧螺丝钉,但是对于一个有追求的程序猿来说,一定的造轮子能力也是一种使自己在追求技术成长上的动力;
这个RPC是没有参考目前主流的RPC,二是基于“远程过程调用,将远程调用本地话”的理念去写的,所以很多地方并不是很好,存在很多可以优化的地方,这里就大致讲讲这个RPC都有些啥,之后在讲讲一些自定义用法;
技术栈
- jdk 1.8
- netty-4.1.36.Final
- maven
- spring、springboot
- redis、mysql
RPC的功能
- 远程过程调用;
- 可扩展的各种filter;
- 全链路追踪,以及数据收集和统计;
- SPI机制;
- 负载均衡;
- 自定义协议编解码;
- 配置加载器;
- 心跳检测;
- 优雅上下线;
RPC的核心实现
- 网络层就是基于netty的nioChannel实现的;在编解码层自定义自己的编解码协议,请求头+ body体的方式;
- 类调用用的是java的动态代理;
- 负载均衡是结合注册中心完成的,通过SPI可以自定义自己的负载策略;
- 注册中心使用的是redis的实现,同样支持SPI机制去实现注册中心,不过这里是需要统一的数据格式;提供注册元信息;mysql也提供了实现,但是存在滞后性;个人未修改;
- 序列化,目前core里面用的是protostuff;然后也可以使用SPI实现自己的序列化逻辑;
- 压缩,这方面一般就直接默认使用序列化里面的压缩,一般压缩率都很好,当然core里面也提供了GZIP的压缩方式;
- 配置中心,在core里面使用的是hutool相关工具类 + 文件(
META-INF/simple-rpc.properties
)实现对指定文件的加载;这里有个优先级的操作,之后可以看看; - 心跳加载是netty提供的
IdleStateHandler
去实现的,具体是客户端每5s做一次写操作去维护心跳,服务端是进行检测,若是客户端30s后无写操作,会自动断开此次连接,节省连接资源; - 链路追踪是基于bytebuddy实现的类aop形式;通过启动的时候根据javaagent参数指定jar;然后代码里面远程调用的traceId传递是通过filter来实现的;
- 优雅下线是在容器退出的时候,监听事件,然后将已有请求全部执行完,然后将服务从注册中心里面将元信息移除(暂未完成),将新请求全部打倒对应的未下线机器上;
RPC调用的技术整合
- 整合了spring,这里单独说的话是使用了spring的一个xml解析器,其实可以叫这里是使用xml的方式去完成的整合;
- 整合springboot,这里就是根据自己自定义的注解去实现服务扫描和服务注册,很多配置信息都在放在了
properties
文件中;使用起来更加方便吧; - 按照之前的想法,我是打算将core单独拿出来,也可以去整合其他的技术框架,不过后面也是没有去实现,自己目前除了spring相关的技术栈,还没有使用过其他的,比如
vertx
、jfinal
等;
RPC项目模块介绍
看看截图:
每个单独模块都简单介绍一下:
simple-rpc-common
:这个模块里面都是一些公用的东西,接口、实体等基本信息;simple-rpc-core
:这个模块里面是比较核心的内容,网络通信、编解码协议、远程调用、注册中心、负载均衡;也就是netty相关的操作都在这里面;simple-rpc-boot-starter
:整合springboot的操作,在bean的生命周期做一些操作,并在容器销毁的时候做hook关联,取消注册;spring-simple-rpc
:与spring的整合,其实跟boot相差的就是这里使用的是xml注册,和xml解析器去解析,其实大致差不多(暂时停止更新);simple-rpc-test
:这里面就是各测试相关的东西,里面几个子项目对应的就是不通的测试;simple-rpc-agent
:这里是链路追踪的实现,类似于pinpoint和skywalking;simple-rpc-static-starter
:这里是一些agent统计相关的东西,然后不加 starter的打算用来做core的,但是觉得太麻烦了,就没写了;然后这里还有前端的项目;simple-rpc-statistic-vue
:这个就是上面统计的前端;
RPC调用的链路图
这里的话是基于整合springboot的方式去说的;这里放个processon的链接
processOn图片
RPC的实际应用
这里我是写了一个自己的项目,然后将自己的rpc用上了,因为rpc在这项目里面就解决了远程调用这种动作,所以具体的业务这里可能就不讲了,可以自己看看源码;
项目:
这里是一个基于DDD实现的一个项目,这里就simple-lottery-rpc
里面用了rpc相关的功能,将服务注册到redis,然后供消费者使用;其他模块就不讲了,可以简单说下技术(里面很多技术在我之前的公众号里面都有写):
- kafka
- 自研的分页插件;
- 自研的分库分表插件;
- 自研的idea插件用于dto转换、用于代码生成;
- 自研的RPC框架;
谢谢大家阅读!!!
公众号: 搜索关注,爱搞技术的吴同学 ,公众号上会经常写实用性的文章,谢谢关注!!回复:“加好友”,可获取我的微信二维码,欢迎加好友,一起学习!!!
大量源码: 欢迎star,可能会分享微服务实战,分页插件等;gitee