我已经谈过一些关于Nginx的常见问题,其中有一些是关于如何优化Nginx,很多Nginx新用户是从Apache迁移过来的,因些他们过去常常调整配置和执行魔术操作来确保服务器高效运行。

  我有一些坏消息要告诉你,你不能像Apache一样优化Nginx。它没有魔术配置来减半负载或是让PHP运行速度加快一倍。高兴的是,Nginx已经优化的非常好了,当你决定使用Nginx并用apt-get,yum或是make命令安装的时候它已经进行了佳优化。 (注意那些库经常过期,Wiki的安装页面上通常有新的库)

  是说,很多影响Nginx行为的参数其默认值并不是完全适合高并发的情况。我们也要考虑Nginx运行所在的平台,优化我们的操作系统当有一些限制的时候。

  总的来说,我们无法优化单个连接的负载时间,但是我们可以确保Nginx的高并发处理环境。当然, 对于高并发我指的是每秒数百个请求连接,大多数人不需要了解这些。假如你太好奇或是想知道那继续读吧。

  首先,我们需要认识到Nginx几乎可能需要在所有的平台上使用,MacOS,Linux,FreeBSD,Solaris,Windows甚至一些更深奥的系统。他们大部分(这么翻译好些)实现了高性能的基于事件的polling方法,不幸的是Nginx的只支持其中4个系统。在四个系统中我倾向于FreeBSD,但你不会看到太大的性能差异,所以选择的操作系统让你用起来顺手,比选择优化的操作系统更重要。

  我想你一定猜到了windows不在其中。 Windows上的nginx确实没有什么理由让你值得使用。 Windows有自己的一套处理事件polling。 所以nginx的作者选择了不支持。 因此默认的还是使用select() 这种不是很高效而且性能会下降很多的方式。(初次翻译不是很好希望多多指教)

  第二个大的限制, 也是大多数人会遇到的问题是和操作系统相关的。 打开一个Shell窗口, 使用su命令切换到Nginx的运行用户, 运行命令`ulimit -a`。 这些值也会在Nginx在运行中对它进行限制。 在许多操作系统中, “open files”的值是相当有限的, 在我使用的操作系统中, 它的值是 1024。 如果Nginx在运行中操作了这个限制他会记录error log(24: Too many open files) 接着返回一个操作给客户端。 当然Nginx可以处理的文件数可以更大你也可以针对操作系统做一些改动, 你可以放心的去增加这个值。

  两种方式可以实现, 你可以通过ulimit设置os的:“open files”, 你还可以通过(nginx)配置worker_rlimit_nofile 来申明你期望的值。

  Nginx 限制除了注意操作系统的限制, 现在我来深入到Nginx本身,看看一些指令和方法,我们可以用它来调整Nginx。

  Worker Processes(用英文会更好一些)worker_process 是Nginx的主干, 一旦主进程绑定到指定的IP和端口,会使用nginx指定的用户孵化出子进程, 之后他们会处理所有的工作。 Workers 不是多线程的, 所以不能扩展它超过CPU的核数。 所以我们应该理解设置多个(>1)workers的原理, 通常一个CPU核对应一个worker。 过犹不及,2-4个workers会伤害CPU, 在CPU成为问题之前Nginx会遇到其他的瓶颈。而通常你只是看到了空闲的进程。(这段翻的太烂了希望大家多多改进)

  当你正在处理下面这种情况, 你有很多的阻塞(blocking)磁盘IO,这是你可以适当增加worker_process的值。 你需要针您的配置进行测试,检查静态文件的等待时间(waiting time), 如果值比较大,可以适当的增加worker_process。(这段翻译完有想哭的感觉)

  Worker Connectionsworker_connections 是个稍稍有点怪的概念。 我不是很了解这个指令的目的, 但是它有效的限制了在同一时间内每个worker可以维护的连接数。 如果我没猜错的话, 这个配置是为了确保在keep-alive配置不正确的情况下, 当你使用的端口将要耗尽之时,增加连接数。(这个翻译的好难不知道是否正确因为作者也是forced to guess 我也只能被逼去猜了望指正)

  默认的值是1024。 我们假设一个李兰奇一般情况下打开2个连接来通过管道获取网站资源,也是多可以同时处理512个用户的请求。听起来实在是太少了,但是我们在想一下默认的keepalive-timeout是65(在默认配置文件里面提供了65这个值, 如果没有设置该值,默认值是75,请参考wiki keepalive_timeout),也是说我们实际上每秒只能处理8个连接。 显然这个值高于许多人期望的(我没觉得高呵呵), 尤其是考虑到我们通常会设置2-4个workers。 但是对于流量较大的网站 使用keep-alive是值得的。(翻译完了又想哭了)

  此外,我们还必须考虑反向代理, 这将打开一个额外的连接到后台,但是,自Nginx的不支持持久连接到后台,这不是太大的问题,除非你有长时间运行的后台进程。

  所有关于worker连接的配置应该是相当清楚的,如果你流量增加了,你要相应的增加worker连接的数量。 2048对于大多数人来说应该是满足了,但老实说,如果你的流量增长了,那么对于workers的数量值应该是多少应该是很清楚的。

  CPU 亲和力设置CPU的亲和力,基本上意味着你告诉每个程序使用的CPU核心,而他们将只使用这个CPU核心。关于这一条,我不想说很多,但你要知道,如果你准备这样做,则必须非常小心。 要知道,你操作系统的 CPU 调度器处理负载均衡的能力要远远超过你。当然,如果你认为你的 CPU 负载均衡有问题,在调度层面上优化它,可能的话找一个替代的调度器。除非你知道你在做什么,否则不要碰这个。

  Keep Alivekeep_alive 是 HTTP的一个特性, 它允许客户端维护与服务器已经创建的连接进行一批请求的处理直到指定的超时时间到达。 这个实际上不会在很大程度上改变我们的Nginxserver的性能, 因为Nginx能够很好的处理空闲的连接。 Nginx的作者声称10,000个空闲的连接智慧使用2。5兆内存(unbelievable), 我个人的使用来说这个值也是靠谱的。

  我在这篇性能文章里面提到这个原因非常简单。 对于终用户来说keep alive对加载时间有着巨大的影响。 这是重要的指标之一也是我们不断优化的原因。如果你的网站对用户来说感觉加载起来很快,他们会很开心。 Amazon和一些其他的大型在线零售商做过许多类似的研究表明, 网站的加载时间和网站订单的完成有着直接的关系。

  为什么keep alive有着如此巨大的影响, 应该是显而易见的, 那是你避免为所有的HTTP请求创建各自的连接, 这是非常低效的。 也许你不需要把keepalive-timeout设置为65, 但是10-20应该是比较通用的选择,正如上面一段所说, Nginx会很好的处理这方面。

  tcp_nodelay 和 tcp_nopush这两个指令也许是难理解的nginx配置, 他们对于nginx的影响在网络的较低层。 你可以简单的认为这些指令决定了操作系统如何处理网络缓存和他们何时将这些缓存输出到终用户(客户端)。 我只能建议大家如果你之前不了解这些概念你好不要动它。 他们不会显著的改善或者改变性能, 所以好使用他们的默认值。