一个简单的基于Protobuf的RPC框架

  在喜迎新年的这段稍微清闲的日子中,在阅读代码的时候受到logcabin项目之启发,于是便沿着原作者的思路做了一个简单的C++用RPC开发框架tzrpc,目前该项目的基本功能已经完成了。


  可能说到“RPC开发框架”名字听起来比较唬人,但是正如自己当初在之前的文章中所提到的,RPC框架的核心就是统一规范化数据编解码和网络传输方面的细节,方便快速开发实现互联网程序而已,究其本质内容的话,其实和普通的互联网开发相比没有什么另类差异的,所以也就不足为奇。之所以要做这个东西,一方面原因是现在工作中所用到的基于socket的网络开发库的确是不怎么的好,就一个简单的两字节长度做为头部,然后就追加流式消息体了,如果将一个非法的请求错误地打向这个端口,那么很可能会让服务卡死甚至崩溃掉,另一方面Thrift和grpc很好很强大,但是如果想要做一些个性化的定制和功能增加,就会觉得难以下手,而后一个原因也是很多互联网公司为了满足自己业务需求,另起炉灶开发内部RPC框架的最主要原因了。而我写这个工具的原因,也就是想整理出一套自己摸得透、掌控得了、可以按需求随意定制的网络开发库,增加后续网络服务的开发效率,增加在网络服务开发中的积累。
  
  tzrpc也是采用基于boost.asio实现的高并发、高性能的异步框架,以实现网络层的高性能传输,数据编解码也是使用的是常见的protobuf 2,当然也可以扩充采用其他数据(反)序列化的方式。网络连接支持并建议优先使用长连接,除了性能考量之外,主要是避免TPS过高的情况下后导致的大量TIME_WAIT占用端口号的问题;数据方面则分别在网络传输层和上层应用层进行了封装,校验失败的数据会返回给调用方,增加了服务整体的可靠性;同时还在错误码设计上进行细分和细致的考量,以方便调用者根据不同的异常情形选择合理的处理方式。目前项目还仅仅处于实现了基本功能的阶段,后续还期待会逐步完善并发和过载保护、线程池自动伸缩、监控和告警等各项功能,当然后续遇到的其他RPC框架较好的特性也会努力引入到这个项目中来。
  和之前的tzmonitor项目一样,tzrpc提供了服务端和客户端的支持,客户端只需要一个库文件和若干个头文件就足够了,数据编解码和网络传输的细节也被封装了起来,这样就方便和其他项目简单快速地集成起来。
  
  在写这个项目的时候,也顺便将之前的tzhttpd这个HTTP服务库也做了一次重构工作。该库之前设计最大的缺陷是业务处理Handler是在HTTP请求接收和解析完之后,直接嵌入到boost.asio线程池中同步化执行的,所以如果Handler处理的时间比较长的话,会严重影响到整个网络IO的并发和传输性能,而这次按照和tzrpc框架一样的模式,将请求接收和解析完之后放置到一个队列中,由独立的工作线程组去按序处理,其响应结果也放到boost.asio异步框架中高效的返回给调用端;同时各个虚拟主机采用独立可配置的线程池处理,也实现了资源的隔离保护;整个项目的组织也进行了调整,变的更加的清晰和易于理解了。不过项目减少了对参数动态更新的支持,主要是感觉为了支持参数的动态更新,需要考虑到很多的临界情况、作出很多的竞争态保护工作,整个项目因此变得更加的复杂,而实际上非关键服务直接重启一下也不困难,而核心服务也可以通过ZooKeeper这类服务进行治理,进行灰度操作也能达到不停服务更新的效果。
  当然现在tzhttpd和tzrpc两个项目算是高度相似了,以后任何一个的改进更新都可以选择性地同步到另外一方去,总体的维护成本都大大降低了。
  
  顺便要说一下的是,后面本站关于软件工具、协议等方面的学习整理型的文章基本不会再写了,个人现在倾向于使用思维导图来管理知识内容了,而学习整理的内容今后可能会开源和大家分享。而本站后面会更加倾向于分享项目中遇到的问题和学习到的经验、一些开发和管理相关的心得体会,以及生活、学习、社会、文学方面的感触之类的内容了。希望持续关注。