给算法岗擦屁股的人应该明白那种痛苦的感觉。为了解耦不同服务之间的程序,但又能像调用原生函数一样调用远程函数,我在过去写下了 rpc.py。用了一段时间之后,过年守岁的时候闲着没事花了一夜把 coverage 提高到了 100%,修了几个隐藏的小 bug,现在基本稳定。
当然在造轮子之前我了解和使用过 grpc,怎么说呢……用起来挺蛋疼的。注册很麻烦,调用很麻烦,和其它服务配合起来也很麻烦。于是研究了一下 grpc 的原理,自己写了一个。
由于是基于 ASGI/WSGI 这两个通用网关协议的,所以 HTTP 部分我就可以偷懒不处理了,用社区发展十几年的成果就行。你想用 HTTP/1.0 、1.1 还是 2.0,或者更激进点直接 3.0,都可以。Python 社区都有现成方案。
基于这两通用网关协议,还有一个好处就是可以方便的和现有的 Django 、Bottle 、Flask 、Starlette 、FastAPI 、Sanic 、CherryPy 、Responder 、IndexPy……总之你能想到的支持这两个协议中至少一种的任何 Web 框架集成。也就是说,鉴权之类的工作,都可以用现成的。自己独立弄一个是不存在的,如果可以,这辈子我都不想自己造轮子了。
序列化协议上是天然解耦的,目前只内置了 JSON 、pickle 和 msgpack,如果大家还有什么高性能序列化协议,可以提 PR 或者发个 Discussion 。当然,也可以只在自己代码里用,自己注册一个还是很方便的。
基于 Type hint,可以自动转换类型,客户端在调用的时候还会主动检查类型。当然你不用 Type hint 也是可以正常用的。基于 Type hint 生成文档,似乎新框架都自带这个了哈哈哈
https://github.com/abersheeran/rpc.py
最后,造这个轮子的主要原因就是之前某项目大概有上千个函数需要批量转成可远程调用的接口。历史包袱、历史包袱。
1
lipcao 2021-02-18 09:34:59 +08:00
过年守岁的时候闲着没事花了一夜把 coverage 提高到了 100% 重点,要考
|
2
yazoox 2021-02-18 10:05:28 +08:00
不明觉厉!
|
3
abersheeran OP |
4
jenlors 2021-02-18 10:13:55 +08:00
楼主 github 头像本人?
|
5
fy1993 2021-02-18 10:16:22 +08:00
楼主 github 头像本人?
|
6
musi 2021-02-18 10:18:56 +08:00
看了下楼主的博客,这文采做程序员真的屈才了。多写写小说没准已经拍成电视剧了
|
8
madpecker009 2021-02-18 10:29:07 +08:00
这妹子好看啊
|
9
abersheeran OP |
10
jenlors 2021-02-18 10:34:01 +08:00
看了楼主 blog,不去写小说可惜了。
|
11
abersheeran OP @long2ice 😀
|
12
z740713651 2021-02-18 10:51:06 +08:00
大佬太牛了 公司业务正好要用到 rpc.py 感谢大佬
|
13
lewinlan 2021-02-18 10:53:12 +08:00 via Android
grpc 蛋疼是 python 的问题。换其他语言写 grpc 快乐的很
|
14
abersheeran OP |
15
no1xsyzy 2021-02-18 11:30:01 +08:00
所以说 Client.remote_call 和 RPC.register 有什么形式上的差别吗?
完全可以用同一个函数去注册不是吗? Client 没必要分离吧( |
16
johnsona 2021-02-18 12:03:44 +08:00 via iPhone
是不是要有负载均衡(乱说的 bushi
|
17
silymore 2021-02-18 12:36:58 +08:00 via iPhone
开源工作相关的框架需要公司同意吗
|
18
gscsnm 2021-02-18 12:37:53 +08:00
喜欢你的博客,请问下博客是自己开发的吗?还是用的什么?
|
19
poplar50 2021-02-18 13:15:51 +08:00 via iPhone
楼主 github 头像本人?
|
20
jaswer 2021-02-18 13:34:52 +08:00
楼主 github 头像本人?
|
21
skies457 2021-02-18 13:38:42 +08:00
直接白嫖阿里云的 serverless 函数计算不香吗(狗头
|
22
HashV2 2021-02-18 13:49:21 +08:00
楼主 github 头像本人?
|
23
cornetCat 2021-02-18 14:05:40 +08:00
楼主不是妹子吧
看腾讯离职那篇提到有女朋友的 |
24
XingWu 2021-02-18 14:34:11 +08:00
为啥不用 serverless 呢
|
25
abersheeran OP @no1xsyzy ?如果你客户端代码和服务端代码写在一起了,直接调用不就好了吗
|
26
abersheeran OP @silymore 这不是我所在公司需要用到的。也不是工作期间开发的。
|
27
abersheeran OP |
28
abersheeran OP @silymore 想了想,所在的公司或许后续要上微服务,所以可能会被用到。但是直到目前为止,它仍然和我目前所在的公司没什么关系。我上班期间为这家公司造的轮子,是仅内部使用的,而且因为特殊的原因,就算开源了也没有通用价值。轮子造了快三个月,所以我才说不想再造轮子了。
公司正在用的我的开源项目,唯一一个就是 Index\.py 。我入职前基本完工的,公司现在在用。 详细解释一下免得让大家以为我把公司项目给开源了。 |
29
no1xsyzy 2021-02-18 16:01:23 +08:00
@abersheeran 我的服务端会有一些缓存,而且是再请求上游服务器的,上游服务器效率非常差( ping 超 300ms,更不用说每组有意义的请求通常包含三个来回),但有更新推送,所以可以拿一个中间服务器作为缓存,根据推送重新获取信息。
|
30
abersheeran OP @no1xsyzy 原来如此。
|
31
seth19960929 2021-02-18 16:22:28 +08:00
楼上怎么关注点不同呀. 老是关注楼主身份. 搞得点进来的人都无法专心看问题啦.
---- 话说这样, 和直接暴露一个 path 接口, 然后反射调用然后返回函数返回值有什么区别吗? |
32
abersheeran OP @seth19960929 你的意思是直接用某个 web 框架创建接口?其实没有本质上的差别。只不过需要自己约定一个规则和序列化工具。对于生成器函数需要自己手写一下 SSE (目前为止好像没有几个 Py 框架支持这个)。
我在写出 rpcpy 之前,都是用的 bottlepy 作为代替。但 web 框架的大部分功能其实是用不上的,所以效率上可能稍差一点。 用 web 框架手写更自由,也更可控。不过代码量就…… |
33
seth19960929 2021-02-18 17:02:52 +08:00
是否支持其他语言客户端? 如果支持, 怎么保证序列化每一种语言的实现. 去用 ProtoBuf ?
如果只支持 Python 有专门的库把任意 Python 数据类型序列化成字符串. 然后客户端反序列化用就好了. |
34
todd7zhang 2021-02-18 17:03:06 +08:00
2.7 老古董看到 typing 脑壳昏, 是不是应该学一学这个 typing 了
|
35
abersheeran OP @seth19960929 现在内置的三个序列化器,JSON 、Msgpack 都是跨语言的。JSON 自然不必多说,Msgpack 也有很多语言可以支持。ProtoBuf 考虑过,不过没有好用的库,就作罢了。
@todd7zhang 没事,不用 typing 也可以正常工作的。只不过有 type hint 的信息,功能更丰富一点罢了。 |
36
NeilWang 2021-02-19 10:58:07 +08:00
"可以方便的和现有的 Web 框架集成。也就是说,鉴权之类的工作,都可以用现成的"
楼主,你的意思是说 注册到 rpc.py 的函数,可以转换成 Flask 等 Web 框架的视图函数? Web 框架转 ASGI/WSGI 应用倒是很简单,不过没见过 ASGI/WSGI 应用转 Web 框架视图函数的。不知道我的理解对不对,有相关的例子可以提供吗 |
37
abersheeran OP @NeilWang 不能转视图函数。这里我说的是 WSGI/ASGI Application 组合。Flask 我不记得能不能 mount wsgi app,但是 Bottle.mount 可以,所以我猜 Flask 应该也实现了这个功能。具体的你可以去 Flask 社区问问。
|