【转载】nginx&php-fpm优化文章

vps只有700m内存,每次上去看到内存被占到500m都心惊肉跳的,稍微有个扫描什么的,内存就会爆炸,mysql或者php就会被oom,查看了下发现内存主要是陪php-fpm启动的子进程占用的,于是查找资料,要么缩减进程数量,要么减少子进程的存活时间,修改之后现在内存只有330m,很有效,如下是启动的进程变成2个,最小限制进程1个最大3个,子进程处理完200个请求之后退出。

pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200

完整参考链接

I wrote before a guide Howto install Nginx/PHP-FPM on Fedora 20/19, CentOS/RHEL 6.5/5.10, but this guide is just installation guide and many cases Nginx and PHP-FPM basic configuration is good enough, but if you want to squeeze all the juice out of your VPS or web server / servers and do your maintenance work little bit easier, then this guide might be useful. These tips are based entirely on my own experience, so they may not be an absolute truth, and in some situations, a completely different configuration may work better. It’s also good to remember leave resources for another services also if you run example, MySQL, PostgreSQL, MongoDB, Mail server, Name server and/or SSH server on same machine.

And yes here we go…

Nginx Configuration and Optimizing Tips and Tricks

Nginx Tip 1. – Organize Nginx Configuration Files

Normally Nginx configuration files are located under /etc/nginx path.
One good way to organize configuration files is use Debian/Ubuntu Apache style setup:


Bash

<span class="token comment" spellcheck="true">## Main configuration file ##</span>
/etc/nginx/nginx.conf

<span class="token comment" spellcheck="true">## Virtualhost configuration files on ##</span>
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/

<span class="token comment" spellcheck="true">## Other config files on (if needed) ##</span>
/etc/nginx/conf.d/
`</pre>
Virtualhost files have 2 paths, because **sites-available** directory can contain any stuff, like test configs, just copied/created configs, old configs and so on. And **sites-enabled** contains only really enabled configurations, actually **just only symbolic links** to sites-available directory.

Remember add following includes at the end of your **nginx.conf** file:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token comment" spellcheck="true">## Load virtual host conf files. ##</span>
include /etc/nginx/sites-enabled/*<span class="token punctuation">;</span>

<span class="token comment" spellcheck="true">## Load another configs from conf.d/ ##</span>
include /etc/nginx/conf.d/*<span class="token punctuation">;</span>
`</pre>

### Nginx Tip 2\. – Determine Nginx worker_processes and worker_connections

Default setup is okay for _worker_processes_ and _worker_connections_, but these values could be little bit optimized:
**max_clients = worker_processes * worker_connections**

Just Nginx basic setup can handle hundreds of concurrent connection:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
worker_processes  1<span class="token punctuation">;</span>
worker_connections  1024<span class="token punctuation">;</span>
`</pre>
Normally 1000 concurrent connection / per one server is good, but sometimes other parts like disks on server might be slow, and it causes that the Nginx is locked on I/O operations. To avoid locking use example following setup: **one worker_precess / per processor core**, like:
**Worker Processes**
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
worker_processes <span class="token punctuation">[</span>number of processor cores<span class="token punctuation">]</span><span class="token punctuation">;</span>
`</pre>
To check how many processor cores do you have, run following command:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token function">cat</span> /proc/cpuinfo <span class="token operator">|</span><span class="token function">grep</span> processor
processor    <span class="token keyword">:</span> 0
processor    <span class="token keyword">:</span> 1
processor    <span class="token keyword">:</span> 2
processor    <span class="token keyword">:</span> 3
`</pre>
So here is 4 cores and worker_processes final setup could be following:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
worker_processes 4<span class="token punctuation">;</span>
`</pre>
**Worker Connections**
Personally I stick with 1024 worker connections, because I don’t have any reason to raise this value. But if example 4096 connections per second is not enough then it’s possible to try to double this and set 2048 connections per process.

