运行中的nginx进程间的关系
一般情况下, worker 进程数与服务器上的 CPU 核心数相同。
worker 进程负责提供服务,
而 master 进程负责监控与管理这些 worker 进程,当任意一个 worker 进程出现严重错误时, master 进程会立刻启动新的 worker 进程,实现高可用
worker 进程之间会通过共享内存 、 原子操作等进程间通信机制来实现负载均衡等功能。
多个 worker 进程处理请求可以充分利用 SMP 多核架构,从而实现真正意义上的多核并发处理。当 Nginx 上的进程数与 CPU 核心数相等,并让每个 worker 进程都绑定特定的 CPU 核心时,就可以保障进程间切换最小化,保障高性能
对称多处理 " ( SymmetricalMulti-Processing )简称 SMP ,是指在一个计算机上汇集了一组处理器 ( 多 CPU ) ,各 CPU 之间共享内存子系统以及总线结构。它是相对非对称多处理技术而言的,是一种应用十分广泛的并行技术。
查看CPU核数
[root@VM-12-5-centos server]# cat /proc/cpuinfo|grep 'processor'
processor : 0
processor : 1
[root@VM-12-5-centos server]# ps -ef | grep nginx
root 23833 1 0 14:54 ? 00:00:00 nginx: master process /www/server/nginx/sbin/nginx -c /www/server/nginx/conf/nginx.conf
www 23834 23833 0 14:54 ? 00:00:00 nginx: worker process
www 23835 23833 0 14:54 ? 00:00:00 nginx: worker process
www 23836 23833 0 14:54 ? 00:00:00 nginx: cache manager process
root 24432 30780 0 15:38 pts/0 00:00:00 grep --color=auto nginx
nginx配置的通用语法
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
-
块配置项
events { ... } http { upstream baskend { server 127.0.0.1:8080; } gzip on; server { ... location /webstatic { gzip off; } }
-
配置项的语法格式
配置项名 配置项值1 配置项值2 … ;
-
配置项单位
当指定空间大小时,可以使用单位
K或者k千字节
M或者m兆字节
gzip_buffers 4 8k; client_max_body 64M;
当指定时间时,可以使用的单位包括
ms,s,m,h,d,w,M,y
expires 10y; proxy_read_timeout600; client_body_timeout 2m;
-
配置项中使用变量
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
Nginx服务的基本配置
nginx在运行时,必须加载几个核心模块和一个事件类模块。
用于调试进程和定位问题的配置项
- 是否以守护进程方式
daemon on | off
默认daemon on;
- 是否以master/worker方式工作
master_process on | off
默认master_process on;
如果off,则master进程不会fork出worker子进程来处理请求,而是master进程自身来处理请求
- error日志的设置
error_log /path/file level;
默认error_log logs/error.log error;
日志文件可以是/dev/null就不会输出任何日志了,直接关闭日志。
日志文件可以是stderr ,这样日志会输出到标准错误文件中
level:debug,info,notice,warn,error,crit,alert,emerg。从左到右级别依次增大
- 是否处理几个特殊的调试点
debug_points [stop | abort]
用来帮助用户追踪调试nginx的,如果设置了stop,那么gninx的代码执行到调试点时就会发出SIGSTOP信号以用于调试,如果设置为abort,则会产生一个coredump文件,可以使用gdb来查看nginx当时的各种信息
- 仅对指定的客户端输出debug级别的日志
debug_connection [IP | CIDR]
这个配置项实际属于事件类配置。因为需要放在events中
events { debug_connection 10.2.3.4 debug_connection 10.2.3.5/24 }
- 限制coredump核心转储文件的大小
worker_rlimit_core size;
当进程发生错误或者收到信号终止时,系统会将进程执行时的内存内容写入一个文件,以作为调试,这就是核心转储。
- 指定coredump文件生成目录
working_directory path;
workder进程的工作目录。这个配置的唯一用途就是设置coredump文件所放置的目录,协助定位问题。因此,需要确保worker进程有权限向working_directory指定的目录写入文件
正常运行的必备配置项
- 定义环境变量
env VAR|VAR = VALUT
env TESTPATH=/tmp/;
直接设置操作系统上的环境变量
- 嵌入其他配置文件
include /path/file
include mime.types; include vhost/*.conf;
可以是具体文件名,也可以是通配符
- pid文件的路径
pid path/file
默认pid logs/nginx.pid
保存master进程ID的pid文件存放路径
- nginx worker进程运行的用户及用户组
user username [groupname];
user nobody nobody;
user用于设置master进程启动后,fork出的worker进程运行在哪个用户和用户组下,如果不写用户组,则用户组名和用户名相同
- 指定nginx worker进程打开的最大句柄描述符个数
worker_rlmit_nofile limit;
设置一个worker进程可以打开的最大文件句柄数
- 限制信号队列
worker_rlimit_sigpending limit;
设置每个用户发往nginx的信号队列的大小。当某个用户的信号队列满了,这个用户再发送的信号量会被丢掉
优化性能的配置项
- nginx worker进程个数
worker_processes number;
默认worker_processes 1;
在master/worker运行方式下,定义worker进程的个数,worker进程的数量会直接影响性能。
每个worker进程都是单线程的进程,他们会调用各个模块以实现多种多样的功能,如果各个模块确认不会出现阻塞式的调用,那么worker数=CPU内核数
如果各个模块可能出现阻塞式调用,需要配置稍多一些的worker进程
例如:业务需要读取本地磁盘文件,内存小,则可能磁盘IO调用会阻塞worker。
多worker进程可以充分利用多核系统架构,但是worker进程数量大于CPU核数,会增大进程间切换带来的消耗(Linux是抢占式内核)
所以一般情况worker数=CPU核数,且配置worker_cpu_affinity配置绑定CPU内核
- worker_cpu_affinity cpumask
worker_processes 4
worker_cpu_affinity 1000 0100 0010 0001;
设置每个worker独享一个CPU。
假定每一个worker进程都非常繁忙,如果多个worker进程都在抢同一个CPU,会出现同步问题
参数仅对linux系统有效,linux使用sched_setaffinity()系统调用实现
- SSL硬件加速
ssl_engine device
如果服务器上存在SSL硬件加速设备,可以配置。通过openssl engine -t查看是否存在
- 系统调用gettimeofday的执行频率
默认情况下,每次内核时间调用(如epoll,select,poll,kqueue等)返回时,都会执行一次gettimeofday,实现内核的时钟来更新Nginx中缓存时钟。
早期gettimeofday都会有一次内核态到用户态的内存复制,代价很大。可以设置timer_resolution配置调用时间
timer_resolution 100ms
但是目前大多数内核中,如x86-64体系架构,gettimeofday只是一次vsyscall,只是对共享内存中的数据做访问,不是通常的系统调用,代价不大。
- Nginx worker进程优先级设置
worker_priority nice;
worker_priority 0;
设置Nginx worker进程的优先级。如果优先级越高,进程分配的时间片也会越大
事件类配置项
- 是否打开accept锁
accept_mutex [on | off]
默认 accept_mutex on;
accept_mutex是nginx的负载均衡锁。
可以让多个worker进程轮流地,序列化地与新的客户端建立TCP连接。当某个worker进程建立的连接数量达到worker_connections配置的最大连接数的7/8时,会大大减小该worker进程试图建立新TCP连接的机会。
从而实现所有worker进程处理的客户端请求数尽量接近
默认打开,如果关闭它,那么建立TCP连接到耗时会更短,但是worker进程之间的负载会非常不均衡,因此建议关闭
- lock文件的路径
lock_file path/file;
lock_file logs/nginx.lock;
accept锁需要这个lock文件,如果关闭accept则此配置不生效,使用文件锁
- 使用accept锁后到真正建立连接之间的延迟时间
accept_mutex_delay Nms;
默认:accept_mutex_delay 500ms;
同一时刻只有一个worker进程能够取到accept锁。这个accept锁不是阻塞锁,如果取不到会立刻返回,至少等accept_mutex_delay 时间间隔后才能再次试图取锁
- 批量建立新连接
multi_accept [ on | off ]
默认:multi_accept off;
当事件模型通知有新连接时,尽可能对本地调度中客户端发起的所有TCP请求都建立连接
- 选择事件模型
use [ kqueue | rtsig | epoll | /dev/pool | select | poll | eventport ];
Nginx会自动使用最合适的事件模型,对于linux系统可供选择epoll,poll,select。
epoll是性能最高的,epoll可以处理大并发连接
- 每个worker的最大连接数
worker_connections number;