简介:Getty 保护团队不谋求无意义的 benchmark 数据,不做无意义的炫技式优化,只依据生产环境需要来进行本身改良。只有保护团队在,Getty 稳定性和性能定会越来越优良。
集体从事互联网基础架构零碎研发十年余,包含我本人在内的很多敌人都是轮子党。
2011 年我在某大厂干活时,很多应用 C 语言进行开发的共事都有一个本人的私人 SDK 库,尤其是网络通信库。集体刚融入这个环境时,感觉不能写一个基于 epoll/iocp/kqueue 接口封装一个异步网络通信库,会在共事背后矮人三分。当初想起来过后很多共事很大胆,把本人封装的通信库间接在测试生产环境上线应用,据说那时候整个公司投入生产环境运行的 RPC 通信库就有 197 个之多。
集体过后消耗两年周末休息时间造了这么一个私人 C 语言 SDK 库:大部分 C++ STL 容器的 C 语言实现、定时器、TCP/UDP 通信库、输入速度可达 150MiB/s 的日志输入库、基于 CAS 实现的各种锁、躲避了 ABA 问题的多生产者多消费者无锁队列 等等。本人过后不懂 PHP,其实略微封装下就能够做出一个相似于 Swoole 的框架。如果始终保持写下来,可能它也堪媲美老朋友郑树新老师的 ACL 库了。
本人 2014 年开始接触 Go 语言,通过一段时间学习之后,发现了它有 C 语言一样的特点:根底库太少 — 又能够造轮子了。我清晰地记得本人造出来的第一个轮子每个 element 只应用一个指针的双向链表 xorlist【见参考 1】。
2016 年 6 月我在做一个即时通讯我的项目时,原始网关是一个基于 netty 实现的 Java 我的项目,起初应用 Go 语言重构时其 TCP 网路库各个接口实现就间接借鉴了 netty。同年 8 月份在其上增加了 websocket 反对时,感觉 websocket 提供的 onopen/onclose/onmessage 网络接口极其不便,就把它的网络接口改为 OnOpen/OnClose/OnMessage/OnClose,把全副代码放到了 github 上,并在小范畴内进行了宣传【见参考 2】。
Getty 分层设计
Getty 严格遵循着分层设计的准则。次要分为数据交互层、业务管制层、网络层,同时还提供十分易于扩大的监控接口,其实就是对外裸露的网络库应用接口。
1、数据交互层
很多人提供的网络框架本人定义好了网络协议格局,至多把网络包头部格局定义好,只容许其下层使用者在这个头部以下做扩大,这就限度了其应用范畴。Getty 不对下层协定格局做任何假如,而是由使用者本人定义,所以向上提供了数据交互层。
就其本身而言,数据交互层做的事件其实很繁多,专门解决客户端与服务器的数据交互,是序列化协定的载体。应用起来也非常简单,只有实现 ReadWriter interface 即可。
Getty 定义了 ReadWriter 接口,具体的序列化 / 反序列化逻辑 则交给了用户手动实现。当网络连接的一端通过 net.Conn 读取到了 peer 发送来的字节流后,会调用 Read 办法进行反序列化。而 Writer 接口则是在网络发送函数中被调用,一个网络包被发送前,Getty 先调用 Write 办法将发送的数据序列化为字节流,再写入到 net.Conn 中。
ReadWriter 接口定义代码如上。Read 接口之所以有三个返回值,是为了解决 TCP 流粘包状况:
– 如果产生了网络流谬误,如协定格局谬误,返回 (nil, 0, error)– 如果读到的流很短,其头部 (header) 都无奈解析进去,则返回 (nil, 0, nil)– 如果读到的流很短,能够解析出其头部 (header) 但无奈解析出整个包 (package),则返回 (nil, pkgLen, nil)– 如果可能解析出一个残缺的包 (package),则返回 (pkg, 0, error)
2、业务管制层
业务管制层是 Getty 设计的精髓所在,由 Connection 和 Session 组成。
– Connection**
负责建设的 Socket 连贯的治理,次要包含:连贯状态治理、连贯超时管制、连贯重连管制、数据包的相干解决,如数据包压缩、数据包拼接重组等。
– Session**
负责客户端的一次连贯建设的治理、记录着本次连贯的状态数据、治理 Connection 的创立、敞开、控制数据的发送 / 接口的解决。
2.1 Session
Session 能够说是 Getty 中最外围的接口了,每个 Session 代表着一次会话连贯。
–向下
Session 对 Go 内置的网络库做了欠缺的封装,包含对 net.Conn 的数据流读写、超时机制等。
– 向上
Session 提供了业务可切入的接口,用户只需实现 EventListener 就能够将 Getty 接入到本人的业务逻辑中。
目前 Session 接口的实现只有 session 构造体,Session 作为接口仅仅是提供了对外可见性以及遵循面向编程接口的机制,之后咱们谈到 Session,其实都是在讲 session 构造体。
2.2 Connection
Connection 依据不同的通信模式对 Go 内置网络库进行了形象封装,Connection 别离有三种实现:
– gettyTCPConn:底层是 *net.TCPConn
– gettyUDPConn:底层是 *net.UDPConn
– gettyWSConn:底层应用第三方库实现
2.3 网络 API 接口 EventListener
本文结尾提到,Getty 网络 API 接口命名是从 WebSocket 网络 API 接口借鉴而来。Getty 维护者之一 郝洪范 同学喜爱把它称为“监控接口”,理由是:网络编程最麻烦的中央当呈现问题时不晓得如何排查,通过这些接口能够晓得每个网络连接在每个阶段的状态。
「OnOpen」:连贯建设时提供给用户应用,若以后连贯总数超过用户设定的连接数,则能够返回一个非 nil 的 error,Getty 就会在初始阶段敞开这个连贯。「OnError」:用于连贯有异样时的监控,Getty 执行这个接口后敞开连贯。「OnClose」:用于连贯敞开时的监控,Getty 执行这个接口后敞开连贯。「OnMessage」:当 Getty 调用 Reader 接口胜利从 TCP 流 /UDP/WebSocket 网络中解析出一个 package 后,通过这个接口把数据包交给用户解决。「OnCron」:定时接口,用户能够在这里接口函数中执行心跳检测等一些定时逻辑。
这五个接口中最外围的是 OnMessage,该办法有一个 interface{} 类型的参数,用于接管对端发来的数据。
可能大家有个纳闷,网络连接最底层传输的是二进制,到咱们应用的协定层个别以字节流的形式对连贯进行读写,那这里为什么要应用 interface{} 呢?
这是 Getty 为了让咱们可能专一编写业务逻辑,将序列化和反序列化的逻辑抽取到了 EventListener 里面,也就是后面提到的 Reader/Writer 接口,session 在运行过程中,会先从 net.Conn 中读取字节流,并通过 Reader 接口进行反序列化,再将反序列化的后果传递给 OnMessage 办法。
如果想把对应的指标接入到 Prometheus,在这些 EventListener 接口中很容易增加各种 metrics 的收集。
Getty 网络端数据流程
下图是 Getty 外围构造的类图,囊括了整个 Getty 框架的设计。
|阐明:图中灰色局部为 Go 内置库
上面以 TCP 为例介绍下 Getty 如何应用以及该类图里各个接口或对象的作用。其中 server/client 是提供给用户应用的封装好的构造,client 的逻辑与 server 很多水平上统一,因而本章只讲 server。
Getty server 启动代码流程图如上。在 Getty 中,server 服务的启动流程只须要两行代码:
第一行非常明显是一个创立 server 的过程,options 是一个 func (*ServerOptions) 函数,用于给 server 增加一些额定性能设置,如启用 ssl,应用工作队列提交工作的模式执行工作等。
第二行的 server.RunEventLoop(NewHelloServerSession) 则是启动 server,同时也是整个 server 服务的入口,它的作用是监听某个端口(具体监听哪个端口能够通过 options 指定),并解决 client 发来的数据。RunEventLoop 办法须要提供一个参数 NewSessionCallback,该参数的类型定义如下:
这是一个回调函数,将在胜利建设和 client 的连贯后被调用,个别提供给用户用于设置网络参数,如设置连贯的 keepAlive 参数、缓冲区大小、最大音讯长度、read/write 超时工夫等,但最重要的是,用户须要通过该函数,为 session 设置好要用的 Reader、Writer 以及 EventListener。
至此,Getty 中 server 的解决流程大体如下图:
对于这些接口的应用,除了 getty 本身提供的代码示例外,另一篇极好的例子就是 seata-golang,感兴趣的敌人可参阅《分布式事务框架 seata-golang 通信模型》一文【参考 6】。
优化
软件开发一条教训法令是:“Make it work, make it right, make it fast”,过早优化是万恶之源。
比拟晚期的一个例子是 erlang 的发明者 Joe Armstrong 早年破费了相当多的精力去熬夜加班改良 erlang 性能,其结果之一是他在前期发现晚期做的一些优化工作很多是无用功,其二是过早优化损坏了 Joe 的衰弱,导致 2019 年在他 68 岁的年纪便挂掉了。
把工夫单位拉长到五年甚至是十年,可能会发现晚期所做的一些优化工作在前期会成为保护工作的累赘。2006 年时很多专家还在举荐大家只用 Java 做 ERP 开发,不要在互联网后盾编程中应用 Java,理由是在过后的单核 CPU 机器上与 C/C++ 相比其性能的确不行,理由当然能够怪罪于其解释语言的实质和 JVM GC,然而 2010 年之后就简直很少听见有人再埋怨其性能了。
2014 年在一次饭局上碰到支付宝前架构师周爱民老师,周老师过后还调侃道,如果支付宝把次要业务编程语言从 Java 切换到 C++,大略服务器数量能够省掉 2/3。
类比之,作为一个比 Java 年老很多的新语言,Go 语言定义了一种编程范式,编程效率是其首要思考,至于其程序性能尤其是网络 IO 性能,这类问题能够交给工夫,五年之后以后大家埋怨的很多问题可能就不是问题了。如果程序真的遇到网络 IO 性能瓶颈且机器估算缓和,能够思考换成更低级的语言如 C/C++/Rust。
2019 年时 MOSN 的底层网络库应用了 Go 语言原生网络库,每个 TCP 网络连接应用了两个 goroutine 别离解决网络收发,当然起初经优化后做到了单个 TCP 连贯做到了单 TCP 仅应用一个 goroutine,并没有采纳 epoll 零碎调用的形式进行优化。
再举个例子。
字节跳动从 2020 年便在知乎开始发文宣传其 Go 语言网络框架 kitex 的优良性能【见参考 3】,说是基于原生的 epoll 后“性能已远超官网 net 库”云云。过后它没开源代码,大家也只能姑妄信之。2021 年年初,头条又开始进去宣传了一把【见参考 4】,声称“测试数据表明,以后版本(2020.12) 相比于上次分享时 (2020.05),吞吐能力 ↑30%,提早 AVG ↓25%,TP99 ↓67%,性能已远超官网 net 库”。而后终于把代码开源了。8 月初鸟窝大佬通过测试,并在《2021 年 Go 生态圈 rpc 框架 benchmark》(链接见 参考 5)一文中给出了测试论断。
说了这么多,发出话题,总结一句话就是:Getty 只思考应用 Go 语言原生的网络接口,如果遇到网络性能瓶颈也只会在本身层面寻找优化突破点。
Getty 每年都会一次重大的降级,本文给出 Getty 近年的几次重大降级。
1、Goroutine Pool
Getty 初始版本针对一个网络连接启用两个 goroutine:一个 goroutine 进行网络字节流的接管、调用 Reader 接口拆解出网络包 (package)、调用 EventListener.OnMessage() 接口进行逻辑解决;另一个 goroutine 负责发送网络字节流、调用 EventListener.OnCron() 执行定时逻辑。
起初出于晋升网络吞吐的须要,Getty 进行了一次大的优化:将逻辑解决这步逻辑从第一个 goroutine 工作中拆散,增加 Goroutine Pool【下文简称 Gr pool】专门解决网络逻辑。
即网络字节流接管、逻辑解决和网络字节流发送都有独自的 goroutine 解决。
Gr Pool 成员有工作队列【其数目为 M】和 Gr 数组【其数目为 N】以及工作【或者称之为音讯】,依据 N 的数目变动其类型分为可伸缩 Gr pool 与固定大小 Gr pool。可伸缩 Gr Pool 益处是能够随着工作数目变动增减 N 以节约 CPU 和内存资源。
1.1 固定大小 Gr Pool
依照 M 与 N 的比例,固定大小 Gr Pool 又辨别为 1:1、1:N、M:N 三类。
1:N 类型的 Gr Pool 最易实现,集体 2017 年在我的项目 kafka-connect-elasticsearch 中实现过此类型的 Gr Pool:作为消费者从 kafka 读取数据而后放入音讯队列,而后各个 worker gr 从此队列中取出工作进行生产解决。
这种模型的 Gr pool 整个 pool 只创立一个 chan,所有 Gr 去读取这一个 chan,其毛病是:队列读写模型是 一写多读,因为 go channel 的低效率【整体应用一个 mutex lock】造成竞争强烈,当然其网络包解决程序更无从保障。
Getty 初始版本的 Gr pool 模型为 1:1,每个 Gr 多有本人的 chan,其读写模型是一写一读,其长处是可保障网络包解决程序性,如读取 kafka 音讯时候,依照 kafka message 的 key 的 hash 值以取余形式【hash(message key) % N】将其投递到某个 task queue,则同一 key 的音讯都能够保障解决有序。但这种模型的缺点:每个 task 解决要有工夫,此计划会造成某个 Gr 的 chan 外面有 task 梗塞,就算其余 Gr 闲着,也没方法解决之【工作解决“饥饿”】。
更进一步的 1:1 模型的改良计划:每个 Gr 一个 chan,如果 Gr 发现自己的 chan 没有申请,就去找别的 chan,发送方也尽量发往生产快的协程。这个计划相似于 go runtime 外部的 MPG 调度算法应用的 goroutine 队列,但其算法和实现会过于简单。
Getty 起初实现了 M:N 模型版本的 Gr pool,每个 task queue 被 N/M 个 Gr 生产,这种模型的长处是兼顾解决效率和锁压力均衡,能够做到总体层面的工作解决平衡,Task 派发采纳 RoundRobin 形式。
其整体实现如上图所示。具体代码实现请参见 gr pool【参考 7】连贯中的 TaskPool 实现。
1.2 无限度 Gr Pool
应用固定量资源的 Gr pool,在申请量加大的状况下无奈保障吞吐和 RT,有些场景下用户心愿尽可能用尽所有的资源保障吞吐和 RT。
起初借鉴 “A Million WebSockets and Go” 一文【参考 8】中的“Goroutine pool”实现了一个 可有限扩容的 gr pool。
具体代码实现请参见 gr pool【参考 7】连贯中的 taskPoolSimple 实现。
1.3 网络包解决程序
固定大小的 gr pool 长处是限定了逻辑解决流程对机器 CPU/MEMORY 等资源的应用,而 无限度 Gr Pool 尽管放弃了弹性但有可能耗尽机器的资源导致容器被内核杀掉。但无论应用何种模式的 gr pool,getty 无奈保障网络包的解决程序。
譬如 Getty 服务端收到了同一个客户端发来的 A 和 B 两个网络包,Gr pool 模型可能造成服户端先解决 B 包后处理 A 包。同样,客户端也可能先收到服务端对 B 包的 response,而后才收到 A 包的 response。
如果客户端的每次申请都是独立的,没有前后程序关系,则带有 Gr pool 个性的 Getty 不思考程序关系是没有问题的。如果下层用户关注 A 和 B 申请解决的前后程序,则能够把 A 和 B 两个申请合并为一个申请,或者把 gr pool 个性敞开。
2、Lazy Reconnect
Getty 中 session 代表一个网络连接,client 其实是一个网络连接池,保护肯定数量的连贯 session,这个数量当然是用户设定的。Getty client 初始版本【2018 年以前的版本】中,每个 client 独自启动一个 goroutine 轮询检测其连接池中 session 数量,如果没有达到用户设定的连贯数量就向 server 发动新连贯。
当 client 与 server 连贯断开时,server 可能是被下线了,可能是意外退出,也有可能是假死。如果下层用户断定对端 server 的确不存在【如收到注册核心发来的 server 下线告诉】后,调用 client.Close()
接口把连接池敞开掉。如果下层用户没有调用这个接口把连接池敞开掉,client 就认为对端地址还无效,就会一直尝试发动重连,保护连接池。
综上,从一个旧 session 敞开到创立一个新 session,getty client 初始版本的重连解决流程是:
- 旧 session 敞开
网络接管 goroutine
; - 旧 session
网络发送 goroutine
探测到网络接管 goroutine
退出后终止网络发送,进行资源回收后设定以后 session 有效; - client 的轮询 goroutine 检测到有效 session 后把它从 session 连接池删除;
- client 的轮询 goroutine 检测到无效 session 数目少于 getty 下层使用者设定的数目 且 getty 下层使用者没有通过
client.Close()
接口敞开连接池时,就调用连贯接口发动新连贯。
下面这种通过定时轮询形式一直查验 client 中 session pool 中每个 session 有效性的形式,可称之为被动连贯。被动连贯的毛病显然是每个 client 都须要独自启用一个 goroutine。当然,其进一步优化伎俩之一是能够启动一个全局的 goroutine,定时轮询检测所有 client 的 session pool,不用每个 client 独自启动一个 goroutine。然而集体从 2016 年开始始终在思考一个问题:是否换一种 session pool 保护形式,去掉定时轮询机制,齐全不应用任何的 goroutine 保护每个 client 的 session pool?
2018 年 5 月集体在一次午饭后遛弯时,把 getty client 的重连逻辑又从新梳理了一遍,忽然想到了另一种办法,在步骤 2 中齐全能够对 网络发送 goroutine
进行“废物利用”,在这个 goroutine 标记以后 session 有效的逻辑步骤之后再加上一个逻辑:
- 如果以后 session 的维护者是一个 client【因为 session 的使用者也可能是 server】;
- 且如果其以后 session pool 的 session 数量少于下层使用者设定的 session number;
- 且如果下层使用者还没有通过
client.Close()
设定以后 session pool 有效【即以后 session pool 无效,或者说是对端 server 无效】 - 满足下面三个条件,
网络发送 goroutine
执行连贯重连即可; - 新网络连接 session 建设胜利且被退出 client 的 session pool 后,
网络发送 goroutine
使命实现间接退出。
我把这种重连形式称之为 lazy reconnect
,网络发送 goroutine
在其生命周期的最初阶段应该被称之为 网络重连 goroutine
。通过 lazy reconnect
这种形式,上述重连步骤 3 和 步骤 4 的逻辑被合入了步骤 2,client 当然也就没必要再启动一个额定的 goroutine 通过定时轮询的形式保护其 session pool 了。
lazy reconnect
整体流程图如上。如果对相干代码流程感兴趣,请移步 “ 参考 13” 给出的链接,很容易自行剖析进去。
3、定时器
在引入 Gr pool 后,一个网络连接至多应用三个 goroutine:
- 一个 goroutine 进行网络字节流的接管、调用 Reader 接口拆解出网络包 (package)
- 第二个 goroutine 调用
EventListener.OnMessage()
接口进行逻辑解决 - 第三个 goroutine 负责发送网络字节流、调用
EventListener.OnCron()
执行定时逻辑以及lazy reconnect
在连贯较少的状况下这个模型尚可稳固运行。但当集群规模到了肯定规模,譬如每个服务端的连接数达 1k 以上时,单单网络连接就至多应用 3k 个 goroutine,这是对 CPU 计算资源和内存资源极大地节约。下面三个 goroutine 中,第一个 goroutine 无可拆解,第二个 goroutine 理论是 gr pool 一部分,可优化的对象就是第三个 goroutine 的工作。
2020 年底 Getty 保护团队首先把网络字节流工作放入了第二个 goroutine:解决完逻辑工作后立刻进行同步网络发送。此处改良后,第三个 goroutine 就只剩下一个 EventListener.OnCron() 定时解决工作。这个定时逻辑其实能够抛给 Getty 下层调用者解决,但出于不便用户和向后兼容的思考,咱们应用了另一种优化思路:引入工夫轮治理定时心跳检测。
2017 年 9 月时,我曾实现了一个 Go 语言 timer 工夫轮库 timer wheel
(链接见参考 10),兼容 Go 的 timer 所有原生接口,其长处是所有工夫工作都在一个 goroutine 内执行。2020 年 12 月把它引入 getty 后,getty 所有的EventListener.OnCron()
定时解决工作均交由 timer wheel 解决,第三个 goroutine 就能够完满地隐没了【后续:两个月后发现 timer 库被另一个善于拉 star 的 rpc 我的项目“借鉴”走了 ^+^】。
此时第三个 goroutine 就剩下最初一个工作:lazy reconnect
。当第三个 goroutine 不存在后,这个工作齐全能够放入第一个 goroutine:在当 网络字节流接管 goroutine
检测到网络谬误退出前的最初一个步骤,执行 lazy reconnect
。
优化改良后的一个网络连接最多只应用两个 goroutine:
- 一个 goroutine 进行网络字节流的接管、调用 Reader 接口拆解出网络包 (package)、
lazy reconnect
- 第二个 goroutine 调用
EventListener.OnMessage()
接口进行逻辑解决、发送网络字节流
第二个 goroutine 来自 gr pool。思考到 gr pool 中的 goroutine 都是可复用的公共资源,单个连贯实际上只独自占用了第一个 goroutine。
4、Getty 压测
Getty 保护团队的郝洪范同学,借鉴了 rpcx 的 benchmark 程序后实现了 getty benchmark【参考 11】,对优化后的 v1.4.3 版本进行过压测。
「压测环境」:
「压测后果」:
压测后果如上,服务端 TPS 数达 12556,网络吞吐可达 12556 * 915 B/s ≈ 11219 KiB/s ≈ 11 MiB/s。
如上图,可见网络压测前后服务单的 CPU/MEMORY 资源变动,getty 服务端仅仅应用了 6% 的 CPU,内存占用也仅越 100MiB,且在测试压力去掉后很快就把资源还给了零碎。
测试时 getty 服务端的 goroutine 应用见下图:单个 TCP 连贯仅应用一个 goroutine。
整个测试后果以及相干代码请加入 benmark result (链接见【参考 12】)。这个压测当然没有压出 Getty 的极限性能,但曾经可能满足阿里次要场景下的应用需要。
倒退 timeline
从我集体 2016 年时写 Getty 开始,到目前有一个专门的开源团队保护 Getty,Getty 一路走来殊为不易。
梳理其 timeline,其次要倒退工夫节点如下:
– 2016 年 6 月份开发出第一个生产可用版本,反对 TCP/websocket 两种通信协议,同年 10 月在 gocn 上发帖 https://gocn.vip/topics/8229 推广;
– 2017 年 9 月时,实现了一个 Go 语言 timer 工夫轮库 timer wheel_https://github.com/AlexStocks/goext/blob/master/time/time.go_
– 2018 年 3 月在其上退出 UDP 通信反对;
– 2018 年 5 月反对基于 protobuf 和 json 的 RPC;
– 2018 年 8 月退出基于 zookeeper 和 etcd 的服务注册和发现性能,取名 micro;
– 2019 年 5 月 getty 的底层 tcp 通信实现被独立拆出迁入 github.com/dubbogo,后迁入 github.com/apache/dubbo-getty;
– 2019 月 5 月 Getty RPC 包被携程的两位同学迁入 [https://github.com/apache/dub…](https://github.com/apache/dub…),构建了 dubbogo 基于 hessian2 协定的 RPC 层;、
– 2019 年 5 月,退出固定大小 goroutine pool;
– 2019 年底,刘晓敏同学告知其基于 Getty 实现了 seata-golang;
– 2020 年 11 月,把网络发送与逻辑解决合并放入 gr pool 中解决;
– 2021 年 5 月,实现定时器优化;
最初,还是如第三节优化结尾局部所说,Getty 保护团队不谋求无意义的 benchmark 数据,不做无意义的炫技式优化,只依据生产环境需要来进行本身改良。只有保护团队在,Getty 稳定性和性能定会越来越优良。
如果对 getty 感兴趣,欢送退出搜寻钉钉群号 23331795 钉钉群与社区进行交换。
|作 者 介 绍|
_「于雨」_ GitHub 账号 AlexStocksdubbogo 社区负责人。一个有十一年服务端基础架构和中间件研发一线工作教训的程序员。陆续参加和改良过 Redis/Pika/Pika-Port/etcd/Muduo/Dubbo/dubbo-go/Sentinel-golang/Seata-golang 等出名我的项目,目前在蚂蚁团体可信原生技术部从事云原生工作。
_「郝洪范」_ GitHub 账号 georgehaoApache Dubbo Committer,getty 保护团队成员。目前在京东批发部大数据平台,熟练掌握 Go runtime 底层技术。
_「董剑辉」_ GitHub 账号 Mulavar2021 年 5 月份从浙江大学驰名 VLIS 实验室研究生毕业。曾在蚂蚁团体杭州总部领取业务资金服务技术部实习,目前就任于美团大数据北京总部计算引擎组,从事 flink 相干开发工作。
|参 考|
- 1
https://github.com/alexstocks/goext/blob/master/container/xorlist/xorlist.go
- 2 兼容 tcp 和 websocket 的一个简洁网络框架 getty
https://gocn.vip/topics/8229
- 3 字节跳动在 Go 网络库上的实际
https://juejin.cn/post/6844904153173458958
- 4 字节跳动 Go RPC 框架 KiteX 性能优化实际
https://mp.weixin.qq.com/s/Xoaoiotl7ZQoG2iXo9\_DWg
- 5 2021 年 Go 生态圈 rpc 框架 benchmark
https://colobu.com/2021/08/01/benchmark-of-rpc-frameworks/
- 6 分布式事务框架 seata-golang 通信模型
https://mp.weixin.qq.com/s/7xoshM4lzqHX9WqANbHAJQ
- 7 gr pool
https://github.com/dubbogo/gost/blob/master/sync/task\_pool.go
- 8 A Million WebSockets and Go
https://www.freecodecamp.org/news/million-websockets-and-go-cc58418460bb/
- 9 task pool
https://github.com/dubbogo/gost/blob/master/sync/base\_worker\_pool.go
- 10 timer wheel
https://github.com/dubbogo/gost/blob/master/time/timer.go
- 11 getty benchmark
- https://github.com/apache/dubbo-getty/tree/master/benchmark
- 12 benmark result
- https://github.com/apache/dubbo-getty/pull/61#issuecomment-865698715
- 13 lazy connection
- https://github.com/AlexStocks/getty/blob/73b0928b957ab6b6773f6cfe95c909ae39001687/transport/client.go#L412
版权申明:本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。