worker_processes final setup could be following:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
worker_connections 1024<span class="token punctuation">;</span>
`</pre>
I have seen some configurations where server admins are used too much Apache and think if I set Nginx worker_processes to 50 and worker_connections to 20000 then my server could handle all traffic once what we get monthly…but yes it’s not true. It’s just wasting of resources and might cause some serious problems…

### Nginx Tip 3\. – Hide Nginx Server Tokens / Hide Nginx version number

This is good for security reasons hide server tokens / hide Nginx version number, especially, if run some outdated version of Nginx. This is very easy to do just set **server_tokens off** under **http/server/location** section, like:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
server_tokens off<span class="token punctuation">;</span>
`</pre>

### Nginx Tip 4\. – Nginx Request / Upload Max Body Size (client_max_body_size)

If you want to allow users upload something or upload personally something over the HTTP then you should maybe **increase post size**. It can be done with **client_max_body_size** value which goes under **http/server/location** section. On default it’s 1 Mb, but it can be set example to 20 Mb and also increase buffer size with following configuration:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
client_max_body_size 20m<span class="token punctuation">;</span>
client_body_buffer_size 128k<span class="token punctuation">;</span>
`</pre>
If you get following error, then you know that **client_max_body_size** is too low:
“Request Entity Too Large” (413)

### Nginx Tip 5\. – Nginx Cache Control for Static Files (Browser Cache Control Directives)

Browser caching is import if you want save resources and bandwith. It’s easy setup with Nginx, following is very basic setup where logging (access log and not found log) is turned off and expires headers are set to 360 days.
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
location ~* \.<span class="token punctuation">(</span>jpg<span class="token operator">|</span>jpeg<span class="token operator">|</span>gif<span class="token operator">|</span>png<span class="token operator">|</span>css<span class="token operator">|</span>js<span class="token operator">|</span>ico<span class="token operator">|</span>xml<span class="token punctuation">)</span>$ <span class="token punctuation">{</span>
    access_log        off<span class="token punctuation">;</span>
    log_not_found     off<span class="token punctuation">;</span>
    expires           360d<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
`</pre>
If you want more complicated headers or some other expiration by filetypes then you could configure those separately.

### Nginx Tip 6\. – Nginx Pass PHP requests to PHP-FPM

