Nginx详细使用
Nginx详细使用
文章目录
- Nginx详细使用
- 简介
- 概述
- 指令索引
- 进程
- 常用的命令 & 配置文件
- 启动命令
- 关闭命令
- 检查nginx配置
- 重新加载命令
- 配置文件
- 配置说明
- 参数解释(优先在这里找想要的参数)
- location 指令说明
- location前缀
- location匹配顺序
- alias与root
- rewrite
- if使用
- $内置变量
- log_format
- 动静分离
- 反向代理配置
- 代理协议(proxy)
- 反向代理一
- 反向代理二
- 负载均衡配置:upstream
- HTTP负载均衡
- 轮训
- 权重(weight)
- ip_hash
- fair(第三方)
- TCP/UDP负载均衡
- 健康检查
- HTTP健康检查
- 被动健康检测
- 服务器慢启动
- 主动健康检查
- 重写HTTP响应
- 高可用集群
- 准备工作
- 安装 keepalived
- 高可用配置(主从配置)
- 第一步
- 第二步
- 第三步
- 第四步
简介
概述
Nginx 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好
指令索引
https://nginx.org/en/docs/dirindex.html
进程
NGINX 有一个主进程和一个或多个工作进程。如果启用缓存,缓存加载器和缓存管理器进程也会在启动时运行
-
主进程的主要目的是读取和评估配置文件,以及维护工作进程
-
工作进程实际处理请求。 NGINX 依靠依赖于操作系统的机制在工作进程之间有效地分配请求。工作进程的数量由 nginx.conf 配置文件中的worker_processes指令定义,可以设置为固定数量,也可以配置为自动调整为可用CPU核心的数量
> ps -ef | grep nginx | grep -v grep sa_clus+ 10631 1 0 2023 ? 00:00:01 nginx: master process ./sbin/nginx sa_clus+ 28523 10631 0 Mar08 ? 00:00:59 nginx: worker process sa_clus+ 28524 10631 0 Mar08 ? 00:00:57 nginx: worker process sa_clus+ 28525 10631 0 Mar08 ? 00:00:57 nginx: worker process sa_clus+ 28526 10631 0 Mar08 ? 00:00:58 nginx: worker process sa_clus+ 28528 10631 0 Mar08 ? 00:00:10 nginx: cache manager process
常用的命令 & 配置文件
启动命令
- sbin/nginx
关闭命令
- 正常关闭:sbin/nginx -s quit
- 立即关闭:sbin/nginx -s stop
检查nginx配置
- sbin/nginx -t
重新加载命令
- sbin/nginx -s reload
配置文件
- nginx.conf
- 路径:nginx/conf/nginx.conf
配置说明
参数解释(优先在这里找想要的参数)
# 运行 Nginx 服务的用户和组
user nobody;
# Nginx的worker工作进程的数量,设置worker数量为1,如果使用 auto 则数量为cpu的核数
worker_processes 1;
# 错误日志文件的路径和名称
error_log logs/error.log;
# 存储 Nginx 主进程标识符(PID)的文件路径
pid logs/nginx.pid;# 一般连接处理
events {# 每个 worker process 能够同时打开的最大连接数worker_connections 1024;# 控制 Nginx 处理新连接请求时的互斥锁设置。当设置为 on(默认值,开启),防止多个 worker processes 同时接受同一个 socket 上的连接accept_mutex on;
}# HTTP 流量
http {# 包含 mime.types 文件,这个文件通常定义了文件扩展名到 MIME 类型的映射。这有助于 Nginx 正确地设置 Content-Type 响应头include mime.types;# 设置了默认的 MIME 类型,当请求的文件类型在 mime.types 文件中没有找到匹配项时,Nginx 会使用这个默认类型default_type application/octet-stream;# 允许自定义请求头名中的下划线underscores_in_headers on;# 包含(加载)指定的文件或目录中的配置include ../conf.d/web.conf;# 启用了 sendfile 技术(数据零拷贝),这是一种高效的文件传输方式,允许操作系统直接将文件内容从磁盘传输到网络,减少了 CPU 的使用和内存的复制开销sendfile on;# 启用了 TCP_NOPUSH 选项,它告诉 Nginx 在发送数据时避免不必要的网络包合并,这可以减少延迟,提高响应速度tcp_nopush on;# 持久连接(Keep-Alive)的超时时间。如果 65 秒内没有新的请求通过同一个连接发送,Nginx 将关闭连接keepalive_timeout 65;# 启用了 Gzip 压缩,这可以减少发送到客户端的数据量,加快页面加载速度gzip on;# 启用gzip压缩并定义哪些类型的MIME类型(或文件类型)将被压缩gzip_types text/plain text/css application/json application/javascript application/octet-stream;# 负载配置,如果要具体看负载均衡请移步到本文章负载均衡章节upstream server_stream {# 创建一个共享内存区域(zone),用于存储服务器的状态信息,如健康检查结果。my_backend 是这个共享内存区域的名称,而 32k 指定了区域的大小。这个区域将用于存储关于 server_stream 服务器组的信息zone server_stream 32k;# 添加一个服务器到 server_stream 服务器组server backend1.example.com:12345;server backend2.example.com:12345;server backend3.example.com:12346;}# HTTP serverserver {# 监听 80 端口listen 80;# 定义服务器的主机名server_name localhost;# 处理对根目录(/)的请求location / {# 指定了资源的根目录,在这个例子中,Nginx 会在 html 目录下查找文件root html;# 定义了目录索引文件的顺序,Nginx 会按照这个顺序查找文件,直到找到一个存在的文件index index.html index.htm;}# 404 错误页面的路径error_page 404 /404.html;# 将服务器错误页重定向到静态页 /50x.htmlerror_page 500 502 503 504 /50x.html;# 这个 location 块专门处理对 /50x.html 文件的请求,root html; 指定了这个文件的根目录location = /50x.html {root html;}# 这个 location 块处理所有以 .php 结尾的请求location ~ \.php$ {# 设置 header 中 Host,$http_host(host:ip),$host:(只有host,没有ip)proxy_set_header Host $http_host;# 反向代理,将这些请求代理到别的服务器上,服务器监听在 127.0.0.1(localhost)的 80 端口上proxy_pass http://127.0.0.1;# 修改代理服务器返回的重定向头。在这个例子中,它将 Location 头中包含的 http://localhost:8104 替换为 http://$host:$server_portproxy_redirect http://localhost:8104 http://$host:$server_port;}# 前缀匹配location ^~ /modules/etltool/static {# 设置了响应的过期时间,即客户端缓存的内容将在10年内不过期expires 10y;# 关闭了对匹配这个location的请求的访问日志记录access_log off;# 向响应头中添加了一个Cache-Control: public头部,指示任何缓存都可以存储这个响应,并可以向任何请求提供这个响应add_header Cache-Control "public";# 设置了字符集为UTF-8,这是为了确保发送给客户端的文本内容使用正确的字符编码charset UTF-8;# 重写请求的URI,【括号'()'里面的为变量,例如 (.*) 里面的 .* 的内容为后面的 $1,有多个括号 () 则里面依次为 $1 $2 $3 ...】rewrite ^/modules/etltool/static/(.*)$ /static/$1 break;# 指定了用于查找重写后URI的根目录root /sensorsdata/main/dingkai/program/dk_sctk/data_etl_web/build;}server {listen 8106;# 打开文件缓存,并设置了最大缓存数量为8。这可以提高对日志文件的写入性能open_log_file_cache max=8;# 定义一个名为 main 的日志格式log_format main '$clientRealIp - $remote_user [$time_local] $http_x_request_id "$request" $request_time $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$sa_username" "$request_body" "$upstream_addr"';log_format sa_extractor '"$proxy_add_x_forwarded_for" ++_ "$msec" ++_ "$request_method" ++_ "$arg_gzip" ++_ "$arg_data" ++_ "$arg_data_list" ++_ "$request_body" ++_ "$http_user_agent" ++_ "$arg_project" ++_ "$http_cookie" ++_ "$arg_token" ++_ "$arg_ext"';# 打印日志,日志的存储位置和使用的日志格式access_log logs/access.log main;# 客户端请求体的最大允许大小为8MB。如果请求体超过了这个大小,Nginx将拒绝该请求client_max_body_size 8m;# 用于存储请求体的缓冲区大小为8MBclient_body_buffer_size 8m;# Nginx将整个请求体存储在一个单一的缓冲区中,而不是多个缓冲区client_body_in_single_buffer on;# 大型客户端请求头的缓冲区数量和大小。这里配置了4个20KB的缓冲区large_client_header_buffers 4 20k;location /sa.gif {# 添加了一个CORS(跨源资源共享)头,允许任何域访问这个APIadd_header 'Access-Control-Allow-Origin' '*';# 添加了Cache-Control头,指示客户端和中间缓存不缓存这个请求的响应add_header Cache-Control 'no-cache, no-store, must-revalidate';# 添加了Pragma头,与Cache-Control头一起工作,确保响应不被缓存add_header Pragma 'no-cache';# 设置了Expires头,使响应的过期时间非常早,从而避免缓存add_header Expires 'Mon, 28 Sep 1970 05:00:00 GMT';# 打印日志,日志的存储位置和使用的日志格式($year$month$day$hour:年月日时)access_log logs/access_log.$year$month$day$hour sa_extractor;echo_read_request_body}location /sa {add_header Cache-Control 'no-cache, no-store, must-revalidate';access_log /sensorsdata/stdata/nginx/access_log.$year$month$day$hour sa_extractor;echo_read_request_body}}}# HTTPS serverserver {# 监听 443 端口,并启用 SSL(ssl 关键字是可选的,用于明确指定该监听器将使用 SSL)listen 443 ssl;server_name localhost;# 指定了 SSL 证书文件的路径ssl_certificate cert.pem;# 指定了 SSL 证书的私钥文件的路径ssl_certificate_key cert.key;# 定义 SSL 会话缓存的大小和有效期。在这个例子中,它使用了一个共享的缓存区,大小为 1MBssl_session_cache shared:SSL:1m;# 设置了 SSL 会话的超时时间。在这个例子中,会话在 5 分钟内有效ssl_session_timeout 5m;# 指定 SSL/TLS 连接允许使用的密码套件列表。在这个例子中,它被设置为只使用高强度的密码套件,并且排除了匿名(aNULL)和 MD5 相关的密码套件ssl_ciphers HIGH:!aNULL:!MD5;# 与客户端协商密码套件时优先使用服务器指定的密码套件,而不是客户端提议的密码套件ssl_prefer_server_ciphers on;location / {root html;index index.html index.htm;}}
}# TCP/UDP 流量
stream {# 负载配置upstream stream_backend {server backend1.example.com:12345;server backend2.example.com:12345;server backend3.example.com:12346;}# 负载配置upstream dns_servers {server 192.168.136.130:53;server 192.168.136.131:53;}# TCP serverserver {# 监听端口listen 12345;# 反向代理proxy_pass stream_backend;}# UDP serverserver {# 监听端口listen 53 udp;# 反向代理proxy_pass dns_servers;}
}
location 指令说明
location前缀
-
语法
location [ = | ~ | ~ | ^~] uri* {
…
}
- / :通用匹配,任何请求都会匹配到
- = :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
- ~:用于表示 uri 包含正则表达式,并且区分大小写。
- ~*:用于表示 uri 包含正则表达式,并且不区分大小写。
- ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。
-
注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~ 标识。*
location匹配顺序
- 多个正则location直接按书写顺序匹配,成功后就不会继续往后面匹配
- 普通(非正则)location会一直往下,直到找到匹配度最高的(最大前缀匹配)
- 当普通location与正则location同时存在,如果正则匹配成功,则不会再执行普通匹配
- 所有类型location存在时,“=”匹配 > “^~”匹配 > 正则匹配 > 普通(最大前缀匹配)
alias与root
root用来设置根目录,而alias在接受请求的时候在路径上不会加上location
- alias 指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的
- root 指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的
- 使用 alias 标签的目录块中不能使用 rewrite 的 break
- alias 虚拟目录配置中,location匹配的path目录如果后面不带"/“,那么访问的url地址中这个path目录后面加不加”/“不影响访问,访问时它会自动加上”/“; 但是如果location匹配的path目录后面加上”/“,那么访问的url地址中这个path目录必须要加上”/“,访问时它不会自动加上”/“。如果不加上”/",访问就会失败!
- root 目录配置中,location匹配的path目录后面带不带"/",都不会影响访问
rewrite
rewrite 是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。
参数说明
rewrite <regex> <replacement> [flag];
rewrite:关键字,不能改变
<regex>:正则,perl兼容正则表达式语句进行规则匹配
<replacement>:替代内容,将正则匹配的内容替换成replacement
[flag]:flag标记,rewrite支持的flag标记last:本条规则匹配完成后,继续向下匹配新的location URI规则break:本条规则匹配完成即终止,不再匹配后面的任何规则redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址# 样例:将 /modules/etltool/static/ 重定向到 /static/,【括号'()'里面的为变量,例如 (.*) 里面的 .* 的内容为后面的 $1,有多个括号 () 则里面依次为 $1 $2 $3 ...】
rewrite ^/modules/etltool/static/(.*)$ /static/$1 break;
if使用
正则表达式匹配:
- =,!= :等值比较;
- ~ :与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写;
- !~ :与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写;
- ~* :与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写;
- !~* :与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写;
文件及目录匹配判断:
- -f, !-f :判断指定的路径是否为存在且为文件;
- -d, !-d :判断指定的路径是否为存在且为目录;
- -e, !-e :判断指定的路径是否存在,文件或目录均可;
- -x, !-x :判断指定路径的文件是否存在且可执行
location ~ ^/config {# 等值if ($arg_app_id = "123") {...}# 正则匹配 区分大小写(根据查询字符串中 project 参数值为 default)if ( $query_string ~ "project=(default)" ){...}# 正则不匹配 区分大小写(根据查询字符串中 project 参数值不为 default)if ( $query_string !~ "project=(default)" ){...}# 路径判断if (!-d "$request_filename/sdk_config") {...}# 文件判断if ( -f "$request_filename/$sdk_config_path/$1_${arg_v}_nv$arg_nv" ) {...}
}
$内置变量
参数 | 说明 |
---|---|
$arg_app_id | 获取 URL 查询字符串中名为 app_id 的参数的值 |
$arg_data | 记录请求参数中名为data的值; |
$arg_data_list | 记录请求参数中名为data_list的值; |
$arg_ext | 记录请求参数中名为ext的值。 |
$arg_gzip | 记录请求参数中名为gzip的值; |
$arg_name | 请求中的的参数名,即“?”后面的arg_name=arg_value形式的arg_name |
$arg_project | 记录请求参数中名为project的值; |
$arg_token | 记录请求参数中名为token的值; |
$args | 请求中的参数值 |
$body_bytes_sent | 已发送的响应主体的字节数。 |
$clientRealIp | 客户端真实的IP地址。 |
$http_cookie | 记录请求头中的cookie信息; |
$http_referer | 来源页,即链接到当前页面的前一页面的URL。 |
$http_user_agent | 记录用户的浏览器信息; |
$http_x_forwarded_for | 客户端的IP地址,当你的服务在一个反向代理服务器后面时,用这个变量可以获取到原始客户的IP地址 |
$http_x_request_id | 请求ID,通常用于追踪请求路径。 |
$http_host | 完整的请求头中的Host字段,包括端口号 |
$host | 完整的请求头中的Host字段,不包括端口号 |
$msec | 当前的时间戳; |
$proxy_protocol_addr | 原始客户端的 IP地址 |
$proxy_protocol_port | 原始客户端的 端口 |
$proxy_host | 目标地址的主机名或 IP 地址(不包括端口) |
$query_string | 请求的查询字符串(如果 URL 包含查询参数,如 http://xxx?param=value,那么 $query_string 的值将是 param=value) |
$remote_addr | 负载均衡器的 IP 地址 |
$remote_port | 负载均衡器的 端口 |
$proxy_add_x_forwarded_for | 记录代理添加的X-Forwarded-For的头信息,用于获取客户端的原始IP地址; |
$remote_user | 用于认证的用户名,如果没有认证则为空 |
$request | 整个请求行,包括请求方法,请求URI和HTTP协议版本。 |
$request_body | 记录请求的body内容(POST或PUT请求数据); |
$request_filename | 包含请求的文件名,不包括查询字符串。(在 http://xxx/file.txt 请求中,$request_filename 的值将是 file.txt) |
$request_method | 记录请求的方法,如GET或POST; |
$request_time | 处理一个请求所需的时间,单位为秒,精确到毫秒。 |
$sa_username | 这应该是特定于您的应用程序的某种用户身份标识符。 |
$status | 响应的状态码。 |
$time_local | 在本地时间格式下的当前时间, |
$upstream_addr | 后端服务器的地址。 |
log_format
log_format main '$clientRealIp - $remote_user [$time_local] $http_x_request_id "$request" $request_time $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$sa_username" "$request_body" "$upstream_addr"';$clientRealIp: 客户端真实IP地址
$remote_user: 用于认证的用户名,如果没有认证则为空
$time_local: 在本地时间格式下的当前时间,
$http_x_request_id: 经过处理的请求头中的x-request-id
$request: 用户的原始请求行
$request_time: 请求处理的总时间, 以秒为单位,精确到毫秒
$status: HTTP响应状态码
$body_bytes_sent: HTTP响应内容的长度
$http_referer: 引向当前请求的链接的地址
$http_user_agent: 客户端代理信息
$http_x_forwarded_for: 客户端的IP地址,当你的服务在一个反向代理服务器后面时,用这个变量可以获取到原始客户的IP地址
$sa_username: 没有明确的含义,可能是自定义的变量
$request_body: 对应请求的消息体
$upstream_addr: 后端服务的地址
log_format main_without_request_body '$clientRealIp - $remote_user [$time_local] $http_x_request_id "$request" $request_time $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$sa_username" "$upstream_addr"';$clientRealIp:客户端真实的IP地址。
$remote_user:远程用户的名称。
$time_local:本地时间。
$http_x_request_id:请求ID,通常用于追踪请求路径。
$request:整个请求行,包括请求方法,请求URI和HTTP协议版本。
$request_time:处理一个请求所需的时间,单位为秒,精确到毫秒。
$status:响应的状态码。
$body_bytes_sent:已发送的响应主体的字节数。
$http_referer:来源页,即链接到当前页面的前一页面的URL。
$http_user_agent:用户代理,即发起请求的浏览器或其他客户端的类型和版本信息。
$http_x_forwarded_for:代理服务器通过此字段通知服务器客户端的真实IP。
$sa_username:这应该是特定于您的应用程序的某种用户身份标识符。
$upstream_addr:后端服务器的地址。
log_format sa_extractor '"$proxy_add_x_forwarded_for" ++_ "$msec" ++_ "$request_method" ++_ "$arg_gzip" ++_ "$arg_data" ++_ "$arg_data_list" ++_ "$request_body" ++_ "$http_user_agent" ++_ "$arg_project" ++_ "$http_cookie" ++_ "$arg_token" ++_ "$arg_ext"';$proxy_add_x_forwarded_for:记录代理添加的X-Forwarded-For的头信息,用于获取客户端的原始IP地址;
$msec:当前的时间戳;
$request_method:记录请求的方法,如GET或POST;
$arg_gzip:记录请求参数中名为gzip的值;
$arg_data:记录请求参数中名为data的值;
$arg_data_list:记录请求参数中名为data_list的值;
$request_body:记录请求的body内容(POST或PUT请求数据);
$http_user_agent:记录用户的浏览器信息;
$arg_project:记录请求参数中名为project的值;
$http_cookie:记录请求头中的cookie信息;
$arg_token:记录请求参数中名为token的值;
$arg_ext:记录请求参数中名为ext的值。
动静分离
- Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。
- 动静分离从目前实现角度来讲大致分为两种
- 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
- 另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。
配置 nginx.conf 文件
server {listen 80;server_name 192.168.37.130;#访问**192.168.37.130/www/** ,将访问路径 **/fzk/www** 中的静态资源location /www/ {root /fzk/;index index.html index.htm;}#访问**192.168.37.130/images/** ,将访问路径 **/fzk/images** 中的静态资源location /images/ {root /fzk/;#列出静态资源 autoindex on;}
反向代理配置
代理协议(proxy)
PROXY 协议使 NGINX 能够接收通过代理服务器和负载均衡器传递的客户端连接信息(通俗来讲PROXY协议可以将 上游请求的信息负载转发到下游)
参数 | 说明 | |
---|---|---|
$proxy_protocol_addr | 原始客户端的 IP地址 | |
$proxy_protocol_port | 原始客户端的 端口 | |
$remote_addr | 负载均衡器的 IP 地址 | |
$remote_port | 负载均衡器的 端口 | |
$realip_remote_addr | 保留负载均衡器的地址 | |
$realip_remote_port | 保留负载均衡器的端口 |
location ^~ /me/api/ {proxy_pass http://me_backend;proxy_set_header Host $proxy_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;
}
反向代理一
实现效果
- 使用 nginx 反向代理,访问 nginx的ip 直接跳转到 127.0.0.1:8080 页面内容
配置 nginx.conf 文件
-
监听 80 端口,访问 192.168.37.130,不加端口号时默认为 80 端口,访问时会跳转到 127.0.0.1:8080 路径上
-
修改 server_name
-
在 location 中添加 proxy_pass
server {listen 80;server_name 192.168.37.130;location / {proxy_pass http://127.0.0.1:8080;proxy_read_timeout 1800s;proxy_set_header X-Real-IP $clientRealIp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host:$proxy_port;}
-
反向代理二
实现效果
- 使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中 nginx 监听端口为 9001
- 访问 http://127.0.0.1:9001/edu/ 直接跳转到 127.0.0.1:8081
- 访问 http://127.0.0.1:9001/vod/ 直接跳转到 127.0.0.1:8082
配置 nginx.conf 文件
server {listen 9001;server_name 192.168.37.130;location ~ /edu/ {proxy_pass http://127.0.0.1:8081;}location ~ /vod/ {proxy_pass http://127.0.0.1:8082;}
负载均衡配置:upstream
HTTP负载均衡
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
- 轮训(默认)
- 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除
- 权重(weight)
- weight 代表权重,默认为 1,权重越高被分配的客户端越多
- 指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况
- ip_hash
- 每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题
- fair(第三方)
- 按后端服务器的响应时间来分配请求,响应时间短的优先分配
轮训
实现效果
- 访问 Nginx 实现 http://127.0.0.1:8081,http://127.0.0.1:8082 两个地址轮训访问
配置 nginx.conf 文件
-
添加 upstream
- upstream myserver
- myserver :分配方法的 ip 和 端口号
- upstream myserver
-
添加 proxy_pass
upstream myserver{server 127.0.0.1:8081;server 127.0.0.1:8082; }server{listen 80;server_name 192.168.37.130;location / {proxy_pass http://myserver;}
权重(weight)
实现效果
- 访问 Nginx 实现 http://127.0.0.1:8081,http://127.0.0.1:8082 两个地址按权重访问
配置 nginx.conf 文件
- weight:默认为1
- n:权重值(越大,负载的权重就越大)
- down:表示当前的server暂时不参与负载
- backup: 其它所有的非backup机器down或者忙的时候,请求backup机器
upstream myserver{server 127.0.0.1:8081 weight=5 down;server 127.0.0.1:8082 weight=2;server 127.0.0.1:8082 weight=2 backup;
}server {listen 80;server_name 192.168.37.130;location / {proxy_pass http://myserver;}
ip_hash
实现效果
- 访问 Nginx 实现 http://127.0.0.1:8081,http://127.0.0.1:8082 两个地址按ip_hash访问
配置 nginx.conf 文件
-
在 upstream 中添加 ip_hash;
upstream myserver{ip_hash;server 127.0.0.1:8081;server 127.0.0.1:8082; }server {listen 80;server_name 192.168.37.130;location / {proxy_pass http://myserver;}
fair(第三方)
实现效果
- 访问 Nginx 实现 http://127.0.0.1:8081,http://127.0.0.1:8082 两个地址**按fair(第三方)**访问
配置 nginx.conf 文件
-
在 upstream 中添加 fair;
upstream myserver{server 127.0.0.1:8081;server 127.0.0.1:8082;fair; }server {listen 80;server_name 192.168.37.130;location / {proxy_pass http://myserver;}
TCP/UDP负载均衡
同HTTP负载均衡配置
https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
健康检查
HTTP健康检查
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/
被动健康检测
在事务发生时对其进行监控,并尝试恢复失败的连接。如果事务仍然无法恢复,NGINX 会将服务器标记为不可用,并暂时停止向其发送请求,直到服务器再次标记为活动状态。
# max_fails:设置在 fail_timeout 期间必须发生的失败尝试次数,服务器才会被标记为不可用(默认为 1 次尝试)
# fail_timeout:设置必须发生多次失败尝试才能将服务器标记为不可用的时间,以及服务器标记为不可用的时间(默认值为 10 秒)
# 在以下示例中,如果 NGINX 在 30 秒内 3 次未能向服务器发送请求或未收到服务器的响应,则将服务器标记为不可用 30 秒
upstream my_upstream {server backend1.example.com;server backend2.example.com max_fails=3 fail_timeout=30s;
}
服务器慢启动
# slow_start:恢复的服务器很容易被连接淹没,这可能会导致服务器再次被标记为不可用。慢启动允许上游服务器在恢复或变得可用后逐渐将其权重从零恢复到其标准值(慢启动是 NGINX Plus 独有的)
upstream my_upstream {server backend1.example.com slow_start=30s;server backend2.example.com;server 192.0.0.1 backup;
}
主动健康检查
通过向每台服务器发送特殊的健康检查请求并验证正确的响应来定期检查上游服务器的健康状况
# health_check:主动健康检查upstream backend {zone backend 64k;server backend1.example.com;server backend2.example.com;server backend3.example.com;
}### 定义了一个服务器,它将所有请求 ( location / ) 传递到名为 backend 的上游组。它还通过 health_check 指令启用高级运行状况监控:默认情况下,NGINX Plus 每五秒向 backend 组中的每个服务器发送一个“/”请求。如果发生任何通信错误或超时(服务器响应的状态代码超出 200 到 399 范围),则运行状况检查将失败。服务器被标记为不健康,NGINX Plus 不会向其发送客户端请求,直到它再次通过健康检查
server {location / {proxy_pass http://backend;health_check;}
}### 指定另一个端口进行运行状况检查,例如,用于监控同一主机上许多服务的运行状况。使用 health_check 指令的 port 参数指定新端口
# port:端口号
server {location / {proxy_pass http://backend;health_check port=8080;}
}# interval 参数将运行状况检查之间的延迟从默认的 5 秒增加到 10 秒
# fails 参数要求服务器未通过三项运行状况检查才能被标记为不运行状况(高于默认检查)
# passes 参数意味着服务器必须通过两次连续检查才能再次标记为健康状态,而不是默认的检查
location / {proxy_pass http://backend;health_check interval=10 fails=3 passes=2;
}
重写HTTP响应
有时需要重写或更改 HTTP 响应中的内容,将一个字符串替换为另一个字符串。可以使用 sub_filter 指令来定义要应用的重写。该指令支持变量和替换链,使更复杂的更改成为可能。
# 更改引用除代理之外的服务器的绝对链接
location / {# 在响应内容中查找所有出现的 /blog/ 字符串,并将它们替换为 /blog-staging/sub_filter /blog/ /blog-staging/;# 配置了sub_filter的行为。# 设置为off时,意味着Nginx将对响应内容中的所有匹配项进行替换,而不仅仅是第一次出现的匹配项。# 设置为on(默认值),则只替换第一次出现的匹配项sub_filter_once off;
}# 将方案从 http:// 更改为 https:// ,并将 localhost 地址替换为请求标头字段中的主机名
location / {sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/';sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/';sub_filter_once on;
}
高可用集群
准备工作
- 需要两台服务器192.168.17.129和192.168.17.131(两台为自己的服务器ip),虚拟ip:192.168.55.100
- 在两台服务器安装 nginx
- 在两台服务器安装 keepalived
安装 keepalived
- 使用 yum 命令进行安装
- yum install keepalived –y
高可用配置(主从配置)
第一步
-
修改 /etc/keepalived/keepalivec.conf 配置文件
-
第一台机器
global_defs {router_id LVS_DEVEL01 }# 检测脚本,间隔两秒 vrrp_script chk_http_port {script "/usr/local/src/nginx_check.sh"interval 2weight 2 } vrrp_instance VI_1 { state MASTER # 主机 MASTER,备机 BACKUP interface ens33 # 网卡virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同 priority 90 # 主、备机取不同的优先级,主机值较大,备份机值较小 advert_int 1 authentication {auth_type PASSauth_pass 1111}# 虚拟ip地址配置virtual_ipaddress {192.168.55.100 # VRRP H 虚拟地址} }
-
第二台机器
global_defs {router_id LVS_DEVEL02 }# 检测脚本,间隔两秒 vrrp_script chk_http_port {script "/usr/local/src/nginx_check.sh"interval 2weight 2 } vrrp_instance VI_1 { state BACKUP # 主机 MASTER,备机 BACKUP interface ens33 # 网卡virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同 priority 50 # 主、备机取不同的优先级,主机值较大,备份机值较小 advert_int 1 authentication {auth_type PASSauth_pass 1111}# 虚拟ip地址配置virtual_ipaddress {192.168.55.100 # VRRP H 虚拟地址} }
-
第二步
-
在两台机器的 /usr/local/src 目录添加检测脚本 nginx_check.sh
#!/bin/bash A=`ps -C nginx –no-header |wc -l` if [ $A -eq 0 ];then/usr/local/nginx/sbin/nginxsleep 2if [ `ps -C nginx --no-header |wc -l` -eq 0 ];thenkillall keepalivedfi fi
第三步
- 把两台服务器上 nginx 和 keepalived 启动
- 启动 nginx:./nginx
- 启动 keepalived:systemctl start keepalived.service
第四步
- 测试
- 1、在浏览器地址栏输入虚拟 ip 地址 192.168.55.100,看能否访问到 Nginx 主界面
- ip为keepalivec.conf配置文件中的 virtual_ipaddress配置
- 2、把主服务器(192.168.17.129)nginx 和 keepalived 停止,再输入 192.168.17.50, 看能否访问到 Nginx 主界面
- 1、在浏览器地址栏输入虚拟 ip 地址 192.168.55.100,看能否访问到 Nginx 主界面