高流量站点NGINX与PHP-fpm配置优化

使用Nginx搭配PHP已有7年的这份经历让我们学会如何为高流量站点优化NGINX和PHP-fpm配置。

以下正是这方面的一些提示和建议:

1. 将TCP切换为UNIX域套接字

UNIX域套接字相比TCP套接字在loopback接口上能提供更好的性能(更少的数据拷贝和上下文切换)。

但有一点需要牢记:仅运行在同一台服务器上的程序可以访问UNIX域套接字(显然没有网络支持)。

upstream backend
{
    # UNIX domain sockets
    server unix:/var/run/fastcgi.sock;

    # TCP sockets
    # server 127.0.0.1:8080;
}

2. 调整工作进程数

现代计算机硬件是多处理器的,NGINX可以利用多物理或虚拟处理器。

多数情况下,你的Web服务器都不会配置为处理多种任务(比如作为Web服务器提供服务的同时也是一个打印服务器),你可以配置NGINX使用所有可用的处理器,NGINX工作进程并不是多线程的。

运行以下命令可以获知你的机器有多少个处理器:

Linux上 –

cat /proc/cpuinfo | grep processor

FreeBSD上 –

sysctl dev .cpu | grep location

将nginx.conf文件中work_processes的值设置为机器的处理器核数。

同时,增大worker_connections(每个处理器核心可以处理多少个连接)的值,以及将”multi_accept”设置为ON,如果你使用的是Linux,则也使用”epoll”:

# We have 16 cores
worker_processes 16;

# connections per worker
events
{
    worker_connections 4096;
    multi_accept on;
}

3. 设置upstream负载均衡

以我们的经验来看,同一台机器上多个upstream后端相比单个upstream后端能够带来更高的吞吐量。

例如,如果你想支持最大1000个PHP-fpm子进程(children),可以将该数字平均分配到两个upstream后端,各自处理500个PHP-fpm子进程:

upstream backend {
    server unix:/var/run/php5-fpm.sock1 weight=100 max_fails=5 fail_timeout=5;
    server unix:/var/run/php5-fpm.sock2 weight=100 max_fails=5 fail_timeout=5;
}

以下是两个来自php-fpm.conf的进程池:

<section name="pool">

    <value name="name">www1</value>
    <value name="listen_address">/var/run/php5-fpm.sock1</value>

    <value name="listen_options">
        <value name="backlog">-1</value>
        <value name="owner"></value>
        <value name="group"></value>
        <value name="mode">0666</value>
    </value>

    <value name="user">www</value>
    <value name="group">www</value>

    <value name="pm">
        <value name="style">static</value>
        <value name="max_children">500</value>
    </value>

    <value name="rlimit_files">50000</value>
    <value name="rlimit_core">0</value>
    <value name="request_slowlog_timeout">20s</value>
    <value name="slowlog">/var/log/php-slow.log</value>
    <value name="chroot"></value>
    <value name="chdir"></value>
    <value name="catch_workers_output">no</value>
    <value name="max_requests">5000</value>
    <value name="allowed_clients">127.0.0.1</value>

    <value name="environment">
        <value name="HOSTNAME">$HOSTNAME</value>
        <value name="PATH">/usr/local/bin:/usr/bin:/bin</value>
        <value name="TMP">/usr/tmp</value>
        <value name="TMPDIR">/usr/tmp</value>
        <value name="TEMP">/usr/tmp</value>
        <value name="OSTYPE">$OSTYPE</value>
        <value name="MACHTYPE">$MACHTYPE</value>
        <value name="MALLOC_CHECK_">2</value>
    </value>

</section>

<section name="pool">

    <value name="name">www2</value>
    <value name="listen_address">/var/run/php5-fpm.sock2</value>

    <value name="listen_options">
        <value name="backlog">-1</value>
        <value name="owner"></value>
        <value name="group"></value>
        <value name="mode">0666</value>
    </value>

    <value name="user">www</value>
    <value name="group">www</value>

    <value name="pm">
        <value name="style">static</value>
        <value name="max_children">500</value>
    </value>

    <value name="rlimit_files">50000</value>
    <value name="rlimit_core">0</value>
    <value name="request_slowlog_timeout">20s</value>
    <value name="slowlog">/var/log/php-slow.log</value>
    <value name="chroot"></value>
    <value name="chdir"></value>
    <value name="catch_workers_output">no</value>
    <value name="max_requests">5000</value>
    <value name="allowed_clients">127.0.0.1</value>

    <value name="environment">
        <value name="HOSTNAME">$HOSTNAME</value>
        <value name="PATH">/usr/local/bin:/usr/bin:/bin</value>
        <value name="TMP">/usr/tmp</value>
        <value name="TMPDIR">/usr/tmp</value>
        <value name="TEMP">/usr/tmp</value>
        <value name="OSTYPE">$OSTYPE</value>
        <value name="MACHTYPE">$MACHTYPE</value>
        <value name="MALLOC_CHECK_">2</value>
    </value>

</section>

4. 禁用访问日志文件

这一点影响较大,因为高流量站点上的日志文件涉及大量必须在所有线程之间同步的IO操作。

access_log off;
log_not_found off;
error_log /var/log/nginx-error.log warn;

