安装

直接上sh脚本。包源:

  • rpm包地址:http://nginx.org/packages/
  • win和二进制包地址:https://nginx.org/en/download.html
vi install_nginx.sh
#!/bin/bash

# 安装和更新基本库
sudo yum update
sudo yum install pcre2

# 检查是否以root用户运行脚本
if [ "$(id -u)" != "0" ]; then
    echo "错误:请使用root用户运行此脚本"
    exit 1
fi

rpm -ivh http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.24.0-1.el7.ngx.x86_64.rpm --force --nodeps


# 更新软件包缓存
# yum update -y

# 安装Nginx包
# yum install nginx

# 启动Nginx服务
systemctl start nginx
systemctl enable nginx

  • 复制脚本,并起名install_nginx.sh。直接怼进去
  • 赋予权限:
chmod +x install_nginx.sh
  • 执行脚本:
./install_nginx.sh
  • 查看版本
nginx -v

配置文件介绍

1. 先进入安装目录,找到默认配置文件

cd /etc/nginx

2. 打开默认配置

vi nginx.conf

3. 调整一下,改成如下配置,这里需要注意一下http的日志路径,和全局的异常日志路径


user  nginx;
worker_processes  auto; # 设置工作进程数量,auto 表示自动设置为 CPU 核心数
worker_rlimit_nofile 100000; # 设置每个 worker 进程能打开的最大文件描述符数,高并发场景必须设置。需要配合内核优化,允许修改系统文件描述符等参数

# 事件处理模型配置
events {
    use epoll;  # Linux 高效 I/O 事件模型,处理大量连接
    multi_accept on;  # 一个 worker 同时接受多个新连接
    worker_connections  50000; # 单个 worker 最大并发连接数,计算总并发:worker_processes × worker_connections
    accept_mutex off; # 启用连接接受互斥锁,避免"惊群"问题,在Linux内核在3.9,nginx1.9.1或者之上的时候,可以关闭,选用listen 后加上reuseport,这是更高效的方案
    accept_mutex_delay 100ms; # worker 等待互斥锁的最长时间
}


