默认
打赏 发表评论 12
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
阅读(204599) | 评论(12 收藏19 淘帖2 2
微信扫一扫关注!

1、前言


微信于2013年开源的ibco库,是微信后台大规模使用的c/c++协程库,2013年至今稳定运行在微信后台的数万台机器上。libco在2013年的时候作为腾讯六大开源项目首次开源,ibco支持后台敏捷的同步风格编程模式,同时提供系统的高并发能力。

有关开发libco的背后故事,请见文章《微信异步化改造实践:8亿月活、单机千万连接背后的后台解决方案》。

2、libco支持的特性


libco主要特性:

  • 无需侵入业务逻辑,把多进程、多线程服务改造成协程服务,并发能力得到百倍提升;
  • 支持CGI框架,轻松构建web服务(New);
  • 支持gethostbyname、mysqlclient、ssl等常用第三库(New);
  • 可选的共享栈模式,单机轻松接入千万连接(New)。

libco完善简洁的协程编程接口:

  • 类pthread接口设计,通过co_create、co_resume等简单清晰接口即可完成协程的创建与恢复;
  • 类__thread的协程私有变量、协程间通信的协程信号量co_signal (New);
  • 非语言级别的lambda实现,结合协程原地编写并执行后台异步任务 (New);
  • 基于epoll/kqueue实现的小而轻的网络框架,基于时间轮盘实现的高性能定时器。

3、libco产生的背景


早期微信后台因为业务需求复杂多变、产品要求快速迭代等需求,大部分模块都采用了半同步半异步模型。接入层为异步模型,业务逻辑层则是同步的多进程或多线程模型,业务逻辑的并发能力只有几十到几百。随着微信业务的增长,系统规模变得越来越庞大,每个模块很容易受到后端服务/网络抖动的影响。

4、异步化改造的选择


为了提升微信后台的并发能力,一般的做法是把现网的所有服务改成异步模型。这种做法工程量巨大,从框架到业务逻辑代码均需要做一次彻底的改造,耗时耗力而且风险巨大。于是我们开始考虑使用协程。

但使用协程会面临以下挑战:

  • 业界协程在c/c++环境下没有大规模应用的经验;
  • 如何控制协程调度;
  • 如何处理同步风格的API调用,如Socket、mysqlclient等;
  • 如何处理已有全局变量、线程私有变量的使用。

最终我们通过libco解决了上述的所有问题,实现了对业务逻辑非侵入的异步化改造。我们使用libco对微信后台上百个模块进行了协程异步化改造,改造过程中业务逻辑代码基本无修改。至今,微信后台绝大部分服务都已是多进程或多线程协程模型,并发能力相比之前有了质的提升,而libco也成为了微信后台框架的基石。

5、libco框架技术架构图


libco在框架分为三层,分别是接口层、系统函数Hook层以及事件驱动层。

开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]_1.png

6、libco对同步风格API的创新处理


对于同步风格的API,主要是同步的网络调用,libco的首要任务是消除这些等待对资源的占用,提高系统的并发性能。一个常规的网络后台服务,我们可能会经历connect、write、read等步骤,完成一次完整的网络交互。当同步的调用这些API的时候,整个线程会因为等待网络交互而挂起。

虽然同步编程风格的并发性能并不好,但是它具有代码逻辑清晰、易于编写的优点,并可支持业务快速迭代敏捷开发。为了继续保持同步编程的优点,并且不需修改线上已有的业务逻辑代码,libco创新地接管了网络调用接口(Hook),把协程的让出与恢复作为异步网络IO中的一次事件注册与回调。当业务处理遇到同步网络请求的时候,libco层会把本次网络请求注册为异步事件,本协程让出CPU占用,CPU交给其它协程执行。libco会在网络事件发生或者超时的时候,自动的恢复协程执行。

大部分同步风格的API我们都通过Hook的方法来接管了,libco会在恰当的时机调度协程恢复执行。

7、libco达到千万级协程的支持


