为什么BFE可以取代Nginx:十问十答
https://github.com/bfenetworks/bfe
在“为什么BFE可以取代Nginx”(可点击查看)的文章发布后,我收到了不少网友的评论和问题。这里对其中的一些公共问题尝试给出答复。
Q1:BFE在HTTP的极端场景下,性能仅为Nginx的1/5,为什么不优化?
答:
首先,这个性能测试是在长连接场景(一个连接内持续发送HTTP请求)下测试得到的数据。在真实的场景下,一个TCP连接(在BFE中称为会话)内一般请求数在3个以内。所以在真实的场景下,性能的差距不会那么大。但是为了客观的陈述事实,我还是把“5倍”这个数字展示出来了。
其次,BFE的性能差是因为使用了Go原生的系统协议栈,而没有做很多的优化。我们认为,协议栈的一致性是非常重要的。深度的优化可能会破坏协议的一致性,也可能会引发稳定性和安全性方面的问题。
最后,对于绝大部分场景来说,性能所造成的问题并不是那么严重。性能并不是越高越好,而是够用就好。如果从优化性能所获得的硬件收益甚至不足有覆盖所投入的人力成本,那么这个优化就是不值得做的。
Q2:为什么要重新自研BFE?为什么不直接使用其它开源(如OpenResty)?
答:
外部可见的开源软件,在深入使用后,都会发现不够用。很多功能这些开源软件都不支持,例如:多租户的支持,配置的无损动态加载,路由表的强大表达能力,分布式限流能力,日志的保存信息,程序内部状态信息的获取等等。而对于第三方开源库中已经有的功能,从“有”到“精”也需要大量的研发资源投入。
而基于Nginx/OpenResty或Envoy来做修改,学习曲线和研发成本都是非常高的。安全性和稳定性也是非常重要的考虑。BFE毕竟是一个服务于全公司的万亿级流量转发平台,安全性、稳定性、快速迭代以满足业务需求,都是我们需要考虑的。
回到2014年初,在BFE当年重构做选型的时候,确实考虑过Nginx/OpenResty,但是最终我们选择了Go。现在看,这个选择是非常正确的。
Q3:为什么你文章中说使用Nginx团队需要5个人,而使用BFE只需要2个人?
答:
这里对于团队的规模,是有前提和假设的,也就是容量达到100万QPS。如果按照百度BFE平台万亿级请求规模(对应千万级QPS)来推断,100万QPS对应的每日请求应该是几百亿到1000亿。
据我所知,如果不算CDN的话,能够达到这样量级的企业在中国并不是很多,能有这么大流量的基本都是中国一线的互联网企业。对于这样的企业来说,如果基于Nginx来建立统一的七层接入转发平台,是需要至少5个人的(这方面我确实调研过,但是抱歉不能说是哪些公司)。
如果你所在的公司使用了Nginx建立统一转发平台,流量已经达到了100万QPS,而人数不到5个人,只有2种可能:
(1) 这5个人能力都非常强
(2) 贵公司在七层负载均衡方面所做的功能非常有限,只有非常基础的功能。确实有很多公司的七层转发平台只是做非常简单的处理,很多功能都还是下游的服务自己来做。这方面其实还是有很大的优化空间的。
Q4:BFE支持插件热更新吗?
答:
BFE开源项目目前已经支持插件热更新了。但是,我个人认为这个功能并不是刚需,而且需要谨慎使用。
负载均衡软件的变更应该是一个非常谨慎的操作。考虑到程序的修改可能对内存中的数据组织方式有改变,比较稳妥的方式还是对程序做重启操作。
在运维中真正高频的操作是配置的热加载。这方面BFE有很好的支持。
Q5:如果业务规模比较小,不需要对开源代码进行修改,是不是BFE就没有优势了?
答:
在小规模业务场景下,BFE和Nginx相比,硬件成本的差距大大缩小了(很多场景使用2台服务器就够了,或者在云化的场景下,有2台虚机就够了)。而如果没有扩展开发的需求,研发成本方面的差距也不是重点考虑到因素。
在小规模场景下,功能和可运维性成为关键的考察因素。
BFE是面向企业级场景而设计的,具有以下特点(详见【视频分享】BFE:企业级七层负载均衡开源软件):
1. 极高的安全性和稳定性
这源于Go语言的优秀特效。在内存管理方面的难度和风险降低,并且可以捕捉异常。
2. 功能快速开发
BFE提供了良好的插件化设计,且Go语言代码更容易编写和维护
3. 复杂场景的支持
(1) BFE内置提供了多租户的支持
(2) BFE支持强大的路由转发模型,不仅提供了非常完整的能力,而且避免了正则表达式带来的可维护性问题和性能退化隐患(详见 BFE和Nginx有什么差异?- 转发模型的对比)
(3) BFE支持多数据中心的调度场景
4. 运维友好的支持
(1) BFE内置大量的状态探针,便于对程序的运行状态做监控
(2) BFE的配置可动态热加载,在配置加载过程中不会影响处理中的请求和连接
而且,在2021年10月,BFE完成了控制面的开源。这样大家可以更容易的对BFE集群进行管理。详见 喜大普奔!BFE 控制平面正式开源发布!
Q6:是不是Nginx的运维更加好找,而BFE的运维不好找?
答:
如果仅仅站在运维(而不是研发)的角度,配置Nginx或配置BFE都是很容易学习的。如果有需求,这并不需要招聘以前曾经有Nginx运维经验的人,而只需要找有软件运维和网络方面经验的人。
有人提出,是不是找“懂Go程序运维的人”比较难。这个问题的提出非常有意思。运维和程序的编程语言是没有关系的。对于像Go这样编译型的编程语言,运维Go语言编写的程序和运维用C/C++、Java编写的程序不会有什么差别的。
Q7:你为啥说Nginx和OpenResty在安全性和稳定性方面有问题?有啥证据吗?
答:
说明一个事情的方法有两种,一种叫理论证明,另外一种叫举例。第一种方法比第二种方法要有力量的多。
一个使用自动内存回收机制的语言,其稳定性和安全性比使用手动内存回收机制的语言要高,这是理论上推导出来的,而不是靠举例子的。对应的代价是运行内存回收逻辑的成本,这个在文章中也说明了。
建议大家阅读一下Go语言的设计思想和诞生历史。或许大家没有注意到,Go语言的作者之一Ken Thompson正是C语言的作者。为什么老爷子在发明C语言数十年后又发明一种新的语言?
也可以去阅读一下OpenSSL修改Bug的历史,看看其中由于内存管理产生了多少问题(https://www.openssl.org/news/vulnerabilities.html)。类似这样的错误是无法根除的,这是C语言设计机制的问题,不是写程序的人小心一些、系统多运行几年就可以解决的。
Q8:你在文章中说HTTPS场景下,BFE配了加速卡才和Nginx相当,那在这种场景下BFE还是不如Nginx?
答:
根据文章(即 为什么BFE可以取代Nginx)中的推导,即使HTTP场景下性能差距5倍,BFE在综合成本方面仍然优于Nginx。而在HTTPS场景下,性能差距大大缩小了,成本方面的差距也变小了,BFE的综合优势就更大了。
BFE和RSA加速卡配合使用,用时髦的话来说这叫做“异构计算”。通过使用廉价的硬件,使Go语言方案可以更好的被应用,解决了安全性和稳定性方面的问题,提升了研发效率,这不应该被视为缺点,而应该被视为进步!
Q9:你在文章中主要说的是Nginx的问题,那OpenResty中主要使用Lua,是不是就没问题了? 而且OpenResty目前也大规模落地了,使用的地方也很多呀。
答:
Lua语言的定位,本来就不是用于大规模工程开发的,而只是用于做小规模的功能扩展开发。在OpenResty(包括Kong和APISIX)场景中,由于Nginx底层太难修改了,Lua成了主角,被用于编写大量的逻辑。我们要看到,这并不是合理的,而是被迫的,这只是针对Nginx的问题所做的一种权宜之计(有些像NAT之于IPv4)。
现在很多人已经认识到Python并不是适合高稳定性和大规模的工程场景。Lua在工程支持方面的能力比Python语言更弱。几种语言在工程支持和稳定性方面的对比,大家可以自己去搜索一下,这方面的文章已经很多了,如:
1. 动态类型的编程语言适合编写大型程序吗?(知乎)
https://www.zhihu.com/question/380207572
2. 动态语言一时爽呀,代码重构火葬场呀(B站)
https://www.bilibili.com/video/av52775766
Q10:Go语言的性能太差,写高性能服务性能瓶颈来得太早了
答:
关键要看我们到底需要多高的性能。是否要优化性能,要看是否有这方面的问题和需求,以及投入的成本(更准确的说,是投入产出比)。
很多公司并不需要那么高的性能。QPS能到10万的公司能有几个? 能到100万的就更少了。在这种场景下,追求性能没有必要,使劲优化性能其实反而花了更多的钱 - 是人力的钱。人力的成本和研发时间的成本似乎不可见,大家浪费的一点儿都没有感觉。
欢迎关注“BFE开源项目”微信公众号,获得本项目的更多信息。谢谢!