nginx备忘录
安装
rpm (离线)
直接进nginx下载包页面
选择你要的版本连接
wget https://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.20.2-1.el7.ngx.x86_64.rpm
rpm -ivh nginx-1.20.2-1.el7.ngx.x86_64.rpm
systemctl start nginx
systemctl status nginx
nginx -V
yum (rhel/centos)
yum -y install nginx
apt (debian/ubuntu)
apt update
apt install nginx
Nginx配置文件
/etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
# 运行用户,默认是 nginx,可以不进行设置
user nginx;
#Nginx 进程,一般设置和 cpu 核数一样,默认自动。
worker_processes auto;
#错误日志存放位置
error_log /var/log/nginx/error.log;
#进程 pid 存放位置
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;---#单个后台进程的最大并发数
}
http {
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;
#是否开启高效传输模式 on 开启 off 关闭
sendfile on;
减少网络报文段的数量
tcp_nopush on;
tcp_nodelay on;
#保持连接的时间,也叫超时时间
keepalive_timeout 65;
types_hash_max_size 2048;
#文件扩展名和类型映射表
include /etc/nginx/mime.types;
#默认的文件类型
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information. #包含的子配置项的位置和文件
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;#配置监听端口
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;#服务默认启动目录
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;# 配置 404 页面
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;#错误状态码的显示页面,配
置后需要重启
location = /50x.html {
}
}
# Settings for a TLS enabled server. #
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
反向代理
先安装Tomcat测试tomcat下载页面
JDKjdk下载页面
反向代理模块介绍Module ngx_stream_proxy_module
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.74/bin/apache-tomcat-9.0.74.tar.gz
tar -zxvf apache-tomcat-9.0.74.tar.gz
mkdir /usr/tomcat
mv apache-tomcat-9.0.74 /usr/tomcat
cd /usr/tomcat/apache-tomcat-9.0.74/bin
./startup.sh
ss -ntl #查看tomcat端口,默认8080
反向代理配置(proxy-pass)
#vim /etc/nginx/nginx.conf
http {
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend-server:8080;
}
}
}
修改配置文件,添加反向代理server块
#vim /etc/nginx/nginx.conf
server{
listen 81;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
nginx -t #检查配置
nginx -s reload #重新加载配置
输入你的nginx主页面地址加上:81 就能出现tomcat页面
负载均衡
方式
负载均衡模块介绍Module ngx_stream_upstream_module
- 轮询(Round Robin): 将请求按顺序分配给后端服务器,每个请求依次分配给每台服务器。这种方式是Nginx默认的负载均衡策略。
- 权重轮询(Weighted Round Robin):根据不同后端服务器的权重来分配请求,权重越高的服务器处理的请求越多。可以根据服务器的性能和负载情况,灵活调整权重来实现负载均衡。
- IP Hash:基于客户端Ip地址的哈希值来选择后端服务器,同一个客户端的请求会被分配到同一个后端服务器上,可以解决session共享的问题。
- URL Hash:基于请求的URL的哈希值来选择后端服务器,同一个URL的请求会被分配到同一个后端服务器上。
负载均衡(upstream)模块配置
#vim /etc/nginx/nginx.conf
http {
upstream backend {
server backend-server1:8080;
server backend-server2:8080;
server backend-server3:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
}
修改配置文件进行负载均衡配置
#vim /etc/nginx/nginx.conf
upstream bakend{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8080 max_fails=3 fail_timeout=10s weight=5;
}
server{
listen 81;
location / {
proxy_pass http://bakend;
}
}
nginx -t #检查配置
nginx -s reload #重新加载配置
输入主机地址:81出现tomcat页面为完成配置
动静分离
location ~*\.(html|jpg|jpeg|png|bmp|gif|ico|mp3|mid|wma|mp4|swf|flv|rar|zip|doc|ppt|xls|pdf)$ {
root /usr/share/nginx/html;
expires 7d;
}
"~*" 表示忽略大小写,"." 表示匹配 "." 字符,"|" 表示或操作,"$" 表示匹配结尾。expires 7d
表示该资源的过期时间为7天
资源限制和流量限制
#下边这个信息放到 http 框架里面
limit_req_zone $binary_remote_addr zone=allips:100m rate=10r/s;
- `limit_req_zone`:指定创建一个限流区域。
- `$binary_remote_addr`:客户端 IP 地址的二进制表示,作为限流区域的 key。
- `zone`:指定限流区域的名称,本例中为 `allips`。
- `100m`:分配给限流区域的内存大小,本例中为 100MB。
- `rate`:指定限制速率的参数。
- `10r/s`:设置每秒钟最大请求次数为 10 次。
创建一个名为 `allips` 的限流区域,将客户端 IP 地址的二进制表示作为 key,并限制每秒钟同一客户端的请求次数不超过 10 次。
#下边这个配置在 server 里面:
limit_req zone=allips burst=5 nodelay;
- `limit_req`:启用请求限制功能。
- `zone=allips`:指定用于限流的限流区域名称为 `allips`。
- `burst=5`:设置限流区域的令牌桶大小为 5,即在限制请求速率的同时允许一定程度的突发流量。
- `nodelay`:在请求被限制时,不延迟请求处理,而是立即返回 503 错误。
启用请求限制功能,并使用名为 `allips` 的限流区域来限制请求速率。当某个客户端的请求速率超过限制时,Nginx 将返回 503 错误。`burst=5` 参数指定了桶的大小,在限制请求速率的同时允许一定程度的突发流量。`nodelay` 参数则表示在请求被限制时不延迟请求处理,而是立即返回 503 错误。
优化
net.ipv4.tcp_max_tw_buckets = 6000
#timewait的数量,默认是 180000。
net.ipv4.ip_local_port_range = 1024 65000
#允许系统打开的端口范围。
net.ipv4.tcp_tw_recycle = 1
#启用timewait快速回收。
net.ipv4.tcp_tw_reuse = 1
#开启重用。允许将 TIME-WAIT sockets重新用于新的TCP连接。
net.ipv4.tcp_syncookies = 1
#开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。
net.core.somaxconn = 262144
#web应用中listen函数的backlog默认会给我们内核参数的 net.core.somaxconn 限制到 128,而 nginx 定义的 NGX_LISTEN_BACKLOG 默认为 511,所以有必要调整这个值。
net.core.netdev_max_backlog = 262144
#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_orphans = 262144
#系统中最多有多少个 TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的 DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
#记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有 128M 内存的系统而言,缺省值是 1024,小内存的系统则是 128。
net.ipv4.tcp_timestamps = 0
#时间戳可以避免序列号的卷绕。一个 1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 1
#为了打开对端的连接,内核需要发送一个 SYN 并附带一个回应前面一个 SYN 的 ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送 SYN+ACK 包的数量。
net.ipv4.tcp_syn_retries = 1
#在内核放弃建立连接之前发送 SYN 包的数量。
net.ipv4.tcp_fin_timeout = 1
#如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是 60 秒。2.2 内核的通常值是 180 秒,3 你可以按这个设置,但要记住的是,即使你的机器是一个轻载的 WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比 FIN-WAIT-1 要小,因为它最多只能吃掉 1.5K 内存,但是它们的生存期长些。
net.ipv4.tcp_keepalive_time = 30
#当 keepalive 起用的时候,TCP 发送 keepalive 消息的频度。缺省是 2 小时。
内核文件
/etc/sysctl.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
常见问题
如何自定义返回给客户端的 404 错误页面
如何查看服务器状态信息
如果客户端访问服务器提示“Too many open files”如何解决
如何解决客户端访问头部信息过长的问题
如何让客户端浏览器缓存数据
日志切割
开启 gzip 压缩功能,提高数据传输效率
开启文件缓存功能
然后客户机访问此 Web 服务器验证效果:
使用 ab 压力测试软件测试并发量
编写测试脚本生成长头部信息的访问请求
客户端访问不存在的页面,测试 404 错误页面是否重定向
如何自定义返回给客户端的 404 错误页面
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
------------
error_page 404 /40x.html; //自定义错误页面
------------
[root@proxy ~]# vim /usr/local/nginx/html/40x.html //生成错误页面
Oops,No NO no page …
[root@proxy ~]# nginx -s reload
如何查看服务器状态信息
1)编译安装时使用--with-http_stub_status_module 开启状态页面模块
[root@proxy ~]# yum -y install gcc pcre-devel openssl-devel //安装常见依赖包
[root@proxy ~]# tar -zxvf nginx-1.12.2.tar.gz
[root@proxy ~]# cd nginx-1.12.2
[root@proxy nginx-1.12.2]# ./configure \
> --with-http_ssl_module //开启 SSL 加密功能
> --with-stream //开启 TCP/UDP 代理模块
> --with-http_stub_status_module //开启 status 状态页面
[root@proxy nginx-1.12.2]# make && make install //编译并安装
2)启用 Nginx 服务并查看监听端口状态
[root@proxy ~]# /usr/local/nginx/sbin/nginx
[root@proxy ~]# netstat -anptu | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10441/nginx
[root@proxy ~]# ss -anptu | grep nginx
3)修改 Nginx 配置文件,定义状态页面
[root@proxy ~]# cat /usr/local/nginx/conf/nginx.conf
… …
location /status {
stub_status on;
#allow IP 地址;
#deny IP 地址;
}
… …
[root@proxy ~]# nginx
4)优化后,查看状态页面信息
[root@proxy ~]# curl http://192.168.4.5/status
Active connections: 1
server accepts handled requests
10 10 3
Reading: 0 Writing: 1 Waiting: 0
Active connections:当前活动的连接数量。
Accepts:已经接受客户端的连接总数量。
Handled:已经处理客户端的连接总数量。(一般与 accepts 一致,除非服务器限制了连接数量)。
Requests:客户端发送的请求数量。
Reading:当前服务器正在读取客户端请求头的数量。
Writing:当前服务器正在写响应信息的数量。
Waiting:当前多少客户端在等待服务器的响应。
如果客户端访问服务器提示“Too many open files”如何解决
1)优化前使用 ab 高并发测试
[root@proxy ~]# ab -n 2000 -c 2000 http://192.168.4.5/
Benchmarking 192.168.4.5 (be patient)
socket: Too many open files (24) //提示打开文件数量过多
2)修改 Nginx 配置文件,增加并发量
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
.. ..
worker_processes 2; //与 CPU 核心数量一致
events {
worker_connections 65535; //每个 worker 最大并发连接数
use epoll;
}
.. ..
[root@proxy ~]# nginx -s reload
3)优化 Linux 内核参数(最大文件数量)
[root@proxy ~]# ulimit -a //查看所有属性值
[root@proxy ~]# ulimit -Hn 100000 //设置硬限制(临时规则)
[root@proxy ~]# ulimit -Sn 100000 //设置软限制(临时规则)
[root@proxy ~]# vim /etc/security/limits.conf
.. ..
* soft nofile 100000
* hard nofile 100000
#该配置文件分 4 列,分别如下:
#用户或组 硬限制或软限制 需要限制的项目 限制的值
4)优化后测试服务器并发量(因为客户端没调内核参数,所以在 proxy 测试)
[root@proxy ~]# ab -n 2000 -c 2000 http://192.168.4.5/
如何解决客户端访问头部信息过长的问题
1)优化前,使用脚本测试长头部请求是否能获得响应
[root@proxy ~]# cat lnmp_soft/buffer.sh
#!/bin/bash
URL=http://192.168.4.5/index.html?
for i in {1..5000}
do
URL=${URL}v$i=$i
done
curl $URL //经过 5000 次循环后,生成一个长的 URL 地址栏
[root@proxy ~]# ./buffer.sh
.. ..
<center><h1>414 Request-URI Too Large</h1></center> //提示头部信息过大
2)修改 Nginx 配置文件,增加数据包头部缓存大小
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
.. ..
http {
client_header_buffer_size 1k; //默认请求包头信息的缓存
large_client_header_buffers 4 4k; //大请求包头部信息的缓存个数与容量
.. ..
}
[root@proxy ~]# nginx -s reload
3)优化后,使用脚本测试长头部请求是否能获得响应
[root@proxy ~]#cat cat buffer.sh
#!/bin/bash
URL=http://192.168.4.5/index.html?
for i in {1..5000}
doURL=${URL}v$i=$i
done
curl $URL
[root@proxy ~]# ./buffer.sh
如何让客户端浏览器缓存数据
1)使用 Firefox 浏览器查看缓存
以 Firefox 浏览器为例,在 Firefox 地址栏内输入 about:cache 将显示 Firefox浏览器的缓存信息,点击 List Cache Entries 可以查看详细信息。
2)清空 firefox 本地缓存数据。
3)修改 Nginx 配置文件,定义对静态页面的缓存时间
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80; server_name localhost;
location / {
root html;
index index.html index.htm;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
expires 30d; //定义客户端缓存时间为 30 天
}
}
[root@proxy ~]# cp /usr/share/backgrounds/day.jpg /usr/local/nginx/html
[root@proxy ~]# nginx -s reload
4)优化后,使用 Firefox 浏览器访问图片,再次查看缓存信息
[root@client ~]# firefox http://192.168.4.5/day.jpg
在 firefox 地址栏内输入 about:cache,查看本地缓存数据,查看是否有图片以及过期时间是否正确
日志切割
1. 把旧的日志重命名
2. kill USR1 PID(nginx 的进程 PID 号)
1)手动执行
备注:/usr/local/nginx/logs/nginx.pid 文件中存放的是 nginx 的进程 PID 号。
[root@proxy ~]# mv access.log access2.log
[root@proxy ~]# kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
2)自动完成
每周 5 的 03 点 03 分自动执行脚本完成日志切割工作。
[root@proxy ~]# vim /usr/local/nginx/logbak.sh
#!/bin/bash
date=`date +%Y%m%d`
logpath=/usr/local/nginx/logs
mv $logpath/access.log $logpath/access-$date.log
mv $logpath/error.log $logpath/error-$date.log
kill -USR1 $(cat $logpath/nginx.pid)
[root@proxy ~]# crontab -e
03 03 * * 5 /usr/local/nginx/logbak.sh
- `date=`date +%Y%m%d``:
获取当前日期并将其格式化为 `YYYYMMDD` 的形式,保存在变量 `date` 中。
- `logpath=/usr/local/nginx/logs`:
指定 Nginx 访问日志和错误日志的存储路径为 `/usr/local/nginx/logs`。
- `mv $logpath/access.log $logpath/access-$date.log`:
将当前访问日志文件 `access.log` 重命名为 `access-YYYYMMDD.log` 的形式,以便进行归档。
重命名后的文件将保存在 Nginx 日志存储路径下。
- `mv $logpath/error.log $logpath/error-$date.log`:
将当前错误日志文件 `error.log` 重命名为 `error-YYYYMMDD.log` 的形式,以便进行归档。
重命名后的文件将保存在 Nginx 日志存储路径下。
- `kill -USR1 $(cat $logpath/nginx.pid)`:
发送 `USR1` 信号给 Nginx 进程,使其重新打开日志文件并开始写入新的日志。
`$(cat $logpath/nginx.pid)` 命令用于获取 Nginx 进程的 PID。
开启 gzip 压缩功能,提高数据传输效率
1)修改 Nginx 配置文件
[root@proxy ~]# cat /usr/local/nginx/conf/nginx.conf
http {
.. ..
gzip on; //开启压缩
gzip_min_length 1000; //小文件不压缩
gzip_comp_level 4; //压缩比率
gzip_types text/plain text/css application/json application/x-javascript text/xml
application/xml application/xml+rss text/javascript; //对特定文件压缩,类型参考mime.types
.. ..
}
开启文件缓存功能
1)如果需要处理大量静态文件,可以将文件缓存在内存,下次访问会更快。
http {
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
//设置服务器最大缓存 2000 个文件句柄,关闭 20 秒内无请求的文件句柄
//文件句柄的有效时间是 60 秒,60 秒后过期
//只有访问次数超过 5 次会被缓存
}
#使配置立即生效可使用如下命令: /sbin/sysctl -p