libco默认是每一个协程独享一个运行栈,在协程创建的时候,从堆内存分配一个固定大小的内存作为该协程的运行栈。如果我们用一个协程处理前端的一个接入连接,那对于一个海量接入服务来说,我们的服务的并发上限就很容易受限于内存。为此,libco也提供了stackless的协程共享栈模式,可以设置若干个协程共享同一个运行栈。同一个共享栈下的协程间切换的时候,需要把当前的运行栈内容拷贝到协程的私有内存中。为了减少这种内存拷贝次数,共享栈的内存拷贝只发生在不同协程间的切换。当共享栈的占用者一直没有改变的时候,则不需要拷贝运行栈。

开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]_2.png

libco协程的共享协程栈模式使得单机很容易接入千万连接,只需创建足够多的协程即可。我们通过libco共享栈模式创建1千万的协程(E5-2670 v3 @ 2.30GHz * 2, 128G内存),每10万个协程共享的使用128k内存,整个稳定echo服务的时候总内存消耗大概为66G。

8、libco协程级私有变量


多进程程序改造为多线程程序时候,我们可以用__thread来对全局变量进行快速修改,而在协程环境下,我们创造了协程变量ROUTINE_VAR,极大简化了协程的改造工作量。

因为协程实质上是线程内串行执行的,所以当我们定义了一个线程私有变量的时候,可能会有重入的问题。比如我们定义了一个__thread的线程私有变量,原本是希望每一个执行逻辑独享这个变量的。但当我们的执行环境迁移到协程了之后,同一个线程私有变量,可能会有多个协程会操作它,这就导致了变量冲入的问题。为此,我们在做libco异步化改造的时候,把大部分的线程私有变量改成了协程级私有变量。协程私有变量具有这样的特性:当代码运行在多线程非协程环境下时,该变量是线程私有的;当代码运行在协程环境的时候,此变量是协程私有的。底层的协程私有变量会自动完成运行环境的判断并正确返回所需的值。

协程私有变量对于现有环境同步到异步化改造起了举足轻重的作用,同时我们定义了一个非常简单方便的方法定义协程私有变量,简单到只需一行声明代码即可。

9、libco的gethostbyname Hook方法介绍


对于现网服务,有可能需要通过系统的gethostbyname API接口去查询DNS获取真实地址。我们在协程化改造的时候,发现我们hook的socket族函数对gethostbyname不适用,当一个协程调用了gethostbyname时会同步等待结果,这就导致了同线程内的其它协程被延时执行。我们对glibc的gethostbyname源码进行了研究,发现hook不生效主要是由于glibc内部是定义了__poll方法来等待事件,而不是通用的poll方法;同时glibc还定义了一个线程私有变量,不同协程的切换可能会重入导致数据不准确。最终gethostbyname协程异步化是通过Hook __poll方法以及定义协程私有变量解决的。

gethostbyname是glibc提供的同步查询dns接口,业界还有很多优秀的gethostbyname的异步化解决方案,但是这些实现都需要引入一个第三方库并且要求底层提供异步回调通知机制。libco通过hook方法,在不修改glibc源码的前提下实现了的gethostbyname的异步化。

10、libco定义了协程信号量的概念


在多线程环境下,我们会有线程间同步的需求,比如一个线程的执行需要等待另一个线程的信号,对于这种需求,我们通常是使用pthread_signal 来解决的。在libco中,我们定义了协程信号量co_signal用于处理协程间的并发需求,一个协程可以通过co_cond_signal与co_cond_broadcast来决定通知一个等待的协程或者唤醒所有等待协程。

11、libco技术小结


libco是一个高效的c/c++协程库,提供了完善的协程编程接口、常用的Socket族函数Hook等,使得业务可用同步编程模型快速迭代开发。随着几年来的稳定运行,libco作为微信后台框架的基石发挥了举足轻重的作用。

12、源码打包下载


libco-20161207snapshot(52im.net).zip (42.39 KB , 下载次数: 33 , 售价: 1 金币)