若你不能关闭访问日志文件,至少应该使用缓冲:

access_log /var/log/nginx/access.log main buffer=16k;

5. 启用GZip

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

6. 缓存被频繁访问的文件相关的信息

open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

7. 调整客户端超时时间

client_max_body_size 500M;
client_body_buffer_size 1m;
client_body_timeout 15;
client_header_timeout 15;
keepalive_timeout 2 2;
send_timeout 15;
sendfile on;
tcp_nopush on;
tcp_nodelay on;

8. 调整输出缓冲区大小

fastcgi_buffers 256 16k;
fastcgi_buffer_size 128k;
fastcgi_connect_timeout 3s;
fastcgi_send_timeout 120s;
fastcgi_read_timeout 120s;
reset_timedout_connection on;
server_names_hash_bucket_size 100;

9. /etc/sysctl.conf调优

# Recycle Zombie connections
net.inet.tcp.fast_finwait2_recycle=1
net.inet.tcp.maxtcptw=200000

# Increase number of files
kern.maxfiles=65535
kern.maxfilesperproc=16384

# Increase page share factor per process
vm.pmap.pv_entry_max=54272521
vm.pmap.shpgperproc=20000

# Increase number of connections
vfs.vmiodirenable=1
kern.ipc.somaxconn=3240000
net.inet.tcp.rfc1323=1
net.inet.tcp.delayed_ack=0
net.inet.tcp.restrict_rst=1
kern.ipc.maxsockbuf=2097152
kern.ipc.shmmax=268435456

# Host cache
net.inet.tcp.hostcache.hashsize=4096
net.inet.tcp.hostcache.cachelimit=131072
net.inet.tcp.hostcache.bucketlimit=120

# Increase number of ports
net.inet.ip.portrange.first=2000
net.inet.ip.portrange.last=100000
net.inet.ip.portrange.hifirst=2000
net.inet.ip.portrange.hilast=100000
kern.ipc.semvmx=131068

# Disable Ping-flood attacks
net.inet.tcp.msl=2000
net.inet.icmp.bmcastecho=1
net.inet.icmp.icmplim=1
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1

10. 监控

持续监控打开连接的数目,空闲内存以及等待状态线程的数目。

设置警报在超出阈值时通知你。你可以自己构建这些警报,或者使用类似ServerDensity的东西。

确认安装了NGINX的stub_status模块。该模块默认并不会编译进NGINX,所以可能你需要重新编译NGINX –

./configure --with-http_ssl_module --with-http_stub_status_module --without-mail_pop3_module
--without-mail_imap_module --without-mail_smtp_module
make install BATCH=yes

原文发布于微信公众号 - 马哥Linux运维(magedu-Linux)

原文发表时间:2014-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

关于switchover的流程和补充(r9笔记第4天)

对于Oracle Data Guard中的Switchover一般是计划内的操作,自己其实也处理了不少的故障,也算是轻门熟路。复杂的事情简单做,简单的事情重复做...

2725
来自专栏企鹅号快讯

R基础入门(1)——搭建运行环境

R和Python都是最近比较火的开源数据分析与挖掘语言。两者各有千秋,都可以胜任基本的数据分析、挖掘、可视化以及大数据集的处理。我们先了解R,然后是Python...

2060
来自专栏帘卷西风的专栏

关于cocos2dx程序的BUG调试解决方案

      今天说一下手机游戏开发的调试问题吧。不得不说的是和PC平台游戏、软件开发相比,手机上开发游戏和软件要困难的多。原因是多方面的,比如说开发环境比较复杂...

882
来自专栏互联网技术栈

kafka0.9.0 新特性(对比0.8)

0.9.0相比0.8.2,引入了一个新的Consumer API,这个API不再使用high level和low level的基于zookeeper的clien...

873
来自专栏企鹅号快讯

R基础入门(1)——搭建运行环境

R和Python都是最近比较火的开源数据分析与挖掘语言。两者各有千秋,都可以胜任基本的数据分析、挖掘、可视化以及大数据集的处理。我们先了解R,然后是Python...

2645
来自专栏地方网络工作室的专栏

Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十三)集成 UEditor 百度富文本编辑器

Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十三)集成 UEditor 百度富文本编辑器 前情回顾 通过前面系统的学...

3058
来自专栏架构之美

如何打造高可靠高性能的消息队列(ZZMQ)

互联网公司使用最频繁的服务调用组件是RPC框架,RPC同步调用有些场景并不是很适用,而这些场景刚好是一个可靠MQ的适用场景。

4264
来自专栏北京马哥教育

Zmap详细用户手册和DDOS的可行性

0x00 背景 Zmap是美国密歇根大学研究者开发出一款工具。在第22届USENIX安全研讨会,以超过nmap 1300倍的扫描速度声名鹊起。相比大名鼎鼎的nm...

39310
来自专栏运维

Ubuntu10.04 sudoers文件损坏又没有root密码修复

Ubuntu10.04 sudoers文件损坏又没有root密码修复 昨天遇到一个案子: 一台GIT服务器是安装的Ubuntu10.04的系统,上面有几个普...

1322
来自专栏拂晓风起

浅谈HTML5单页面架构(一)——requirejs + angular + angular-route

1912

扫码关注云+社区