二、nginx
- 80端口转发443端口,需要七层架构
1.源码编译安装
- yum不包含,需要编译源码
- 关闭gcc的debug模式
vim auto/cc/gcc
注释掉 CFLAGS="$CFLAGS -g"
- 首先configure,需要预先安装prce-devel和openssl-devel
[root@rhel86 nginx-1.20.2]# ll
total 792
drwxr-xr-x 6 1001 1001 326 Jan 9 06:40 auto
-rw-r--r-- 1 1001 1001 312251 Nov 16 2021 CHANGES
-rw-r--r-- 1 1001 1001 476577 Nov 16 2021 CHANGES.ru
drwxr-xr-x 2 1001 1001 168 Jan 9 06:40 conf
-rwxr-xr-x 1 1001 1001 2590 Nov 16 2021 configure
drwxr-xr-x 4 1001 1001 72 Jan 9 06:40 contrib
drwxr-xr-x 2 1001 1001 40 Jan 9 06:40 html
-rw-r--r-- 1 1001 1001 1397 Nov 16 2021 LICENSE
-rw-r--r-- 1 root root 438 Jan 9 06:52 Makefile
drwxr-xr-x 2 1001 1001 21 Jan 9 06:40 man
drwxr-xr-x 3 root root 174 Jan 9 06:53 objs
-rw-r--r-- 1 1001 1001 49 Nov 16 2021 README
drwxr-xr-x 9 1001 1001 91 Jan 9 06:40 src
[root@rhel86 nginx-1.20.2]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-threads
- 然后make
- 然后make install
- 测试
[root@rhel86 nginx-1.20.2]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
- 创建软连接
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/
- 创建nginx服务
-
- 文档:https://www.nginx.com/resources/wiki/start/topics/examples/systemd/
vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- 本地测试
root@rhel86 sbin]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@rhel86 sbin]# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
2.升级
- 查看当前版本
[root@rhel86 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Mon, 09 Jan 2023 15:26:42 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 09 Jan 2023 15:05:34 GMT
Connection: keep-alive
ETag: "63bc2d3e-264"
Accept-Ranges: bytes
- 编译新版本需要注意问题:不能make install
- 备份原可执行文件
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
- 拷贝新编译的程序覆盖源程序
cp -f objs/nginx /usr/local/nginx/sbin/
- 获取当前nginx主进程pid
[root@rhel86 nginx-1.22.1]# ps ax|grep nginx
47039 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
47041 ? S 0:00 nginx: worker process
49912 pts/0 R+ 0:00 grep --color=auto nginx
- 升级新程序
此时同时运行着两个nginx进程,新程序自动启动
[root@rhel86 nginx-1.22.1]# kill -USR2 47039
[root@rhel86 nginx-1.22.1]# ps ax|grep nginx
47039 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
47041 ? S 0:00 nginx: worker process
49921 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49922 ? S 0:00 nginx: worker process
49924 pts/0 R+ 0:00 grep --color=auto nginx
此时新进程并没有接管原进程
[root@rhel86 nginx-1.22.1]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Mon, 09 Jan 2023 15:41:18 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 09 Jan 2023 15:05:34 GMT
Connection: keep-alive
ETag: "63bc2d3e-264"
Accept-Ranges: bytes
- 关闭原worker进程,保留原master进程,方便回滚
[root@rhel86 nginx-1.22.1]# kill -WINCH 47039
[root@rhel86 nginx-1.22.1]# ps ax|grep nginx
47039 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49921 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49922 ? S 0:00 nginx: worker process
49961 pts/0 R+ 0:00 grep --color=auto nginx
[root@rhel86 nginx-1.22.1]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Mon, 09 Jan 2023 15:43:09 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 09 Jan 2023 15:05:34 GMT
Connection: keep-alive
ETag: "63bc2d3e-264"
Accept-Ranges: bytes
- 版本回滚
# 先将bak覆盖源程序
cp -f /usr/local/nginx/sbin/nginx.bak /usr/local/nginx/sbin/nginx
# 唤醒原master进程
[root@rhel86 nginx-1.22.1]# kill -HUP 47039
[root@rhel86 nginx-1.22.1]# ps ax|grep nginx
47039 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49921 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49922 ? S 0:00 nginx: worker process
50028 ? S 0:00 nginx: worker process
50030 pts/0 R+ 0:00 grep --color=auto nginx
# 关闭现在的worker进程
[root@rhel86 nginx-1.22.1]# kill -WINCH 49921
[root@rhel86 nginx-1.22.1]# ps ax|grep nginx
47039 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
49921 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
50028 ? S 0:00 nginx: worker process
50042 pts/0 R+ 0:00 grep --color=auto nginx
[root@rhel86 nginx-1.22.1]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Mon, 09 Jan 2023 15:49:04 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 09 Jan 2023 15:05:34 GMT
Connection: keep-alive
ETag: "63bc2d3e-264"
Accept-Ranges: bytes
3.nginx配置
- 配置文件路径:/usr/local/nginx/conf
- 主配置文件:nginx.conf
#user nginx; # 默认使用nobody用户
worker_processes 1; # 可以设置成auto,跟cpu数量有关
worker_cpu_affinity 01 10; # 设置cpu独占
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 65535; # 最大并发量,默认1024,会消耗内核的文件描述符,需要修改OS中热插拔模块的pam_limits.so的/etc/security/limits.conf
}
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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
······
- 添加nginx专属用户
[root@server conf]# useradd -M -d /usr/local/nginx -s /sbin/nologin nginx # 创建不设置主目录,不能进行系统登陆的nginx用户
[root@server conf]# id nginx
uid=1001(nginx) gid=1001(nginx) groups=1001(nginx)
- 修改最大并发量
vim /etc/security/limits.conf
nginx - nofile 65535
- 修改HTTP请求的负载平衡
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
http {
upstream backend {
# ip_hash # 来自同一IP的请求由同一rs处理
server rs1 weight=2; # 可以设置权重,默认是1
server rs2;
# server rs3 down; # 表示处于维护状态
# server 127.0.0.1 backup; # 当rs全挂之后生效
}
server {
listen 80;
server_name alexw.study;
location / {
proxy_pass http://backend;
}
}
}
alexw.study这个nginx的服务器别名需要在自己的hosts和访问者的hosts里注册
- nginx默认对后端有健康检测
4. nginx添加新模块
- https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
- 对于静态编译
# 仍然先configure,注意添加--add-module路径
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-threads --add-module=/root/nginx-goodies-nginx-sticky-module-ng-08a395c66e42
# make后不要make install
- 也可以将nginx编译成动态:添加–add-dynamic-module参数
5. nginx控制并发连接数及并发处理速率
- 官方文档:https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/
- 控制并发量
修改nginx.conf
# 在http块添加
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 修改server块的location
location /download/ {
limit_conn addr 1; # 控制来自同一IP的并发量为1
}
使用ab做压力测试,因为每个ip只能有一个并发,所以其余的请求失败
yum install -y httpd-utils
[root@rhel86 ~]# ab -n 10 -c 5 http://192.168.147.134/download/1.jpg
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.147.134 (be patient).....done
Server Software: nginx/1.20.2
Server Hostname: 192.168.147.134
Server Port: 80
Document Path: /download/1.jpg
Document Length: 324704 bytes
Concurrency Level: 5
Time taken for tests: 0.019 seconds
Complete requests: 10
Failed requests: 4
(Connect: 0, Receive: 0, Length: 4, Exceptions: 0)
Non-2xx responses: 4
Total transferred: 1952410 bytes
HTML transferred: 1950200 bytes
Requests per second: 515.52 [#/sec] (mean)
Time per request: 9.699 [ms] (mean)
Time per request: 1.940 [ms] (mean, across all concurrent requests)
Transfer rate: 98291.08 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.3 1 1
Processing: 4 6 1.7 7 9
Waiting: 1 4 2.0 5 6
Total: 4 7 1.8 7 9
Percentage of the requests served within a certain time (ms)
50% 7
66% 7
75% 8
80% 9
90% 9
95% 9
98% 9
99% 9
100% 9 (longest request)
-
nginx日志都保存在/usr/local/nginx/logs目录里
-
控制并发处理速率
# 修改nginx.conf
# 在http块添加
limit_conn_zone $binary_remote_addr zone=addr:10m rate=1r/s;
- 允许请求队列
location /download/ {
limit_conn addr 1; # 控制来自同一IP的并发量为1
limit_req zone=one burst=5 nodelay; # 允许队列,队列长度为5,队列满不再处理新请求
limit_rate=100k; # 限制带宽为100k
autoindex on; # 允许客户端获取到当前目录的索引
}
- 设置图片静态资源长期缓存
location ~ .*\.(gif|jpg|png)$ {
expires 365d;
root html;
}
注意这里正则匹配了gif|jpg|png为后缀的文件,并设置了过期时间为1年(注意’{'前有个空格)
6. nginx日志轮询和可视化
- 编写日志截断脚本
/opt/nginx_log.sh
[root@server nginx]# vim /opt/nginx_log.sh
#!/bin/bash
cd /usr/local/nginx/logs && mv access.log access_$(date +%F -d -1day).log # 重命名旧的access.log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` # 向当前nginx发送信号,重新生成log(即记录新一天的log)
- 创建定时任务
crontab -e
00 00 * * * /opt/nginx_log.sh
* * * * * date
* * * * * sleep 10; date
* * * * * sleep 20; date
* * * * * sleep 30; date
* * * * * sleep 40; date
* * * * * sleep 50; date
- 源码编译goaccess
# 源码下载地址https://tar.goaccess.io/goaccess-1.7.tar.gz
# 需要提前安装依赖,geoip-devel和ncurses-devel
# geoip-devel需要下载rpm,依次安装:GeoIP-data、GeoIP、GeoIP-devel需要版本对应
# https://ftp.lysator.liu.se/pub/opensuse/ports/aarch64/distribution/leap/15.3/repo/oss/noarch/GeoIP-data-1.6.12-6.3.1.noarch.rpm
# https://download-ib01.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/g/GeoIP-1.6.12-7.el8.x86_64.rpm
# https://download-ib01.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/g/GeoIP-devel-1.6.12-7.el8.x86_64.rpm
# 源码编译goaccess
./configure --enable-debug --enable-geoip=legacy
make
make install
# 下载GeoIP.dat放在/usr/share/GeoIP
# 后台允许goaccess实时监控nginx的access.log
goaccess /usr/local/nginx/logs/access.log -o /usr/local/nginx/html/report.html --log-format=COMBINED --real-time-html &
7. 其他配置
- 关闭不必要的访问记录
# 正则匹配以这些文件后缀名结尾的文件名,关闭其access_log
location ~ .*\.(js|jpg|jpeg|png|css|bmp|gif)$ {
access_log off;
}
- 拒绝对.sh|.php的访问
location ~ ^/images/.*\.(sh|php)$ {
deny all;
}
- 解决中文乱码
charset utf8;
- 限制IP
location / {
deny 172.25.0.100;
allow 172.25.0.0/24;
deny all;
}
if ($remote_addr = 172.25.0.254) {
return 403;
}
- 防止恶意域名解析
server {
listen 80;
server_name localhost;
#return 500; # 返回500
rewrite ^(.*) http://alexw.study permanent; # 或重定向
- 80重定向443
server {
listen 80;
server_name localhost;
rewrite ^/(.*)$ https://alexw.study/$1 permanent; # $1表示一个占位符,用于匹配前面正则表达式中'(.*)'括号内的内容
- 站点独立后重定向
rewrite ^/bbs$ http://bbs.alexw.study permanent;
rewrite ^/bbs/(.*)$ http://bbs.alexw.study/$1 permanent;
- 防盗链
location ~ \.(jpg|png)$ {
valid_referers none blocked alexw.study; # 标识合法的refer
if ($invalid_referer) {
return 403;
}
}