13、最新源码地址


https://github.com/52im/libco

附录1:全站精品资源下载


[1] 精品源码下载:
轻量级即时通讯框架MobileIMSDK的iOS源码(开源版)[附件下载]
开源IM工程“蘑菇街TeamTalk”2015年5月前未删减版完整代码 [附件下载]
微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示 [附件下载]
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示 [附件下载]
用于IM中图片压缩的Android工具类源码,效果可媲美微信 [附件下载]
高仿Android版手机QQ可拖拽未读数小气泡源码 [附件下载]
一个WebSocket实时聊天室Demo:基于node.js+socket.io [附件下载]
Android聊天界面源码:实现了聊天气泡、表情图标(可翻页) [附件下载]
高仿Android版手机QQ首页侧滑菜单源码 [附件下载]
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
分享java AMR音频文件合并源码,全网最全
微信团队原创Android资源混淆工具:AndResGuard [有源码]
一个基于MQTT通信协议的完整Android推送Demo [附件下载]
Android版高仿微信聊天界面源码 [附件下载]

[2] 精品文档和工具下载:
计算机网络通讯协议关系图(中文珍藏版)[附件下载]
史上最全即时通讯软件简史(精编大图版)[附件下载]
基于RTMP协议的流媒体技术的原理与应用(技术论文)[附件下载]
独家发布《TCP/IP详解 卷1:协议》CHM版 [附件下载]
良心分享:WebRTC 零基础开发者教程(中文)[附件下载]
MQTT协议手册(中文翻译版)[附件下载]
经典书籍《UNIX网络编程》最全下载(卷1+卷2、中文版+英文版)[附件下载]
音视频开发理论入门书籍之《视频技术手册(第5版)》[附件下载]
国际电联H.264视频编码标准官方技术手册(中文版)[附件下载]
Apache MINA2.0 开发指南(中文版)[附件下载]
网络通讯数据抓包和分析工具 Wireshark 使用教程(中文) [附件下载]
最新收集NAT穿越(p2p打洞)免费STUN服务器列表 [附件下载]
高性能网络编程经典:《The C10K problem(英文)》[附件下载]
即时通讯系统的原理、技术和应用(技术论文)[附件下载]
技术论文:微信对网络影响的技术试验及分析[附件下载]
华为内部3G网络资料: WCDMA系统原理培训手册[附件下载]
网络测试:Android版多路ping命令工具EnterprisePing[附件下载]
Android反编译利器APKDB:没有美工的日子里继续坚强的撸
一款用于P2P开发的NAT类型检测工具 [附件下载]
两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]

[3] 精选视频、演讲PPT下载:
QQ空间移动端10亿级视频播放技术优化揭秘(视频+PPT)[附件下载]
RTC实时互联网2017年度大会精选演讲PPT [附件下载]
微信分享开源IM网络层组件库Mars的技术实现(视频+PPT)[附件下载]
微服务理念在微信海量用户后台架构中的实践(视频+PPT)[附件下载]
移动端IM开发和构建中的技术难点实践分享(视频+PPT)[附件下载]
网易云信的高品质即时通讯技术实践之路(视频+PPT)[附件下载]
腾讯音视频实验室:直面音视频质量评估之痛(视频+PPT)[附件下载]
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT[附件下载]
微信朋友圈海量技术之道PPT[附件下载]
手机淘宝消息推送系统的架构与实践(音频+PPT)[附件下载]
如何进行实时音视频的质量评估与监控(视频+PPT)[附件下载]
Go语言构建高并发消息推送系统实践PPT(来自360公司)[附件下载]
网易IM云千万级并发消息处理能力的架构设计与实践PPT [附件下载]
手机QQ的海量用户移动化实践分享(视频+PPT)[附件下载]
钉钉——基于IM技术的新一代企业OA平台的技术挑战(视频+PPT)[附件下载]
微信技术总监谈架构:微信之道——大道至简(PPT讲稿)[附件下载]
Netty的架构剖析及应用案例介绍(视频+PPT)[附件下载]
声网架构师谈实时音视频云的实现难点(视频采访)
滴滴打车架构演变及应用实践(PPT讲稿)[附件下载]
微信海量用户背后的后台系统存储架构(视频+PPT)[附件下载]
在线音视频直播室服务端架构最佳实践(视频+PPT)[附件下载]
从0到1:万人在线的实时音视频直播技术实践分享(视频+PPT)[附件下载]
微信移动端应对弱网络情况的探索和实践PPT[附件下载]
Android版微信从300KB到30MB的技术演进(PPT讲稿)[附件下载]

