Environment
- Mac
- Nginx 1.15.8
Process
Mac
- 在 Mac 上,可以使用 brew 系列命令进行软件包的操作。在国内的情况下,需要先切换其镜像源。
brew install nginx
Nginx
- 在 /usr/local/etc/nginx/nginx.conf 配置 Nginx 的全局参数。
#user www www;
worker_processes 1;
error_log /usr/local/var/log/nginx/error.log error;
pid /usr/local/var/run/nginx.pid;
events {
multi_accept on;#设置是否允许,Nginx在已经得到一个新连接的通知时,接收尽可能更多的连接
worker_connections 100000; # 根据请求量,以及服务器资源配置
#use epoll;
}
#协议级别配置
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 $request_time $upstream_response_time $upstream_addr $upstream_status';
#access_log logs/access.log main;
# 触发条件,所有访问ip 限制每秒10个请求(防DOS攻击)
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
# sendfile 部分配置
sendfile on;#sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。
tcp_nopush on;
tcp_nodelay on;
#server_tokens off;
# [emerg] 8232#14924: could not build server_names_hash, you should increase server_names_hash_bucket_size
server_names_hash_max_size ;
# server name 的字符串长度上限值,最好设置为32倍数
server_names_hash_bucket_size 64;
# 客户端请求缓存处理
client_body_buffer_size 6m;
client_header_buffer_size 1m;
large_client_header_buffers 4 125k;
# 客户端上传文件的限制
client_max_body_size 4m;
keepalive_timeout 65;
# gzip部分配置
#Gzip Compression
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# fastcgi php-fpm 部分配置。这模块配置不当,会造成大文件上传超时报错,以及读出大量数据失败。
fastcgi_connect_timeout 300;#fastcgi连接超时时间
fastcgi_send_timeout 180;#fastcgi请求超时时间
fastcgi_read_timeout 180;#接收fastcgi应答超时时间
fastcgi_buffer_size 127k;#读取fastcgi应答需要多大缓冲区
fastcgi_buffers 64 127k;#指定本地需要多少个和多大的缓冲区来缓冲fastcgi应答请求(缓冲区大小设置建议跟fastcgi_buffer_size一样就可以了)
fastcgi_busy_buffers_size 256k;#默认值是fastcgi_buffer的2倍
fastcgi_temp_file_write_size 127k;#写入缓存文件使用多大的数据块
fastcgi_cache_valid 200 302 1h;#指定缓存状态及失效时间
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_intercept_errors on;
# open_file_cache 静态文件缓存部分配置
#If you have a lot of static files to serve through Nginx then caching of the files' metadata (not the actual files' contents) can save some latency.
#在上述配置中,为1,000个元素定义了一个缓存。inactive参数配置到期时间为20秒。没有必要为该指令设置非活动时间段,默认情况下,非活动时间段为60秒。
open_file_cache max=1000 inactive=20s;
#NGINX的open_file_cache保存信息的快照。由于信息在源处更改,快照可能在一段时间后无效。 open_file_ cache_valid指令定义时间段(以秒为单位),之后将重新验证open_file_cache中的元素。默认情况下,60秒后重新检查元素。
open_file_cache_valid 30s;
#NGINX将在非活动时间段之后从高速缓存中清除元素。此指令可用于配置最小访问次数以将元素标记为活动使用。默认情况下,最小访问次数设置为1次或更多次。
open_file_cache_min_uses 2;
#如前所述,NGINX可以缓存在文件访问期间发生的错误。但是这需要通过设置open_file_cache_errors指令来启用。如果启用错误缓存,则在访问资源(不查找资源)时,NGINX会报告相同的错误。默认情况下,错误缓存设置为关闭。
open_file_cache_errors on;
include servers/*;
}
- 在 /usr/local/etc/nginx/cappu.conf 配置 Nginx 的各个服务器的具体参数以及对应的 php-fpm 处理端口。
# 注意,一定要设置调度算法。
# 不指定服务器端口,默认80。
# 水平拓展,分压。
# 物理无状态接口请求。需要将调度策略设置为 ip_hash 算法,保证用户请求以及相关日志的连续性。
# upstream模块调度算法:
# 1 静态调度算法。分配的时候,不需要考虑后端节点服务器的情况
# (1)rr轮询
# (2)wrr权重轮序
# (3)ip_hash
# 2 动态调度算法。根据自身的情况调度,根据后端节点状态是否响应很快进行调度。对请求服务更均衡化。
# (1)fair。根据后端节点服务器的响应时间来分配请求,时间短的优先分配,必须下载nginx的相关模块upstream_fair。
# (2)least_conn。根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。
# (3)url_hash算法。和ip_hash类似,一般用于web缓存,根据访问URL的hash结果来分配请求的,每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果明显。
# (4)一致性hash算法。一致性hash算法一般用于代理后端业务为缓存服务(squid,memcached)的场景,通过将用户请求的URI或指定字符串进行计算,然后调度到后端服务器上,此后任何用户查找同一个RUI或者指定字符串都会被调度到这一台服务器上,此后后端的每个节点缓存的内容都是不同的。
upstream notifyserver {
server www.cappu.net:80 weight=1 backup;
server www.sirius.net:8080 weight=1 max_fails=3 fail_timeout=600s;
# 健康检查
check interval=3000 rise=2 fall=5;
}
#服务器级别配置
server {
listen 80;
#listen 443 ssl;
#listen [::]:80 default_server ipv6only=on;
server_name www.cappu.net;
#charset koi8-r;
#access_log /usr/local/var/log/nginx/access.log main;
# 配置根目录,Mac 有些目录在可视化操作界面是不能访问的,注意路径的选择啦。
root /Library/WebServer/www/cappu/public;
index index.html index.htm index.php;
#ssl_certificate /opt/cert/api.cappu.com/1_api.cappu.com_bundle.crt;
#ssl_certificate_key /opt/cert/api.cappu.com/2_api.cappu.com.key;
#ssl_session_timeout 5m;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;#按照这个套件配置
#ssl_prefer_server_ciphers on;
# 跨域处理
# Access-Control-Allow-Origin 的值为 "*" 时,"*" 只能有一个。当其值为 IP 或者域名时,过 "," 拼接起来。
# add_header Access-Control-Allow-Origin $http_origin;
# add_header Access-Control-Allow-Methods $http_access_control_request_method;
# 服务端接受跨域带过来的Cookie,当为true时,origin必须是明确的域名不能使用*
# add_header Access-Control-Allow-Credentials true;
# add_header Access-Control-Allow-Headers $http_access_control_request_headers;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
add_header Access-Control-Allow-Headers Origin,X-Requested-With,Content-Type,Accept;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
# Cache-Control:自动为:no-cache, private但是如果源站 Cache-control 字段为 private、no-store 或 no-cache,此时 ECDN 节点对此资源不做缓存。
# IOS 小程序也会根据这个头部信息缓存数据,甚至造成接口数据过期,无法及时刷新
more_set_headers "Cache-Control: public, max-age=7200";
more_set_input_headers "Cache-Control: public, max-age=3600";
# 执行的动作,通过zone名字对应
limit_req zone=one burst=5 nodelay;
# 直接在Nginx拦截请求,返回成功Json
location = /v2/histories {
return 200 '{"code":0,"msg":"操作成功","data":{}}';
}
# redirect server error pages to the static page /50x.html
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root html;
# }
location = /notify
{
#rewrite ^/(.*)$ /$1 break;
proxy_set_header Host $host; # 在代理向后端服务器发送的http请求头中加入host字段信息,用于后端服务器配置有多个虚拟主机,可以识别那个虚拟主机
proxy_set_header X-Forwarded-For $remote_addr; # 用于接收用户真实IP,而不是代理服务器ip
proxy_pass http://notifyserver;
}
# 代理
location ~ /(uploadfiles|ueditor)
{
rewrite ^/(.*)$ /$1 break;
proxy_pass http://wap.esnewcollege.com;
}
location ~ \.php$ {
try_files $uri /index.php =404;
# 对应的 php-fpm 处理端口
fastcgi_pass 127.0.0.1:9003;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$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;
}
# 防盗链
# 对静态资源进行 referer 来源地址匹配,或者进行路径文件夹匹配,拦截他方的非法请求
location ~* \.(gif|jpg|png|swf|flv)$ {
# valid_referers 定义白名单
# none 代表请求头中没有referer信息,这一般是直接在浏览器输入静态资源网址
# blocked 代表被防火墙过滤,标记过的请求
valid_referers none blocked www.cappu.net;
# $invalid_referer 内置变量,通过判断 valid_referers 值返回0,或者1
if ($invalid_referer) {
# 可以通过设定指定的图片来代替目标图片
# rewrite ^/ http://www.cappu.net/error.png;
# 如果访问来源不在白名单内,则返回403错误
return 403;
}
}
# 加密签名:使用第三方模块HttpAccessKeyModule实现Nginx防盗链
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
accesskey on;
accesskey_hashmethod md5; #加密算法,和php的加密算法保持一直
accesskey_arg "sign"; #url请求签名的参数名
accesskey_signatrue "mypass$remote_addr"; #加密规则 md5( 'mypass'+客服端的ip地址);
}
#请求级别配置
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ /\.
{
deny all;
}
}
- 前后端分离,前端目录配置,避免跨域,用代理转发接口请求
server {
listen 80;
server_name web.sirius.com;
root /data/www/sirius/build;
index index.html index.htm index.php;
location / {
# 用于配合 browserHistory使用
try_files $uri $uri/ /index.html;
# 如果有资源,建议使用 https + http2,配合按需加载可以获得更好的体验
#rewrite ^/(.*)$ https://preview.pro.ant.design/$1 permanent;
}
location /api/ {
# 由于跨域请求,浏览器会先发送一个OPTIONS的预检请求,我们可以缓存第一次的预检请求的失效时间
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 2592000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# 代理接口访问
proxy_pass http://api.sirius.cn;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}
Nginx 的信号控制
- TERM, INT 快速关闭
- QUIT 从容关闭
- HUP 平滑重启,重新加载配置文件
- USR1 重新打开日志文件,在切割日志时用途较大
- USR2 平滑升级可执行程序
- WINCH 从容关闭工作进程
# 从容停止
kill -QUIT `cat /opt/nginx/logs/nginx.pid`
# 快速停止
kill -TERM `cat /opt/nginx/logs/nginx.pid`
kill -INT `cat /opt/nginx/logs/nginx.pid`
# 平滑重启
kill -HUP `cat /opt/nginx/logs/nginx.pid`
检查 Nginx
查看TCP链接详细情况:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
- 返回信息
SYN_RECV 3
ESTABLISHED 323
FIN_WAIT1 27
FIN_WAIT2 25
TIME_WAIT 1090
- 参数解释
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉
- 优化调整
修改配置文件 /etc/sysctl.conf 的参数:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
- 让修改生效
/sbin/sysctl -p
Conclusion
不同的版本,对应的文件路径会有些出入,以上仅供参考,请君灵活处理。
References
- nginx location匹配优先级
- Nginx location 匹配顺序
- Nginx gzip参数详解
- nginx 之 proxy_pass详解
- 实现负载均衡的几种方式
- nginx的负载均衡模块详解
- Nginx负载均衡后端健康检查
- Cache-Control
- Nginx 的启动、停止、平滑重启、信号控制和平滑升级
- Nginx里Header修改
- nginx+php产生大量TIME_WAIT连接解决办法
- TIME_WAIT过高的处理
- nginx配置选项try_files详解
- Nginx 之 Rewrite 规则
转载本文,请注明出处、作者