Nginx 反向代理为什么可以提高网站性能?

如果作为纯粹的反向代理服务器,不做任何缓存,也没有静态文件服务,每一个请求都转发到后端,这样还能提高性能吗?
关注者
1,896
被浏览
231,969

50 个回答

最高赞回答的点是buffer,这个其实意义不大,应用层的服务器自己也可以开buffer。反向代理的主要作用是分发请求。

首先我们要了解系统的性能瓶颈在哪里,一般来说网络io速度和内存io接近,都远高于磁盘io。假定一个接口请求返回数据100k(一般没有这么大,只是假定一个方便计算的值),10个并发请求就是1M,那么全双工千兆网卡(现在还有万兆网卡,但成本太高,应用还不广),可以支撑并发10000个请求,开双网卡,理论的上限就是20000个并发请求。

假设我们收到请求马上就返回,那么最高并发数就是我们上面计算的结果,但是,问题在于,应用服务器做不到马上返回,因为它有很多业务逻辑需要执行处理,比如给用户发推送发短信发邮件,本地磁盘写日志,请求数据库增删改查,调用微信的登录接口等等等等,都附加了各个层面的io。

所以第一层的优化,我们会尽量优化应用服务自身,把发推送发短信发邮件的活推到队列,让别的服务器去干。这个一般用内存队列,io很高。

开多线程或者协程的方式异步写日志,但再怎么优化,磁盘io的上限突破不了,这个io很低。还有更激进的方案,干脆日志也写内存,或者通过内网网络同步到别的服务器上,可以更优化。

数据库复用连接池,减少连接和断开的时间开销。查询语句尽量优化,减少等待数据库操作的时间。当然,再怎么优化,一样有个上限。

调用微信的登录接口等外部接口,这个就更难办了,受制于人,除了tcp连接池复用能稍微优化一点点,完全是取决于外部条件。

木桶理论取最短板,所有这些条件里,总有最慢最落后的那个。假如拖后腿的这个,最佳状态也只能优化到支持2000个并发,那就尴尬了,本来能支持20000个请求的系统,只能用到1/10性能。

( 当然也可以在dns对应不同ip方式分布请求,但是dns层面的分布更复杂更麻烦,因为dns缓存的原因,请求也不能均匀分布,而且ip地址也是越来越稀缺的资源,没有背景没有后台的,搞这么多ip也不容易啊 )

单个公网ip算一个节点的话,这个节点本来的潜力是响应20000个并发请求,实际在应用层面只能到2000并发,潜力还未发掘啊。这个时候,就是反向代理起到用武之地的时候了。

首先一个反向代理的服务器抛开所有业务层的东西,只单纯的接下请求再返回,那么可以支持到20000并发了。接下来应用层面谁来处理?找来10个小弟,转发给他们,每人2000正好。这样这个节点系统虽然性价比只有10/11,但是性能潜力好歹挖尽了。

这就是反向代理的作用了。
对于后端是动态服务来说,比如Java和PHP。这类服务器(如JBoss和PHP-FPM)的IO处理能力往往不高。Nginx有个好处是它会把Request在读取完整之前buffer住,这样交给后端的就是一个完整的HTTP请求,从而提高后端的效率,而不是断断续续的传递(互联网上连接速度一般比较慢)。同样,Nginx也可以把response给buffer住,同样也是减轻后端的压力。