libhv
是一个跨平台的
c/c++
网络库,本文写在
libhv
开源四周年之际,借机回顾了
libhv
的发展历程。
github
地址:https://github.com/ithewei/libhv
文章目录
无心插柳,扬长避短
时光荏苒,如白驹过隙。
往事回首,恰插柳成荫。
libhv 的 first commit 记录是在2018年8月28日,芳龄25的我在阅面科技搬砖,刚刚从
PC
客户端转型做
linux
服务端开发(想扒拉我牛马一生的可以看我的另一篇博客,一个程序猿的自传)。
libhv
最初只是我个人积累的一些跨平台基础设施代码片段,连库都算不上,如时间、日志、线程、字符串等,也就是现在的 base模块,她最初也不叫
libhv
,叫
hw
(不是碰瓷华为,也不是硬件,仅仅是我个人名字的首字母缩写),后面因为在项目中使用过
libevent、libuv
(c语言领域大名鼎鼎的网络库),但总觉得有不好用或者不好理解的地方,如
libevent
的
bufferevent
就非常难以理解,函数命名也不统一,参数里有很多宏定义,造成了极大的认知负担;
libuv
的命名倒是非常规整,统一以
uv_
作为前缀,唯一我认为极不好用的一点是
uv_write
函数,需要扩展
uv_write_t
结构体构造一个写请求,然后在写完成回调里去释放
uv_buf_t
和这个写请求结构体,对于非阻塞写的内存管理完全交给用户,没有提供一个便捷的内置实现,这里对新手来说非常难以使用好,每次写请求都需要
malloc/free
的示例写法绝不是合理的。关于常见
c/c++
网络库的
echo-server
写法比较以及
ping-pong
性能测试见 echo-servers 目录。
于是我发奋图强,凿壁借二大爷家的光,走马观花了
libevent、libev、libuv、nginx、redis
源码,给
hw
加上了event 事件循环模块,封装了
select、poll、epoll、kqueue
等多种IO多路复用模型,(
libhv
拥有了
event
模块,就犹如张无忌获得了九阳神功这门高深内功,开发应用层协议那就是小菜一碟),并易名为
libhv
,寓意高性能的事件循环库
High-performance event loop library
(强行寓意,我TM真是个人才啊)。但
libhv
绝不是闭门造车和简单的重复造轮子,她站在巨人上的肩膀上再创作,扬长避短,去糟取精,精雕细琢,她有着自己的信仰和使命,为国产争光。
当然有人说没必要开发使用网络库,直接使用
epoll
不行吗?也就
socket->bind->listen->accept、epoll_create、epoll_ctl、epoll_wait
几个系统API,当然可以,但当你真正工程实践时,且不论
跨平台
,
定时心跳、定时推送需要用到定时器
、
write、close的线程安全问题
、
非阻塞写队列的维护
、
读缓冲readbuf的自动扩缩容
、
粘包分包的处理
、
负载均衡策略
,哪一项不是有挑战性的难题,久而久之自然就形成了一层封装,形成所谓的网络库,而且网络库需要时间的沉淀和考验。
精心呵护,深耕细作
一颗幼苗想要长成为参天大树,必先深深扎根于大地,然后不断施肥浇水、悉心照料,才能茁壮成长。
在2019年到2020年,2年的时间里,libhv都在不断完善和新增功能阶段,包括:
- 参考 陈硕的muduo 和 奇虎360的evpp,提供了c++类封装的 evpp 模块;
- 实现了本世纪最通用的
HTTP
协议以及WebSocket
协议,源代码见 http 模块,客户端接口设计参考了 python 的 requests ,服务端接口设计参考了 golang 的 gin 和 nodejs 的 express(所以libhv
真不是闭门造车,反倒是山寨之王); - 集成了
openssl、mbedtls、gnutls
等SSL/TLS
库提供加密功能,源代码见 ssl 模块;
起步阶段,
libhv
的
star
数量增长是非常缓慢的,我记得在我2020年5月面试字节时(想了解字节面试的可以看我的另外一篇博客 十面字节跳动,欢迎找我内推),
libhv
才四百多星,下图是我在 star-history 网站下载的一张
star
走势图:
在2020年11月,有一段直线上升期,那是因为该月内上了几次
github trending
榜,所以
star
数量猛增突破了1k星,为此我还高兴了好一阵,特写了一篇博文纪念之,见 纪念libhv上github trending (决不放过任何一个可以吹牛的机会)。
直到2021年2月28日,我才正式release了第一个版本,见 github releases 记录 。
2021、2022两年的时间里,主要是完善了教程和技术支持,包括:
- 建立了 QQ技术交流群
739352073
,目前已有群成员1k+,欢迎入群交流; - 提供了很多的示例代码,见 examples 目录;
- 编写了 libhv入门教程(写教程可一点不比写代码轻松);
当然也有技术上的重大更新,包括:
- 内置拆包模式,支持
固定包长、分隔符、头部长度字段
三种常见的拆包方式(这个在c/c++
领域绝对是首屈一指,目前我只在java
的netty
里见过),详见 TCP如何处理粘包与分包; http
添加了HttpService::Static
设置静态资源目录,以及HttpService::Proxy
设置代理转发,可以很方便实现和nginx
的配置文件里location、root、proxy_pass
类似功能;- 添加了 mqtt 模块(利用了上面提到的拆包功能,整个
mqtt
协议实现只花了不到 600 行,非常适合学习开发自定义协议) 可靠UDP
支持,集成了KCP
(私下实现了c语言版本的kcptun
,这部分尚未开源)
齐心协力,厚积薄发
世上绝没有随随便便的成功,一切偶然其实也是必然。
令我欣慰的是,自建群以来,我收到不少说
libhv简单易用
、
已用于生产环境
、
通过libhv学到了很多
等正向反馈;当然也有出现bug的反馈,也都会及时跟进修复;群管理员也非常给力,非常耐心地答疑解惑,再次感谢他们的付出(当然也呼吁大家提问前能先翻阅下 FAQ文档,80%的问题可以在这里面找到答案,关于网络编程里常见的坑请参考 网络编程十宗罪 排查下);另外 contributors 也多了十几位,可惜我没有薪资报酬你们,都是用爱发电。
libhv
的口号是
让世上没有难写的网络程序
,虽然目前已取得一些成效,但还有很长的路要走。
关于
libhv
的一些后续计划,见 https://github.com/ithewei/libhv/blob/master/docs/PLAN.md
包括:
- 开发
libhv官网
redis client
:redis
同步/异步客户端mysql client
:mysql
同步/异步客户端(虽然我不太赞成使用c/c++
开发数据库CURD
业务)async DNS
:异步DNS
(自实现或者接入cares
)- 绑定到其它语言,如
lua、js、python
,可以使用脚本开发业务逻辑 hrpc
:基于libhv
实现RPC
框架,兼容grpc
、thrift
协议(注:简单的rpc
实现可以参考 examples目录 下的 jsonrpc,protorpc,当然一个完善的RPC
框架涉及IDL
自动生成各种语言的脚手架、服务注册与发现、负载均衡、重试、熔断、限流等,推荐看 brpc的文档,能学到很多,目前能满足多语言版本的成熟RPC
框架也就grpc
、thrift
)rudp
: 可靠UDP
(目前接入了KCP
,后续可能接入FEC、QUIC
)io_uring
:接入io_uring
尝鲜coroutine
:协程,我的想法是等c++20
成熟后,直接基于c++20
的协程实现cppsocket.io
:基于libhv
实现c++
版本的 socket.ioIM-libhv
:基于libhv
实现IM即时通信
,例如网页即时聊天、即时消息推送、微信小程序、手机app消息推送、PC软件消息推送等等MediaServer-libhv
:基于libhv
实现流媒体服务
,类似 srs、ZLMediaKitGameServer-libhv
:基于libhv
实现游戏服务
,类似 skynet、kbengine
以上列举的这些计划和应用场景仅供参考,抛砖引玉,给大家提供一个思路;
一个人的时间精力毕竟有限,只有依靠社区的力量才能做大做强,建立起生态,希望有越来越多的人能加入到
libhv
的贡献中来。
最后,想说的是:
即使c++推出标准网络库,我希望ta也有用武之地;
即使终将凋零,至少ta曾经绽放过;
为开源精神点赞!
为国产争光!
版权归原作者 ithewei 所有, 如有侵权,请联系我们删除。