http {
	# 日志配置
	access_log off;  # 生产环境建议关闭访问日志,高并发下主要性能瓶颈在io,可以提升10到30的性能
	log_format main '[$time_local] - [$ssl_protocol/$ssl_cipher] - [$scheme://$host$request_uri $status $request_method] - [$remote_addr] - [$http_user_agent] - [$http_host] - [$upstream_addr - $upstream_status]';
	access_log /var/log/nginx/access.log main buffer=64k flush=5m;
	error_log /var/log/nginx/error.log warn;
		
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

	# 网络传输优化
    sendfile        on; # 使用内核零拷贝技术发送文件,减少 CPU 消耗
    tcp_nopush     on; # 仅在数据包满时发送(需配合 sendfile)
	tcp_nodelay 	on; # 禁用 Nagle 算法,小数据包立即发送
	
	# 减少 TCP 握手开销,提高 HTTPS 性能(全局默认,可在server单独设置覆盖)
    keepalive_timeout  30; # 连接保持打开的时间
    keepalive_requests 100000; # 单个连接的最大请求数

    # 超时控制,如果是文件上传和网关 或者websocket,需要适当延长(全局默认,可在server单独设置覆盖)
    proxy_connect_timeout 5s; # 连接到后端超时
    proxy_send_timeout 30s; # 发送请求到后端超时
    proxy_read_timeout 60s; # 读取响应超时
    
	# 上传限制(全局默认,可在server单独设置覆盖)
    client_max_body_size 10M;

	# 缓冲全局配置(全局默认,可在server单独设置覆盖)
	proxy_buffers 4 16k;          
    proxy_busy_buffers_size 32k;
    proxy_buffering on; 

	# 安全头部配置
	server_tokens off; # 隐藏 Nginx 版本号
	add_header X-Frame-Options "SAMEORIGIN" always; # 禁止页面被嵌入 iframe 防止点击劫持
	add_header X-Content-Type-Options "nosniff" always; # 阻止浏览器 MIME 类型嗅探
	add_header X-XSS-Protection "1; mode=block" always; # 启用浏览器 XSS 过滤器,旧浏览器支持
	add_header Referrer-Policy "strict-origin-when-cross-origin" always; # 控制 Referer 头信息泄露
	# add_header Referrer-Policy "no-referrer-when-downgrade" always; # 控制Referer信息泄露,平衡安全与兼容性。
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # 添加 HSTS 头

	# 请求头传递
    # proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP,只包含最后一个代理认定的真实 IP(单值),适用于简单代理架构
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递客户端真实IP,包含完整的代理链 IP 列表(逗号分隔),最左侧是原始客户端IP,适用于多层代理架构
    proxy_set_header X-Forwarded-Proto $scheme; # 传递客户端真实协议
    proxy_set_header X-Forwarded-Host $host; # $host 变量优先包含请求中的 Host 头,若不存在则使用服务器名(server_name)。后端服务可通过此头识别客户端访问的原始域名,适用于多域名场景
	proxy_set_header X-Forwarded-Port $server_port; # $server_port 变量为 Nginx 监听的端口(如 80 或 443),后端服务可能需此信息构建完整的 URL(尤其是非标准端口时)。
    proxy_set_header Host $host; # 重写或传递 Host 头到后端服务器。默认情况下,Nginx 会将客户端的 Host 头透传给后端。显式设置 Host $host 可确保后端收到统一的域名(避免代理修改端口或协议影响原始头)。与 X-Forwarded-Host 的区别在于,Host 是标准 HTTP 头,直接影响后端服务器的虚拟主机路由;X-Forwarded-Host 仅用于信息传递。
    proxy_set_header Accept-Encoding ""; # 清空Accept-Encoding头,防止后端压缩,避免双重压缩。如果后端已经强制压缩,则关闭nginx压缩

    # 压缩
	gzip on;
	gzip_min_length 2k; # 大于 2KB 才压缩
	gzip_comp_level 6; # 压缩级别(1-9),6 是性能/压缩比最佳平衡
	gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml image/svg+xml font/woff2; # 指定压缩的文件类型
	gzip_vary on; # 添加 "Vary: Accept-Encoding" 头
	gzip_proxied any; # 对所有代理请求启用压缩
	gzip_disable "msie6"; # 对 IE6 禁用压缩(它不支持 gzip 解压)

	# 启用CSP,控制资源来源,有一定的防止XSS、防止劫持等能力,可以填写允许的域名,支持通配符*(例如https://ceshi.demo.com https://*.ceshi1.com)
	# default-src 'self':没有明确制定的额情况下,默认只允许同源资源。self表示只允许加载当前域名(相同协议/端口) 下的资源
	# script-src:允许指定的 JS 来源
		# 'unsafe-inline':允许内联脚本(必要时),如 <script>...</script> 或事件处理器 onclick="..."
	# style-src: 允许的css来源
		# 'unsafe-inline':允许内联脚本(必要时),如 css的<style>...</style> 或 style="..."
	# img-src: 允许制定的图片来源
		# data::允许通过 Data URLs 嵌入图片(如 src="data:image/png;base64,...")
	# report-uri:违规报告收集端点,用于接收 JSON 格式违规报告的 URI),需要能够接收POST请求,并记录报告内容。
    add_header Content-Security-Policy 
    "default-src 'self'; 
     script-src 'nonce-{random}'; 
     style-src 'self' 'unsafe-inline'; 
     frame-src 'self' blob:;
     img-src 'self' data: blob:; " 
    always;
	
    include /etc/nginx/conf.d/*.conf;
}

stream {
    include /etc/nginx/tcp.conf.d/*.conf;
}

  1. 剩下的就简单了,只需要在conf.d文件夹下面创建自己想要的配置。例如我这里创建一个监听域名为ceshi.csym.com的请求,来跟着走
cd conf.d
vi ceshi.csym.com

把下面的内容给我怼进去

server {
    server_name ceshi.csym.com; # 监听的目标域名
    listen 80 reuseport;
    listen 443 ssl http2 reuseport; # 启用 HTTP/2 协议(多路复用,头部压缩)


    # access_log  /var/log/nginx/ceshi.csym.com.log  main; # 这里可以单独指定日志
    
	

     # SSL/TLS 安全配置
    ssl_certificate conf.d/ssl/ceshi.csym.com.pem;
	ssl_certificate_key conf.d/ssl/ceshi.csym.com.key;
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # TLS 1.2 及以下使用的加密套件(传统 cipher list)
	ssl_protocols TLSv1.2 TLSv1.3; # 启用 TLS 1.3(OpenSSL 1.1.1+ 自动支持其默认 cipher suites)
	ssl_ecdh_curve X25519:prime256v1;  # 优先现代曲线
	ssl_session_cache shared:SSL:50m;   # 足够大的缓存
	ssl_session_timeout 1d;
	ssl_buffer_size 4k;      # 优化内存使用,对于高延迟网络,可以适当增加(如16k)以提升性能
	ssl_session_tickets off; #  禁用 session tickets(存在安全风险)
	ssl_stapling on; # OCSP 装订,加速证书验证
	ssl_stapling_verify on; # 在 ssl_stapling on; 的基础上,强制 Nginx 验证它从 CA 获取到的 OCSP 响应的真实性(签名)和有效性(未过期)。这是确保装订机制安全可靠的关键步骤。

	# 静态资源缓存
	#location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
	 # expires 1y; # 浏览器缓存 1 年
	  #add_header Cache-Control "public, immutable"; # public:允许代理服务器缓存,immutable:内容永不变,跳过验证
	#}

	# 字体文件缓存,参数类似静态资源配置
	#location ~* \.(?:eot|ttf|otf|woff|woff2)$ {
	#  expires 1y;
	#  add_header Cache-Control "public";
	#  add_header Access-Control-Allow-Origin "*"; # 额外添加跨域头,解决 CDN 字体加载问题。这里是允许任意域名加载。
	}
	# 默认请求地址,/ 也就是域名本身访问的时候,一般指向前端页面
	location / {
	   root   /usr/share/nginx/html/ceshi; # ceshi代表分包名
	   index  index.html;

	# 解决刷新404问题
	   try_files $uri $uri/ /index.html;
	}
   
	# location / {
		# return 301 https://www.baidu.com$; # 永久重定向到百度
	# }


	# 请求地址是http://ceshi.csym.com/server/ 的时候执行的代码块,这里是代理到http://127.0.0.1:8444/。注意,如果Nginx做了ssl,这里可以是http
	location /server/ {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		# 2. 路径重写,rewrite 移除 /server 前缀,break 停止后续重写规则。
		# - 原始URL:`/server/abc/def`
		# - 重写后:`/abc/def`
		# rewrite ^/server/(.*)$ /$1 break;

		proxy_set_header X-Forwarded-Prefix /server/; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# 特殊的功能 
	location /upload {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		client_max_body_size 2G; # 允许的最大文件大小
		proxy_read_timeout 1800s; # 读取响应超时
		client_body_temp_path /tmp/nginx_upload 1 2; # 临时文件地址,二级子目录
		create_full_put_path on;   # 自动创建目录

		# 大文件下载优化
		proxy_buffer_size 32k;
		proxy_buffers 8 256k;
		proxy_busy_buffers_size 1m;
		proxy_max_temp_file_size 2g;  # 启用磁盘缓存
		proxy_request_buffering off;  # 禁用缓冲提升大文件上传性能
		proxy_set_header X-Forwarded-Prefix /upload; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# 高并发覆盖配置
	location /api/ {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		proxy_read_timeout 15s;  # API接口缩短超时
		proxy_buffers 4 16k;          # 减少内存占用
		proxy_busy_buffers_size 32k;
		proxy_buffering on;           # 保持小数据缓冲

		proxy_set_header X-Forwarded-Prefix /api/; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# WebSocket覆盖配置
	location /ws {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		proxy_read_timeout 3600s; # 读取响应超时时间
		proxy_send_timeout 3600s; # 发送超时时间

		# Websocket 支持,如果Nginx做了ssl,这里会自动升级为wss.如果是netty等框架单独写的websocket,可以单独开一个代码块,也能升级wss
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
    }

}

如果你前后端分离,又不想额外用前缀来区分后端api和web服务,可以如下配置

location / {
        root   /usr/share/nginx/html/ceshi; # ceshi代表分包名
        index  index.html;

	# 解决刷新404问题
        try_files $uri $uri/ @backend;
    }

	
    location @backend {
        
		# 代理到后端
        proxy_pass   http://127.0.0.1:8000;
        
        proxy_read_timeout 15s;  # API接口缩短超时
        proxy_buffers 4 16k;          # 减少内存占用
        proxy_busy_buffers_size 32k;
        proxy_buffering on;           # 保持小数据缓冲
			
    }

当然这个配置需要的条件比较苛刻,如果是老的服务器和旧的浏览器,可以用下面这个修改后得到

server {
    server_name ceshi.csym.com; # 监听的目标域名
    listen 80 reuseport;
    listen 443 ssl reuseport; # 启用 HTTP/2 协议(多路复用,头部压缩)


    # access_log  /var/log/nginx/ceshi.csym.com.log  main; # 这里可以单独指定日志
    
	ssl_certificate conf.d/ssl/ceshi.csym.com.pem;
	ssl_certificate_key conf.d/ssl/ceshi.csym.com.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 

    ssl_session_cache shared:SSL:50m;   
    ssl_session_timeout 1d;
    ssl_buffer_size 4k;      
    ssl_session_tickets off; 
    ssl_stapling on; 
    ssl_stapling_verify on; 

	# 静态资源缓存
	location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
	  expires 1y; # 浏览器缓存 1 年
	  add_header Cache-Control "public, immutable"; # public:允许代理服务器缓存,immutable:内容永不变,跳过验证
	}

	# 字体文件缓存,参数类似静态资源配置
	location ~* \.(?:eot|ttf|otf|woff|woff2)$ {
	  expires 1y;
	  add_header Cache-Control "public";
	  add_header Access-Control-Allow-Origin "*"; # 额外添加跨域头,解决 CDN 字体加载问题。这里是允许任意域名加载。
	}
	# 默认请求地址,/ 也就是域名本身访问的时候,一般指向前端页面
	location / {
	   root   /usr/share/nginx/html/ceshi; # ceshi代表分包名
	   index  index.html;

	# 解决刷新404问题
	   try_files $uri $uri/ /index.html;
	}
   
	# location / {
		# return 301 https://www.baidu.com$; # 永久重定向到百度
	# }


	# 请求地址是http://ceshi.csym.com/server/ 的时候执行的代码块,这里是代理到http://127.0.0.1:8444/。注意,如果Nginx做了ssl,这里可以是http
	location /server/ {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		# 2. 路径重写,rewrite 移除 /server 前缀,break 停止后续重写规则。
		# - 原始URL:`/server/abc/def`
		# - 重写后:`/abc/def`
		# rewrite ^/server/(.*)$ /$1 break;

		proxy_set_header X-Forwarded-Prefix /server/; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# 特殊的功能 
	location /upload {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		client_max_body_size 2G; # 允许的最大文件大小
		proxy_read_timeout 1800s; # 读取响应超时
		client_body_temp_path /tmp/nginx_upload 1 2; # 临时文件地址,二级子目录
		create_full_put_path on;   # 自动创建目录

		# 大文件下载优化
		proxy_buffer_size 32k;
		proxy_buffers 8 256k;
		proxy_busy_buffers_size 1m;
		proxy_max_temp_file_size 2g;  # 启用磁盘缓存
		proxy_request_buffering off;  # 禁用缓冲提升大文件上传性能
		proxy_set_header X-Forwarded-Prefix /upload; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# 高并发覆盖配置
	location /api/ {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		proxy_read_timeout 15s;  # API接口缩短超时
		proxy_buffers 4 16k;          # 减少内存占用
		proxy_busy_buffers_size 32k;
		proxy_buffering on;           # 保持小数据缓冲

		proxy_set_header X-Forwarded-Prefix /api/; # 记录原始请求在经过代理或负载均衡器后发生的变化的路径前缀,这里是/server/,例如使用knife4j代理后文档异常问题
	}

	# WebSocket覆盖配置
	location /ws {

		# 代理到后端
		proxy_pass   http://127.0.0.1:8444/;

		proxy_read_timeout 3600s; # 读取响应超时时间
		proxy_send_timeout 3600s; # 发送超时时间

		# Websocket 支持,如果Nginx做了ssl,这里会自动升级为wss.如果是netty等框架单独写的websocket,可以单独开一个代码块,也能升级wss
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
    }

}

这里的匹配规则需要注意一下。按照上面的配置,假如我们有这样一个场景:

  • 地址:http://ceshi.csym.com/server/ceshi.html
  • location :/server/
  • proxy_pass:https://127.0.0.1:8444/aaa,它由A和B两部分组成:
    1. A:https://127.0.0.1:8444
    2. B:/aaa
  • 如果proxy_pass由uri+url组成,那么就应该是location去匹配地址信息,然后包含location在内的左边部分,全部替换proxy_pass的值。什么意思呢?举个例子
请求地址 location proxy_pass 实际请求地址 说明
http://ceshi.csym.com/server/ceshi.html /server/ https://127.0.0.1:8444/aaa/ https://127.0.0.1:8444/aaa/ceshi.html proxy_pass红色标记部分替换了请求地址中的红色标记部分
http://ceshi.csym.com/server/ceshi.html /server https://127.0.0.1:8444/aaa/ https://127.0.0.1:8444/aaa//ceshi.html proxy_pass红色标记部分替换了请求地址中的红色标记部分,因为匹配过程中location 没有/,导致地址中余下一个/,然后proxy_pass中又带有一个"/",所以出现了双“/”。
http://ceshi.csym.com/server/ceshi.html /server/ https://127.0.0.1:8444/aaa https://127.0.0.1:8444/aaaceshi.html -
http://ceshi.csym.com/server/ceshi.html /server/ https://127.0.0.1:8444 https://127.0.0.1:8444/server/ceshi.html 当且仅当proxy_pass只由A组成时,末尾没有“/”,那么就会成为全代理

4. 每次修改配置文件之后,需要刷新一下配置

nginx -s reload

5. 有时候会遇到一些代理问题,尤其是自己建立的虚拟机

例如代理的时候请求不到上游服务器,出现以下日志

 connect() to XXXX failed (13: Permission denied) while connecting to upstream,

这个是由于谷歌的SeLinux框架导致的,执行以下命令

setsebool -P httpd_can_network_connect 1

后续一大堆的域名文件,都可直接丢到这个文件夹下,Nginx会自动识别分别执行的,充分合理利用二级域名(千万不要直接拿www的主域名来做接口,不然你就是大冤种),每一个二级域名都是一个项目,一个或者多个后端地址。后端地址的代理通过可以监听不同的域名(域名可以指向同一个IP),或者同一个域名不同的url,还可以同一个域名监听不同端口来实现。而且这三种方式并非独立选择,而是相辅相成,多种混合使用的关系。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