Here you could use default tpc/ip stack or use directly Unix socket connection. You have to also setup PHP-FPM listen exactly same ip:port or unix socket (with Unix socket also socket permission have to be right). Default setup is use ip:port (127.0.0.1:9000) you could of course change ips and ports what PHP-FPM listens. Here is very basic configuration with Unix socket example commented out:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token comment" spellcheck="true"># Pass PHP scripts to PHP-FPM</span>
location ~* \.php$ <span class="token punctuation">{</span>
    fastcgi_index   index.php<span class="token punctuation">;</span>
    fastcgi_pass    127.0.0.1:9000<span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">#fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;</span>
    include         fastcgi_params<span class="token punctuation">;</span>
    fastcgi_param   SCRIPT_FILENAME    <span class="token variable">$document_root</span><span class="token variable">$fastcgi_script_name</span><span class="token punctuation">;</span>
    fastcgi_param   SCRIPT_NAME        <span class="token variable">$fastcgi_script_name</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
`</pre>
It’s also possible to run PHP-FPM another server and Nginx another.

### Nginx Tip 7\. – Prevent (deny) Access to Hidden Files with Nginx

It’s very common that server root or other public directories have hidden files, which starts with dot (.) and normally those is not intended to site users. Public directories can contain version control files and directories, like _.svn_, some IDE properties files and _.htaccess_ files. Following deny access and turn off logging for all hidden files.
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
location ~ /\. <span class="token punctuation">{</span>
    access_log off<span class="token punctuation">;</span>
    log_not_found off<span class="token punctuation">;</span> 
    deny all<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
`</pre>

## PHP-FPM Configuration Tips and Tricks

### PHP-FPM Tip 1\. – PHP-FPM Configuration files

Normally PHP-FPM configuration files are located on _/etc/php-fpm.conf_ file and _/etc/php-fpm.d_ path. This is normally excellent start and all pool configs goes to _/etc/php-fpm.d_ directory. You need to add following include line on your _php-fpm.conf_ file:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
include<span class="token operator">=</span>/etc/php-fpm.d/*.conf
`</pre>

### PHP-FPM Tip 2\. – PHP-FPM Global Configuration Tweaks

Set up _emergency_restart_threshold_, _emergency_restart_interval_ and _process_control_timeout_. Default values for these options are totally off, but I think it’s better use these options example like following:
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s
`</pre>
**What this mean?** So if 10 PHP-FPM child processes exit with SIGSEGV or SIGBUS within 1 minute then PHP-FPM restart automatically. This configuration also sets 10 seconds time limit for child processes to wait for a reaction on signals from master.

### PHP-FPM Tip 3\. – PHP-FPM Pools Configuration

With PHP-FPM it’s possible to use different pools for different sites and allocate resources very accurately and even use different users and groups for every pool. Following is just example configuration files structure for PHP-FPM pools for three different sites (or actually three different part of same site):
<pre>/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf
</pre>
Just example configurations for every pool:
**/etc/php-fpm.d/site.conf**
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token punctuation">[</span>site<span class="token punctuation">]</span>
listen <span class="token operator">=</span> 127.0.0.1:9000
user <span class="token operator">=</span> site
group <span class="token operator">=</span> site
request_slowlog_timeout <span class="token operator">=</span> 5s
slowlog <span class="token operator">=</span> /var/log/php-fpm/slowlog-site.log
listen.allowed_clients <span class="token operator">=</span> 127.0.0.1
pm <span class="token operator">=</span> dynamic
pm.max_children <span class="token operator">=</span> 5
pm.start_servers <span class="token operator">=</span> 3
pm.min_spare_servers <span class="token operator">=</span> 2
pm.max_spare_servers <span class="token operator">=</span> 4
pm.max_requests <span class="token operator">=</span> 200
listen.backlog <span class="token operator">=</span> -1
pm.status_path <span class="token operator">=</span> /status
request_terminate_timeout <span class="token operator">=</span> 120s
rlimit_files <span class="token operator">=</span> 131072
rlimit_core <span class="token operator">=</span> unlimited
catch_workers_output <span class="token operator">=</span> <span class="token function">yes</span>
env<span class="token punctuation">[</span>HOSTNAME<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$HOSTNAME</span>
env<span class="token punctuation">[</span>TMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TMPDIR<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TEMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
`</pre>
**/etc/php-fpm.d/blog.conf**
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token punctuation">[</span>blog<span class="token punctuation">]</span>
listen <span class="token operator">=</span> 127.0.0.1:9001
user <span class="token operator">=</span> blog
group <span class="token operator">=</span> blog
request_slowlog_timeout <span class="token operator">=</span> 5s
slowlog <span class="token operator">=</span> /var/log/php-fpm/slowlog-blog.log
listen.allowed_clients <span class="token operator">=</span> 127.0.0.1
pm <span class="token operator">=</span> dynamic
pm.max_children <span class="token operator">=</span> 4
pm.start_servers <span class="token operator">=</span> 2
pm.min_spare_servers <span class="token operator">=</span> 1
pm.max_spare_servers <span class="token operator">=</span> 3
pm.max_requests <span class="token operator">=</span> 200
listen.backlog <span class="token operator">=</span> -1
pm.status_path <span class="token operator">=</span> /status
request_terminate_timeout <span class="token operator">=</span> 120s
rlimit_files <span class="token operator">=</span> 131072
rlimit_core <span class="token operator">=</span> unlimited
catch_workers_output <span class="token operator">=</span> <span class="token function">yes</span>
env<span class="token punctuation">[</span>HOSTNAME<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$HOSTNAME</span>
env<span class="token punctuation">[</span>TMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TMPDIR<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TEMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
`</pre>
**/etc/php-fpm.d/forums.conf**
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
<span class="token punctuation">[</span>forums<span class="token punctuation">]</span>
listen <span class="token operator">=</span> 127.0.0.1:9002
user <span class="token operator">=</span> forums
group <span class="token operator">=</span> forums
request_slowlog_timeout <span class="token operator">=</span> 5s
slowlog <span class="token operator">=</span> /var/log/php-fpm/slowlog-forums.log
listen.allowed_clients <span class="token operator">=</span> 127.0.0.1
pm <span class="token operator">=</span> dynamic
pm.max_children <span class="token operator">=</span> 10
pm.start_servers <span class="token operator">=</span> 3
pm.min_spare_servers <span class="token operator">=</span> 2
pm.max_spare_servers <span class="token operator">=</span> 4
pm.max_requests <span class="token operator">=</span> 400
listen.backlog <span class="token operator">=</span> -1
pm.status_path <span class="token operator">=</span> /status
request_terminate_timeout <span class="token operator">=</span> 120s
rlimit_files <span class="token operator">=</span> 131072
rlimit_core <span class="token operator">=</span> unlimited
catch_workers_output <span class="token operator">=</span> <span class="token function">yes</span>
env<span class="token punctuation">[</span>HOSTNAME<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$HOSTNAME</span>
env<span class="token punctuation">[</span>TMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TMPDIR<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
env<span class="token punctuation">[</span>TEMP<span class="token punctuation">]</span> <span class="token operator">=</span> /tmp
`</pre>
So this is just example howto configure multiple different size pools.

### PHP-FPM Tip 4\. – PHP-FPM Pool Process Manager (pm) Configuration

Best way to use PHP-FPM process manager is use dynamic process management, so PHP-FPM processes are started only when needed. This is almost same style setup than Nginx worker_processes and worker_connections setup. So very high values does not mean necessarily anything good. Every process eat memory and of course if site have very high traffic and server lot’s of memory then higher values are right choise, but servers, like VPS (Virtual Private Servers) memory is normally limited to 256 Mb, 512 Mb, 1024 Mb. This low RAM is enough to handle even very high traffic (even dozens of requests per second), if it’s used wisely.

It’s good to test how many PHP-FPM processes a server could handle easily, first start Nginx and PHP-FPM and load some PHP pages, preferably all of the heaviest pages. Then check memory usage per PHP-FPM process example with Linux _top or htop command_. Let’s assume that the server has 512 Mb memory and 220 Mb could be used for PHP-FPM, every process use 24 Mb RAM (some huge content management system with plugins can easily use 20-40 Mb / per PHP page request or even more). Then simply calculate the server max_children value:
220 / 24 = 9.17

So good _pm.max_children_ value is 9\. This is based just quick average and later this could be something else when you see longer time memory usage / per process. After quick testing it’s much easier to setup **pm.start_servers** value, **pm.min_spare_servers** value and **pm.max_spare_servers** value.

**Final example configuration could be following:**
<div class="prism-show-language">
<div class="prism-show-language-label">Bash</div>
</div>
<pre class=" language-bash">`
pm.max_children <span class="token operator">=</span> 9
pm.start_servers <span class="token operator">=</span> 3
pm.min_spare_servers <span class="token operator">=</span> 2
pm.max_spare_servers <span class="token operator">=</span> 4
pm.max_requests <span class="token operator">=</span> 200

Max request per process is unlimited by default, but it’s good to set some low value, like 200 and avoid some memory issues. This style setup could handle large amount of requests, even if the numbers seems to be small.

转载请注明来源链接 http://just4fun.im/2017/01/01/e3-80-90-e8-bd-ac-e8-bd-bd-e3-80-91nginxphp-fpm-e4-bc-98-e5-8c-96-e6-96-87-e7-ab-a0/ 尊重知识,谢谢:)