Nginx使用手册
Nginx(发音为 "engine-x")是一个高性能、开源的HTTP和反向代理服务器,也可以作为电子邮件(IMAP/POP3)代理服务器、以及通用的TCP/UDP代理服务器。它由俄罗斯的程序员Igor Sysoev创建于2002年,其目的是解决C10K问题(即可以同时处理10000个并发连接)。它采用异步非阻塞的事件驱动模型,可以处理成千上万个并发连接,同时使用少量的CPU和内存资源。
本篇带着大家一起领略nginx的常见使用技巧
优势
高性能
:Nginx具有高并发、低内存消耗以及高稳定性的特点,可以很好地应对大流量的访问高可扩展性
:Nginx支持模块化扩展,可以灵活增加新功能。用户可以根据自己的需求选择相应的模块,从而实现定制化的功能高可靠性
:Nginx具有故障自动恢复、热部署等功能,能够保证服务器在遇到问题时仍能继续提供服务反向代理与负载均衡
:Nginx可以作为反向代理服务器,提供负载均衡功能。通过负载均衡,Nginx可以将请求分发到多个后端服务器,从而实现高可用和高性能的服务静态文件处理
:Nginx在处理静态文件方面(如HTML、CSS、JS、图片等)具有非常高的性能,可以作为Web服务器或者静态资源服务器使用灵活的配置
:Nginx的配置文件结构清晰,易于理解和修改。用户可以根据自己的需求对Nginx进行灵活的配置
功能
- HTTP服务器:作为Web服务器,可以处理HTTP请求,提供网页浏览服务
- 反向代理:将客户端的请求转发到其他服务器,并将服务器的响应返回给客户端。这样可以隐藏服务器的真实IP地址,提高安全性
- 负载均衡:在多个服务器之间分配客户端的请求,实现请求的负载均衡
- 缓存和压缩:Nginx支持内容缓存和压缩,可以加快页面加载速度,降低服务器负载
- 虚拟主机:通过配置虚拟主机,可以使用一个Nginx服务器处理多个域名的请求
- 安全性:支持SSL/TLS加密,可以对传输的数据进行加密,保证数据的安全性
- 电子邮件代理:作为电子邮件服务器,可以处理IMAP/POP3协议,提供邮件收发服务
安装nginx
yum install nginx -y
本人使用的是ARM架构的centos进行安装的,当执行以下命令时提示没有可用的安装包,如果你和我一样,可以访问官方下载页面进行nginx的repo配置:
下载准备:
yum install yum-utils
设置YUM存储库,创建名为/etc/yum.repos.d/nginx.repo
的文件,并复制以下内容:
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
2
3
4
5
6
7
8
9
10
11
12
13
14
15
以上配置好了后再次进行nginx的下载应该就可以了
下载好后查看nginx版本:
➜ nginx -v
nginx version: nginx/1.22.1
2
配置开机启动:
➜ systemctl enable nginx --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
2
常用命令
- 查看nginx版本sh
➜ nginx -v nginx version: nginx/1.22.1 # 详细内容(版本号、编译器版本、安装路径、日志路径、PID文件路径、HTTP模块、SSL模块、GZIP模块等等) ➜ nginx -V nginx version: nginx/1.22.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --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 --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
1
2
3
4
5
6
7
8
9
10 - 测试 Nginx 配置文件的语法和逻辑是否正确sh
➜ nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # 检测并输出配置文件,快速诊断配置文件问题 ➜ nginx -T
1
2
3
4
5
6 - 启动nginx与重启sh
➜ nginx ➜ nginx -s reload
1
2 - 关闭nginxsh
# 立即停止 ➜ nginx -s stop # 处理完请求后停止 ➜ nginx -s quit
1
2
3
4
有时候会在机器上查找nginx的一些重要文件路径,如:配置文件、日志文件等等,可以使用nginx -V
命令,在终端搜索log
、nginx.conf
等关键字即可
配置文件
可以使用nginx -t
知道nginx的配置文件路径具体位置,打开配置文件如下:
# /etc/nginx/nginx.conf
user nginx;
# 数量大,并发高,会受到硬件的配置影响
worker_processes auto; # number/auto
error_log /var/log/nginx/error.log notice; # notice、info
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# 定义文件类型映射表,返回浏览器会在头部加上对应的文件类型
include /etc/nginx/mime.types;
# mime中无对应类型,默认流类型
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;
# sendfile 是一种高效的文件传输方式,它可以将文件数据直接从磁盘读取到内核缓冲区,再通过网络传输到客户端,避免了将文件数据从内核缓冲区复制到用户空间的开销,提高了文件传输的效率。
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
# gzip压缩
gzip on;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
}
include /etc/nginx/conf.d/*.conf;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
由以上的默认配置可以看出nginx配置是由以下几部分组成的:
- main块:主要包含全局配置参数,服务器的用户(组)、worker 进程数、进程 ID 文件路径、日志存放路径等
- events块:用于配置事件模块的参数,例如 worker 进程的连接数、事件模型等
- http块:用于配置 HTTP 协议相关的参数,例如服务器监听的端口、虚拟主机、代理、缓存等
- server块:属于http块中的模块,用于配置一个虚拟主机的参数,例如监听的端口、域名、SSL 证书、代理、缓存等,http块中可以包含多个server块(常用server来配置虚拟主机)
- location块:属于server块中的模块,用于配置一个 URI 的参数,例如 URI 匹配规则、代理、缓存等(匹配主机路径)
Nginx 配置文件采用了一种层次结构的格式,每个块都以花括号 {} 包含,其中的参数和指令以分号 ; 结尾。通过修改 Nginx 配置文件,可以自定义 Nginx 服务器的行为和参数,以适应不同的需求和场景
在默认配置文件结尾会将conf.d
路径下的所有*.conf
结尾的配置文(server级别)件引入到主配置文件,这样可以根据不同的server模块进行划分配置,便于管理和维护:
include /etc/nginx/conf.d/*.conf;
server
server 块用于配置一个虚拟主机的参数,例如监听的端口、域名、SSL 证书、代理、缓存等。每个 server 块都必须包含一个 listen 指令,用于指定虚拟主机监听的端口和 IP 地址
示例:
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
2
3
4
5
6
7
8
以上的server监听80端口并匹配域名exemple.com
,当访问/
时会访问/usr/share/nginx/html/index.html
文件。
listen
表示当前虚拟主机监听的端口,可以写多个,如监听https端口可以写listen 443 ssl;
server_name
表示匹配的域名,可以写正则来匹配,如*.example.com
表示exempe.com的所有二级域名都可以匹配到
除了基本参数外,server 块还可以配置其他的参数,如:sl_certificate 和 ssl_certificate_key用于配置 SSL 证书和私钥的路径等等
location
location用来匹配server中的访问路径(path),如访问https://blog.usworn.cn/me
可以匹配path/me
。location支持全匹配和正则表达式:
- 全匹配:= /xxx
- 正则匹配:
~
:区分大小写~*
:不区分大小写^~
:用于不含正则表达式uri前,nginx找到和请求uri匹配度最高的 location 后,立即用此location,不再用location 中的正则匹配
例子:
server {
# ...
# 全匹配 /me
location = /me {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 匹配 以/admin 开头的path
location ~ ^/admin {}
# 同上,这里不区分大小写相当于 /admin
location ~* ^/ADMIN {}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
静态服务
作为静态服务使用时,可以提供高效的静态文件传输和缓存服务,从而加速网站的加载速度,提升用户体验
server {
# 指定静态文件的根目录,nginx 会根据 uri 在 根目录下匹配路径
location ~ {
root /usr/share/nginx/html;
index index.html;
}
# 路径映射,可以对外隐藏真实的路径
location /images/ {
alias /documents/icons/;
}
}
2
3
4
5
6
7
8
9
10
11
12
假如访问index.html,内容如下:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<img src="/images/icon-docker.png" >
</body>
</html>
2
3
4
5
6
7
8
9
访问页面时会请求请求图片,在nginx中替换掉图片地址为/documents/icons/icon-docker.png
,这对外部来说隐藏了内部的真实地址
也可以作为资源目录列表:
server {
# 资源列表
location / {
autoindex on; # 开启资源列表目录
autoindex_exact_size on; # 显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
autoindex_localtime on; # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
}
}
2
3
4
5
6
7
8
访问控制
使用 deny 指令来进行访问控制,该指令可以限制某些 IP 地址或 IP 地址段的访问
nginxserver { # 禁止指定IP location /foo { deny 192.168.10.10; } # 禁止IP 地址段 location /bar { deny 192.168.1.0/24; } # 允许指定IP location / { deny all; allow 192.168.1.10; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15设置用户名和密码鉴权
安装
httpd-tools
,用来生成账户名和密码shyum install httpd-tools -y
1设置用户名和密码:这里将会生成新的文件
/etc/nginx/.htpasswd
,用户名为ihengshuai,密码提示你输入sh➜ htpasswd -c /etc/nginx/.htpasswd ihengshuai New password: Re-type new password: Adding password for user ihengshuai
1
2
3
4查看用户名和密码:默认生成的密码会被加密,密码加密算法有好几种,你也可以使用明文密码,请参考
htpasswd -h
了解更多sh➜ cat /etc/nginx/.htpasswd ihengshuai:$apr1$FvO5arNB$nsrzQ8e.4DX.c8JUSJJTE1
1
2接下来进行nginx配置:
nginx# vim /etc/nginx/default.conf server { #... auth_basic "请输入用户名和密码"; auth_basic_user_file /etc/nginx/.htpasswd; }
1
2
3
4
5
6
重定向
nginx中支持rewrite
和return
关键字进行重定向
rewrite
rewrite <regexp> <replacement> [flag];
- regexp:路径匹配,如匹配:^/admin
- replacement:替代的内容,比如换成 https://blog.usword.cn
- flag:标识符
- last:匹配完后继续向下匹配 location
- break:匹配完后,不再匹配后面的规则
- redirect:302临时重定向,浏览器会显示新的URL
- permanent:301永久重定向,浏览器会显示新的URL
例子:
server {
location / {
rewrite ^(/frontend(.*))$ https://blog.usword.cn$1 permanent;
# 不管是啥都重定向到另一个域名
# rewrite ^(.*)$ https://blog.usword.cn$1 redirect;
# 设置状态码 418 的错误 路径
error_page 418 = @redirect_stop;
# 重定向 次数超过 10次时 ,返回状态码 418
if ($redirect_count > 10) {
return 418;
}
}
location @redirect_stop {
# do something
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
当访问路径中以/frontend
开头时永久重定向到http://blog.usword.cn
,并将路径拼接到后面(这里需要了解正则表达式使用)
如果重写规则不正确,可能会导致死循环或者无限重定向。为了避免这种情况,可以使用 error_page
指令或者 return
指令设置重定向的最大次数或者超时时间
return
return <code> [text];
- code:一个 HTTP 响应码,用于指示服务器应该返回哪种类型的响应
- text:可选的文本字符串,用于指定响应正文
例子:
server {
location /api {
add_header 'Content-Type' 'application/json';
return 200 '{"code": 200, "msg": "ok"}';
}
location ~* ^(/frontend(.*))$ {
return 302 https://blog.usword.cn$1;
}
}
2
3
4
5
6
7
8
9
以上当访问/api时设置状态码200并以json的形式返回数据,当匹配到/frontend
开头的路径时重定向到https://blog.usword.cn 并将path拼接到后面
GZIP压缩
使用 gzip 模块对 HTTP 响应进行压缩。这可以显著减少传输数据的大小,从而提高网站的性能和响应速度。gzip压缩功能由ngx_http_gzip_module和ngx_http_gzip_static_module模块提供
开启gzip:可以用在http、server、location中
gzip on;
其他用法:
server {
gzip on;
gzip_types text/html text/css application/javascript;
gzip_static on;
gzip_proxied expired no-cache auth;
gzip_buffers 16 8k;
gzip_min_length 2k;
gzip_comp_level 4;
gzip_http_version 1.0;
gzip_vary on;
gzip_disable "MSIE [1-6]\\.";
}
2
3
4
5
6
7
8
9
10
11
12
gzip_types
:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;gzip_static
:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;gzip_proxied
:默认 off,nginx 做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;gzip_buffers
:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得gzip_min_length
:允许压缩的页面最小字节数,页面字节数从 header 头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大gzip_comp_level
:gzip 压缩比,压缩级别是 1-9,默认6,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;gzip_http_version
:默认 1.1,启用 gzip 所需的 HTTP 最低版本;gzip_vary
:用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;gzip_disable
指定哪些不需要 gzip 压缩的浏览器,正则匹配 请求头的User-Agent
例子:对图片进行压缩
location ~* (png|jpeg|gif)$ {
gzip on;
gzip_comp_level 6;
gzip_types image/png image/jpeg image/jpg image/gif;
}
2
3
4
5
图像转换
nginx中可以使用http_image_filter_module
模块的功能进行图片的转换如:缩放、裁剪、质量等等,使用此功能需要安装这个模块,这里演示在Centos中的安装过程,若已安装可以跳过此步骤。
首先检查是否安装了此模块,运行命令:如果发现有此模块将会高亮显示,如果没有什么都不会输出
➜ nginx -V 2>&1 | grep 'http_image_filter_module'
configure arguments: --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 --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' `--with-http_image_filter_module`
2
3
安装模块依赖环境:
➜ yum install gd-devel pcre pcre-devel -y
如果原来是使用yum安装的nginx,则需要在官方网站上找到对应版本的nginx包下载到本地:这里我以1.22.1版本为例
# 下载
➜ wget https://nginx.org/download/nginx-1.22.1.tar.gz
# 解压
➜ tar xf nginx-1.22.1.tar.gz
2
3
4
为了不影响原来的nginx的数据和配置,使用和原版本的nginx同样的编译参数,然后在后面添加上--with-http_image_filter_module
参数即可:
# 查看原来版本的编译参数,并复制configure arguments 的值
➜ nginx -V
# 编译nginx
➜ cd nginx-1.22.1
➜ ./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 --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' `--with-http_image_filter_module`
# 编译安装文件
➜ make && make install
# 重启nginx
➜ nginx -s reload
# 可以再次使用一下命令进行验证是否安装成功
➜ nginx -V 2>&1 | grep 'http_image_filter_module'
2
3
4
5
6
7
8
9
10
11
12
13
到这里就可以使用http_image_filter_module模块的功能了,官方文档配置戳👉这里
以上安装此模块后编译如果出现其他的错误,请按照提示安装上相关的依赖即可解决
image_filter使用参数:
image_filter off;
:关闭模块image_filter test;
:确保图片格式为PNG、JPEG、GIF、WEBP,否则返回415状态码image_filter size;
:以json的形式输出图片的信息,如:'{"img":{"width":1135,"height":500,"type":"jpeg"}}',resize、crop等同时使用时无效果image_filter rotate 90|180|270;
:旋转图像,可以和resize、crop一起使用image_filter resize width height;
:按比例缩放图像,要减少一个维度可以将另一个值设置为-
image_filter crop width height;
:按比例将图像缩小到较大的一侧,并在另一侧产生无关边缘image_filter_buffer size;
:读取图片缓冲区大小,若图片太大缓冲区太小则会抛415错误image_filter_interlace on;
:如果启用,最终图像将交错。对于JPEG,最终图像将采用"逐行JPEG"格式。image_filter_jpeg_quality 1-100;
:设置转换的JPEG图像的质量。可接受的值是从1到100的范围内。较小的值通常意味着图像质量越低,以达到减少数据传输。推荐的最大值为95,参数值可以包含变量image_filter_webp_quality 1-100
:设置webp图片质量,同上image_filter_transparency on|off;
:定义在使用调色板指定的颜色转换GIF图像或PNG图像时是否应保留透明度。透明度的降低会导致质量更好的图像,PNG中的alpha通道透明度始终保留。image_filter_sharpen 1-100;
:增加最终图像的清晰度,锐度百分比可以超过100。零值将禁用锐化。参数值可以包含变量
TIP
注意以上大部分操作都会耗时,尤其是对于很大的图片,如果裁剪、缩放的比例很大,将会增加耗时,应合理设置处理流程
此模块处理图像出现异常的情况下基本都是抛出415错误,因此在不能正常处理图像情况下,重定向到指定的位置更为友好
例子:
server {
location /images/ {
# 初始化 width 为-,也就是原始大小
set $width -;
# 匹配图片url上的 w参数 如:/images/cat.png?w=1 | w=xx
# 正则判断是纯数字且大于0时将值 赋值给 width
if ($arg_w ~* ^[1-9]\d+$) {
set $width $arg_w;
}
# 设置缓冲区 5M
image_filter_buffer 5m;
image_filter test;
# 缩放图片 width,另一侧按比例缩放
image_filter resize $width -;
alias /documents/;
allow all;
# 当抛出 415 错误时,走 @image_filter_error 路由
error_page 415 @image_filter_error;
}
# 重定向到 错误图片
location @image_filter_error {
return 301 /images/error.png;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
在浏览器上测试使用w参数:大于0都可以正常处理,其他的都会以原始大小返回;当图像大小大于5M时,由于太大将会重定向到错误图片,以上根据实际情况自行处理
除了以上对图片进行转换外,还可以使用ngx_http_set_misc_module
模块或Lua
脚本将图片转换成webp格式,提高图像加载,这里就不介绍了
缓存
nginx默认支持静态资源的缓存和代理缓存
静态资源缓存
可以使用expires
和Cache-Control
请求头设置缓存
- 使用expires进行缓存,Expires 是 HTTP/1.0 中定义的字段,它指定了在过期之前客户端可以缓存响应的时间。服务器会在响应头中设置一个到期日期,客户端在该日期之前可以缓存响应。Expires 头部的时间格式是 GMT 格式的绝对时间,如 "Expires: Wed, 21 Oct 2015 07:28:00 GMT"。nginx
server { location ~ \.(png|jpg|jpeg|gif|webp)$ { expires 1d; } }
1
2
3
4
5 - 使用Cache-Control进行缓存,它是 HTTP/1.1 中定义的字段,它提供了更为灵活的缓存控制方式。它可以指定缓存的时间、缓存的位置、缓存的类型等。常用的指令包括
max-age
、no-cache
、no-store
、must-revalidate
等。其中,max-age
指定了缓存的最长时间,它的值是一个相对时间,如 "Cache-Control: max-age=86400" 表示缓存 1 天。nginxCache Control可以使用的参数如下:server { location ~ \.(png|jpg|jpeg|gif|webp)$ { add_header Cache-Control "public, max-age=86400"; } }
1
2
3
4
5- public:指示响应可以被任何中间缓存缓存,包括客户端和代理服务器。
- private:指示响应只能被客户端缓存,不应该被代理服务器缓存。
- max-age:指示缓存存储的最长时间,单位为秒。例如,Cache-Control: max-age=3600 表示缓存有效期为 1 小时。
- s-maxage:与 max-age 类似,但只适用于共享缓存(比如代理服务器)。如果同时设置了max-age 和 s-maxage,则 s-maxage 优先级更高。
- no-cache:指示客户端必须在使用缓存之前重新验证资源的有效性。如果资源未被修改,则可以从缓存中读取资源。否则,需要重新下载资源。
- no-store:指示不应将响应存储在任何缓存中,包括客户端和代理服务器。
- must-revalidate:指示在过期之后,缓存必须从原始服务器重新获取资源,以确保缓存仍然有效。如果不能从原始服务器重新获取资源,则缓存必须标记为过期。
二者的区别和对比:
Expires 和 Cache-Control 的区别主要在于过期时间的计算方式不同。Expires 是基于服务器时间的绝对时间,因此它的缺点是服务器时间和客户端时间可能不同步,可能导致缓存不一致。而 Cache-Control 则是相对时间,可以避免这个问题。此外,Cache-Control
还支持更为灵活的控制方式,可以更好地控制缓存策略。建议使用Cache-Control 来设置 HTTP 缓存控制,而Expires则可以用作向后兼容,或在某些场景下作为备用方案。
代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
server {
location /proxy {
proxy_pass http://localhost:10000;
# 定义缓存的键名
proxy_cache_key "$scheme$proxy_host$request_uri";
# 缓存的有效期为 5 分钟
proxy_cache_valid 200 5m;
# 根据 Pragma 字段决定是否跳过缓存
proxy_cache_bypass $http_pragma;
# 制重新验证缓存
proxy_cache_revalidate on;
# 启用代理缓存,并指定缓存区名称
proxy_cache my_cache;
# 启用缓存背景更新
proxy_cache_background_update on;
# 设置缓存背景更新的时间间隔为 1 小时
proxy_cache_background_update_interval 1h;
# 设置缓存背景更新的失败重试次数为 2 次
proxy_cache_background_update_retries 2;
# 设置缓存背景更新时使用的临时文件路径
proxy_cache_background_update_temp_path /tmp/nginx_cache;
# 启用缓存锁定,控制并发缓存请求
proxy_cache_lock on;
# 设置缓存锁定的超时时间为 5 秒
proxy_cache_lock_timeout 5s;
# 缓存锁定失败时,是否返回错误码 503
proxy_cache_lock_age on;
# 启用缓存失效时使用旧的缓存数据
proxy_cache_use_stale error timeout updating;
# 设置缓存失效时使用旧的缓存数据的有效期为 1 分钟
proxy_cache_valid 404 1m;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
防盗链
防盗链(Referer 防盗链)是指在网站或服务器端设置一些规则,只允许指定的域名或网站引用自己的资源,防止非法盗链,减少带宽浪费。
在 Nginx 中,可以使用 valid_referers 指令来实现防盗链的功能。该指令用于设置有效的引用来源(Referer)列表,只有在该列表中的来源才能访问指定的资源。
valid_referers [none|blocked|server_names|string ...];
none
:允许空的引用来源(Referer)。blocked
:阻止所有的引用来源(Referer)。server_names
:允许与服务器名匹配的引用来源(Referer)。string
:允许指定字符串的引用来源(Referer),可以使用通配符和正则表达式进行匹配。
例子:
server {
server_name *.general-mac.com;
location ~ \.(png|jpg|jpeg|gif|webp)$ {
valid_referers blocked server_names "~.*general-mac\.com$";
if ($invalid_referer) {
return 403;
}
}
}
2
3
4
5
6
7
8
9
10
11
上面的例子设置了不允许refer为none(不允许单独打开图片),使用正则匹配只允许refer为 general-mac.com
或其任何子域名,其余的都会返回403,
反向代理
server {
location /proxy {
proxy_pass http://localhost:10001;
# 添加响应头部返回给客户端
add_header X-Real-IP $remote_addr;
# 传给目标服务器设置的头部信息
# 源host
proxy_set_header Host $http_host;
#上层请求真实IP (一般设置在第一层代理服务器)
proxy_set_header X-Real-IP $remote_addr;
# 访问的协议
proxy_set_header X-Forwarded-Scheme $scheme;
# 将经过多个代理服务器的ip以 逗号 拼接,最左边是用户真实ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Websocket
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
# 目标服务器数据回传超时时间
proxy_send_timeout 10;
# 目标服务器响应超时时间
proxy_read_timeout 30;
# 和目标服务器连接超时时间
proxy_connect_timeout 90;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
使用nodejs简单的写一个后端服务:
const express = require("express");
const app = express();
const port = 10001;
app.use((req, res) => {
res.json({
port,
code: 200,
msg: "ok",
url: req.url
})
})
app.listen(port, () => console.log('server is running on port' + port));
2
3
4
5
6
7
8
9
10
11
12
13
14
测试:
➜ curl general-mac.com/proxy -I
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Thu, 06 Apr 2023 13:17:41 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 290
Connection: keep-alive
X-Powered-By: Express
ETag: W/"122-vJBMYWLUDf/IIuHJiL8M6GUx+Wo"
X-Real-IP: 192.168.10.1
2
3
4
5
6
7
8
9
10
配置跨域
跨域是怎么产生的这里不再赘述,在nginx中进行反向代理的跨域配置
# 后端服务器,使用上面的nodejs
server {
listen 10010;
location /proxy {
# 设置允许的源(IP+PORT)
add_header Access-Control-Allow-Origin $http_origin;
# 设置允许的 请求方法
add_header Access-Control-Allow-Methods 'OPTIONS, GET, POST, PUT, DELETE';
# 设置允许的请求头
add_header Access-Control-Allow-Headers 'x-locale';
# 其他自定义...
# 预检请求 204 快速返回
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header X-Http-Host $http_host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
新建一个HTML页面:
<html>
<head><meta charset='utf8'/></head>
<body>
<input id='input'>
<button>请求</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', async e => {
const res = await fetch('http://192.168.10.9:10010/proxy', {
mode: 'cors',
headers: {
'x-locale': 'zh'
}
})
.then(res => res.json())
console.log(res)
})
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
负载均衡
nginx中可以使用nginx_http_upstream_module
模块实现负载均衡,请确保已安装
upstream backend {
# 使用三个后端服务地址
server backend1.example.com weight=1;
server backend2.example.com;
server backend3.example.com;
# 轮询
# round_robin;
# 连接最小数
# least_conn;
# IP哈希
# ip_hash;
}
server {
location / {
proxy_pass http://backend;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nginx可以根据不同的负载均衡策略进行流量分发
配置HTTPS
在使用HTTPS之前,需要获得SSL证书。可以从证书颁发机构(CA)购买证书,或者使用免费的证书颁发机构(如Let's Encrypt)获得证书,这里采用OpenSSL自签证书,便于使用封装成以下脚本auto-cetificate.sh
:
#!/bin/bash
# https://docs.azure.cn/zh-cn/articles/azure-operations-guide/application-gateway/aog-application-gateway-howto-create-self-signed-cert-via-openssl
echo "请使用sudo运行以获取系统权限!"
echo "请输入域名:"
read userdomain
# 啥都不输退出
if [ ! "$userdomain" ]; then
exit
fi
# 使用OpenSSL签发证书
# 1. 生成服务器私钥 (domain.com.key) domain.com 随便起的名字
openssl genrsa -out $userdomain.key 4096
# 2.生成证书签名请求(CSR) domain.com.csr
# 生成 CSR 的过程中,会提示输入一些信息,其中一个提示是 Common Name (e.g. YOUR name),
# 这个非常重要,这一项应填入 FQDN(Fully Qualified Domain Name)完全合格域名/全称域名,
# 如果您使用 SSL 加密保护网络服务器和客户端之间的数据流,
# 举例被保护的网站是 https://test.chinacloudsites.cn,
# 那么此处 Common Name 应输入 test.chinacloudsites.cn
openssl req -new -key $userdomain.key -out $userdomain.csr
# 3.使用上一步的证书签名请求签发证书
openssl x509 -req -days 365 -in $userdomain.csr -signkey $userdomain.key -out $userdomain.crt -extensions SAN
# pem
# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
# openssl s_client -showcerts -connect gitlab.ihengshuai.com:443 -servername gitlab.ihengshuai.com < /dev/null 2>/dev/null | openssl x509 -outform PEM > /certs/gitlab.ihengshuai.com.crt
echo
echo "Generate success!"
echo
# 将本地域名写入host
echo 需要将域名写入host吗[yes/no]?
read confirm_read_host
if [ "$confirm_read_host" != "yes" ]; then
exit
fi
echo 需要保持和证书域名相同不[yes/no]?
read confirm_write_host
if [ "$confirm_write_host" == "no" ]; then
echo 请填写待写入host的域名
read custom_host_domain
cp /etc/hosts /etc/hosts.old
echo "127.0.0.1 $custom_host_domain" >>/etc/hosts
exit
fi
cp /etc/hosts /etc/hosts.old
echo "127.0.0.1 $userdomain" >>/etc/hosts
echo "Write success!"
sleep 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
执行脚本根据提示输入生成证书:
➜ ./auto-cetificate.sh
最终会产生如下文件:
➜ ls && pwd
auto-cetificate.sh general-mac.com.crt general-mac.com.csr general-mac.com.key
/root/certificates
2
3
生成DH加密参数:
# 此过程会耗时
openssl dhparam -out dhparam.pem 2048
2
对于SSL相关配置、握手不太清楚的可以阅读我的「HTTP协议及安全防范」一文
在nginx中配置https:
server {
listen 80;
listen 443 ssl;
server_name general-mac.com;
# 证书
ssl_certificate /root/certificates/general-mac.com.crt;
ssl_certificate_key /root/certificates/general-mac.com.key;
# TLS版本、加密套件
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 加密套件根据自己需求调整
# 服务器推荐加密套件
ssl_prefer_server_ciphers on;
# DH参数
ssl_dhparam /root/certificates/dhparam.pem;
# TLS会话恢复
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# 重定向https
if ($ssl_protocol = '') {
rewrite ^(.*) https://$server_name$request_uri permanent;
}
# 判断有多种方式
#if ($scheme = 'http') {
# rewrite ^(.*) https://$server_name$request_uri permanent;
#}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
配置好后记得重启nginx,打开游览器访问general-mac.com
:由于自签证书没有被CA认证会被浏览器鉴定不安全的链接,点击高级进一步访问即可,或者将证书放入系统根证书中让操作系统信任
优化https:
启用了https后由于会进行SSL握手会消耗更多的CPU资源,通过启用SSL会话重用来优化:
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;
ssl_session_tickets off;
2
3
ssl_session_cache
:这个指令用于配置SSL会话缓存,它指定了缓存的名称("shared:SSL")和大小("50m")。SSL会话缓存是用来存储SSL握手过程中生成的会话密钥的,这些会话密钥可以被重用来加速后续的SSL握手过程。通过启用SSL会话缓存,可以减少SSL握手的时间和CPU负载,从而提高服务器的性能ssl_session_timeout
:这个指令用于配置SSL会话缓存的超时时间,它指定了会话缓存的有效期为1个小时。一旦会话缓存过期,会话密钥将被删除,下一次SSL握手将会重新生成一个新的会话密钥。通过使用合适的会话超时时间,可以平衡服务器的安全性和性能
配置HTTP2/3
要在nginx中启用HTTP/2需要在nginx版本1.9.5或更高版本中启用,只支持在加密通道上运行,因此只能在HTTPS上使用,在以上的基础上添加http2
server {
listen 443 ssl http2;
location / {
# HTTP2 server push功能
http2_push /style.css;
}
}
2
3
4
5
6
7
8
打开浏览器访问:如果你没有看到h2,需要勾选显示protocol一栏 HTTP/2使用多路复用技术,可以在单个TCP连接上同时发送多个请求和响应。这样可以减少延迟和提高并发性,从而加快页面加载速度;HTTP/2使用二进制协议,可以减少网络流量和解析时间,从而提高了网络性能和效率
虽然HTTP2使用多路复用技术减少连接时间,由于其存在队头阻塞
的问题,当一个请求或响应被阻塞时,后续请求或响应也会被阻塞,从而导致整个连接的性能下降,因此它仍不是完美的协议也是存在一些缺点
什么是队头阻塞
在HTTP/2中,多个请求和响应可以通过单个TCP连接并行传输。但是,由于HTTP/2使用了帧的概念来分割请求和响应,而帧必须按顺序发送和接收,因此如果前面的请求或响应被阻塞,后续的请求或响应也必须等待前面的请求或响应完成后才能发送或接收。这就是队头阻塞的问题。
那如何解决队头阻塞问题呢?可以使用多域名请求提高并发度、优化请求队列(性能好的放前面之类)、采用HTTP3
这里来讲QUIC协议(HTTP3),一种基于UDP协议的传输层协议,其优势如下:
- 更快的连接建立和恢复
- 更好的多路复用:使用流来分隔请求和响应,可以更好地实现多路复用,并且不需要使用帧头部,从而提高了头部压缩效率。此外,QUIC还支持优先级,可以更好地控制请求和响应的优先级
- 更好的拥塞控制:QUIC采用基于TCP的拥塞控制算法,但可以更快地适应网络环境的变化,从而提高了网络传输的效率。同时,QUIC还支持基于连接的流量控制,可以更好地适应不同的应用需求
- QUIC使用TLS 1.3来保护数据的安全性和隐私性,并且支持0-RTT、1—RTT握手,可以更快地建立安全连接。此外,QUIC还支持源地址验证和连接迁移等功能,可以更好地防止网络攻击和提高网络的可靠性
如何使用?可以安装nginx-quic使用其功能,这里就不介绍如何安装了,可以参考nginx-quic官方配置或quiche配置nginx
server {
listen 443 ssl http2; #TCP
listen 443 http3 quic reuseport; # QUIC
ssl_protocols TLSv1.3;
# 开启 TLS 1.3 0-RTT
ssl_early_data on;
add_header Alt-Svc 'h3-29=":8443"; ma=2592000,h3-T051=":8443"; ma=2592000,h3-Q050=":8443"; ma=2592000,h3-Q046=":8443"; ma=2592000,h3-Q043=":8443"; ma=2592000,quic=":8443"; ma=2592000; v="46,43"';
}
2
3
4
5
6
7
8
9
参考文档:
- nginx-quic官方配置
- nginx-quic-repository
- Binary Packages to Preview Nginx HTTP3/QUIC Implementation
- quiche配置nginx
keepalived实现高可用
由于流量都是通过nginx入口分发给应用服务,nginx很难保持永久正常服务状态,当nginx挂了时就会导致所有应用都无法访问,因此使用多个机器进行备份待用实现高可用是必然的
keepalived是一款常用于搭建高可用性服务的软件,可以与nginx等应用程序一起使用,以确保在一个节点故障时,服务能够在另一个节点上继续运行,从而提高应用程序的可用性和稳定性。keepalived需要绑定和主机同一网段的一个或多个虚拟ip,根据检测机制将虚拟ip绑定到指定的机器上,当机器宕机时,又会绑定到另一个健康的机器上。使用keepalived实现高可用至少需要2台主机,这里准备两台虚拟机。
每个节点都安装keepalived和nginx
shyum install keepalived nginx -y
1查看节点网卡,这里显示我有两张网卡ens160和ens256,这里使用ens256网卡地址,两个节点的ip分别为
192.168.10.9
和192.168.10.8
sh# 节点1 ➜ keepalived ip a 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether xx:xx:xx:xx:76:b0 brd ff:ff:ff:ff:ff:ff inet 192.168.3.92/24 brd 192.168.3.255 scope global noprefixroute dynamic ens160 valid_lft 79657sec preferred_lft 79657sec 3: ens256: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether xx:xx:xx:xx:72:86 brd ff:ff:ff:ff:ff:ff inet 192.168.10.9/24 brd 192.168.10.255 scope global noprefixroute ens256 valid_lft forever preferred_lft forever # 节点2 ➜ keepalived ip a # ... 192.168.10.8/24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15配置keepalived,
vim /etc/keepalived/keepalived.conf
:默认的配置文件应该有很多,只需要以下配置即可,其他可以直接删除掉注意每个节点都需要配置以下内容,不同的节点请注意配置文件中的提示进行修改
nginx# /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id LVS_DEVEL #vrrp_strict vrrp_skip_check_adv_addr vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_script chk_http_ port { # 检测nginx健康状态脚本,根据下一步骤创建 script "/etc/keepalived/nginx_check.sh" interval 2 weight 2 } vrrp_instance VI_1 { # 指定keepalived的角色,MASTER为主,BACKUP为备,当前节点设置为MASTER,其余节点设置为BACKUP state MASTER # 指定网卡,根据自己节点网卡的名称 替换ens256 interface ens256 # vrrp实例id,所有节点的值必须一致 virtual_router_id 51 # 数值越大,优先级越大,获取处理请求的优先级越高,根据节点的性能自行调整 priority 100 # 检测节点状态的心跳间隔 advert_int 1 # 节点间通信类型和密码 authentication { auth_type PASS # 密码类型 auth_pass 1111 # 密码 } # 虚拟ip,根据当前节点的ip网段设置 virtual_ipaddress { # 设置其中一个虚拟ip为 192.168.10.5 网卡 ens256 打标签 ens256:vip51 192.168.10.5/24 dev ens256 label ens256:vip51 } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40配置检测nginx状态脚本,同样每个节点都需要,
vim /etc/keepalived/nginx_check.sh
:bash#! /bin/bash # 查看nginx的进程数 A=`ps -C nginx --no-heading | wc -l` # 进程数位0时,启动nginx if [ $A -eq 0 ];then /usr/sbin/nginx sleep 2 # 两秒后nginx进程还是0则杀死keepalived,进行VIP的转移,将会飘到另一节点上 if [ `ps -C nginx --no-heading | wc -l` -eq 0 ];then killall keepalived fi fi
1
2
3
4
5
6
7
8
9
10
11
12
13所有节点添加
keepalived_script
用户并赋予执行脚本权限:sh➜ useradd keepalived_script ➜ visudo # 添加以下内容 keepalived_script ALL=(ALL) NOPASSWD: ALL
1
2
3所有节点启动nginx和keepalived,请确保nginx可以正常访问:为了方便演示,可以将不同节点的nginx首页设置成不同的
sh# 启动nginx,或 systemctl start nginx,安装包的在bin文件下执行 ➜ nginx # 启动keepalived ➜ systemctl start keepalived # 查看keepalive状态 ➜ systemctl status keepalived -l keepalived.service - LVS and VRRP High Availability Monitor Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled) Active: active (running) since 六 2020-04-08 18:08:52 CST; 18min ago Process: 5171 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS) Main PID: 5172 (keepalived) CGroup: /system.slice/keepalived.service ├─5172 /usr/sbin/keepalived -D ├─5173 /usr/sbin/keepalived -D └─5174 /usr/sbin/keepalived -D 4月 08 18:08:54 general-mac Keepalived_vrrp[5174]: Sending gratuitous ARP on ens256 for 192.168.10.5 4月 08 18:08:54 general-mac Keepalived_vrrp[5174]: Sending gratuitous ARP on ens256 for 192.168.10.5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19在主节点上查看ip:可以看到当前主节点的ens256网卡上会绑定一个VIP(192.168.10.5),就是keepalived设置的虚拟ip
192.168.10.5
,查看其他机器是没有当前VIP的sh➜ ip a #省略其他... 3: ens256: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether xx:xx:xx:xx:72:86 brd ff:ff:ff:ff:ff:ff inet 192.168.10.9/24 brd 192.168.10.255 scope global noprefixroute ens256 valid_lft forever preferred_lft forever inet 192.168.10.5/24 scope global secondary ens256:vip51 valid_lft forever preferred_lft forever
1
2
3
4
5
6
7
8浏览器访问VIP地址
192.168.10.5
当所有节点都没有问题时keepalived会将访问导向
priority
优先级最高的节点上,上面主节点优先级最高,所以会返回主节点上的nginx首页(包含k8s图片)这里停用主节点上的keepalived来演示宕机的情况,宕机后VIP会从当前节点剔除并根据优先级绑定到另一节点,这样再次访问时就会访问到另一节点的nginx上,而当宕机恢复后keepalived又会根据优先级回到原来的节点上,感兴趣可以试试
sh# 主节点上停止 ➜ systemctl stop keepalived # 主节点上查看ip,网卡上没了VIP ➜ ip a # 另一节点上查看,会发现绑定了VIP,再次刷新浏览器发现网页变了 ➜ ip a
1
2
3
4
5
6
7
内置变量
以下是一些常用的内置变量,对于配置是有很大帮助的
$arg_PARAMETER #GET 请求中变量名 PARAMETER 参数的值
$args #这个变量等于 GET 请求中的参数,例如,foo=123&bar=blahblah;这个变量可以被修改
$binary_remote_addr #二进制码形式的客户端地址
$body_bytes_sent #传送页面的字节数
$content_length #请求头中的 Content-length 字段
$content_type #请求头中的 Content-Type 字段
$cookie_COOKIE #cookie COOKIE 的值
$document_root #当前请求在 root 指令中指定的值
$document_uri #与 $uri 相同
$host #请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的 server 名称(处理请求的 server 的 server_name 指令的值)。值为小写,不包含端口
$hostname #机器名使用 gethostname 系统调用的值
$http_HEADER #HTTP 请求头中的内容,HEADER 为 HTTP 请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent 的值)
$sent_http_HEADER #HTTP 响应头中的内容,HEADER 为 HTTP 响应中的内容转为小写,-变为_(破折号变为下划线),例如:sent_http_content_type…
$is_args #如果 $args 设置,值为"?",否则为""
$limit_rate #这个变量可以限制连接速率
$nginx_version #当前运行的 nginx 版本号
$query_string #与 $args 相同
$remote_addr #客户端的IP地址
$remote_port #客户端的端口
$remote_port #已经经过 Auth Basic Module 验证的用户名
$request_filename #当前连接请求的文件路径,由 root 或 alias 指令与 URI 请求生成
$request_body #这个变量(0.7.58+)包含请求的主要信息。在使用 proxy_pass 或 fastcgi_pass 指令的 location 中比较有意义
$request_body_file #客户端请求主体信息的临时文件名
$request_completion #如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空
$request_method #这个变量是客户端请求的动作,通常为 GET 或 POST。包括 0.8.20 及之前的版本中,这个变量总为 main request 中的动作,如果当前请求是一个子请求,并不使用这个当前请求的动作
$request_uri #这个变量等于包含一些客户端请求参数的原始 URI,它无法修改,请查看 $uri 更改或重写 URI
$scheme #所用的协议,例如 http 或者是 https,例如 rewrite ^(.+)$$scheme://example.com$1 redirect
$server_addr #服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数
$server_name #服务器名称
$server_port #请求到达服务器的端口号
$server_protocol #请求使用的协议,通常是 HTTP/1.0、HTTP/1.1或HTTP/2
$uri #请求中的当前 URI(不带请求参数,参数位于 args ) , 不 同 于 浏 览 器 传 递 的 args),不同于浏览器传递的 args),不同于浏览器传递的 request_uri 的值,它可以通过内部重定向,或者使用 index 指令进行修改。不包括协议和主机名,例如 /foo/bar.html
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
如何打印一些变量?
- 通过log 指令,通过 $variable 语法打印变量
# http上下文
log_format main3 '$uri'; # 定义日志格式
access_log /opt/var/log/nginx/access.log main3; # 定义日志的路径
2
3
4
- 可以不用log,通过将变量返回给客户端,就可以查看了
location / {
return 200 $uri; # 直接返回出去
# 或
add_header X-uri $uri; # 通过header返回
# 以及其他方法均可...
}
2
3
4
5
6