Skip to content

nginx配置文件信息

bash
# 查看nginx版本号
$ nginx -v
# 启动nginx
$ nginx
# 关闭nginx
$ nginx -s stop
# 重新加载
$ nginx -s reload
# 等待工作进程处理完成后关闭
$ nginx -s quit
# 测试配置文件的语法是否正确
$ nginx -t

nginx配置文件基本结构

nginx
# 全局块
worker_processes  1; # nginx处理并发的数量,值越大可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约,通常与CPU数量一致或更少即可

# events 块
# 影响nginx服务器与用户网络的连接
events {
    # 连接数worker_connection:发送一次请求,占用work的几个连接数2或4个
    
    # 支持最大并发数:
    ## 请求本地资源:worker_connections * worker_processes
    ## 支持http1.1:worker_connections * worker_processes / 2
    ## 反向代理:worker_connections * worker_processes / 4
    
    worker_connections  1024; # 每个worker_processes支持的最大连接数
}

# http 块
# 包含http全局块和server块
http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    include E:/software/nginx/conf/conf.d/*.conf;
}

## http全局块:指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时、单链接请求数上限等
## server块:与虚拟主机密切相关,每个http可以包含多个server,每个server块也分为server全局块和location块

反向代理

基础代理

nginx
server{
	listen 80;
	server_name xxx.xxx.xxx;
	location / {
		proxy_pass http://xxx.xxx.xxx.xxx:8080;
		proxy_redirect off;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_set_header HOST $host:$server_port;
		proxy_set_header Cookie $http_cookie;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

WEB SOCKET

nginx
map $http_upgrade $connection_upgrade {
	default upgrade;
	'' close;
}

server{
	listen 80;
	# WEB_SOCKET
	location /xxpt_api {
		proxy_pass http://xxx.xxx.xxx.xxx;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $connection_upgrade;
		proxy_set_header Host $host;
		proxy_read_timeout 7200s; # 超时时间,超过这个时间哪怕一直连接的websocket也会断
	}
}

负载均衡

nginx
upstream xxxxxx{
	server xxx.xxx.xxx.xxx:8000 weight=9;
	server xxx.xxx.xxx.xxx:8001 weight=9;
	server xxx.xxx.xxx.xxx:8002 weight=9;
}

server{
	listen 80;
	location / {
		proxy_pass http://xxxxxx;
		proxy_redirect off;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_set_header HOST $host:$server_port;
		proxy_set_header Cookie $http_cookie;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		client_max_body_size 100M;
		client_body_buffer_size 100M;
	}
}

负载均衡策略

轮询【默认】

不做任何配置

nginx
upstream xxxxxx{
	server xxx.xxx.xxx.xxx:8000;
	server xxx.xxx.xxx.xxx:8001;
	server xxx.xxx.xxx.xxx:8002;
}

weight权重

weight权重默认为1,权重越高被分配客户端越多。weight与访问率成正比,用于后端服务器性能不均的情况。

nginx
upstream xxxxxx{
	server xxx.xxx.xxx.xxx:8000 weight=9;
	server xxx.xxx.xxx.xxx:8001 weight=9;
	server xxx.xxx.xxx.xxx:8002 weight=9;
}

ip_hash

每个请求按IP的hash结果进行分配,也就是每个访客固定请求一台服务器,如果有session问题可以尝试使用这个解决。

nginx
upstream xxxxxx{
	ip_hash;
	server xxx.xxx.xxx.xxx:8000;
	server xxx.xxx.xxx.xxx:8001;
	server xxx.xxx.xxx.xxx:8002;
}

fair【第三方】

按后端服务器的响应时间来分配请求,响应时间短的优先分配

nginx
upstream xxxxxx{
	server xxx.xxx.xxx.xxx:8000;
	server xxx.xxx.xxx.xxx:8001;
	server xxx.xxx.xxx.xxx:8002;
    fair;
}

down

表示当前的server暂时不参与负载

backup

其它所有的非backup机器down或者忙的时候,请求backup机器

动静分离

可以将动态资源和静态资源分开部署,通过nginx进行代理;也可以将动态和静态的资源放在一起,通过location进行不同后缀的代理;

expires:设置浏览器缓存的过期时间,减少与服务器之间的请求和流量。它是给资源设定一个过期时间,在这个时间内无需去服务端验证是否更新,这种方式适合不经常变动的资源。在过期时间内访问URL,发送一个请求,对比服务该文件最后更新时间没有变化,则不会从服务端获取资源,而返回304,如果有修改,则直接从服务器重新下载,返回200。

高可用集群

需要:NginxKeepalived

主从配置

修改/etc/keepalived/keepalivec.conf 配置文件

nginx
global_defs {
	 notification_email {
		 acassen@firewall.loc
		 failover@firewall.loc
		 sysadmin@firewall.loc
	 }
	 notification_email_from Alexandre.Cassen@firewall.loc
	 smtp_server 192.168.17.129 # 当前主机IP
	 smtp_connect_timeout 30
	 # 通过它,可以访问到主机,在hosts文件中,要做映射关系,类似于 127.0.0.1 LVS_DEVEL
	 router_id LVS_DEVEL  
}

vrrp_script chk_http_port {
	 script "/usr/local/src/nginx_check.sh"	 # 执行脚本所在的位置
	 interval 2 	         # 检测脚本执行的间隔,单位秒,每个2秒执行一次脚本
	 weight 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 PASS
		 auth_pass 1111
 	}
	 virtual_ipaddress {
	 	192.168.17.50 	     # VRRP H 虚拟地址
	 }
}

在/usr/local/src 添加检测脚本,检查Nginx是否还活着

bash
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
    /usr/local/nginx/sbin/nginx 	#Nginx启动命令的位置
    sleep 2
    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
        killall keepalived
    fi
fi

把两台服务器上 nginx 和 keepalived 启动

bash
systemctl start nginx
systemctl start keepalived

常用配置

禁止文件缓存

开发环境经常改动代码,由于浏览器缓存需要强制刷新才能看到效果。这是我们可以禁止浏览器缓存提高效率

nginx
location ~* \.(js|css|png|jpg|gif)$ {
    add_header Cache-Control no-store;
}

防盗链

nginx
location ~* \.(gif|jpg|png)$ {
    # 只允许 192.168.0.1 请求资源
    valid_referers none blocked 192.168.0.1;
    if ($invalid_referer) {
       rewrite ^/ http://$host/logo.png;
    }
}

UrlRewrite路径重写

nginx
rewrite	<regex>	 <replacement>	 [flag];
关键字 	正则 		替代内容 	   flag标记

关键字:不能改变 正则:perl兼容正则表达式语句进行规则匹配 替代内容:将正则匹配的内容替换成replacement flag标记:rewrite支持的flag标记

  • last:本条规则匹配完成后,继续向下匹配新的location URI规则
  • break:本条规则匹配完成即终止,不再匹配后面的任何规则
  • redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
  • permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

rewrite参数的标签段位置:server,location,if

用户认证

生成认证文件

bash
# printf "用户名:$(openssl passwd -crypt 密码)\n" >> htpasswd
# 如
printf "test:$(openssl passwd -crypt 123456)\n" >> htpasswd
cat /home/htpasswd 
test:xyJkVhXGAZ8tM

配置网站conf文件

nginx
server{
	listen 80;   
	location / {
		auth_basic "Please enter your username and password";
		auth_basic_user_file /nginx/htpasswd; 
		autoindex on;
	}
}

访问限制

可以在 httpserverlocation 块中使用

nginx
# 黑名单:拒绝特定 IP 地址访问
deny 192.168.1.100;
# 拒绝整个子网访问
deny 192.168.2.0/24;
nginx
# 白名单:允许特定 IP 地址访问
allow 192.168.1.100;
allow 192.168.1.0/24;  # 允许 192.168.1.0 到 192.168.1.255 的所有 IP 地址访问
# 拒绝所有其他 IP 地址访问
deny all;
bash
# 允许特定域名的反向代理 IP 地址访问(假设反向代理服务器的 IP 是 192.168.3.5)
allow 192.168.3.5;

# 拒绝所有其他 IP 地址访问
deny all;

自定义403页面注意:

nginx
server{
	listen 80;

	deny all;
	error_page 403 /white_list_403.html;
	location = /white_list_403.html {
		allow   all; # 注意要允许,不然还是会展示原来的403
     	root   /data; # white_list_403.html文件所在目录
    }
}

配置说明

proxy_set_header

proxy_set_headerNginx 配置中的一个重要指令,特别是在使用 Nginx 作为反向代理时。该指令允许你修改由 Nginx 传递给代理后端的请求头。这对于确保后端应用程序能够接收到正确的客户端信息(如 IP 地址、主机名等)以及控制缓存行为等场景非常有用。

设置 Host 头

Nginx 代理请求到后端服务器时,默认情况下会保留原始的 Host 头。但是,在某些情况下,你可能需要覆盖这个值:

nginx
proxy_set_header Host $host;
proxy_set_header Host $host:$proxy_port; # 服务器名称和端口一起通过代理服务器传递

这里 $hostNginx 变量,它包含了请求的主机名

传递真实客户端 IP

Nginx 位于负载均衡器或 CDN 后面时,后端服务器看到的客户端 IP 可能是负载均衡器或 CDN 节点的 IP,而不是真实用户的 IP。为了解决这个问题,你可以使用 X-Real-IPX-Forwarded-For 头来传递真实 IP。

nginx
proxy_set_header X-Real-IP $remote_addr;  
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

$remote_addr 是客户端的 IP 地址。$proxy_add_x_forwarded_for 是一个特殊的 Nginx 变量,它包含了原始请求的 X-Forwarded-For 头的内容,并附加上客户端的 IP 地址。

控制缓存:

你可以通过修改或添加特定的头来控制后端服务器或中间缓存的行为

nginx
proxy_set_header Cache-Control "no-cache, no-store, must-revalidate";  
proxy_set_header Pragma no-cache;  
proxy_set_header Expires 0;

这些头通常用于确保请求不会被缓存,或者用于控制缓存的持续时间

自定义头:

除了修改标准 HTTP 头之外,你还可以添加自定义头来传递额外的信息给后端服务器

nginx
proxy_set_header My-Custom-Header "SomeValue";

删除头:

虽然 proxy_set_header 主要用于添加或修改头信息,但你也可以通过将其设置为空值来删除不需要的头。如果请求头的存在空的字段将不会通过代理服务器传递出去。

bash
proxy_set_header Accept-Encoding "";

这将删除 Accept-Encoding 头,可能是因为你不希望后端服务器对内容进行压缩

条件性地设置头:

结合 Nginxmap 模块,你可以根据条件来设置头信息。例如,你可以创建一个映射来根据 $http_user_agent 变量的值设置不同的头。

注意安全性:

当使用 proxy_set_header 时,要注意不要泄露敏感信息或允许未授权访问。确保你了解每个设置的安全影响,并遵循最佳实践来保护你的应用程序和数据。

proxy_set_header自定义header头无效的问题

解决办法

nginx
# nginx underscores_in_headers默认off
nginx underscores_in_headers on;

自定义日志输出格式

参考配置

nginx
http {
	# 自定义日志输出格式
	log_format aka_logs
    '{"@timestamp":"$time_iso8601",'
    '"host":"$hostname",'
    '"server_ip":"$server_addr",'
    '"client_ip":"$remote_addr",'
    '"xff":"$http_x_forwarded_for",'
    '"domain":"$host",'
    '"url":"$uri",'
    '"referer":"$http_referer",'
    '"args":"$args",'
    '"upstreamtime":"$upstream_response_time",'
    '"responsetime":"$request_time",'
    '"request_method":"$request_method",'
    '"status":"$status",'
    '"size":"$body_bytes_sent",'
    '"request_body":"$request_body",'
    '"request_length":"$request_length",'
    '"protocol":"$server_protocol",'
    '"upstreamhost":"$upstream_addr",'
    '"file_dir":"$request_filename",'
    '"http_user_agent":"$http_user_agent"'
    '}';
	# 指定日志输出位置 /var/log/nginx/access.log
    access_log  /var/log/nginx/access.log  aka_logs;
    
	...
}

内置变量参考

nginx
$args                    # 请求中的参数值
$query_string            # 同 $args
$arg_NAME                # GET请求中NAME的值
$is_args                 # 如果请求中有参数,值为"?",否则为空字符串
$uri                     # 请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如"/foo/bar.html"。
$document_uri            # 同 $uri
$document_root           # 当前请求的文档根目录或别名
$host                    # 优先级:HTTP请求行的主机名>"HOST"请求头字段>符合请求的服务器名.请求中的主机头字段,如果请求中的主机头不可用,则为服务器处理请求的服务器名称
$hostname                # 主机名
$https                   # 如果开启了SSL安全模式,值为"on",否则为空字符串。
$binary_remote_addr      # 客户端地址的二进制形式,固定长度为4个字节
$body_bytes_sent         # 传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的"%B"参数保持兼容
$bytes_sent              # 传输给客户端的字节数
$connection              # TCP连接的序列号
$connection_requests     # TCP连接当前的请求数量
$content_length          # "Content-Length" 请求头字段
$content_type            # "Content-Type" 请求头字段
$cookie_name             # cookie名称
$limit_rate              # 用于设置响应的速度限制
$msec                    # 当前的Unix时间戳
$nginx_version           # nginx版本
$pid                     # 工作进程的PID
$pipe                    # 如果请求来自管道通信,值为"p",否则为"."
$proxy_protocol_addr     # 获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串
$realpath_root           # 当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径
$remote_addr             # 客户端地址
$remote_port             # 客户端端口
$remote_user             # 用于HTTP基础认证服务的用户名
$request                 # 代表客户端的请求地址
$request_body            # 客户端的请求主体:此变量可在location中使用,将请求主体通过proxy_pass,fastcgi_pass,uwsgi_pass和scgi_pass传递给下一级的代理服务器
$request_body_file       # 将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传 递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off,uwsgi_pass_request_body off,or scgi_pass_request_body off
$request_completion      # 如果请求成功,值为"OK",如果请求未完成或者请求不是一个范围请求的最后一部分,则为空
$request_filename        # 当前连接请求的文件路径,由root或alias指令与URI请求生成
$request_length          # 请求的长度 (包括请求的地址,http请求头和请求主体)
$request_method          # HTTP请求方法,通常为"GET"或"POST"
$request_time            # 处理客户端请求使用的时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$request_uri             # 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:"/cnphp/test.php?arg=freemouse"
$scheme                  # 请求使用的Web协议,"http" 或 "https"
$server_addr             # 服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中
$server_name             # 服务器名
$server_port             # 服务器端口
$server_protocol         # 服务器的HTTP版本,通常为 "HTTP/1.0" 或 "HTTP/1.1"
$status                  # HTTP响应代码
$time_iso8601            # 服务器时间的ISO 8610格式
$time_local              # 服务器时间(LOG Format 格式)
$cookie_NAME             # 客户端请求Header头中的cookie变量,前缀"$cookie_"加上cookie名称的变量,该变量的值即为cookie名称的值
$http_NAME               # 匹配任意请求头字段;变量名中的后半部分NAME可以替换成任意请求头字段,如在配置文件中需要获取http请求头:"Accept-Language",$http_accept_language即可
$http_cookie
$http_host               # 请求地址,即浏览器中你输入的地址(IP或域名)
$http_referer            # url跳转来源,用来记录从那个页面链接访问过来的
$http_user_agent         # 用户终端浏览器等信息
$http_x_forwarded_for
$sent_http_NAME          # 可以设置任意http响应头字段;变量名中的后半部分NAME可以替换成任意响应头字段,如需要设置响应头Content-length,$sent_http_content_length即可
$sent_http_cache_control
$sent_http_connection
$sent_http_content_type
$sent_http_keep_alive
$sent_http_last_modified
$sent_http_location
$sent_http_transfer_encoding

筛选日志内容

日期区间筛选

bash
grep '2024-01-01T12:[3-5][0-9]' access.log > temp.log

匹配 2024年1月1日 12:30 —— 12:59 区间的日志。输出到新文件 temp.log

条件或

bash
grep -E '"url":"/event/list"|userId=' temp.log

匹配url...userId两个条件

条件与

bash
grep '"url":"/event/list"' temp.log | grep 'userId'

多次过滤,实现 and

open_log_file_cache

每一条日志记录的写入顺序都是先打开文件,写入记录,然后关闭日志文件。

如果日志文件路径中使用到了变量,如access_log /var/logs/$host/nginx-access.log,为了提高性能,可以使用open_log_file_cache指令设置日志文件描述符的缓存。

语法

nginx
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
  • max 设置缓存中最多容纳的文件描述符数量,如果被占满,采用LRU算法将描述符关闭。

  • inactive 设置缓存存活时间,默认是10s。

  • min_uses 在inactive时间段内,日志文件最少使用几次,该日志文件描述符记入缓存,默认是1次。

  • valid:设置多久对日志文件名进行检查,看是否发生变化,默认是60s。

  • off:不使用缓存。默认为off。

日志归档

bash
$ vi location.conf 
map $time_iso8601 $logdate {
    default 'date-not-found';
    '~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
}

在nginx.conf中添加

nginx
include       location.conf;
access_log  logs/access-$logdate.log  main;