附录2:相关文章汇总


[1] 有关QQ、微信的技术文章:
微信后台团队:微信后台异步消息队列的优化升级实践分享
微信团队原创分享:微信客户端SQLite数据库损坏修复实践
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)
微信Mars:微信内部正在使用的网络层封装库,即将开源
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]
微信团队原创分享:Android版微信从300KB到30MB的技术演进
微信技术总监谈架构:微信之道——大道至简(演讲全文)
微信技术总监谈架构:微信之道——大道至简(PPT讲稿) [附件下载]
如何解读《微信技术总监谈架构:微信之道——大道至简》
微信海量用户背后的后台系统存储架构(视频+PPT) [附件下载]
微信异步化改造实践:8亿月活、单机千万连接背后的后台解决方案
微信朋友圈海量技术之道PPT [附件下载]
微信对网络影响的技术试验及分析(论文全文)
一份微信后台技术架构的总结性笔记
架构之道:3个程序员成就微信朋友圈日均10亿发布量[有视频]
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
快速裂变:见证微信强大后台架构从0到1的演进历程(二)
微信团队原创分享:Android内存泄漏监控和优化技巧总结
全面总结iOS版微信升级iOS9遇到的各种“坑”
微信团队原创资源混淆工具:让你的APK立减1M
微信团队原创Android资源混淆工具:AndResGuard [有源码]
Android版微信安装包“减肥”实战记录
iOS版微信安装包“减肥”实战记录
移动端IM实践:iOS版微信界面卡顿监测方案
微信“红包照片”背后的技术难题
移动端IM实践:iOS版微信小视频功能技术方案实录
移动端IM实践:Android版微信如何大幅提升交互性能(一)
移动端IM实践:Android版微信如何大幅提升交互性能(二)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
移动端IM实践:iOS版微信的多设备字体适配方案探讨
>> 更多同类文章 ……

[2] 有关QQ、微信的技术故事:
技术往事:创业初期的腾讯——16年前的冬天,谁动了马化腾的代码
技术往事:史上最全QQ图标变迁过程,追寻IM巨人的演进历史
开发往事:深度讲述2010到2015,微信一路风雨的背后
开发往事:微信千年不变的那张闪屏图片的由来
开发往事:记录微信3.0版背后的故事(距微信1.0发布9个月时)
一个微信实习生自述:我眼中的微信开发团队
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:微信移动端应对弱网络情况的探索和实践PPT [附件下载]下一篇:网易IM云千万级并发消息处理能力的架构设计与实践PPT [附件下载]

本帖已收录至以下技术专辑

推荐方案
评论 12
楼主有正式使用过libco吗
引用:william 发表于 2017-01-04 09:19
楼主有正式使用过libco吗

我没正式用过,但你如果精通c++的话值得花时间研究一下,这样的东西目前基本没有第种实现。
嗯,我现在线上是用的,效果还可以
引用:william 发表于 2017-01-04 13:58
嗯,我现在线上是用的,效果还可以

用在你自已的IM服务端了?性能有微信官方说的这么好吗?
值得学习
签名: talk is cheap,show me the code
感谢分享!!!!!!!!
mark
签名: 样样精通
感谢分享
感谢分享!
必须学习一下,谢谢分享
这些都是erlang语言的特性啊
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部