这篇文章不会过多介绍这几个代理,毕竟在网上可以搜到很多它们的优劣对比和适用场景,只要看几篇文章就可以初步了解。此处更专注于在高并发场景下它们的发挥和配置,而且只针对HTTP和TCP。
Nginx
Nginx是我最先接触的,也是相对来说最熟悉的,可以用来部署一个静态WEB网站,最多的应该是用来当反向代理,提供负载均衡的服务。
Nginx的性能是非常高的,一个普通的服务器部署静态页面单机就可以几万QPS,要想再进一步提高性能,可以参考以下几个方面:
系统调优
可以看前面的文章 《Linux系统调优》对系统参数做适当调整。
配置调优
经过系统调优可以确保系统的高并发,但是对于Nginx来说,还需要修改nginx.conf 主要配置文件里面的参数。
- worker_processes 可以调整工作进程数,工作进程数不是越多越好,当和CPU核数相同时可以充分利用CPU,但是我建议不要这样配置,而是空闲一部分CPU用来保持其他进程的正常使用。 比如8核CPU可以配置6或者4,这样Nginx最多也就占用75%的CPU。
- worker_cpu_affinity 可以调整CPU亲和力,让不同的工作进程绑定到不同的核。这个地方就涉及到系统中断的概念了,参考上一篇《软中断》,可以尝试将工作的CPU绑定到软中断核或者避开软中断,再测试性能,这个比较我没测试过,而HAProxy中是推荐和网卡中断绑定到同一个CPU,不同的核上面。
- event 部分
- worker_connections 单个工作进程可以允许同时建立外部连接的数量,无论这个连接是外部主动建立的,还是内部建立的,这个数量会受到操作系统的最大文件数限制,一个TCP连接就相当于一个文件,如果进行了系统参数调优则直接修改就行,否则要先调整系统参数,这个数量可以调大一些,比如10240,65535之类,具体的数值要经过测试才会合理。
- http 部分
- keepalive_timeout 指定每个 TCP 连接最多可以保持多长时间,可以设置为60,75之类的,不要设置过大的数据,也不能太短,既要避免TCP连接过长时间不释放占用资源,也要避免过快关闭连接导致重新建立连接消耗资源。
- server 部分
- proxy_set_header Connection “”; 这个设置也很重要,作用是将http请求头Connection置空,不会传给真实后端服务器(上游服务器),因为proxy_set_header Connection 默认是’close’,会关闭长连接,也就是说客户端发的请求到了nginx是正常的,但是nginx和真实后端的http通信都是短连接,这个是很耗费性能的,而且由于此时nginx相当于客户端,还会受到端口数限制,高并发情况会产生大量连接,会有很多time_wait状态的TCP链接。proxy_http_version 1.1; 也需要设置。
- upstream 部分
- keepalive 开启与真实后端服务器(上游服务器)之间的连接池, 其数值为每个nginx worker可以保持的最大连接数,默认不设置,这是一个连接池,也是为了保证nginx的长连接,减少资源消耗。
上面只是写了需要注意的几个参数,还有一些调优的并没有写出来,比如GZIP压缩、缓存配置、fastcgi和限流等等。完整的配置可以随便搜一下,重点关注上面几个,然后再根据测试情况适当调整参数。
HAProxy
HAProxy也可以用来做负载均衡,但是不能做WEB server,是多线程模型,而Nginx是多进程的,虽然HA也支持多进程,但我测试发现有的时候多进程性能不如单进程好,而且HA会更多利用CPU内核操作,top命令可以看到内核占用百分比很大,相对Nginx来说性能差不多,可能会稍微好一点,但是不如Nginx模块丰富。
系统调优
参考Nginx提到的系统调优
配置调优
我用HAProxy来做四层代理,也就是TCP层,所以配置会少很多,不过用来做负载均衡要注意IP透传之类的,让后端可以拿到真实IP
- nbproc 配置进程数,建议配置一下进行测试,搭配cpu亲和绑定,有可能会提高性能,进程不要超过内核数,避免服务器满载。
- cpu-map 绑定进程和CPU内核,可以将进程绑定到网卡中断CPU的不同内核上,再配合性能测试调整
- maxconn 设定每个haproxy进程所接受的最大并发连接数,这个可以调大一些,几十万都可以
- balance 负载均衡方式,可以通过业务情况调整
LVS
lvs已经在内核里面了,性能非常高,虽然这三个都支持4层负载均衡,但是LVS是不一样的。LVS支持DR、NAT、隧道、FULLNAT模式。
- DR模式:通过改写请求报文的目标MAC地址,将请求发送给真实服务器,而真实服务器将相应后的处理结果直接返还给客户端用户。极大地提高集群的伸缩性,但LB与RS必须在同一局域网环境。
- NAT模式:通过网络地址转换,LB重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器,真实服务器的响应报文处理之后,返回时必须通过LB,经过LB时报文的源地址被重写,再返回给客户。
- 隧道模式:LB把请求的报文通过IP隧道转发至真实服务器,而真实服务器将响应处理后直接返回给客户端用户。
- FULLNAT模式:数据包进入时,除了做DNAT,还做SNAT,从而实现LVS-RealServer间可以跨vlan通讯,RealServer只需要连接到内网。
从中可以看出除了隧道模式,其他的都是修改数据包中IP、MAC之类的操作,隧道模式是再封装一层,就像VPN一样,这就和Nginx之类有了一个很大区别:不用建立TCP连接,也就不用维护TCP,这样就能节省很多资源,继而提升性能。所以LVS性能要高与HAProxy和Nginx,但是LVS也有一些局限性,需要根据具体场景做取舍。
LVS不需要调优就有很高性能,当然支持网卡多队列,多核处理网卡中断会更好,如果想要有更高的性能,可以去搜一下DPDK。