Nginx、FPM配置及优化

Nginx配置

nginx的配置主要分为6个区域,main(全局设置),events(工作模式),http(http服务),upstream(负载均衡),server(主机设置),location(url规则)。

main
events {

}
http {
    upstream domain {

    }
    server {
        location {

        }
    }
}

main模块

user www www;
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
error_log   /home/git/logs/error_log error;
pid        /usr/local/var/run/nginx/nginx.pid;
worker_rlimit_nofile 65535;
  • user 用来指定worker进程运行的用户及用户组
  • worker_processes 来指定开启的worker进程数,如果是多核CPU,建议指定和CPU的数量一样的进程数即可,这里的CPU数量指物理核数。
  • worker_cpu_affinity 将不同的woker进程绑定到不同的cpu,这里指绑定到CPU[0-3],降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗。
  • error_log 用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少。
  • pid 指定master进程ID存储位置。
  • worker_rlimit_nofile 指定最多打开的文件描述符(fd),查看用户级fd限制(ulimit -n),查看系统级fd限制(cat /proc/sys/fs/file-max),系统fd与系统内存有关。

events 模块

events用来指定nginx的事件模型及连接数上限。

events {
    use epoll;
    worker_connections  65535;
    multi_accept on;
}
  • use 用来指定具体的事件模型,包括select、poll、epoll、kqueue、/dev/poll、eventport、rtsig,其中select、poll是标准的事件模型,epoll(用于linux平台)和kqueue(用于BSD平台)是高效的事件模型。
  • worker_connections 定义每个nginx进程接收的最大连接数,最大客户端连接数Max_clients = worker_processes * worker_connections / 2,而作为反向代理时,Max_clients = worker_processes * worker_connections / 4。
  • multi_accept 让NGINX在接收到一个新连接通知后调用accept()来接受尽可能多的连接。

http模块

负责http服务器的设置,包括虚拟主机和反向代理。

http{
    server_tokens off;
    include    mime.types;
    default_type  application/octet-stream;
    log_format  main '$http_host$clientip$time_local$request_time$request$status$body_bytes_sent$http_referer$http_user_agent';
    access_log  /home/git/logs/access_log  main;
    add_header DPOOL_HEADER $hostname;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    keepalive_timeout 30;
    keepalive_requests 1024;

    send_timeout 10;
    client_body_timeout 10;
    client_header_timeout 10;

    map $http_x_forwarded_for $clientip {
            default $http_x_forwarded_for;
            ""      $remote_addr;
    }
    proxy_set_header X-Forwarded-For $clientip;

    proxy_redirect off;
    chunked_transfer_encoding off;
    proxy_set_header Host $host;
    proxy_ignore_client_abort on;

    proxy_connect_timeout 75;
    proxy_send_timeout 150;
    proxy_read_timeout 150;

    proxy_buffer_size 4k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;

    open_file_cache max=65535 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 3;

    client_header_buffer_size 4k;
    large_client_header_buffers 4 8k;
    client_max_body_size 8m;
    client_body_buffer_size 1024k;
    server_names_hash_bucket_size 256;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_comp_level 2;
    gzip_proxied     expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml application/x-javascript application/json;
    gzip_vary on;

    fastcgi_temp_path /dev/shm/nginx_tmp;
    fastcgi_cache_path /dev/shm/nginx_cache levels=1:2 keys_zone=card_cache:20m inactive=5m max_size=1024m;
    fastcgi_cache_key "$request_method$host$request_uri";
    fastcgi_cache_min_uses 1;
    fastcgi_cache_methods GET HEAD POST;
    fastcgi_cache_bypass $cookie_nocache $arg_nocache;
    fastcgi_no_cache $cookie_nocache $arg_nocache;
    fastcgi_cache_use_stale error timeout http_500 http_404;
}
  • server_tokens off用来关闭nginx版本号显示。
  • include 用来设定文件的mime类型,类型在配置文件mime.types中定义。
  • default_type 设定默认类型为二进制,即当文件类型未定义时使用。
  • log_format 用于记录日志参数及格式,此处声明为main,用于access_log的记录。
  • add_header 增加自定义响应header头,header名为自定义,header值为主机名。

sendfile

  • zero-copy机制高效传输
  • 将tcp_nopush和tcp_nodelay两个指令设置为on即数据包积累到一定量时,尽快发送。

keepalive

  • client到nginx的长连接
    • keepalive_timeout 设置keep-alive客户端连接在服务器端保持开启的超时值。
    • keepalive_requests 设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭。默认是100。
  • nginx到后端server的长连接(反向代理)

