记录个人在使用Nginx做Web服务器时的简单相关应用设置。
1、Nginx的相关并发优化设置(按需)
# 修改worker进程数提高并发
# 修改CPU使用情况,也可以使用auto
worker_processes 2;
worker_cpu_affinity 01 10;
# 单个工作进程并发连接数
worker_connections 51200;
nginx作为http服务器时:
max_clients = worker_processes * worker_connections
nginx作为反向代理服务器时:
max_clients = worker_processes * worker_connections/2
# 使用epoll模型
use epoll;
# 开启文件高效传输模式,同时设置tcp_nopush和tcp_nodelay为on,可以防止网路和磁盘IO阻塞
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 修改用户进程打开文件数限制
/etc/security/limits.conf
nginx - nofile 65535
# Linux系统级的最大打开文件数限制(需要注意的是这一条设置与计算机的物理内存有关,不能随便设置)
fs.file-max = 188414
# 修改网络内核对TCP连接的有关限制
net.ipv4.ip_local_port_range = 1024 65535
# 限制接收新TCP连接侦听队列的大小
net.core.somaxconn = 2048
# 启用tcp连接timewait快速回收和重用
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
2、Nginx平滑升级
首先需要明确的概念:
虽然之前有使用过systemctl reload nginx
等功能,但实际上reload
也是需要时间重载的,虽然更短,但依旧需要时间,所以能够进行平滑升级的情况下自然还是平滑升级更好。
- 下载nginx新版本软件正确执行
./configure
和make
, 但并不进行make install
- 备份原程序
cd /usr/local/nginx/sbin
cp nginx nginx.old
- 拷贝新程序:
cd ~/nginx-1.19.8/objs
cp -f nginx /usr/local/nginx/sbin/
- 测试新版本的nginx是否正常
/usr/local/nginx/sbin/nginx -t
- 给nginx发送平滑迁移信号(若不清楚pid路径,请查看nginx配置文件)
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
运行-USR2
时旧的Nginx主进程将会把自己的进程文件名改名为.oldbin,然后执行新版 Nginx。新旧Nginx会同时运行,共同处理请求
而运行-WINCH
后旧的工作进程就都会随着任务执行完毕而退出,新版的Nginx的工作进程会逐渐取代旧版工作进程。
注意的是,这时主进程依旧会保留,方便进行回滚等操作
回滚时的方法如下:kill -HUP <原进程PID>
kill -WINCH [新进程号]
kill -9 [新进程号]
- 结束工作进程,完成升级
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
3、Nginx限流
控制单IP并发连接数
……
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location / {
limit_conn addr 1;
limit_rate 50k;
}
}
……
相关说明:
$binary_remote_addr
:表示通过remote_addr
这个标识来做限制zone=addr:10m
:表示生成一个大小为10M,名字为addr
的内存区域limit_conn addr
:限制并发数,这里限制并发数为1limit_rate
:限制带宽,这里为50K
限制单位时间内的请求数目和速度
# rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
}
server {
location / {
limit_req zone=one;
#limit_req zone=one burst=5
#limit_req zone=one burst=5 nodelay;
}
}
4、Nginx配置管理
自动索引
当打开服务器中存在的目录时自动生成目录下文件索引并显示,方便下载和浏览
location / {
autoindex on;
}
Nginx Expire缓存配置
对于静态文件而言,使用缓存可以明显降低网站带宽,起到加速用户访问的效果
# 对于html路径下的所有图片作缓存,保存30天
location ~ .*\.(gif|jpg|png)$ {
expires 30d;
root /html;
}
IP访问限制
location / {
deny 192.168.17.150;
allow 192.168.17.130;
deny all;
}
if ($remote_addr = 192.168.17.132) {
return 403;
}
# 两端代码的意思分别为
阻止192.168.17.150访问,允许192.168.17.130访问
阻止其他所有IP访问
如果访问IP为192.168.17.132,返回403页面
禁用不必要的日志记录,节约磁盘IO的消耗
location ~ .*\.(js|jpg|jpeg|png|css|bmp|gif)$ {
access_log off
}
# 就如同写的一样,当请求为后续这些文件格式结尾时,不记录日志
站点目录和文件的限制
location ~ ^/images/.*\.(sh|php)$ {
deny all;
}
##访问image目录下的sh/PHP等可执行文件时拒绝,为了避免注入运行的攻击手段
##当然,同样的语法也可以用来做权限控制
location ~ ^/images/.*\.(sh|php)$ {
allow 192.168.17.150;
deny all;
}
# 这样就实现了宿主机(192.168.17.150)可以运行images目录下的sh和PHP文件,而除此以外的所有人不能
解决中文乱码问题
虽然一般来说中文设置都是网站开发人员在做开发时定义好的,但是Nginx
依旧提供了这个功能。
与其说是解决中文乱码问题不如说是更换nginx
字符集的方法。
# vim /usr/local/nginx/conf/nginx.conf
charset utf-8
Nginx重定向
通过进行访问重定向, 可以防止域名恶意解析到服务器IP
server {
listen 80;
server_name www.example.com;
return 500;
}
# 也可以这样写
server {
listen 80;
server_name www.example.org;
rewrite ^(.*) http://www.example.com permanent;
}
- 前者将访问
www.example.com
的请求全部返回了500
- 后者则将访问请求跳转到了
www.example.com
,避免对原本访问地址的压力
同理,我们可以用它来实现一些业务上的需求
# 80重定向443,实现自动访问加密
server {
listen 80;
listen 443 ssl http2;
server_name www.example.com;
if ($server_port !~ 443){ #若端口不为443,则跳转至443端口
rewrite ^(/.*)$ https://$host$1 permanent;
}
# 或者可以直接使用return跳转(建议使用),需开启两个 server,一个监听80端口,一个监听443端口。
# 将80端口的访问使用下方 return定向跳转到443端口,以使用https访问
#return 301 https://$host$request_uri;
}
##业务域名跳转
# www.example.com/bbs 重定向 bbs.example.com
server {
listen 80;
server_name www.example.com;
rewrite ^/bbs$ http://bbs.example.com permanent;
rewrite ^/bbs/(.*)$ http://bbs.example.com/$1 permanent;
location / {
root /web1;
index index.html;
}
}
server {
listen 80;
server_name bbs.example.com;
location / {
root /bbs;
index index.html;
}
}
# bbs.example.com 重定向 www.example.com/bbs
server {
listen 80;
server_name www.example.com bbs.example.com;
if ($host = "bbs.example.com"){
rewrite ^/(.*)$ http:/www.example.com/bbs/$1 permanent;
}
location / {
root /web1;
index index.html;
}
}
防盗链
# 第一种方式
server {
listen 80;
server_name www.example.com;
location ~ \.(jpg|png)$ {
valid_referers none blocked www.example.com;
if ($invalid_referer) {
return 403;
}
}
}
# 第二种方式
server {
listen 80;
server_name www.example.com;
location ~ \.(jpg|png)$ {
valid_referers none blocked www.example.com;
if ($invalid_referer) {
rewrite ^/ http://192.168.17.132/daolian.jpg;
}
}
}
valid_referers 指令
语法: valid_referers none|blocked|server_names string ...;
默认值: no
使用字段: server, location
功能: 此指令在 referer头的基础上为 $invalid_referer 变量赋值,可以实现简单的防盗链功能
如果 valid_referers 列表中没有匹配Referer请求头,$invalid_referer将被设置为1,否则为0(或空值)
参数:
none
请求头中不存在 Referer 字段('空值',比如直接在浏览器打开一个图片URI)
blocked
请求头中存在 Referer 字段,但值不是以"http(s)://"开头的字符串(被防火墙或代理服务器修改删除)
server_names
Referer 字段包含服务器名称
arbitrary string
定义服务器名称和可选 URI 前缀,服务器名称的开头或结尾可以有一个"*"
regular expression
使用正则匹配,第一个符号为"~"