Nginx
[toc]
nginx命令
参数
-? / -h 帮助
-c 使用指定的配置文件
-g 指定配置指令
-p 指定运行目录
-s 发送信号
stop 立即停止服务
quit 优雅的停止服务
reload 重载配置文件
reopen 重新开始记录日志文件
-t / -T 测试配置文件是否有语法错误
-v / -V 打印nginx的版本信息, 编译信息等
Nginx启动
/usr/local/nginx/sbin/nginx
通过指定配置文件启动
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
配置文件语法检查
# 检查默认配置文件是否有语法错误
/usr/local/nginx/sbin/nginx -t
# 检查指定配置文件语法是否有错误
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -t
Nginx配置文件解读
#user nobody; # 设置worker进程运行用户
worker_processes 1; # 配置workder进程数量,通常设置为cpu的数量或者cpu数量的2倍
#error_log logs/error.log; # 配置全局日志及日志级别-> debug > info > notice > warn > error > crit > alert > emerg
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; # 配置进程pid文件
# 配置工作模式和连接数
events {
worker_connections 1024; # 配置每个worker进程连接数上限,nginx总连接数等于 worker_processes * worker_connections
}
http {
include mime.types; # 配置nginx支持哪些多媒体类型,可以在conf/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日志存放路径,并使用上面定义的main日志格式
#access_log logs/access.log main;
sendfile on; # 开启高效文件传输模式
#tcp_nopush on; # 防止网络阻塞
#keepalive_timeout 0;
keepalive_timeout 65; # 长连接超时时间,单位是秒
#gzip on; # 开启gzip压缩输出
# 配置虚拟主机
server {
listen 80; # 配置监听端口
server_name localhost; # 配置域名
#charset koi8-r; # 配置字符集
#access_log logs/host.access.log main; # 设置此虚拟主机的访问日志,如果没有配置的话则使用全局的access_log
# 默认匹配 / 的请求,当访问路径中有 / , 会被该location匹配并处理
location / {
root html; # root是配置服务器的默认网站根目录位置,默认为nginx安装目录下的html目录
index index.html index.htm; # 配置默认首页文件的名称
}
#error_page 404 /404.html; # 配置404页面
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; # 配置50x页面
# 精确匹配50x.html
location = /50x.html {
root html;
}
# PHP请求全部转发到apache处理
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# PHP请求全部转发到FastCGI处理
# 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;
#}
# 禁止访问.htaccess文件
# 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服务(安全的网络传输协议,加密传输)
# 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;
# }
#}
}
Nginx内置变量
$uri 当前请求的uri,不带参数
$request_uri 请求的uri,带完整参数
$host http请求报文中host首部,如果没有则以处理此请求的虚拟主机的主机名代替
$hostname nginx服务运行在主机的主机名
$remote_addr 客户端IP
$remote_port 客户端端口
$remote_user 使用用户认证时客户端用户输入过的用户名
$request_filename 用户请求中的URI经过本地root或alias转换后映射的本地文件路径
$request_method 请求方法, GET, POST, PUT等
$server_addr 服务器地址
$server_name 服务器名称
$server_port 服务器端口
$server_protocol 服务器向客户端发送响应时的协议,如http/1.1 http/1.0
$scheme 在请求中使用scheme,如http://xxx.com中的http
$http_HEADER 匹配请求报文中指定的HEADER
$http_host 匹配请求报文中的host首部
$document_root 当前请求映射到的root配置文件
$time_local nginx的时间
$request request请求行,GET等方法, http协议等
$status response返回的状态码
$body_bytes_sent 从服务端响应给客户端body信息大小
$http_referer http上一级页面, 防盗链, 用户行为分析时会使用
$http_user_agent http头部信息, 客户端访问设备等信息
$http_x_forwarded_for http请求携带的http信息
alias与root
location /hello {
root /usr/local/nginx/html/myweb;
}
# 实际请求位置是/usr/local/nginx/html/myweb/hello,把/hello拼在后面
location /hello {
alias /usr/local/nginx/html/myweb;
}
# 实际请求位置是/usr/local/nginx/html/myweb
打开目录文件浏览功能
location / {
autoindex on;
}
autoindex
常用参数
官网文档地址 http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
autoindex_exact_size off;
默认为on,显示出文件的确切大小,单位是bytes。
修改为off,显示出文件的大概大小,单位是KB或者MB或者GB
autoindex_localtime on;
默认为off,显示的文件时间为GMT时间。
修改为on,显示的文件时间为文件的服务器时间。
charset utf-8/gbk;
默认中文目录乱码,添加上解决乱码。
整个虚拟主机开启目录浏览
location / {
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
}
单独目录开启目录浏览
直接二级目录开启目录流量
location /down/ {
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
}
虚拟目录开启目录浏览
location /down/ {
alias /home/wwwroot/test/;
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
}
限制nginx每秒向客户端发起响应的速度
location / {
set $limit_rate 1k;
}
日志格式
官网文档地址 http://nginx.org/en/docs/http/ngx_http_log_module.html
ngin x内置模块或第三方模块中的变量都可以配置上去,记录到日志中,这里
main
是日志格式的名称,可以自己起名字.
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;
反向代理
官网文档地址 http://nginx.org/en/docs/stream/ngx_stream_core_module.html
Tcp, U四层代理
在http同级下配置
worker_processes auto;
error_log /var/log/nginx/error.log info;
events {
worker_connections 1024;
}
stream {
upstream backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns {
server 192.168.0.1:53535;
server dns.example.com:53;
}
server {
listen 12345;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass backend;
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
示例
stream {
upstream mysql_server {
server 192.168.101.40:3306;
}
server {
listen 3340;
proxy_connect_timeout 5s;
proxy_timeout 10s;
proxy_pass mysql_server;
}
}
Http七层代理
当我们使用nginx反向代理时,用于与反向代理服务器直接建立一个连接,反向代理与上游服务器建立另一个连接,当上游服务器想拿到用户的真实信息是(比如$remote_addr)时拿到的是反响代理的IP。
解决办法:
用户是直接和反向代理服务器建立连接的,因此我们可以在反向代理服务器上拿到用户的真实信息,我们把这些信息写入到请求头(header)发送给上游服务器,这样上游服务器就可以拿到用户的真实信息了
upstream myserver {
server 127.0.0.1:8080;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://myserver;
}
# 反向代理也可以直接使用proxy_pass转发到上游服务器地址
location /admin {
proxy_pass http://192.168.101.38:8080;
}
flask获取用户真实ip
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/')
def index():
real_ip = request.headers.get('X-Forwarded-For')
if real_ip:
return jsonify({'ip': request.remote_addr, 'real_ip': real_ip})
return jsonify({'ip': request.remote_addr})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
正向代理
server {
listen 80;
# dns
resolver 233.5.5.5;
location / {
proxy_pass http://$http_host$request_uri;
}
}
负载均衡
上游服务器在负载均衡调度中的状态
状态 | 说明 |
---|---|
down | 当前server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 当前服务器请求失败的次数 |
fail_timeout | 经过max_fails失败后,服务暂停时间 |
max_conns | 限制最大连接数 |
负载均衡其它配置
upstream myserver {
server 192.168.101.40:8080;
server 192.168.101.41:8080;
# backup表示备用机器,其它所有非backup机器down的时候,才请求backup机器
server 192.168.101.42:8080 backup;
# down表示当前的server节点是down的状态,不参与负载均衡
server 192.168.101.43:8080 down;
}
upstream myserver {
# weight表示权重,用于上游服务器性能不均的场景
server 192.168.101.40:8080 weight=3;
server 192.168.101.41:8080 weight=1;
}
location / {
proxy_pass http://myserver;
}
负载均衡常用策略
-
轮询(默认)
每个请求轮流分配到不同的上游服务器,如果上游服务器挂掉,将自动剔除
upstream myserver { server 192.168.101.40:8080; server 192.168.101.41:8080; }
-
权重
每个请求按一定比例分发到不同的上游服务器, weight值越大访问比例越大,用于上游服务器性能不均的场景
upstream myserver { server 192.168.101.40:8080 weight=2; server 192.168.101.41:8080 weight=1; }
-
ip_hash
ip_hash也叫IP 绑定,每个请求按访问的hash值分配,这样每个访问的客户端会固定访问一个上游服务器,可以解决会话Session丢失的问题。
upstream myserver { ip_hash; server 192.168.101.40:8080; server 192.168.101.41:8080; }
-
最少连接
请求会被转发到连接数最少的服务器上
upstream myserver { least_conn; server 192.168.101.40:8080; server 192.168.101.41:8080; }
-
url_hash
按照访问的URL的hash结果来分配请求,使每个URL定向到同一个后端服务器
upstream myserver { hash $request_uri; server 192.168.101.40:8080; server 192.168.101.41:8080; }
动静分离
静态资源请求交由nginx处理,动态请求由nginx转发至上游服务器处理
实现静态代理
当访问静态资源的时候,则从
/usr/local/nginx/html/static
目录下获取
基于静态资源后缀匹配
location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp|swf|ico|rar|zip|txt)$ {
root /usr/local/nginx/html/static;
}
~
表示正则匹配
.
第一个点表示任意字符
\.
表示转义字符,把.
转义为原来的.
|
表示或者的意思
$
表示结尾
基于静态文件目录匹配
location ~ .*/(css/js/img/image){
root /usr/local/nginx/html/static;
}
虚拟主机
nginx可通过配置多个server标签来配置多个虚拟主机部署多个网站。
可以通过配置不同端口来配置多个虚拟主机。
也可以通过相同端口不同域名来配置虚拟主机。
使用缓存
用户请求分两种,一种是静态,一种是动态,当不同用户访问同一个URL看到的内容是不同的,这就是一个动态请求,需要交由上游服务器处理,而有些资源是一段时间不会发送变化的,这个时候为了减轻上游服务器的压力,我们可以让nginx把上游服务器返回的内容缓存一段时间,比如缓存一天,在一天之内即使上游服务器对这个内容的响应发生了变化,也不会交由上游服务器去处理,只会去拿nginx缓存中的内容响应给浏览器。因为nginx的性能远远领先于上游服务器的性能,使用这样一种特性,对一些小的站点会有非常大的性能提升。
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m max_size=10g inactive=60m use_temp_path=off;
使用缓存
location / {
proxy_cache mycache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 302 1d;
}
GoAccess实时开始化监控access日志
Nginx进程结构
- Master进程
- Worker进程
- Cache manager进程
- Cache loader进程
说明:
worker进程数量的设置一般对应cpu的数量。
进程结构说明:
Master
是一个父进程,它有很多子进程Worker
,Cache manager
,Cache loader
Master
主要是用来做Worker
进程的管理(监控每个Worker
进程是不是在正常的工作,需不需要做重载配置,需不需要做热部署等工作),真正用来处理请求的是Worker
进程
Cache loader
是用来做缓存的载入。
Cache manager
是用来做缓存的管理。
Nginx进程管理: 信号
- Master进程
- 监控worker进程
- CHLD
- 管理worker进程
- 接收信号
- TERM,INT
- QUIT
- HUP
- USR1
- USR2
- WINCH
- Worker进程
- 接收信号
- TERM,INT
- QUIT
- USR1
- WINCH
- Nginx命令行
- reload -> HUP
- reopen -> USR1
- stop -> TERM
- quit -> QUIT
发送信号
kill -HUP 进程ID
Nginx执行reload
流程
1.向master进程发送HUP信号(reload命令)
2.master进程校验配置语法是否正确
3.master进程打开新的监听端口(或其它应用其它修改的部分)
4.master进程用新配置启动新的worker子进程
5.master进程向老worker子进程发送QUIT新型号
6.老worker进程关闭监听句柄,处理完当前连接后结束进程
Nginx热升级流程
1.将旧nginx文件替换成新的nginx文件(注意备份)
2.向master进程发送USR2信号
3.master进程修改pid文件名,加后缀.oldbin
4.master进程用新nginx文件启动master进程
5.向老master进程发送QUIT信号,关闭老master进程
6.回滚:向老master发送HUP,向新master发送QUIT
worker进程:优雅的关闭(主要针对http请求)
1.设置定时器
worker_shutdown_timeout
2.关闭监听句柄
3.关闭空闲连接
4.在循环中等待全部连接关闭
5.退出进程
Nginx访问限制
连接限制limit_conn_module
# http模块配置
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
# 同一时刻只允许一个客户端IP连接
location / {
limit_conn conn_zone 1;
}
请求限制limit_req_module
# http模块配置,rate限制速率,限制一秒钟最多处理一个IP请求
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s
# location模块配置,1r/s直接收一个请求,多余的直接处理
location / {
limit_req zone=req_zone;
}
# location模块配置,请求超过1r/s,剩下的将被延迟处理
location / {
limit_req zone=req_zone burst=3 nodelay;
}
# 压力测试
ab -n 50 -c 20 页面地址
基于IP的访问控制http_access_module
官方文档地址http://nginx.org/en/docs/http/ngx_http_access_module.html
允许
配置语法
Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
拒绝
配置语法
Syntax: deny address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
拒绝某一个IP,其它的全部允许
location / {
root /home/wwwroot/web;
index index.html;
deny 192.168.10.18;
allow all;
}
如有允许某个IP,其它全部拒绝,那么就先配置允许的,在后面写
deny all
;
基于用户登录认证http_auth_basic_module
官网文档地址http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
配置语法
Syntax: auth_basic string | off;
Default:
auth_basic off;
Context: http, server, location, limit_except
用户密码配置文件
Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except
yum -y install httpd-tools
htpasswd语法
Usage:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password
htpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
参数说明
-c 创建passwdfile.如果passwdfile 已经存在,那么它会重新写入并删去原有内容.
-n 不更新passwordfile,只将加密后的用户名密码显示在屏幕上;
-m 默认采用MD5算法对密码进行加密
-d 采用CRYPT算法对密码进行加密
-p 不对密码进行进行加密,即使用普通文本格式的密码
-s 采用SHA算法对密码进行加密
-b 命令行中一并输入用户名和密码而不是根据提示输入密码,可以看见明文,不需要交互
-D 删除指定的用户
示例
# 创建用户用户
htpasswd -cb /usr/local/nginx/conf/htpasswd wanghaha 123456
# 删除用户
htpasswd -D /usr/local/nginx/conf/htpasswd wanghaha
location / {
auth_basic "closed site";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
gzip压缩
# 开启gzip
gzip off;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 1;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
# 设置压缩所需要的缓冲区大小
gzip_buffers 32 4k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.0;
rewrite
正则测试工具pcretest
yum -y install pcre-tools
语法:
/中间写正则表达式/
[root@localhost ~]# pcretest
PCRE version 8.32 2012-11-30
re> /^(\d{3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
data> 192.168.101.1
0: 192.168.101.1
1: 192
2: 168
3: 101
4: 1
Rewrite标记flag
flag | 说明 |
---|---|
last | 停止rewrite检测 |
break | 停止rewrite检测 |
redirect | 返回302临时重定向,地址栏会显示跳转后的地址 |
permanent | 返回301永久重定向,地址栏会显示跳转后的地址 |
浏览器缓存
# nginx时间单位
ms milliseconds 毫秒
s seconds
m minutes
h hours
d days
w weeks
M months, 30 days
y years, 365 days
# 页面缓存20天
location / {
expires 20d;
}
跨域访问
location ~ .*\.(html|htm)$ {
add_header Access-Control-Allow-Origin http://你的域名.com;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
}
静态资源防盗链
只允许指定服务器IP地址(或域名)来访问静态资源
location \ .*\.(jpg|gif|png)$ {
valid_referers none blocked 192.168.101.40;
if($invalid_referer) {
return 403;
}
}