nginx
http {
upstream BACKEND {
server 192.168.0.1;
keepalive 300;
}
server {
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}
  • upstream流配置keepalive,指定每个nginx worker到后端的最大连接数。
  • location 配置proxy_http_version 1.1(http1.1才支持keepalive), proxy_set_header Connection “”(清空客户端设置,即忽略client与nginx的连接方式)。

超时

  • send_timeout 指定向客户端传输数据的超时时间。
  • client_body_timeout 设定客户端与服务器建立连接后发送Request Body的超时时间,如果客户端在此期间没有发送任何内容,那么Nginx将返回Http 408错误(Request Time Out)。
  • client_header_timeout 设定客户端与服务器建立连接后发送Request Header的超时时间,如果在此期间没有发送数据,则同client_body_timeout一样返回HTTP408。

map

  • 是变量设置的映射表,映射表由两列组成,匹配模式和对应的值,匹配模式可以使正则。这里将clientip的值是从http_x_forwarded_for通过映射规则获取,从而获取到客户端真实的IP,而不是代理服务器IP(也可以使用nginx realip模块实现)。
  • “” 匹配当http_x_forwarded_for为空字符串时(第一次经过代理服务器)
  • default 在没有匹配到任何规则时执行(非第一次经过代理服务器)

proxy

  • proxy_ignore_client_abort 默认是关闭的,即请求过程中如果客户端端主动关闭请求或者客户端网络断掉,那么Nginx会记录499。
  • proxy_connect_timeout 定义了连接代理服务器的超时时间,一般情况下,这个值不超过75s。
  • proxy_read_timeout 定义了与代理服务器获读超时时间。
  • proxy_send_timeout 定义了与代理服务器写超时间时间。
  • proxy_buffer_size 用来响应头的缓冲区,一般4k就够了。
  • proxy_buffers 设置用来接收响应的缓冲区的数量和大小。
  • proxy_busy_buffers_size 设定高负荷下的缓冲区大小,建议为proxy_buffers中单个缓冲区大小的2倍。
  • proxy_max_temp_file_size和proxy_temp_file_write_size 指定临时文件的一次写入临时文件的大小及响应内容大于proxy_buffers指定的缓冲区时, 写入硬盘的临时文件的大小。

openfile

  • open_file_cache 缓存将最近使用的文件描述符和相关元数据(如修改时间,大小等)存储在缓存中,这里为1,000个元素定义了一个缓存,到期时间为20s。
  • open_file_cache_valid 定义时间段(以秒为单位),之后将重新验证open_file_cache中的元素。
  • open_file_cache_min_uses 将在非活动时间段之后从高速缓存中清除元素。 此指令可用于配置最小访问次数以将元素标记为活动使用。

client buffer

  • client_header_buffer_size和large_client_header_buffers 设置用于读取客户端请求头的缓冲区大小,先根据client_header_buffer_size配置的值分配一个buffer,如果分配的buffer无法容纳 request_line/request_header,那么就会再次根据large_client_header_buffers配置的参数分配large_buffer,如果large_buffer还是无法容纳,那么就会返回414(处理request_line)/400(处理request_header)错误。
  • client_max_body_size 设置nginx允许接收的客户端请求内容的最大值,及客户端请求Header头信息中设置的Content-Lenth大最大值。如果超出该指令设置的最大值,nginx将返回“Request Entity Too Large”的错误信息(HTTP的413错误码)
  • client_body_buffer_size 允许客户端请求的最大单个文件字节数。
  • server_names_hash_max_size 当配置多个server时需要开启。

Gzip

  • gzip on,开启Gzip,gzip可以帮助Nginx减少大量的网络传输工作。
  • gzip_min_length 设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。
  • gzip_buffers 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。
  • gzip_comp_level gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但耗CPU,超过2时,压缩率提升已经不明显。
  • gzip_types 匹配MIME类型进行压缩,(无论是否指定)”text/html” 类型总是会被压缩的。
  • gzip_vary 是否发送Header头Vary: Accept-Encoding响应头字段,通知接收方响应使用了gzip压缩。
  • gzip_proxied 根据某些请求和应答来决定是否在对代理请求的应答启用压缩。

fastcgi cache

  • fastcgi_temp_path 缓存文件的临时目录。
  • fastcgi_cache_path 用于设置缓存文件的存放路径。
    • levels:指定了该缓存空间有两层hash目录,设置缓存目录层数
    • keys_zone为这个缓存区起名为zone_name,20m指代缓存空间为20MB
    • inactive=5m 代表如果缓存文件5分钟内没有被访问,则删除
    • max_size代表最大缓存size
  • fastcgi_cache_methods 指定缓存的HTTP method。
  • fastcgi_cache_min_uses URL经过多少次访问被缓存。
  • fastcgi_cache_key 缓存的key名。
  • fastcgi_cache_use_stale 针对错误码的缓存。
  • fastcgi_no_cache和fastcgi_cache_bypass,通过set变量值控制指定参数的0/1,来控制缓存的使用,因为并不是所有情况下都需要缓存。

server模块

server {
    listen 80;
    root /home/git/www/;
    server_name xstudio.me yueqian.sinaapp.com;

    access_log /home/git/logs/access_log main;
    error_log /home/git/logs/error_log error;

    if ($uri !~ "^/(?:crossdomain.xml|favicon.ico|static/.*|robots.txt)$") {
        rewrite  ".*" /index.php last;
    }

    location ~* ^.+.(jpg|jpeg|gif|png|bmp|css|js)$ {
        access_log off;
        expires 1d;
        break;
    }

    location ~ .php$ {
        set $script_uri "";
        if ( $request_uri ~* "([^?]*)?" ) {
                set $script_uri $1;
        }
        fastcgi_param SCRIPT_URL $script_uri;
        fastcgi_pass 127.0.0.1:9001;
        include fastcgi_params;
    }
}
  • listen 监听的服务端口 后边加default_server指定默认虚拟主机。
  • server_name 用来指定IP地址或者域名。
  • root 表示在这整个server虚拟主机内,全部的root web根目录,区别于location下root。

正则

  • ~ 为区分大小写的匹配。
  • ~* 不区分大小写的匹配(匹配firefox的正则同时匹配FireFox)。
  • !~ 不匹配的。
  • ^~ 标识符后面跟一个字符串,将在这个字符串匹配后停止进行正则表达式的匹配。
  • = 表示精确的查找地址。

Rewrite

  • last :相当于Apache里德(L)标记,表示完成rewrite。
  • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则。
  • redirect:返回302临时重定向。
  • permanent:返回301永久重定向。

文件缓存

  • expires 控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标
    • time:可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。
    • time值还控制”Cache-Control”的值:
    • 负数表示no-cache
    • 正数或零表示max-age=time

FPM

  • fastcgi_param 设置fastcgi接收的参数,最终传递给PHP,SCRIPT_URL为url path。
  • fastcgi_pass fastcgi的转发地址。

HTTPS

http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    server {
        listen              443 ssl;
        server_name         www.example.com;
        keepalive_timeout   30;

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key; 

        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        add_header X-Xss-Protection 1;
        #...
  • ssl_session_timeout : 客户端可以重用会话缓存中ssl参数的过期时间
  • ssl_session_cache 设置ssl/tls会话缓存的类型和大小,nginx工作进程共享ssl会话缓存。
  • ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。
  • add_header Strict-Transport-Security,使用 HSTS 策略强制浏览器使用 HTTPS 连接
    • max-age:设置单位时间内強制使用 HTTPS 连接
    • includeSubDomains:可选,所有子域同时生效
    • preload:可选,非规范值,用于定义使用『HSTS 预加载列表』
    • always:可选,保证所有响应都发送此响应头,包括各种內置错误响应
  • HTTP/HTTPS混合配置
  • nginx
    server {
    listen 80;
    listen 443 ssl;
    server_name www.example.com;
    ssl_certificate www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    #…
    }

upstream模块

在多个应用实例间做负载均衡是一个被广泛使用的技术,用于优化资源效率,最大化吞吐量,减少延迟和容错。nginx可以作为一个非常高效的HTTP(7层)负载均衡器来分发请求到多个应用服务器,并提高web应用的性能,可扩展性和可靠性。
nginx支持以下负载均衡机制(或者方法):
– round-robin/轮询: 到应用服务器的请求以round-robin/轮询的方式被分发
– least-connected/最少连接:下一个请求将被分派到活动连接数量最少的服务器
– ip-hash/IP散列: 使用hash算法来决定下一个请求要选择哪个服务器(基于客户端IP地址)

默认轮询(加权)

http {
    upstream myapp1 {
        server srv1.example.com weight=3;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;
        location / {
            proxy_pass http://myapp1;
        }
    }
}

在这个配置中,每5个新请求将会如下的在应用实例中分派: 3个请求分派去srv1,一个去srv2,另外一个去srv3.

最小连接数

当某些请求需要更长时间来完成时,最少连接可以更公平的控制应用实例上的负载。

upstream myapp1 {
    least_conn;
    server srv1.example.com  weight=3;
    server srv2.example.com;
    server srv3.example.com;
}

IP Hash

请注意,在轮询和最少连接负载均衡方法中,每个客户端的后续请求被分派到不同的服务器。对于同一个客户端没有任何方式保证发送给同一个服务器。如果需要将一个客户端绑定给某个特定的应用服务器,那么可以使用ip-hash负载均衡机制。

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

FPM配置

global全局配置

[global]
pid = /home/git/php/var/run/php-fpm.pid
error_log = /home/git/logs/php-fpm.log
log_level = notice
rlimit_files = 65535
events.mechanism = epoll
daemonize = yes
process_control_timeout = 10
include=/home/git/php/etc/php-fpm.d/*.conf
  • pid主进程pid文件
  • error_log 错误日志文件
  • log_level 错误级别. 可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice.
  • daemonize 后台执行FPM
  • rlimit_files 设置文件打开描述符的rlimit限制。
  • events.mechanism 使用处理event事件的机制,可用以下选项:select、pool、epoll、kqueue (*BSD)、port (Solaris)。 默认值:不设置(自动检测)。
  • process_control_timeout 设置子进程接受主进程复用信号的超时时间,默认为0时,FPM无法真正实现平滑重启。具体看上一篇文章《详解nginx及FPM平滑重启》。
  • include 用于包含一个或多个配置文件

进程池配置

通过监听不同的端口可以定义多个不同的子进程池,进程池被用与记录和统计,对于fpm能够处理进程池数目的多少并没有限制,其中$pool变量可以在任何指令中使用,他将会替代相应的进程池名字。

[www]
user=git
group=git
listen = 127.0.0.1:9001
listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 100
pm.start_servers = 60
pm.min_spare_servers = 30
pm.max_spare_servers = 100
pm.max_requests = 500

slowlog = /home/git/logs/slow_log
request_slowlog_timeout = 10
catch_workers_output = yes

php_admin_value[open_basedir] = "./:/home/git/$pool/:/tmp/xhprof/"

env[SRV_SERVER_ROOT]   = /home/git/$pool/
env[SRV_DEVELOP_LEVEL] = 4
  • user和group指定worker运行的用户及组
  • listen指定监听的IP和端口
  • listen.allowwd_clients 设置允许连接到 FastCGI 的服务器 IPV4 地址,多个地址用’,’分隔,为空则允许任何地址发来链接请求。
  • pm 设置进程管理器如何管理子进程。可用值:static,ondemand,dynamic。必须设置。
    • static – 子进程的数量是固定的(pm.max_children)。
    • ondemand – 进程在有需求时才产生(当请求时才启动。与 dynamic 相反,在服务启动时 pm.start_servers 就启动了。
    • dynamic – 子进程的数量在下面配置的基础上动态设置。
  • pm.max_children pm 设置为 static 时表示创建的子进程的数量,pm 设置为 dynamic 时表示最大可创建的子进程的数量。
  • pm.start_servers 设置启动时创建的子进程数目。
  • pm.min_spare_servers 设置空闲服务进程的最低数目。
  • pm.max_spare_servers 设置空闲服务进程的最大数目。
  • pm.max_requests 最大处理请求数是指一个php-fpm的worker进程在处理多少个请求后就终止掉,master进程会重新派生一个新的。这个配置的主要目的是避免php解释器或程序引用的第三方库造成的内存泄露。
  • request_slowlog_timeout 当一个请求超过该设置的时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中。
  • slowlog 慢日志文件。
  • catch_workers_output 重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null。
  • php_admin_value 设定PHP配置值,且不会被php ini_set覆盖掉,open_basedir 定义php有权限读写的目录,$pool的值为进程池名字(www)。
  • env 设定环境变量,例如:根目录、开发/测试环境区分等,PHP可以通过$_SERVER读取。

php-fpm占用内存过高分析及解决

昨天刚买了个vps搭建了一个wordPress博客,刚搭建的时候有一大堆的问题。好不容易搭建完成了发现运行一阵子以后内存几乎用完了。开始以为是服务器的问题,费了好大的劲把Apache服务器换成了Nginx。但是问题还是没有解决,最后用top命令看了一下是php-fpm的问题。问题的解决办法如下:

未分类

1、查看php-fpm的进程个数

ps -fe |grep "php-fpm"|grep "pool"|wc -l

2、查看每个php-fpm占用的内存大小

ps -ylC php-fpm --sort:rss

3、配置php-fpm参数

找到php-fpm的配置文件php-fpm.conf

pm = dynamic #对于专用服务器,pm可以设置为static。#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:
pm.max_children #子进程最大数
pm.start_servers #启动时的进程数
pm.min_spare_servers #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers #保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。

对于内存小的服务器,使用动态方式。具体最大数量根据 内存/20M 得到。比如512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间。

nginx+php-fpm出现502 bad gateway错误解决方法

1. php-fpm进程数不够用

使用 netstat -napo |grep “php-fpm” | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。

2. 调高调高linux内核打开文件数量

可以使用这些命令(必须是root帐号)

echo ‘ulimit -HSn 65536’ >> /etc/profile

echo ‘ulimit -HSn 65536’ >> /etc/rc.local

source /etc/profile

3. 脚本执行时间超时

如果脚本因为某种原因长时间等待不返回 ,导致新来的请求不能得到处理,可以适当调小如下配置。

nginx.conf里面主要是如下

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

php-fpm.conf里如要是如下

request_terminate_timeout = 10s

4. 缓存设置比较小

修改或增加配置到nginx.conf

proxy_buffer_size 64k;
proxy_buffers  512k;
proxy_busy_buffers_size 128k;

5. recv() failed (104: Connection reset by peer) while reading response header from upstream

可能的原因机房网络丢包或者机房有硬件防火墙禁止访问该域名

但最重要的是程序里要设置好超时,不要使用php-fpm的request_terminate_timeout,

最好设成request_terminate_timeout=0;

因为这个参数会直接杀掉php进程,然后重启php进程,这样前端nginx就会返回104: Connection reset by peer。这个过程是很慢,总体感觉就是网站很卡。

使用zabbix监控nginx和php-fpm性能

一、系统环境

1.1 软件及其版本

未分类

1.2 软件安装路径

zabbix安装在/usr/local/zabbix路径下,其相关配置文件及二进制执行程序都放置其中。
nginx安装在/usr/local/nginx下,其相关配置文件及二进制执行程序都放置其中。
php安装在/usr/local/php下,其相关配置文件及二进制执行程序都放置其中。
继续后面的操作前,请确认nginx和php-fpm的服务端口都处于监听状态。

二、配置nginx的status

2.1 确认nginx的status已编译到程序包中

使用nginx -V可以查看nginx是否将模块·http_stub_status_module`编译进包中:

[root@monitor-server2 zabbix_agentd.conf.d]# nginx -V
nginx version: nginx/1.10.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.10.3 
--with-http_ssl_module 
--with-http_stub_status_module --with-pcre   
#出现with-http_stub_status_module说明已装载status模块

2.2 启用nginx的status模块

  • 修改nginx.conf文件

一般在默认主机中增加如下location即可:

location /nginx_status {
  stub_status on;
  access_log off;
  allow 127.0.0.1;
  allow 192.168.249.0/24;
  deny all;
  • 查看nginx status

nginx配置文件修改完成以后,使用nginx -t测试配置文件是否有明显逻辑及语法错误,没有问题则重载配置文件。

nginx -t
nginx -s reload

然后使用浏览器或者curl指令查看nginx status:

[root@monitor-server2 zabbix_agentd.conf.d]# curl localhost/nginx_status
Active connections: 2 
server accepts handled requests
 1585 1585 7785 
Reading: 0 Writing: 1 Waiting: 1 

2.3 nginx status数值的含义说明

未分类

三、配置php-fpm的status

php-fpm自带的有用于查询其工作状态的页面,需要进行如下 两步,以启用这一功能。

3.1 启用php-fpm status页面

修改php-fpm.conf文件,去掉status页面的注释,并可以根据需要将其改名。操作如下:

vim /usr/local/php/etc/php-fpm.conf
pm.status_path = /php_fpm-status      
 #去掉了前面的;注释符,并更名为php_fpm-status

3.2 查看php-fpm的status

修改完php-fpm.conf后,使用service php-fpm reload重新加载配置文件,然后在浏览器或者使用curl指令查看php-fpm的status。操作如下:

[root@monitor-server2 zabbix_agentd.conf.d]# curl localhost/php_fpm-status
pool:                 www
process manager:      dynamic
start time:           01/May/2017:15:14:23 +0800
start since:          29536
accepted conn:        5947
listen queue:         0
max listen queue:     3
listen queue len:     128
idle processes:       2
active processes:     1
total processes:      3
max active processes: 3
max children reached: 0
slow requests:        0

php-fpm的status可以查看汇总信息和详细信息,详细信息比汇总信息要多出每一个php-fpm进程的相关信息,同时支持多种格式输出,如xml、html和json,默认情况下分别使用如果指令即可:

Examples for summary status page:
http://example.com/status
http://example.com/status?json
http://example.com/status?html
http://example.com/status?xml
Example for detailed status page:
http://example.com/status?full
http://example.com/status?json&full
http://example.com/status?html&full
http://example.com/status?xml&full

使用何种格式查看status决定了后续使用zabbix进行监控获取status数值的方式。本文以上述curl localhost/php_fpm-status的输出为例。

3.3 php-fpm status的含义

未分类

四、编写status数据提取脚本

在适当的位置,一般是/usr/local/zabbix/bin里准备脚本用于提取status里每个字段的数值。

4.1 nginx的status数值提取脚本

此脚本为/usr/local/zabbix/bin/nginx_status.sh,其内容如下:

#!/bin/bash
#check nginx status
ip=127.0.0.1
function ping() {                              #用于检测nginx进程是否存在
    /sbin/pidof nginx | wc -l
}

function active() {                 #用于提取status中的active数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '1p' | awk '{print $NF}'
}

function accepts() {            #用于提取status中的accepts数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $1}'
}

function handled() {          #用于提取status中的handled数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $2}'
}

function requests() {        #用于提取status中的request数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $3}'
}

function reading() {        #用于提取status中的reading数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $2}'
}

function writing() {        #用于提取status中的writing数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $4}'
}

function waiting() {     #用于提取status中的waiting数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $6}'
}

$1                           #通过第一个位置参数的值来调用相应的函数  

4.2 php-fpm status数值提取脚本

php-fpm status数值提取脚本为/usr/local/zabbix/bin/php_fpm_status.sh,内容如下:

#!/bin/bash
#check php-fpm status
case $1 in
    ping)                           #检测php-fpm进程是否存在
    /sbin/pidof php-fpm | wc -l
    ;;
    start_since)             #提取status中的start since数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==4{print $3}'
    ;;
    conn)                     #提取status中的accepted conn数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==5{print $3}'
    ;;
    listen_queue)         #提取status中的listen queue数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==6{print $3}'
    ;;
     max_listen_queue)  #提取status中的max listen queue数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==7{print $4}'
    ;;
    listen_queue_len)    #提取status中的listen queue len
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==8{print $4}'
    ;;
    idle_processes)      #提取status中的idle processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==9{print $3}'
    ;;
    active_processes)   #提取status中的active processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==10{print $3}'
    ;;
     total_processes)    #提取status中的total processess数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==11{print $3}'
    ;;
    max_active_processes)     #提取status中的max active processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==12{print $4}'
    ;;
     max_children_reached)    #提取status中的max children reached数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==13{print $4}'
    ;;
    slow_requests)   #提取status中的slow requests数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==14{print $3}'  
    ;;
    *)
    echo "Usage: $0 {conn|listen_queue|max_listen_queue|listen_queue_len|idle_processes|active_processess|total_processes|max_active_processes|max_children_reached|slow_requests}"
    exit 1
    ;;
esac

五、创建zabbix_agentd的子配置文件

在/usr/local/zabbix/etc/zabbix_agentd.d/中创建关联nginx status和php-fpm status的子配置文件,创建一个,或者在已有的某配置文件中增加也可以,我这里分别为它们创建配置文件,文件名可自定义,只要确保此文件夹全部内容在zabbix_agentd.conf中包含(include)了。

5.1 userparameter_nginx.conf

[root@monitor-server2 zabbix_agentd.conf.d]# cat userparameter_nginx.conf 
#/usr/local/zabbix/bin/nginx_status.sh
UserParameter=nginx.status[*],/usr/local/zabbix/bin/nginx_status.sh $1  
 #这种写法比较简洁,参考zabbix 3.2.4中自带的的userparameter_examples.conf
UserParameter=nginx.version,/usr/local/nginx/sbin/nginx -v     
#让zabbix-agentd获取nginx的版本信息 ,一切shell指令都推荐使用绝对路径 

5.2 userparameter_php-fpm.conf

[root@monitor-server2 zabbix_agentd.conf.d]# cat userparameter_php-fpm.conf 
#/usr/local/zabbix/bin/php_fpm_status.sh
UserParameter=php-fpm.status[*],/usr/local/zabbix/bin/php_fpm_status.sh $1
UserParameter=php-fpm.version,/usr/local/php/sbin/php-fpm -v | awk 'NR==1{print $0}'   
#获取php-fpm版本信息

5.3 确认子配置文件被zabbix_agentd配置文件包含

确认在/usr/local/zabbix/etc/zabbix_agentd.conf中包含:Include=/usr/local/zabbix/etc/zabbix_agentd.conf.d/且没有被注释。

六、重启zabbix_agentd服务

service zabbix_agentd restart 让zabbix_agentd加载新的配置文件。

七、测试zabbix_get能否取到数据

在zabbix server上使用如下指令测试能否获取到nginx和php-fpm status数值。

[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[ping]'      
1
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[active]'
6
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[requests]'  
1841
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'php-fpm.status[ping]' 
1
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'php-fpm.status[conn]'
1247

注意:

  • zabbix_get指令在zabbix server上运行。
  • userparameter_*.conf文件位于zabbix_agentd端。
  • nginx_status.sh和php_fpm_status.sh位于zabbix_agentd端。
  • zabbix-get后-s指定的ip为zabbix-agentd的监听ip。

八、zabbix server上配置相应的模板

这里的模板包含对nginx status和php-fpm status要监控的item、trigger、Graphs等一系列内容。对于在zabbix server上新增要监控的内容,最好的办法就是从模板开始,然后按照顺序依次配置相应内容,无需去网上找现成的模板导入,对于系统的监控按需配置是最好的。下面是相应的操作过程。

8.1 添加nginx status监控模板

未分类

新建nginx status模板

未分类

定义nginx status模板

未分类

新建nginxApplication

未分类

定义nginx status items,这里我使用的是被动临控

未分类

增加nginx status状态码映射

未分类

nginx trigger定义

未分类

定义nginx监控视图

8.2 添加php-fpm status监控模板

php-fpm status的模板添加步骤和上述方法一样,此处不在赘述。

8.3 选择相应的主机或主机组关联上相应的模板

未分类

给主机或主机组关联模板

九、实际监控效果展示

查看监控效果可以通过查看Monitoring—->Latest data,过滤出相应的主机及应用名进行查看,最新收集的各item的监控结果,凡是监控到数据的item会显示数据,出现灰色的表示没有监控到数据,需要排查原因。如下所示:

未分类

nginx的监控数据

也可以通过定义的Graphs查看监控效果:

未分类

nginx statur监控视图

十、小结

zabbix中要实现对用户自定义的item的监控,大致过程如下:

  • 启用相应软件的性能统计功能
  • 编写性能统计数据提取脚本
  • 配置自定义的userparameter conf文件
  • 重启zabbix_agentd服务
  • zabbix server web上添加相应的模板
  • 给主机或主机组调用模板

mysql慢查询和php-fpm慢日志

MySQL慢查询

在web开发中,我们经常会写出一些SQL语句,一条糟糕的SQL语句可能让你的整个程序都非常慢,超过10秒一般用户就会选择关闭网页,如何优化SQL语句将那些运行时间 比较长的SQL语句找出呢?MySQL给我们提供了一个很好的功能,那就是慢查询!所谓的慢查询就是通过设置来记录超过一定时间的SQL语句!

PHP-FPM慢日志

php-fpm慢日志slowlog设置可以让开发者很好的查找哪些php进程速度过慢而导致的网站问题,让开发者方便的找到问题的所在。该方法同样适用于排查nginx的500、502问题根源,当nginx收到如上错误码时,可以确定后端php-fpm解析php出了某种问题,比如,执行错误,执行超时。

MySQL慢查询的不足

  • MySQL5.0版本, long_query_time时间粒度不够细,最小值为1秒。对于高并发性能的网页脚本而言,1秒出现的意义不大。即出现1秒的查询比较少。直到mysql5.1.21才提供更细粒度的long_query_time设定.

  • 不能将服务器执行的所有查询记录到慢速日志中。虽然MySQL普通日志记录了所有查询,但是它们是解析查询之前就记录下来了。这意味着普通日志没办法包含诸如执行时间,锁表时间,检查行数等信息。

  • 如果开启了log_queries_not_using_indexes选项,slow query日志会充满过多的垃圾日志记录,这些快且高效的全表扫描查询(表小)会冲掉真正有用的slow queries记录。比如select * from category这样的查询也会被记录下来。

1、如何开启慢查询?  

首先我们先查看MYSQL服务器的慢查询状态是否开启.

mysql>show variables like '%quer%';

    
开启慢查询非常简单, 操作如下:

方法一

vi  /etc/my.cnf       注:my.cnf是mysql的配置文件

      
在mysqld下方加入慢查询的配置语句(一定要在[mysqld]的下方加入)

[mysqld]

    log-slow-queries = /var/lib/mysql/mysql-slow.log

    long_query_time = 1

保存退出   重启mysql

log-slow-queries : 代表MYSQL慢查询的日志存储目录, 此目录文件一定要有写权限。

long_query_time: sql最长执行时间。

方法二

在mysql命令行下执行如下操作:

set global slow_query_log=ON;

未分类

set global long_query_time=1;

未分类

测试

1、查看生成的慢日志记录 此时是空的没有记录

cat mysql-slow.log 

未分类
        
2、执行一条超过设置时间的sql语句 在查看是否被记录

如:select sleep(1); 再去查看慢日子记录

未分类

到此mysql慢查询就OK了。

2、 如何开启php-fpm慢日志?

php-fpm.conf的配置文件中有一个参数request_slowlog_timeout是这样描述的:

未分类 

当request_slowlog_timeout 设为一个具体秒时request_slowlog_timeout =5,表示如果哪个脚本执行时间大于5秒,会记录这个脚本到慢日志文件中

request_slowlog_timeout =0表示关闭慢日志输出。

慢日志文件位置默认在php的安装目录下的log文件夹中,可以通过修改slowlog = log/$pool.log.slow参数来指定。

php-fpm慢日志的例子,慢日志会记录下进程号,脚本名称,具体哪个文件哪行代码的哪个函数执行时间过长。

request_slowlog_timeout 和 slowlog需要同时设置,开启request_slowlog_timeout的同时需要开启 slowlog

慢日志路径需要手动创建 (slowlog)

具体开启步骤如下:

未分类

结束。

linux的php-fpm的pool、慢执行日志、进程管理及open_basedir介绍

php-fpm的pool

Nignx可以配置多个虚拟主机,php-fpm同样也支持配置多个pool,每一个pool可以监听一个端口,也可以监听一个socket。

php-fpm配置说明:

和LAMP不同的是,在LNMP架构中,php-fpm作为独立的一个服务存在,既然是独立服务,那么它必然有自己的配置文件。php-fpm的配置文件为/usr/local/php-fpm/etc/php-fpm.conf,它同样也支持include语句,类似于nginx.conf里面的include。

1. 编辑配置文件

[root@gary-tao ~]# cd /usr/local/php-fpm/etc/
[root@gary-tao etc]# ls
pear.conf  php-fpm.conf  php-fpm.conf.default  php.ini
[root@gary-tao etc]# cat php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
[root@gary-tao etc]# vim php-fpm.conf  

//增加一个以下配置:

include = etc/php-fpm.d/*.conf

//include的这一行比较特殊,请注意等号后面的路径,必须写上etc目录,然后需要创建配置文件目录和子配置文件。

编辑好后把php-fpm.conf配置文件里的www以下pool删除,只留下[global]部分

未分类

2. 创建php-fpm.d目录及目录下文件

[root@gary-tao etc]# mkdir php-fpm.d
[root@gary-tao etc]# cd php-fpm.d
[root@gary-tao php-fpm.d]# vim www.conf
[root@gary-tao php-fpm.d]# vim aming.conf
[root@gary-tao php-fpm.d]# ls
aming.conf  www.conf

//两个文件分别增加内容如下:

[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

[aming.com]
listen = /tmp/aming.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

3. 如何把两个站点隔开

  • 原有站点test.com.conf配置如下:

未分类

  • 增加一个aaa.com.conf站点信息,操作如下:
[root@gary-tao php-fpm.d]# cd /usr/local/nginx/conf/vhost/
[root@gary-tao vhost]# ls
aaa.com.conf  ld.conf  proxy.conf  ssl.conf  test.com.conf
[root@gary-tao vhost]# vim aaa.com.conf 

增加如下配置内容:

location ~ .php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/aming.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/default$fastcgi_script_name;
    }

未分类

4. 测试语法

[root@gary-tao etc]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 16:49:00] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

5. 重启php-fpm

[root@gary-tao etc]# /etc/init.d/php-fpm restart  //或/etc/init.d/php-fpm reload
Gracefully shutting down php-fpm . done
Starting php-fpm  done

6. 查看php-fpm启动状态

输入ps aux |grep php-fpm查看,显示的就有两个pool

未分类

php-fpm慢执行日志

通过php-fpm的慢执行日志,我们可以非常清晰地了解到PHP的脚本哪里执行时间长,它可以定位到具体的行。

1. 编辑配置文件

[root@gary-tao vhost]# vim /usr/local/php-fpm/etc/php-fpm.d/www.conf //针对www文件做一个测试

增加如下内容:

request_slowlog_timeout = 1  //超过一秒中就会记录日志
slowlog = /usr/local/php-fpm/var/log/www-slow.log  //日志存放的路径

1. 测试语法

[root@gary-tao vhost]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Jan-2018 19:15:14] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

2. 重启php-fpm

[root@gary-tao vhost]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done

3. 配置nginx的虚拟主机test.com.conf,把unix:/tmp/php-fcgi.sock改为unix:/tmp/www.sock

4. 编写测试脚本

[root@gary-tao php-fpm.d]# vim /data/wwwroot/test.com/sleep.php

增加如下配置内容:

<?php
echo "test slow log";
sleep(2);
echo "done";
?>

5. 使用curl做测试

[root@gary-tao php-fpm.d]# curl -x127.0.0.1:80 test.com/sleep.php -I  //访问的时候出现500,说明有语法错误。 
HTTP/1.1 500 Internal Server Error
Server: nginx/1.12.1
Date: Tue, 09 Jan 2018 11:23:17 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

报错处理:

  • 进入vim /usr/local/php-fpm/etc/php.ini

  • 找到display_error,改为On,然后访问有错误主就会有输出信息

未分类

  • 记得reload重新加载配置文件

  • 测试出报错信息,因符号问题导致。

[root@gary-tao php-fpm.d]# /etc/init.d/php-fpm reload
Reload service php-fpm  done
[root@gary-tao php-fpm.d]# curl -x127.0.0.1:80 test.com/sleep.php
<br />
<b>Parse error</b>:  syntax error, unexpected 'slow' (T_STRING), expecting ',' or ';' in <b>/data/wwwroot/test.com/sleep.php</b> on line <b>2</b><br />
  • 重新去更改配置文件vim /data/wwwroot/test.com/sleep.php的符号问题

  • 查看慢执行日志

[root@gary-tao php-fpm.d]# cat /usr/local/php-fpm/var/log/www-slow.log  //慢执行日志里指出了哪个脚本运行慢,也指出了是哪一行执行慢 

[09-Jan-2018 19:39:54]  [pool www] pid 81864
script_filename = /data/wwwroot/test.com/sleep.php
[0x00007f5987a07290] sleep() /data/wwwroot/test.com/sleep.php:3
[root@gary-tao php-fpm.d]# cat /data/wwwroot/test.com/sleep.php 
<?php 
echo "test slow log";
sleep(2);       //这个脚本超过1秒
echo "done";
?>

定义open_basedir

open_basedir的目的就是安全,只要在对应的Nginx虚拟主机配置文件中调用对应的pool,就可以使用open_basedir来物理隔离多个站点,从而达到安全目的。

1. 配置虚拟主机文件

[root@gary-tao php-fpm.d]# vim /usr/local/php-fpm/etc/php-fpm.d/www.conf 

增加如下配置内容:

php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

2. 使用curl测试

[root@gary-tao php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I  //正常访问
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Tue, 09 Jan 2018 12:32:50 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

3. 配置错误日志路径测试

  • 增加错误路径
[root@gary-tao php-fpm.d]# vim /usr/local/php-fpm/etc/php.ini //增加错误日志路径及定义日志级别,如下图

未分类

未分类

  • 进入到www.conf配置文件里面把test.com改为aming.com,再次测试,
    查看错误日志

  • 查看错误日志

[root@gary-tao php-fpm.d]# grep error_log /usr/local/php-fpm/etc/php.ini  //查看日志路径
; server-specific log, STDERR, or a location specified by the error_log
; Set maximum length of log_errors. In error_log information about the source is
;error_log = php_errors.log
;error_log = syslog
error_log = /usr/local/php-fpm/var/log/php_errors.log
; OPcache error_log file name. Empty string assumes "stderr".
;opcache.error_log=
[root@gary-tao php-fpm.d]# ls /usr/local/php-fpm/var/log/
php-errors.log  php-fpm.log  www-slow.log

[root@gary-tao php-fpm.d]# ls /usr/local/php-fpm/var/log/ //查看日志路径是否存在
php-fpm.log  www-slow.log
[root@gary-tao php-fpm.d]# touch /usr/local/php-fpm/var/log/php_errors.log  //手动建立一个日志文件
[root@gary-tao php-fpm.d]# chmod 777 /usr/local/php-fpm/var/log/php_errors.log  //更改成所有权限,防止不能写入日志
[root@gary-tao php-fpm.d]# !curl
curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.12.1
Date: Tue, 09 Jan 2018 13:05:05 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

[root@gary-tao php-fpm.d]# cat /usr/local/php-fpm/var/log/php_errors.log  //因为open_basedir限制的地址写错了,所有就会报错,访问出现404
[09-Jan-2018 13:05:05 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/test.com/3.php) is not within the allowed path(s): (/data/wwwroot/aming.com:/tmp/) in Unknown on line 0
[09-Jan-2018 13:05:05 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on lin

php-fpm进程管理

未分类

  1. pm = dynamic //定义php-fpm的子进程启动模式,dynamic为动态进程管理,一开始只启动少量的子进程,根据实际需求,动态地增加或者减少子进程,最多不会超过pm.max_children定义的数值。另外一种模式是static,这种模式下子进程数量由pm.max_children决定,一次性启动这么多,不会减少也不会增加。

  2. pm.max_children = 50 //最大子进程数,ps aux可以查看

  3. pm.start_servers = 20 //针对dynamic模式,它定义php-fpm服务在启动服务时产生的子进程服务时产生的子进程数量。

  4. pm.min_spare_servers = 5 //针对dynamic模式,定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程。

  5. pm.max_spare_servers = 35 //针对dynamic模式,定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程。

  6. pm.max_requests = 500 //针对dynamic模式,定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出。

docker搭建nginx+php-fpm开发环境

一、创建目录

mkdir -p /data1/www/app;
mkdir -p /data1/www/logs;
mkdir -p /data1/www/php;
mkdir -p /data1/www/nginx;
mkdir -p /data1/www/php/fpm.d;
mkdir -p /data1/www/nginx/vhost;
chmod 777 -R /data1/www;

添加项目:

vim /data1/www/app/www.mydemo.com/index.php
<?php
    echo 22;
    phpinfo();

二、启动容器

docker run -it --name=web_container --net=host -v /data1:/data1 centos /bin/bash;
yum -y install wget;
yum -y install initscripts;

三、安装nginx

依赖说明:

  • zlib: Nginx提供gzip模块,需要zlib库支持。
  • openssl: Nginx提供SSL功能
  • pcre: 支持地址重写rewrite功能

依赖安装:

yum -y install zlib zlib-devel openssl openssl-devel pcre-devel;

依赖检测:

rpm -qa  zlib;
rpm -qa  openssl;
rmp -qa  pcre;

nginx安装

wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxvf nginx-1.10.3.tar.gz;
cd nginx-1.10.3;
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_flv_module;
make && make install;

创建用户

groupadd  www
useradd -r -g www  www

在宿主机上修改添加配置文件: vim /data1/www/nginx/mime.types

types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/javascript                js;
    application/atom+xml                  atom;
    application/rss+xml                   rss;

    text/mathml                           mml;
    text/plain                            txt;
    text/vnd.sun.j2me.app-descriptor      jad;
    text/vnd.wap.wml                      wml;
    text/x-component                      htc;

    image/png                             png;
    image/tiff                            tif tiff;
    image/vnd.wap.wbmp                    wbmp;
    image/x-icon                          ico;
    image/x-jng                           jng;
    image/x-ms-bmp                        bmp;
    image/svg+xml                         svg svgz;
    image/webp                            webp;

    application/font-woff                 woff;
    application/java-archive              jar war ear;
    application/json                      json;
    application/mac-binhex40              hqx;
    application/msword                    doc;
    application/pdf                       pdf;
    application/postscript                ps eps ai;
    application/rtf                       rtf;
    application/vnd.apple.mpegurl         m3u8;
    application/vnd.ms-excel              xls;
    application/vnd.ms-fontobject         eot;
    application/vnd.ms-powerpoint         ppt;
    application/vnd.wap.wmlc              wmlc;
    application/vnd.google-earth.kml+xml  kml;
    application/vnd.google-earth.kmz      kmz;
    application/x-7z-compressed           7z;
    application/x-cocoa                   cco;
    application/x-java-archive-diff       jardiff;
    application/x-java-jnlp-file          jnlp;
    application/x-makeself                run;
    application/x-perl                    pl pm;
    application/x-pilot                   prc pdb;
    application/x-rar-compressed          rar;
    application/x-redhat-package-manager  rpm;
    application/x-sea                     sea;
    application/x-shockwave-flash         swf;
    application/x-stuffit                 sit;
    application/x-tcl                     tcl tk;
    application/x-x509-ca-cert            der pem crt;
    application/x-xpinstall               xpi;
    application/xhtml+xml                 xhtml;
    application/xspf+xml                  xspf;
    application/zip                       zip;

    application/octet-stream              bin exe dll;
    application/octet-stream              deb;
    application/octet-stream              dmg;
    application/octet-stream              iso img;
    application/octet-stream              msi msp msm;

    application/vnd.openxmlformats-officedocument.wordprocessingml.document    docx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet          xlsx;
    application/vnd.openxmlformats-officedocument.presentationml.presentation  pptx;

    audio/midi                            mid midi kar;
    audio/mpeg                            mp3;
    audio/ogg                             ogg;
    audio/x-m4a                           m4a;
    audio/x-realaudio                     ra;

    video/3gpp                            3gpp 3gp;
    video/mp2t                            ts;
    video/mp4                             mp4;
    video/mpeg                            mpeg mpg;
    video/quicktime                       mov;
    video/webm                            webm;
    video/x-flv                           flv;
    video/x-m4v                           m4v;
    video/x-mng                           mng;
    video/x-ms-asf                        asx asf;
    video/x-ms-wmv                        wmv;
    video/x-msvideo                       avi;
}

新增fast_cig: vim /data1/www/nginx/fastcgi_params

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

vim /data1/www/nginx/nginx.conf

user  www;
worker_processes  5;

error_log  logs/nginx-error.log;
pid        nginx/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    client_body_temp_path /tmp/client_body_temp_path;
    fastcgi_temp_path /tmp/fastcgi_temp_path;
    proxy_temp_path /tmp/proxy_temp_path;
    scgi_temp_path /tmp/scgi_temp;
    uwsgi_temp_path /tmp/uwsgi_temp_path;

    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
    include vhost/*.conf;
}

配置文件检测

/usr/local/nginx/sbin/nginx -c /data1/www/nginx/nginx.conf -p /data1/www -t

新增项目配置: vim /data1/www/nginx/vhost/mydemo.com.conf

server {
         listen       80 ;
         root /data1/www/app/www.mydemo.com/;
         server_name  www.mydemo.com mydemo.com;

         access_log   logs/nginx_www.mydemo.com-access_log  main;
         error_log    logs/nginx_www.mydemo.com-error_log;
         rewrite  "^/(.*)" /index.php/$1 last;

         location  / {
                   proxy_ignore_client_abort on;
                   fastcgi_pass 127.0.0.1:9023;
                   fastcgi_index index.php;
                   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                   #fastcgi_param  SCRIPT_URL         $script_uri;
                   #fastcgi_param  REQUEST_ID           $request_uid;
                   include fastcgi_params;
         }
}

启动nginx:

/usr/local/nginx/sbin/nginx -c /data1/www/nginx/nginx.conf -p /data1/www

平滑重启

Kill -HUP  ${nginx_pid}

四、安装php-fpm

yum -y install gd-devel zlib-devel libjpeg-devel libpng-devel libiconv-devel freetype-devel libxml2 libxml2-devel openssl openssl-devel curl-devel libxslt-devel libmcrypt-devel mhash mcrypt
wget http://am1.php.net/get/php-7.2.0.tar.bz2/from/this/mirror ;
tar -jxvf mirror;
cd php-7.2.0;
./configure  --prefix=/usr/local/php --enable-fpm --enable-cli --enable-pcntl --with-curl;
make && make install; 

新增配置文件: vim /data1/www/php/php-fpm.conf

[global]
pid = php/php-fpm.pid
error_log = logs/php-fpm.log
emergency_restart_threshold = 20
emergency_restart_interval = 60s
process_control_timeout = 0
process.max = 2048
daemonize = yes
rlimit_files = 65535
rlimit_core = 67108864
events.mechanism = epoll

; auto include phpfpm configure
include = php/fpm.d/*.conf

vim /data1/www/php/php.ini

[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 8M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 2M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
[filter]
[iconv]
[intl]
[sqlite3]
[Pcre]
[Pdo]
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=
[Phar]
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = On
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = On
[OCI8]
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[bcmath]
bcmath.scale = 0
[browscap]
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = 1
[COM]
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[sysvshm]
[ldap]
ldap.max_links = -1
[dba]
[opcache]
[curl]
[openssl]

新增项目配置:

vim /data1/www/php/fpm.d/mydemo.com.conf

 [mydemo.com]
user = www
group = www
listen = 127.0.0.1:9023
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 512
pm.start_servers = 5
pm.min_spare_servers = 4
pm.max_spare_servers = 64
pm.max_requests = 1500

;pm.status_path = /dpool_monitor


slowlog = logs/$pool-slow_log
request_slowlog_timeout = 2

request_terminate_timeout = 30
catch_workers_output = no
security.limit_extensions = ""

access.log=logs/php-fpm_$pool.access.log
access.format = "%R - %u %t "%m %r%Q%q" %s %f %{mili}d %{kilo}M %C%%"

启动命令:

/usr/local/php/sbin/php-fpm -c /data1/www/php/php.ini  -y /data1/www/php/php-fpm.conf  -p /data1/www

平滑重启:

kill -USR2  fpm-pid