2

服务治理与RPC

 2 years ago
source link: https://zhu327.github.io/2018/03/24/%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%E4%B8%8Erpc/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

服务治理与RPC

Mar 24 2018

以前写过Django中使用zerorpc的方法,但是由于我们的Django是运行在gevent下,而zeromq需要启动一个后台进程处理消息,与gevent使用的greenlet携程是冲突的。

在Java的世界里,Spring Cloud全家桶覆盖了微服务的方方面面,专注于服务治理的框架也有阿里的Dubbo,微博的Motan。但是Python这边没有找到合适的轮子,甚至于好的RPC框架也没有,只有gRPC,Thrift这种跨语言的RPC框架。而这些跨语言的RPC框架基本上也是基于C/C++的Python port。

在github上全局搜索Python rpc,找到一个原生支持gevent的MPRPC,而且也找到了微博Motan的Golang版本,所以考虑读Motan-go的源码学习一下什么是服务治理,再基于MPRPC实现自己的轮子。这就有了doge

主流的注册中心服务包括etcd,Consul,zookeeper。这里只考虑了etcd与Consul,etcd相对来说简单些,是一个分布式的KV强一致数据库,数据以树状结构存储。Consul的功能更丰富些,有服务的定义,并且支持对服务的健康检查。etcd不支持健康检查,但是可以通过设置key的ttl,然后服务定时刷新ttl来主动上报。

MPRPC本身提供了一个简单socket pool池,但是在高并发测试下发现池会溢出,其实是一个并发安全的问题,打了一个补丁,解决了该问题。

同时在连接池的基础上封装了EndPoint了,在调用失败多次后,判断EndPoint不可用,并且启动后台协程多次链接socket,一旦连接成功则重新设置为可用。

同时客户端会监听服务的key变化,一旦服务没有刷新ttl,key被删除或过期,对应的EndPint也会被删除。

主流的负载均衡方式有:随机,平均,按负载,HASH。由于RPC主要是在内部网络使用,所以只实现了随机与平均的方式。

简单的方式failfast只调用一次,无论是否出错马上返回。failover会在重试次数以内遍历所有可以用的EndPoint,直到成功才返回。backrequest会在调用时保存所有成功的调用事件,算出一个合适的超市事件来遍历调用,直到成功并返回。

Java有hystrix这种专门用来做熔断,降级的库。Python由于比较简单,可用直接try/except来事件,在熔断以后,直接调用熔断处理函数。

服务端限流

限制连接数,可用通过信号量来实现。限制流速,漏桶算法或者令牌桶算法。事件段内的调用次数,使用计数器。

在开发doge的过程中,学习通过pytest来写单元测试,感觉比unitest更方便一些。同时接入了travis ci在每次push代码的同时执行单元测试。发布到PyPI后补充了codecov代码测试覆盖率。对于开源项目的正确姿势有了更多的理解。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK