基于 libevent 开发的 C++ 11 高性能网络服务器 evpp

BSD 3-Clause
C/C++
跨平台
360
2017-03-06
zieckey

evpp是一个基于libevent开发的现代化C++11高性能网络服务器,自带TCP/UDP/HTTP等协议的异步非阻塞式的服务器和客户端库。

特性:

  • 现代版的C++11接口

  • 非阻塞异步接口都是C++11的functional/bind形式的回调仿函数(不是libevent中的C风格的函数指针)

  • 非阻塞纯异步多线程TCP服务器/客户端

  • 非阻塞纯异步多线程HTTP服务器/客户端

  • 非阻塞纯异步多线程UDP服务器

  • 支持多进程模式

  • 优秀的跨平台特性和高性能(继承自libevent的优点)

除此之外,基于该库之上,还提供两个附带的应用层协议库:

  • evmc :一个纯异步非阻塞式的memcached的C++客户端库,支持membase集群模式。详情请见:evmc readme

  • evnsq : 一个纯异步非阻塞式的NSQ的C++客户端库,支持消费者、生产者、服务发现等特性。详情请见:evnsq readme
    将来还会推出redis的客户端库。

由来:

我们开发小组负责的业务需要用到TCP协议来建设长连接网关服务和一些其他的一些基于TCP的短连接服务,在调研开源项目的过程中,没有发现一个合适的库来满足我们要求。结合我们自身的业务情况,理想中的C++网络库应具备一下几个特性:

  • 接口简单易用,最好是C++接口

  • 多线程,也能支持多进程

  • 最好是基于libevent实现(因为现有的历史遗留框架、基础库等是依赖libevent),这样能很方便嵌入libevent的事件循环,否则改动较大或者集成起来的程序可能会有很多跨线程的调用

基于这些需要,可供选择的不多,所以我们只能自己开发一个。开发过程中,接口设计方面基本上大部分是参考muduo项目来设计和实现的,当然也做了一些取舍和增改;同时也大量借鉴了Golang的一些设计哲学和思想,举几个小例子来说明一下:

  1. Duration : 这是一个时间区间相关的类,自带时间单位信息,参考了Golang项目中的Duration实现。我们在其他项目中见到太多的时间是不带单位的,例如timeout,到底是秒、毫秒还是微秒?需要看文档说明或具体实现,好一点的设计会将单位带在变量名中,例如timeout_ms,但还是没有Duration这种独立的类好。目前C++11中也有类似的实现std::chrono::duration,但稍显复杂,没有咱们这个借鉴Golang实现的版本来的简单明了。

  2. Buffer : 这是一个缓冲区类,融合了muduo和Golang两个项目中相关类的设计和实现

  3. http::Server : 这是一个http服务器类,自带线程池,它的事件循环和工作线程调度,完全是线程安全的,业务层不用太多关心跨线程调用问题。同时,还将http服务器的核心功能单独抽取出来形成

  4. http::Service类,是一个可嵌入型的服务器类,可以嵌入到已有的libevent事件循环中。
    网络地址的表达就仅仅使用"ip:port"这种形式字符串表示,就是参考Golang的设计

  5. httpc::ConnPool是一个http的客户端连接池库,设计上尽量考虑高性能和复用。以后基于此还可以增加负载均衡和故障转移等特性。


另外,我们实现过程中极其重视线程安全问题,一个事件相关的资源必须在其所属的EventLoop中初始化和析构释放,这样我们能最大限度的减少出错的可能。为了达到这个目标我们重载event_add和event_del等函数,每一次调用event_add,就在对应的线程私有数据中记录该对象,在调用event_del时,检查之前该线程私有数据中是否拥有该对象,然后在整个程序退出前,再完整的检查所有线程的私有数据,看看是否仍然有对象没有析构释放,详细代码实现可以参考 https://github.com/Qihoo360/evpp/blob/master/evpp/inner_pre.cc#L46~L87。我们如此苛刻的追求线程安全,只是为了让一个程序能安静的平稳的退出或Reload,因为我们深刻的理解“编写永远运行的系统,和编写运行一段时间后平静关闭的系统是两码事”,后者要困难的多。

的码云指数为
超过 的项目
加载中

评论(18)

j
johnroot
性能很好!
龚欢
龚欢
我之前看过整个项目,感觉还行,但是其实整合libevent是有代价的, 特别是c/C++系列语言, 至少我面对过的,业务和复杂程度超过一定界限之后,别人的不一定有完全自己写的灵活;整合异步client,做新的协议支持, 一些RTB业务的支持等。有兴趣的可以看看:https://github.com/HuanGong/LightingIO 还在开发中,使用c++11和 整合协程 coroutine, 新的协议支持和整合方面还是很好的。
飞鸿眉敛
飞鸿眉敛
一切有码有编译脚本的开源代码都不应该因为编译问题而阻拦我们使用,如果不会编译,那该考虑提高自身能力了,本人windows linux下无压力运行
z
zchao998
缺少开发指南文档,建议开一个社区,让大家涌跃讨论,反馈与解决问题。php workerman(底层也是用libevent,上层用php封装)这个就做的不错。evpp c++版本 。可以考虑加入更多的协议支持,如websocket等。还有一个就是不同协议之间的client也能够通信(这一点php workerman完美做到这一点)。如 TCP clientA 与 Websocket clientB 经过服务器后,这两个client是可以相互通信的。
小黄儿
运行的时候发现找不到evpp_static.lib
wzj1989
wzj1989
研究下先
willnet
willnet
很好很强大,有空测试一下
n
norval
如果是linux,直接用epoll写个简单的封装,最多几百行,完全替代libevent
菩提子
菩提子
代码样例程序能整理一下吗,直接跑都编译不过。虽然我们能自己搞,但是。。。。
billow
billow
还是喜欢libevent,代码相对可控,asio有些地方写得太绕。。

暂无资讯

暂无问答

360 evpp现代化C++11高性能TCP UDP HTTP网络库

1 安装方法,源码包有说明:https://github.com/Qihoo360/evpp ---------------------------------------------------------------------------------------------------------------- 2 tcp...

01/14 16:13
34
0
好用的C++第三方库

---------------------------------------------------------------------------------------------------------------- 1 x2struct https://github.com/xyz347/x2struct 用于将json/xml/li...

01/14 18:36
24
0
区块链开发与区块链应用开发

比特币区块链是用C++开发的没错,以太坊和超级账本使用Go开发的。但是以太坊区块链应用开发用的js(web3.js api方便调用),因为我们只是在公链或联盟链上开发Dapp,所以根本只需要会编写智能...

02/01 16:12
11
0

没有更多内容

加载失败,请刷新页面

没有更多内容

返回顶部
顶部