2019年7月底入职了新的公司,是一家创业公司,在架构组负责一些架构方面的工作。公司人员流动略大,公司自研的RPC框架是前人留下的坑,开发团队已全部跑路,因为最近也是第一次接触,写一下自己的吐槽与思考
吐槽点
微服务框架为什么要自研
我觉得没理由,目前开源成熟的服务框架非常多,具有代表性的:
- spring-cloud体系:强大且易用
- dubbo(可接入spring-cloud):阿里多年前开源的SOA框架,被很多大公司所用,已是apache顶级项目
- servicecomb:华为的开源项目,已是apache顶级项目
成熟的开源产品完全能满足一般创业公司的使用,因此,对于现公司,我觉得完全没有理由自研一套
自研却缺少文档
自研也就算了,没有任何使用说明文档,入门时一脸懵逼,加上开发团队全部跑路,只能向使用过的同学学习如何使用
自研的非常差
自研就自研,但是能不能做好一点呢?从该rpc报出的异常栈以及调用方式就能看出其实现非常粗糙丑陋,毫无优雅性可言
这里先说一说微服务框架的几个考虑点,自底向上分别是:
- 序列化/反序列化
- 服务端/客户端的抽象,用于处理接受请求与发送请求,封装request/response语义
- 通信协议,可选择基于tcp或者http,或者其它
- RPC协议,定义RPC过程中的数据传输方式,支持多种调用方式,比如同步调用,异步调用,不关心返回值以及是否成功的调用等
- 对集群的抽象,封装负载均衡与失败处理,负载均衡可使用roundover, hash等,失败处理可提供failover, failfast等方式,现在的服务框架的负载均衡都使用了软负载
- 服务主册与服务发现
- api/stub/与已有框架的结合等
- 服务治理
但该rpc完全没有考虑上述问题,或者说考虑的非常之少,该rpc的相关情况:
- 序列化/反序列化:json,半自动化,往往还需要人工做json反序列化
- 服务端/客户端的抽象:几乎没有,使用静态方法调用,也没有IO处理,依赖应用本身的tomcat,不是说这样不行,但是太粗糙
- 通信协议:基于http,依赖应用的tomcat以及8080端口,不是说不能使用http协议,使用http协议是没问题的,但是依赖应用的tomcat并不是一个好的方案,因为这样导致应用系统需要关心rpc框架的细节,比如想要写一个Servlet Filter对请求进行拦截,我们需要考虑该Filter会不会拦截到rpc请求
- 负载均衡与失败处理:无考虑,根据异常栈就能看出该rpc的服务注册与服务发现过于粗糙,它是通过域名做http调用,负载均衡依赖nginx,没有软负载,不支持失败处理
- 服务注册与服务发现:基于域名的而不是基于服务的,粒度太粗了,这就导致没法实现对服务的精细化管控,比如A/B测试,兼容性的平滑处理等
- api实现极其丑陋,没有stub或者远程代理这样的概念,rpc的调用是纯手动处理的json,调用方式如下:
String jsonResult = RemoteClientUtil.callRpc(”appName.serviceName“, JSON.toJsonString(params));
Result result = JSON.parseObject(jsonResult, Result.class);
- 完全没有服务治理能力,且没法接入spring-cloud体系,利用spring-cloud的相关能力
毫无扩展性
该自研的rpc框架非常不完善,并且很难与已有的开源项目结合,对于流程管控、服务治理的需求,该rpc框架难以满足
如果要重构,那基本上是重写,目前大量系统在使用,涉及到的系统改造非常大,基本上不现实
总结
对于这样的rpc框架,如果只论技术,它做的非常差,在rpc框架中,它就是demo级别的存在,不有参考价值。
当然,你可以说小公司不需要dubbo,不需要spring-cloud,但是我不这样认为,我认为我们当前对spring-cloud中的组件还是有需求的,但是该rpc没有考虑如何融入到成熟的微服务体系,抬高了我们使用这些成熟组件的门槛
虽然我没有自研过rpc框架,但见到该rpc框架后也要吸取教训,自研基础组件一定要考虑周全,尽量避免与应用共享资源,需要考虑扩展性
最后建议优先选择开源体系作为微服务架构的基础,如果有不满足公司特定需求的可基于开源组件改造