主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
Ibco是微信后台使用的大规模c/c++协作库,自2013年以来一直在微信后台数万台机器上稳定运行。2013年,libco作为腾讯六大开源项目之一首次开放。最近,我们做了一个大更新,并在github.com/tencent/libco.同步更新。Libco在后台支持敏捷同步风格编程模式,并提供系统的高并发性。libco支持的特性无需入侵业务逻辑,将多进程多线程服务转化为协同服务,并发能力提升百倍;支持cgi框架,轻松构建web服务(新);支持gethostbyname、mysqlclient、ssl等常用第三库(新增);可选共享堆栈模式,单机可轻松接入千万级连接(新增);完善简洁的协程编程界面——类pthread界面设计,可通过co_create、co_resume等简单明了的界面完成协程的创建和恢复;–类线程协程私有变量,协程通信的协程信号量co _ signal(new);-非语言级别的lambda实现,结合coroutine编写和执行后台异步任务(新);–基于epoll/kqueue的小型轻型网络框架,以及基于时间轮盘的高性能定时器;libco出现的背景在早期,由于业务需求的复杂多变和产品的快速迭代,大多数模块采用了半同步和半异步模型。接入层是异步模型,而业务逻辑层是同步多进程或多线程模型,业务逻辑的并发能力只有几十到几百。随着微信业务的增长,系统规模越来越大,各个模块很容易受到后端服务/网络抖动的影响。异步改造的选择为了提高微信后台的并发能力,一般的做法是将现有网络的所有服务都改为异步模式。这种方法工作量巨大,需要从框架到业务逻辑代码的彻底转换,耗时耗力且风险极大。所以我们开始考虑使用协程。但使用协通会面临以下挑战:行业协通在c/c++环境下没有大规模应用经验;如何控制协同调度;如何处理同步api调用,如socket、mysqlclient等。如何处理现有全局变量和线程私有变量的使用;最终,我们通过libco解决了上述所有问题,实现了业务逻辑的非侵入式异步转换。我们使用libco对微信后台数百个模块进行异步改造,改造过程中业务逻辑代码基本不变。截至目前,微信后台的大部分服务已经是多进程或多线程协同模式,并发能力较之前有了质的提升,libco也成为微信后台框架的基石。Libco框架libco分为三层,即接口层、系统函数钩子层和事件驱动层。
同步风格API的处理对于同步风格API,它主要是同步网络调用。libco的主要任务是消除这些等待对资源的占用,提高系统的并发性能。对于传统的网络后台服务,我们可能会经历连接、写入和读取等步骤来完成完整的网络交互。当这些API被同步调用时,整个线程将挂起等待网络交互。虽然同步编程风格的并发性能不佳,但它具有代码逻辑清晰、易于编写的优点,可以支持业务的快速迭代敏捷开发。为了保持同步编程的优势,在不修改线路上现有业务逻辑代码的情况下,libco创新性地接管了网络调用接口(Hook),将协议的放弃和恢复视为异步网络IO中的事件注册和回调。当业务流程遇到同步网络请求时,libco层会将此网络请求注册为异步事件,并且此会话将放弃CPU,CPU将移交给其他会话执行。当网络事件发生或超时时,Libco将自动恢复协议的执行。我们已经通过Hook方法接管了大部分同步API,libco将调度该进程在适当的时间恢复执行。默认情况下,libco支持1000万级协程。创建协程时,从堆内存中分配一个固定大小的内存作为协程。如果我们使用协程在前端处理访问连接,那么对于大规模访问服务来说,我们服务的并发限制很容易受到内存的限制。为此,libco还提供了协程共享的无堆栈模式,可以设置几个协程共享同一个运行堆栈。在同一个共享堆栈下的进程之间切换时,需要将当前运行堆栈的内容复制到进程的私有内存中。为了减少内存副本的数量,共享堆栈的内存副本只在不同的进程之间切换。当共享堆栈的占用者没有改变时,没有必要复制正在运行的堆栈。
libco协议的共享协议栈模式使单台计算机可以轻松访问成千上万个连接,只需创建足够的协议即可。我们通过libco的共享堆栈模式创建了1000万个协程(E5-2670 v3 @ 2.30GHz * 2,128G内存),每10万个协程共享128k内存,因此在稳定echo服务时总内存消耗约为66G。当Concordance的私有变量多进程程序转换为多线程程序时,我们可以使用线程快速修改全局变量。在Concordance环境中,我们创建了Concordance变量ROUTINE_VAR,这大大简化了Concordance转换的工作量。因为协程本质上是在线程内串行执行的,所以当我们定义一个线程私有变量时,可能会出现重入问题。例如,我们定义了thread的一个线程私有变量,它原本是每个执行逻辑专用的。然而,当我们的执行环境迁移到协程时,可能会有多个协程操作同一个线程私有变量,这就导致了变量冲的问题。出于这个原因,当我们在进行libco的异步转换时,我们将大多数线程私有变量更改为进程级私有变量。并发私有变量具有以下特征:当代码在多线程非并发环境中运行时,变量是线程私有的;当代码在协程环境中运行时,该变量是协程私有的。底层的私有变量会自动判断运行环境并正确返回所需的值。协同过程的私有变量在现有环境从同步到异步的转变中起着重要作用。同时,我们定义了一种非常简单方便的方法来定义协同过程的私有变量,它就像一行声明代码一样简单。gethostbyname的Hook方法对于现有的网络服务,可能需要通过系统的gethostbyname API接口查询DNS以获取真实地址。在协程转换过程中,我们发现我们的钩子的socket family函数不适用于gethostbyname。当协程调用gethostbyname时,它将同步等待结果,这将导致同一线程中其他协程的执行延迟。我们研究了glibc的gethostbyname的源代码,发现钩子没有生效主要是因为在glibc内部定义了poll方法来等待事件,而不是一般的poll方法。同时,glibc还定义了一个线程私有变量,在不同进程之间切换可能会导致数据不准确。最后,通过Hook poll方法和定义进程的私有变量解决了gethostbyname的异步问题。Gethostbyname是glibc提供的同步查询dns接口,业界也有很多优秀的gethostbyname异步解决方案,但这些实现都需要引入第三方库,并要求底层提供异步回调通知机制。Libco在不修改glibc源代码的情况下,通过hook方法实现了gethostbyname的异步化。在多线程环境中,我们会有线程间同步的需求,例如一个线程的执行需要等待另一个线程的信号。对于这个需求,我们通常使用pthread_signal来解决。在libco中,我们定义了协程信号量co_signal来处理协程之间的并发需求。协程可以通过co_cond_signal和co_cond_broadcast决定通知等待的协程或唤醒所有等待的协程。总结libco是一个高效的c/c++协处理器库,提供了完善的协处理器编程接口、通用的Socket系列函数钩子等。,以便业务可以使用同步编程模型快速迭代开发。随着近年来的稳定运行,libco作为微信后台框架的基石发挥了重要作用。
【相关建议】
1.下载微信微信官方账号平台源代码。
2.阿里子订单系统源代码免费下载。
这几篇文章你可能也喜欢:
- 暂无相关推荐文章
本文由主机参考刊发,转载请注明:教你libco如何支持海量数据。 https://zhujicankao.com/115370.html
评论前必须登录!
注册