关于golang:千万并发连接下如何保障网络性能
过来几十年互联网呈爆发式的增长,内容的丰盛以及层出不穷的DDoS攻打等,对网络性能提出了极大的挑战,也同样促成了网络基础设施的疾速倒退。运营商的带宽越来越大,CPU/网卡等硬件的性能也会越来越强。但在很长时间内,软件的性能晋升落后于硬件的性能晋升,并重大限度了应用程序的性能,大部分工夫不得不依附堆机器来应答,造成了大量的资源节约和老本进步。 随着软件的一直倒退,在新世纪的第一个10年时,通过多线程和事件驱动(kqueue/epoll等)解决了C10K的问题。然而在第二个10年却不堪重负,亟需新的解决方案来应答网络流量的增长。 比方腾讯云对外提供的HttpDNS服务每隔几个月申请量都会翻倍,对高性能的网络解决和用户态协定栈都有强烈的需要。HttpDNS晚期应用的内核协定栈只能做到单机不到10万QPS的TCP 短连贯服务。随着技术的提高和倒退,如REUSEPORT等,后续内核协定栈也能够做到几十万QPS了,但仍然存在十分大的横向扩大瓶颈。基于这样的瓶颈下,腾讯云迫切需要一个高性能的网络服务框架,所以抉择了通过DPDK+用户态协定栈来进行内核旁路来晋升网络性能。 Robert David Graham 在2013年针对C10M的演讲中,对于如何达到千万并发连贯,最次要的观点就是内核才是妨碍性能晋升的问题,咱们应该绕过内核(kernel by pass,内核旁路)以及大量其它的技术优化,如轮询、零拷贝、Hugepage等。 Linux内核后续引入的eBPF和XDP同样可能大幅晋升网络性能,然而其晋升性能的实质仍然是绕过内核,目前还未能对Intel DPDK生态造成本质的冲击,尤其是对高内核版本和网卡驱动的依赖,重大限度了在企业的应用推广。 在此次演讲之前,相干的技术曾经失去了肯定的利用,如演讲中提到的PF_RING,Netmap,IntelDPDK等数据驱动,腾讯云DNSPod在2012年就曾经实现了相干软硬件的调研选型工作,并最终抉择DPDK(此时尚未开源)实现了新一代的权威DNS服务器达到了单10GE 1100万 QPS的性能,大幅晋升了DNS的惯例解析和抗攻击能力。然而的确直到该演讲呈现后,相干技术才在业界失去了大规模的开发利用,尤其是从中怀才不遇的DPDK,简直成了高性能网络程序的标配。而咱们也是在16年的时候将权威DNS中应用DPDK的网络模块独自抽出来作为一个独立的通用的网络框架,能够复用到多个业务上晋升网络性能,也就是当初的F-Stack。 F-Stack介绍及技术特点F-Stack是一个全用户态的高性能的网络接入开发包,基于DPDK、FreeBSD协定栈、微线程接口等,用户只须要关注业务逻辑,简略的接入F-Stack即可实现高性能的网络服务器。将网络包进行内核旁路到应用层进行解决尽管大幅晋升了网络性能,然而也无奈再应用内核的网络协议栈了,这对4层以下以及简略的UDP 7层利用影响不大,然而对其余的7层利用来说,一个成熟的用户态协定栈是必须的,所以F-Stack就是腾讯云DNSPod给出的计划。 F-Stack是根本残缺的网络编程框架,相当于用胶水粘合了了DPDK网络I/O模块、FreeBSD用户态协定栈、POSIX Like API,异步编程接口、局部下层利用等,供用户接入应用。应用纯C开发(局部第三方组件应用了C++,F-Stack进行了封装),容易上手,但也要求用户有肯定的DPDK应用根底。应用BSD 2-Clause开源协定,对商业应用十分敌对。那对于F-Stack都有哪些技术特点呢?接下来将持续介绍。 多过程架构,轮询模式 这里是F-Stack的一个根本架构,采纳多过程模型,全用户态,每个过程与一个CPU外围、网卡收发队列进行绑定,领有更好的内存局部性,防止缓存生效,且过程外部应用轮询模式,无锁、无调度、无上下文切换。 F-Stack 目前采纳多过程架构,各过程领有本人过程独立的协定栈,利用接口和应用层业务逻辑,躲避了内核的多种性能瓶颈,各个过程间无数据共享,有十分好的横向扩大能力。 DPDK 开发套件DPDK是宽泛应用的数据立体开发套件,此处不再对其自身进行过多介绍。 F-Stack对DPDK版本的选用上除了初始开源版本应用了16.07版本之外,很快降级并始终放弃应用DPDK的LTS版本(xx.11)版本,但个别会在最新的LTS版本公布之后数个月在dev分支进行降级反对,并在更晚之后的工夫(个别1年左右)正式公布,如目前F-Stack主力稳固的1.20和1.21版本别离应用了DPDK 18.11.x和19.11.x版本,在开发分支中则反对了20.11.x版本。 FreeBSD 协定栈F-Stack对于选用FreeBSD协定栈进行用户态移植,背地其实是有过很多的思考和尝试的,此处仅列觉几个FreeBSD协定栈的长处,更多信息能够通过前面的 F-Stack 背景故事进行理解。 协定栈功能完善,且有大量工具能够对网络进行调试剖析,如sysctl、ifconfig、netstat、netgraph、ipfw、ndp等。能够跟进社区的改良,无需本人开发保护,有原始用户态移植可供参考,大幅缩小工作量,见libplebnet和libuinet。相比Linux的协定栈实现简单,FreeBSD的代码更清晰易懂;Linux遵循GPL协定开源,可能会限度局部用户的应用。F-Stack 目前公布版本均基于 FreeBSD releng 11.0 版本,并移植了局部后续版本的patch,功能完善但也冗余(去除了局部模块未编译进F-Stack,如SCTP,IPSEC等),调试剖析工具欠缺,运行稳固。后续则会降级到 FreeBSD releng 13.0 版本,并将继续跟进社区的重大改良。 POSIX 兼容接口F-Stack提供了POSIX like接口,前缀为“ff_”,如“ff_socket”“ff_bind”等,并提供了“ff_kqueue”事件驱动接口并同时基于kqueue封装了“ff_epoll”接口,除“ff_epoll”接口的应用上与linux零碎接口略有区别外,其余接口用法齐全兼容,现有程序能够做到简略改变即可接入。 须要留神的是,尽管接口用法齐全兼容,然而因为很多标记位在Linux和FreeBSD零碎的定义并不相同,F-Stack接口外部会进行定义的转换,然而并不能保障100%反对,尤其是后续新增的标记定义,也须要继续进行更新保护。 POSIX like接口对原有利用的移植是敌对的,并且应用上也比拟平安,然而因为波及到内存拷贝,所以性能上并不能达到最优,后续 F-Stack 也会提供一套独立的零拷贝 API 供有须要的用户选用。 微线程框架F-Stack 应用程序必须应用异步模式接口进行编程,但也同时提供了微线程(协程)框架,能够供用户进行同步编程,异步执行。 微线程框架应用了同为腾讯开源的 MSEC 中的一部分 micro_thread,须要特地留神的是微线程模块的开源协定是GPL-2.0,并不是F-Stack 次要的必须外围模块,对 F-Stack 主体开源协定并无影响,然而如果用户以 micro_thread 模块进行利用开发,则需关注开源协定可能造成的影响。 利用移植F-Stack目前是提供 lib 库接入的形式,须要与业务应用程序一起编译打包,并间接提供了曾经移植好的 Nginx 和 Redis 利用供用户间接应用。 ...