一. 了解Nginx架构
1. Nginx架构图
2. 架构说明
- Nginx在启动时,会创建两种类型的进程,一个主进程Master,和一个或多个工作进程Worker(PS:Windows操作系统下只创建一个Worker);其中主进程并不处理网络请求,它只负责工作进程的调度工作,如上图中显示的三项:加载配置、启动工作进程和非停升级。
- Nginx服务器实际处理网络请求和做出响应的是工作进程Worker,在类Unix操作系统中允许配置启动多个Worker,并且每个Worker能同时处理上千个网络请求。
- Nginx的模块化设计:工作进程Worker包含了核心模块和功能性模块,核心模块负责一个运行循环(run-loop),在网络请求处理过程的不同阶段的功能模块的执行工作,如:网络读写、存储读写、内容传输、外出过滤以及将请求发往上游服务器等;其模块化设计的优点是用户可以根据自身需要选择或修改某个功能模块,然后在重新编译后实现功能模块的加载。
- 事件驱动:异步非阻塞模型,这也是Nginx实现高性能的关键
二. Nginx的配置和使用详解
首先我们先来看下未经修改的配置文件内容,nginx配置文件在${NGINX_HOME}/conf/nginx.conf。
# 运行用户
user nobody;
# 启动工作进程,通常设置成和cpu的数量相等
worker_processes 1;
# 全局错误日志及PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#工作模式及连接数上限
events {
# epoll是多路复用IO(I/O Multiplexing)中的一种方式,
# 仅用于linux2.6以上内核,可以大大提高nginx的性能,
# 可选参数:select、poll、kqueue、epoll、rtsig。
use epoll;
# 单个后台worker process进程的最大并发链接数
worker_connections 1024;
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
#ulimit -SHn 65535
}
http {
# 设定mime类型,类型由mime.type文件定义
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"';
# Nginx接收到网络请求的日志文件保存路径
access_log logs/access.log main;
# sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
# 对于普通应用,必须设为 on,
# 如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
# 以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
# 连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
# 开启gzip压缩
gzip on;
gzip_disable "MSIE [1-6].";
# 设定请求缓冲
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
# 设定虚拟主机配置
server {
# 侦听80端口
listen 80;
# 定义使用什么虚拟主机地址访问,可以填写多个值,使用空格分开,支持通配符和正则
server_name localhost;
# 定义服务器的默认网站根目录位置,支持相对路径和绝对路径,此处html为相对路径,等同于${NGINX_HOME}/html
root html;
# 设定本虚拟主机的访问日志
access_log logs/nginx.access.log main;
error_log logs/quancha.error.log;
# 默认请求
location / {
# 定义首页索引文件的名称
index index.php index.html index.htm;
}
# 重定向服务器错误提示页面到静态页面/50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 配置静态文件访问规则
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
# 过期30天,静态文件不怎么更新,过期可以设大一点,
# 如果频繁更新,则可以设置得小一点。
expires 30d;
}
# PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 禁止访问 .ht或.htxxx 文件
location ~ /\.ht {
deny all;
}
}
# 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;
# }
#}
}
关键配置项说明:
1. worker_processes
- Nginx服务器实现并发处理服务的关键,指令格式:
worker_processes number | auto;
number:Nginx进程最多可以产生的工作进程数量
auto: Nginx进程将自动检测
2. location
- 指令格式:
location [ = | ~ | ~* | ^~ ] uri {...}
这里的url可以分成两类:标准uri和正则uri,区别在于uri是否包含正则表达式。 - location表达式类型
-
=
表示对uri执行常规字符串的精确匹配,也就是完全匹配,一旦匹配成功则停止继续匹配其他location。 -
~
表示对uri执行正则匹配,区分大小写。 -
~*
表示对uri执行正则匹配,不区分大小写。 -
^~
表示对uri执行常规字符串的前缀匹配而不是正则匹配,如果该选项匹配,则不再进行其他location的匹配。 -
/
表示通用匹配,如何其他匹配规则都不起作用,则所有请求都会匹配到这,因为任何请求都是以/
开头。
- location匹配优先级
请求uri对location规则的匹配和location在配置文件中定义的顺序无关,而是根据定义的location类型确定,而且相同类型的表达式,字符串长的优先匹配,下面按照优先级从高到低对不同location表达式类型排序:
-
=
类型表达式,优先级最高,如果匹配成功,则停止匹配。 -
^~
类型表达式,如果匹配成功,则停止匹配。 -
~
或~*
类型的正则表达式,以在配置文件中定义的顺序进行优先匹配。 - 常规字符串类型表达式,按前缀匹配。
- 虽然location匹配优先级与定义先后无关,但为了方便阅读,个人建议的书写顺序:
location = uri
>location 完整uri
>location ^~ uri
>location ~/~* uri
>location 部分起始uri
>location /
。 - location规则例子:
location = / {
# 这个规则很常使用,直接匹配网站根,通过域名访问网站首页,使用这条规则可以加速处理,可以转发给后端应用或静态页面
proxy_pass http://host:port/uri
}
# 静态资源文件匹配有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用location。
location ^~ /static/ {
# 匹配任何以/static/开始的请求,并停止匹配其它
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
# 匹配以gif、jpg、jpeg、png、css、js、icoj结尾的请求,但是所有/static/目录的请求优先由上一条处理。
root /webroot/static/;
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长或更精确字符匹配或者正则表达式匹配会优先匹配
root /webroot/
}
3. log_format
Mginx服务器日志相关配置项有两项
- log_format:设置日志格式
- log_format语法
Syntax: log_format name [escape=default|json|none] string …;
Default: log_format combined “…”;
Context: http
- 可使用全局变量
参数 | 说明 | 示例 |
$remote_addr | 客户端地址 | 192.168.0.111 |
$remote_user | 客户端用户名称 | - |
$time_local | 访问时间和时区 | 04/April/2019:19:00:00 +0800 |
$request | 请求的URI和HTTP协议 | “GET /index.html HTTP/1.1” |
$status | HTTP请求状态 | 200 |
$body_bytes_sent | 发送给客户端文件内容大小 | 3458 |
$http_referer | url跳转来源 | |
$http_user_agent | 用户终端浏览器等信息 | Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" |
$http_host | 请求地址,即浏览器中你输入的地址(IP或域名) | |
$ssl_protocol | SSL协议版本 | TLSv1 |
$ssl_cipher | 交换数据中的算法 | RC4-SHA |
$upstream_addr | 后台upstream的地址,即真正提供服务的主机地址 | 192.168.0.333:80 |
$upstream_status | upstream状态 | 200 |
$request_time | 整个请求的总时间 | 0.125 |
$upstream_response_time | 请求过程中,upstream响应时间 | 0.102 |
如需了解更多关于Nginx变量的信息,请点击这里。
- access_log:指定日志文件存放路径、格式和缓存大小,可参考官方模块说明 ngx_http_log_module。
- access_log语法
Syntax:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context:
http, server, location, if in location, limit_except
- 样例:
access_log logs/access.log main;
# 基于域名打印日志
access_log logs/$host.access.log main;
- error_log:指定Error日志文件存放路径
- error_log语法
Syntax:
error_log path level;
Default:
error_log logs/error.log error;
Context:
http, server, location, if in location, limit_except
level是日志的输出级别,取值范围是debug、info、notice、warn、error、crit、alert、emerg
参考:
- 官方文档之核心模块
- 官方文档之变量索引
- nginx中文手册