A.1.6 面向业务的网络编程(www.cppentry.com)的特点
与通用的网络服务器不同,面向公司业务的专用网络程序有其自身的特点。
业务逻辑比较复杂,而且时常变化 如果写一个HTTP 服务器,在大致实现HTTP 1.1 标准之后,程序的主体功能一般不会有太大的变化,程序员会把时间放在性能调优和bug 修复上。而开发针对公司业务的专用程序时,功能说明书(spec)很可能不如HTTP 1.1 标准那么细致明确。更重要的是,程序是快速演化的。以即时聊天工具的后台服务器为例,可能第一版只支持在线聊天;几个月之后发布第二版,支持离线消息;又过了几个月,第三版支持隐身聊天;随后,第四版支持上传头像;如此等等。这要求程序员能快速响应新的业务需求,公司才能保持竞争力。由于业务时常变化(假设每月一次版本升级),也会降低服务程序连续运行时间的要求。相反,我们要设计一套流程,通过轮流重启服务器来完成平滑升级(§9.2.2)。
不一定需要遵循公认的通信协议标准 比方说网游服务器就没什么协议标准,反正客户端和服务端都是本公司开发的,如果发现目前的协议设计有问题,两边一起改就行了。由于可以自己设计协议,因此我们可以绕开一些性能难点,简化程序结构。比方说,对于多线程的服务程序,如果用短连接TCP 协议,为了优化性能通常要精心设计accept 新连接的机制2,避免惊群并减少上下文切换。但是如果改用长连接,用最简单的单线程accept 就行了。
程序结构没有定论 对于高并发大吞吐的标准网络服务,一般采用单线程事件驱动的方式开发,比如HAProxy、lighttpd 等都是这个模式。但是对于专用的业务系统,其业务逻辑比较复杂,占用较多的CPU 资源,这种单线程事件驱动方式不见得能发挥现在多核处理器的优势。这留给程序员比较大的自由发挥空间,做好了"横扫千军",做烂了一败涂地。我认为目前one loop per thread 是通用性较高的一种程序结构,能发挥多核的优势,见§3.3 和§6.6。
性能评判的标准不同 如果开发httpd 这样的通用服务,必然会和开源的Nginx、lighttpd 等高性能服务器比较,程序员要投入相当的精力去优化程序,才能在市场上占有一席之地。而面向业务的专用网络程序不一定是Ibound,也不一定有开源的实现以供对比性能,优化方向也可能不同。程序员通常更加注重功能的稳定性与开发的便捷性。性能只要一代比一代强即可。
网络编程(www.cppentry.com)起到支撑作用,但不处于主导地位 程序员的主要工作是实现业务逻辑,而不只是实现网络通信协议。这要求程序员深入理解业务。程序的性能瓶颈不一定在网络上,瓶颈有可能是CPU、Disk IO、数据库等,这时优化网络方面的代码并不能提高整体性能。只有对所在的领域有深入的了解,明白各种因素的权衡(trade-off),才能做出一些有针对性的优化。现在的机器上,简单的并发长连接echo服务程序不用特别优化就做到十多万qps,但是如果每个业务请求需要1ms 密集计算,在8 核机器上充其量能达到8 000 qps,优化I不如去优化业务计算(如果投入产出合算的话)。