Nginx
简介
1.1 Nginx和Apache对比
Nginx:
- 轻量级
- 抗并发
- 静态处理性能比apache高三倍以上
- 设计高度模块化
- 配置简洁
- 支持7层负载均衡
- 优秀的反向代理服务器
- 易启动
- 社区活跃
Apache:
- rewrite强大
- 模块多
- bug少,稳定
- 对php支持简单
- 处理动态请求时有优势
安装
2.1 安装方式
- 编译安装:版本随意、安装复杂、升级繁琐、规范、便于管理
- epel安装:版本较低、安装简单、配置不易读
- 官方仓库:版本较新、安装简单、配置易读
2.2 配置官方yum源
bash
[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true2.3 编译安装
查看nginx默认模块:
bash
nginx -V安装相关依赖:
bashyum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch下载Nginx源码和第三方模块(如nginx_upstream_check)
bashwget https://nginx.org/download/nginx-1.26.1.tar.gz wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip将第三方模块加载到Nginx模块中
bash# 解压后进入Nginx目录 # 选择一个最接近Nginx版本的 patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch用命令把
--add-module=/root/nginx_upstream_check_module-master添加到nginx -V的参数中bash./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/root/nginx_upstream_check_module-master --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'编译/安装
bashmake && make install
启动方式
通过systemctl启动
使用绝对路径运行
bashnginx # 启动 nginx -s stop # 停止 nginx -s reload # 重载
配置文件
/etc/nginx/nginx.conf
nginx
# 核心模块
user nginx; # 启动nginx虚拟用户
worker_processes auto; # 启动子进程的数量,auto以cpu内核数为准
error_log /var/log/nginx/error.log notice; # 错误日志
pid /var/run/nginx.pid; # 进程PID存放的位置
# 事件模块
events {
worker_connections 1024; # TCP连接的最大连接数
}
# http 模块
http {
include /etc/nginx/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 /var/log/nginx/access.log main; # nginx访问日志
sendfile on; # 文件高效传输
#tcp_nopush on;
keepalive_timeout 65; # 长连接的超时时间
#gzip on; # 是否开启压缩
charset utf-8,gbk # 中文支持
include /etc/nginx/conf.d/*.conf; # 业务配置文件
}业务配置文件:
nginx
server {
listen 80;
server_name www.sliman.com;
location / {
root /code/;
index index.html index.htm;
}
}使用nginx -t检查语法
常用模块
nginx
charset utf-8,gbk; # 中文支持5.1 目录索引
autoindex: off|on 列出目录索引autoindex_localtime: off|on 使用本地时间而不是GMTautoindex_exact_size: on|off 使用精确的文件大小
nginx
autoindex on; # 列出目录索引
autoindex_localtime on; # 使用本地时间而不是GMT
autoindex_exact_size off; # 人性化大小单位5.2 用户认证
nginx
auth_basic test; # string|off 开启用户认证,string是一个描述
auth_basic_user_file auth_pass; # 指定用户和密码文件生成密码文件:
bash
yum -y install httpd-tools # 安装依赖
htpasswd -b -c /etc/nginx/auth_pass sliman sliman # 生成密码5.3 IP限制
nginx
allow 10.11.10.0/24; # address|CIDR|all 白名单
deny 10.11.10.0/24; # address|CIDR|all 黑名单5.4 状态模块
nginx
stub_status; # [location] 访问路径显示nginx连接状态bash
Active connections: 2 # 当前活动连接数
server accepts handled requests
2 2 1
# 已接收连接数量 已处理连接数量 当前http请求数
Reading: 0 Writing: 1 Waiting: 1
# 当前读取请求头数量 当前响应的请求头数量 等待的请求数,开启了keepalive5.5 连接限制
nginx
# [http] 区域名conn_zone,区域大小10m
limit_conn_zone $remote_addr zone=conn_zone:10m;
# [http][server][location] 同时连接数1
limit_conn conn_zone 1;5.6 请求限制
nginx
# [http] 每秒限制请求数
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
# [http][server][location] burst: 超过连接数则延迟加载
limit_req zone=req_zone burst=3 nodelay;
# 重定向错误状态码,默认503
limit_req_status 478;
# 重定向错误页
error_page 478 /www/error/478.html;5.7 上传大小限制
nginx
# Syntax:
client_max_body_size size;
# Default:
client_max_body_size 1m;
# Context: http, server, location
# 网站上传文件的大小限制,默认是1m5.8 内容替换
nginx
sub_filter 'hello' 'goodbye';location语法优先级
| 匹配符 | 匹配规则 | 优先级 |
|---|---|---|
| = | 精确匹配 | 1 |
| ^~ | 以某个字符串开头 | 2 |
| ~ | 区分大小写的正则匹配 | 3 |
| ~* | 不区分大小写的正则匹配 | 4 |
| / | 通用匹配,任何请求都会匹配到 | 5 |
Example:
nginx
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}反向代理
代理配置:
nginx
proxy_pass http://www.baidu.com;7.1 支持范围
Nginx代理服务支持的协议
- HTTP
- HTTPS
- TCP
- websocket
- GRPC
- POP/IMAP
- RTMP
反向代理常用的协议
- HTTP
- HTTPS
- websocket
- GRPC
7.2 携带头部信息
nginx
# 传递Host
proxy_set_header Host $http_host;
# http版本号
proxy_http_version 1.1;
# 向服务器传递真实的$remote_addr
proxy_set_header X-Real-IP $remote_addr;
# 向服务器传递真实的$http_x_forwarded_for
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;7.3 代理TCP超时时间
nginx
# 请求后端服务器连接的超时时间,默认60s
proxy_connect_timeout 60s;
# 等待后端服务器的响应时间,默认60s
proxy_send_timeout 60s;
# 后端服务器传回给Nginx代理的超时时间,默认60s
proxy_read_timeout 60s;7.4 代理缓冲区
Nginx将请求头部和请求主体放在不同的内存缓冲区中
nginx
# 开启缓冲区
proxy_buffering on;
# 头部缓冲区大小
proxy_buffer_size 4k;
# 主体缓冲区大小
proxy_buffers 8 4k;7.5 常用参数
常用参数可以保存至nginx/proxy_params文件中,通过include来引用
nginx
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30s; # 代理连接web超时时间
proxy_read_timeout 60s; # 代理等待web响应超时时间
proxy_send_timeout 60s; # web 回传数据至代理超时时间
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
# 让Nginx反向代理识别更多的后端错误码
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;负载均衡
8.1 地址池
nginx
upstream webs {
server 10.0.0.7;
server 10.0.0.8;
}
location / {
proxy_pass http://webs;
}8.2 调度算法
| 调度算法 | 概述 |
|---|---|
| 轮询 | 按时间顺序逐一分配到不同的后端服务器(默认) |
| weight | 加权轮询,weight越大,分配到的访问几率越高 |
| ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器 |
| url_hash | 按照访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器 |
| least_conn | 最少链接数,哪个机器链接数少就分发给谁 |
轮询(默认)
nginx
upstream webs {
server 10.0.0.7;
server 10.0.0.8;
}weight(加权轮询)
nginx
upstream webs {
server 10.0.0.7 weight=5;
server 10.0.0.8;
}ip_hash
nginx
upstream webs {
ip_hash;
server 10.0.0.7;
server 10.0.0.8;
}url_hash
nginx
upstream webs {
server 10.0.0.7;
server 10.0.0.8;
hash $request_uri;
hash_method crc32;
}8.3 后端服务器状态
| 状态 | 概述 |
|---|---|
| down | 当前的server不参与调度 |
| backup | 其它服务器都无法连接时采用backup服务器 |
| max_fails | 允许请求失败的次数 |
| fail_timeout | max_fails失败后,服务暂停时间 |
| max_conns | 限制最大的接收连接数 |
四层负载
Nginx的四层负载为假四层,采用代理的方式,配置方法如下:
编辑Nginx配置文件,在http模块外设置四层代理
nginxinclude /etc/nginx/conf.c/*.conf;编辑四层负载配置文件
nginxstream { upstream webs{ server 10.0.0.5:80; server 10.0.0.6:80; } server { listen 80; proxy_pass webs; } }
重写
10.1 模块语法
nginx
rewrite 1.html a.html;后缀标记Flag:
| flag | 作用 |
|---|---|
| last | 最后一次rewrite匹配 |
| break | 直接停止向后匹配,直接返回当前的rewrite结果,不再重新发起请求 |
| redirect | 等同于return 302,临时重定向 |
| permanent | 等同于return 301,永久重定向,只请求一次源站,之后浏览器缓存会将请求直接传给目标站点 |
重定向的其它写法:
nginx
return 301 /aaa/1.html
return 302 /bbb/2.html开启rewrite日志:
nginx
http {
rewrite_log on;
}10.2 案例
错误页跳转
nginx
error_page 403 404 500 501 502 @error_test;
location @error_test {
rewrite ^(.*)$ /404.html break;
}在跳转后的请求行加上想要的参数&showoffline=1
nginx
# $args为Nginx内置的请求行参数
set $args "&showoffline=1";网站维护,只允许指定IP访问
nginx
set $ip 0;
if ($remote_addr = "10.0.0.1"){
set $ip 1;
}
if ($ip = 0){
rewrite ^(.*)$ /wh.html break;
}HTTPS
nginx
server {
listen 443 ssl;
ssl_certificate ssl_key/server.crt;
ssl_certificate ssl_key/server.key;
# 让php支持https
fastcgi_param HTTPS on;
}
# 80跳转443
server {
listen 80;
server_name www.wp.com;
return 302 https://$server_name$request_uri;
}性能优化
12.1 压力测试工具
安装
bash
yum install -y httpd-tools语法
bash
ab -n 10000 -c 200 http://127.0.0.1/-n:请求数-c:并发数-k:是否开启长连接
12.2 系统性能优化
文件句柄最大打开数
bash
# /etc/security/limits.conf
* - nofile 65535调整内核参数
让TIME_WAIT状态重用
bash
# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 012.3 代理服务优化
配置代理使用长连接
nginx
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16; # 长连接
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # 清除"Connection"字段
proxy_next_upstream error timeout http_500 http_502 http_503 http_504; # 平滑过度
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30s; # 代理连接web超时时间
proxy_read_timeout 60s; # 代理等待web响应超时时间
proxy_send_timeout 60s; # web 回传数据至代理超时时间
proxy_buffering on; # 开启代理缓冲区
proxy_buffer_size 32k; # 代理接收web响应头信息的缓冲区大小
proxy_buffers 4 128k; # 缓冲代理接收单个长连接内包含的web响应的数量和大小
}
}对于fastcgi服务器,需要设置fastcgi_keep_conn以便保持长连接
nginx
upstream fastcgi_backend {
server 127.0.0.1:9000;
keepalive 8;
}
server {
location /fastcgi/ {
fastcgi_pass fastcgi_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_keepconn on;
fastcgi_connect_timeout 60s;
include fastcgi_params;
...
}
}12.4 静态资源优化
配置静态资源缓存场景
nginx
location ~ .*\.(jpg|gif|png)$ {
expires 7d;
}
location ~ .*\.(js|css)$ {
expires 30d;
}如果开发代码没有正式上线,希望静态文件不被缓存
nginx
location ~ .*\.(js|css|html)$ {
add_header Cache-Control no-store;
add_header Pragma no-cache;
}12.5 静态资源读取
大文件推荐,将多个包一次发送,提升网络传输效率,需开启sendfile
nginx
sendfile on;
tcp_nopush on;小文件推荐,来一个包发一个,提高网络实时性,需开启keepalive
nginx
tcp_nodelay on;12.6 静态资源压缩
nginx
location ~ .*\.(txt|xml|html|json|js|css)$ {
gzip on; # 开启gzip压缩
gzip_http_version 1.1; # 压缩协议版本
gzip_comp_level 1; # 压缩比
gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript; # 压缩哪些文件
}12.7 防止资源盗链
nginx
location ~* \.(jpg|jpeg|gif|png|webp|svg|mp4|webm|ogg)$ {
# 1. 白名单设置
valid_referers none blocked
~\.google\. # 允许谷歌图片搜索抓取
~\.baidu\. # 允许百度图片搜索抓取
*.example.com
example.com;
# 2. 拦截无效引用
if ($invalid_referer) {
return 403;
}
# 3. 开启静态缓存
expires 365d;
add_header Cache-Control "public, immutable";
# 4. 安全头防XSS
add_header X-Content-Type-Options "nosniff";
}12.8 允许跨域访问
nginx
add_header Access-Control-Allow-Origin "https://mysite.com";
add_header Access-Control-Allow-Methods "GET, POST";12.9 CPU亲和配置
查看Nginx worker进程绑定:
bash
ps -eo pid,args,psr|grep [n]ginx在nginx.conf中配置CPU亲和:
bash
worker_processes auto; # 与CPU核心一致即可
worker_cpu_affinity auto; # CPU亲和12.10 通用优化配置
nginx
user www; # nginx进程启动用户
worker_processes auto; #与cpu核心一致即可
worker_cpu_affinity auto; # cpu亲和
error_log /var/log/nginx/error.log warn; # 错误日志
pid /run/nginx.pid;
worker_rlimit_nofile 35535; #每个work能打开的文件描述符,调整至1w以上,负荷较高建议2-3w
events {
use epoll; # 使用epoll高效网络模型
worker_connections 10240; # 限制每个进程能处理多少个连接,10240x[cpu核心]
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8; # 统一使用utf-8字符集
# 定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#定义json日志格式
log_format json_access '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"url":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"status":"$status"}';
access_log /var/log/nginx/access.log main; # 访问日志
server_tokens off; # 禁止浏览器显示nginx版本号
client_max_body_size 200m; # 文件上传大小限制调整
# 文件高效传输,静态资源服务器建议打开
sendfile on;
tcp_nopush on;
# 文件实时传输,动态资源服务建议打开,需要打开keepalive
tcp_nodelay on;
keepalive_timeout 65;
# Gzip 压缩
gzip on;
gzip_disable "MSIE [1-6]\."; #针对IE浏览器不进行压缩
gzip_http_version 1.1;
gzip_comp_level 2; #压缩级别
gzip_buffers 16 8k; #压缩的缓冲区
gzip_min_length 1024; #文件大于1024字节才进行压缩,默认值20
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg;
# 虚拟主机
include /etc/nginx/conf.d/*.conf;
}12.11 优化总结
- CPU亲和、worker进程数、调整每个worker进程打开的文件数
- 使用epool网络模型、调整每个worker进程的最大连接数
- 文件的高效读取sendfile、nopush
- 文件的传输实时性、nodealy
- 开启tcp长连接,以及长连接超时时间keepalived
- 开启文件传输压缩gzip
- 开启静态文件expires缓存
- 隐藏Nginx版本号
- 禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问
- 配置防盗链、以及跨域访问
- 防DDOS、CC攻击,限制单IP并发连接,以及http请求
- 优雅显示Nginx错误页面
- Nginx加密传输https优化
- Nginx proxy_cache、fastcgi_cache、uwsgi_cache 缓存,第三方工具(squid、varnish)