切换为 Nginx 是一个非常常见且高效的做法,特别是在处理静态页面和动态页面时。以下是基于 CentOS 8 的完整迁移流程:
1. 安装 Nginx
sudo dnf install nginx -y
启动 Nginx 并设置开机自启动:
sudo systemctl start nginx
sudo systemctl enable nginx
2. 配置防火墙
firewald
CentOS 8 默认使用 firewalld 作为防火墙管理工具。
添加 Nginx 服务规则:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
删除 Spring 应用的原端口(例如 8080):
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
iptables
Nginx 默认监听 80 和 443 端口。你需要在防火墙中允许这些端口的流量通过。
- 查看当前的
**iptables**
规则: 首先,检查当前的iptables
配置:
sudo iptables -L
- 允许 HTTP (80) 和 HTTPS (443) 流量: 为了让 Nginx 能够通过 HTTP 和 HTTPS 提供服务,你需要允许这两个端口的流量。
- 允许 HTTP 流量(端口 80):
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
- 允许 HTTPS 流量(端口 443):
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
- 保存 iptables 配置: 在 CentOS 8 上,
iptables
的规则在重启后不会自动保存。因此,你需要保存这些规则,以便在系统重启后仍然有效。- 安装
iptables-services
以便保存规则:
- 安装
sudo dnf install iptables-services
- 保存当前的 `iptables` 配置:
sudo service iptables save
- 启动 `iptables` 服务:
sudo systemctl start iptables
- 设置 `iptables` 服务开机启动:
sudo systemctl enable iptables
3. 配置 Nginx
创建站点配置文件:
在 /etc/nginx/conf.d/
目录下创建配置文件,例如 myapp.conf
:
server {
listen 80;
server_name yourdomain.com; # 修改为你的域名或服务器 IP
# 静态文件处理
location /static/ {
root /path/to/static/files; # 修改为你的静态文件目录
}
# 动态请求代理到 Spring Boot 应用
location / {
proxy_pass http://127.0.0.1:8080; # 修改为你的 Spring 监听端口
proxy_set_header Host $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;
}
}
测试并加载配置:
sudo nginx -t
sudo systemctl reload nginx
4. Spring 应用调整
- 静态文件路径优化:确保 Spring 的静态资源目录(通常是
resources/static
)已经正确配置。 - 健康检查端点: 如果未启用 Spring Boot Actuator,推荐启用,并确保
/actuator/health
可访问,用于后续健康检查。 - 端口限制: 将 Spring 应用配置为只监听
127.0.0.1
,避免直接暴露给外部网络。在application.properties
中:
server.address=127.0.0.1
5. 启用 HTTPS(推荐)
安装 Certbot 和 Nginx 插件:
sudo dnf install certbot python3-certbot-nginx -y
配置 HTTPS:
运行以下命令,根据提示输入你的域名:
sudo certbot --nginx -d yourdomain.com
自动续期:
设置 Cron 任务或 systemd 定时任务,确保证书自动续期:
sudo systemctl enable --now certbot-renew.timer
6. 性能优化
修改 Nginx 配置参数:
编辑 /etc/nginx/nginx.conf
,增加优化参数:
worker_processes auto;
worker_connections 1024;
http {
keepalive_timeout 65;
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
调整 Spring 线程池:
根据你的服务器性能和负载情况,调整 Spring 的线程池配置,避免 Nginx 的并发请求造成后端压力。
7. 验证和监控
- 通过
curl
测试:
curl -I http://yourdomain.com
curl -I https://yourdomain.com
- 查看 Nginx 的访问日志和错误日志:
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
8. 禁用原端口转发(防火墙规则)
确认 Spring 的端口转发已不再需要,删除相关规则:
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
完成这些配置后,Nginx 将成为前置反向代理,负责处理静态资源和将动态请求转发到 Spring Boot 应用,结合 HTTPS 提供更安全和高效的服务。
Q&A
nginx默认配置也有80端口,conf.d中的配置与默认配置优先级是什么?
Nginx 的配置是分层的,如果你在 conf.d
目录下有独立的配置文件,而 Nginx 默认的配置文件(通常是 /etc/nginx/nginx.conf
)中也有相同的监听端口(如 80 端口),那么最终生效的配置是由 Nginx 加载的整个配置文件中的所有配置决定的。
配置文件的加载顺序
- 主配置文件: Nginx 的主配置文件通常是
/etc/nginx/nginx.conf
,在该文件中你会看到如下的include
指令:
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
这些 include
指令意味着 Nginx 会加载 conf.d
目录中的所有 .conf
文件,并且在 nginx.conf
中的设置会与 conf.d
中的配置合并。
**conf.d**
** 中的配置**: 在conf.d
目录中的配置文件通常是针对特定网站的虚拟主机配置。Nginx 会在启动时加载这些配置文件并应用其中的设置。- 冲突处理: 如果你在
nginx.conf
和conf.d
中的配置存在冲突(例如,都有监听 80 端口的配置),那么 Nginx 会按照配置文件加载的顺序来处理,后加载的配置会覆盖前面的配置。
Nginx 配置文件结构:
- 主配置文件 (
**/etc/nginx/nginx.conf**
): 在nginx.conf
中,你通常会有全局的配置、http
块中的配置等,这些配置会影响整个 Nginx 实例。 - 虚拟主机配置 (
**/etc/nginx/conf.d/*.conf**
):conf.d
目录通常包含一些独立的配置文件,用于定义虚拟主机(server
块)。这些文件的内容会被 Nginx 加载并生效。
如何确定哪个配置生效:
- 检查 Nginx 配置文件的具体内容: 你可以通过以下命令查看
nginx.conf
文件中的server
块,特别是监听 80 端口的部分:
sudo cat /etc/nginx/nginx.conf
- 检查
**conf.d**
目录下的配置: 查看conf.d
中的配置文件,检查其中是否有监听 80 端口的server
块:
sudo cat /etc/nginx/conf.d/*.conf
- 确认加载的配置: 如果你对配置文件不确定,可以使用以下命令检查 Nginx 是否正确加载了配置:
sudo nginx -T
该命令会输出 Nginx 加载的所有配置内容,包括 nginx.conf
和 conf.d
中的配置。
注意:
- 默认配置:如果没有在
conf.d
中明确配置 80 端口的server
块,而nginx.conf
中有配置,那么默认的配置会生效。 - 优先级:如果在
nginx.conf
和conf.d
中的配置冲突,conf.d
中的配置会覆盖nginx.conf
中的配置,前提是它们被加载在后面。
解决方案:
- 确保
nginx.conf
中的server
块和conf.d
中的server
块没有冲突。 - 如果你希望
conf.d
中的配置生效,可以删除或注释掉nginx.conf
中的 80 端口的server
块,确保conf.d
中的配置是唯一的。
通过这些方法,你可以确保 Nginx 的配置正确并生效。
[error] 530335#0: *39 upstream sent no valid HTTP/1.0 header while reading response header from upstream
错误信息 upstream sent no valid HTTP/1.0 header while reading response header from upstream
通常出现在 Nginx 作为反向代理时,无法正确读取来自后端(upstream)的 HTTP 响应头。这可能是由以下几个原因引起的:
1. 后端服务没有正确响应 HTTP 标头
- 确保你的后端服务(例如 Spring 应用)正确返回了有效的 HTTP 响应头。Nginx 期望接收到一个有效的 HTTP 响应头(例如
HTTP/1.1 200 OK
),如果后端没有发送该响应,或者发送了不符合标准的响应头,Nginx 就会报这个错。
排查方法:
- 检查后端服务的日志,确保没有异常发生,且它正常处理请求并返回有效的 HTTP 头。
- 你可以直接访问后端服务(例如通过
curl
或浏览器)来检查它是否能返回有效的响应头。 - 使用
curl
命令测试后端是否返回了合适的 HTTP 头:
curl -I http://127.0.0.1:8080
2. Nginx 配置中的代理设置问题
- Nginx 在与后端服务器通信时,可能需要正确设置代理头部。某些情况下,缺少特定的头部(如
Host
或Connection
)可能会导致该错误。
解决方法:
- 确保你在 Nginx 配置中为反向代理添加了必要的头部:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $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;
proxy_set_header Connection "keep-alive";
}
3. 后端应用服务响应格式错误
- 如果后端服务的响应内容格式不正确,可能导致 Nginx 无法识别响应头,特别是如果后端服务返回的 HTTP 响应不是标准的 HTTP/1.x 或者 HTTP/2 格式。
排查方法:
- 检查后端服务的日志,看是否有任何异常输出,可能导致服务未能正确处理请求并发送有效响应头。
- 确保后端服务没有返回非标准的 HTTP 格式或者报错信息。
4. Nginx 与后端服务的协议不匹配
- 确保 Nginx 配置与后端服务的协议匹配。例如,如果后端服务使用的是 HTTPS(SSL/TLS),而 Nginx 配置的是 HTTP(非加密协议),也会导致这个错误。
解决方法:
- 如果后端服务使用 HTTPS,确保在 Nginx 配置中使用
https
协议,而不是http
:
location / {
proxy_pass https://127.0.0.1:8080; # 使用 https
proxy_set_header Host $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;
}
5. Nginx 与后端的连接被中断
- 可能由于网络问题或配置错误,Nginx 与后端服务的连接被中断或失败,从而导致无法接收到正确的响应头。
排查方法:
- 检查 Nginx 和后端服务之间的网络连接,确认它们之间的连接是否稳定,尤其是在高负载或并发的情况下。
6. 反向代理的超时配置
- 如果反向代理的连接超时,Nginx 可能会出现类似的错误。你可以检查并调整 Nginx 配置中的超时设置。
解决方法:
- 设置更长的超时时间来避免请求过早中断:
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 60s;
总结:
你可以从以下几个方向来排查问题:
- 检查后端服务:确认它是否能正常返回有效的 HTTP 响应头。
- 检查 Nginx 配置:确保正确设置了代理头和协议。
- 查看日志:检查 Nginx 和后端服务的日志,看看是否有更多的错误信息。
通过这些方法,你应该能够定位并解决问题。如果问题仍然存在,提供更多的配置和日志信息可能有助于进一步诊断。
“/home/admin/dist/index.html” failed (13: Permission denied)
查看nginx的用户
要查看 Nginx 进程的运行用户,可以通过以下几种方式:
1. 查看 Nginx 配置文件中的 user
指令
Nginx 配置文件通常位于 /etc/nginx/nginx.conf
,可以查看其中的 user
指令来确定 Nginx 的用户和用户组。
cat /etc/nginx/nginx.conf | grep user
如果配置了 user
指令,它通常位于配置文件的顶部。例如:
user nginx; # 这表示 Nginx 使用 nginx 用户运行
如果没有明确配置 user
,Nginx 通常会使用默认的用户(在不同的操作系统中可能不同,通常是 www-data
或 nginx
)。
2. 查看 Nginx 进程的实际运行用户
如果你不确定 Nginx 进程的用户,可以直接查看正在运行的 Nginx 进程并检查其所属用户。使用 ps
命令来查看进程:
ps aux | grep nginx
输出示例:
nginx 1234 0.0 0.1 123456 1234 ? Ss 12:34 0:00 nginx: master process /usr/sbin/nginx
www-data 1235 0.0 0.1 123456 1234 ? S 12:34 0:00 nginx: worker process
在这个例子中,nginx
用户正在运行 Nginx 的主进程,而 www-data
用户正在运行工作进程。具体的用户可能会有所不同,取决于你的系统配置。
3. 查看 Nginx 的进程详细信息
你还可以使用 top
或 htop
工具来查看 Nginx 进程的详细信息,特别是进程的用户。
top -u nginx
这将显示所有由 nginx
用户启动的进程。你也可以直接查看所有进程:
top
然后按 u
键并输入 nginx
用户名来过滤显示 Nginx 相关的进程。
总结:
nginx.conf
中的user
指令指示 Nginx 使用的用户。- 使用
ps aux | grep nginx
可以查看正在运行的 Nginx 进程和它们的用户。
确认静态文件目录权限
# 设置目录权限为 755
sudo chmod -R 755 /home/admin/dist
# 设置文件权限为 644
sudo chmod 644 /home/admin/dist/index.html
# 假设 Nginx 用户是 nginx
sudo chown -R nginx:nginx /home/admin/dist
注意:如果静态文件父目录是其他用户也会导致权限问题访问不到,因为父目录的权限就拦截掉访问请求了