本文介绍了Nginx的基本概念、安装方法和常用命令,以及如何配置Nginx作为HTTP服务器和反向代理服务器。还介绍了Nginx的负载均衡功能,并提供了几种常见的负载均衡算法示例。此外,还讨论了如何在Nginx中设置HTTPS服务器和使用HTTP基本身份验证限制访问。
Nginx(发音为"engine x")是一款高性能的HTTP服务器和反向代理服务器,起源于俄罗斯。Nginx是由Igor Sysoev开发的,并于2004年首次发布。它采用C语言编写,具有高性能、稳定性、可扩展性等特点。Nginx在全球范围内得到了广泛的认可和应用,许多知名网站和应用都在使用Nginx来处理海量网络请求。
Nginx的配置文件位于/etc/nginx
目录下,默认名为nginx.conf
。以下是对Nginx配置文件的主要部分进行简要介绍:
全局配置块:全局配置块位于配置文件的最顶部,用于设置一些全局参数,如工作进程、连接数等。
事件模块:事件模块负责处理与连接相关的操作,如接受客户端请求、处理异常等。在此块中,可以设置worker进程数、工作模式、连接超时时间等。
负载均衡模块:负载均衡模块用于在多个后端服务器之间分配请求。在此块中,可以设置服务器组、服务器列表以及负载均衡算法等。
服务器配置块:服务器配置块用于定义虚拟主机和服务器的相关设置。在此块中,可以设置服务器名称、文档根目录、服务器块等。
虚拟主机配置块:虚拟主机配置块用于定义多个虚拟主机的相关设置。在此块中,可以设置虚拟主机名称、默认文档、SSL证书等。
location 配置块:location配置块用于匹配请求的URL,并对匹配到的请求进行相应的处理。在此块中,可以设置URL匹配规则、代理服务器、缓存策略等。
代理服务器配置块:代理服务器配置块用于设置代理服务器的相关参数,如端口号、目标服务器等。
缓存配置块:缓存配置块用于设置缓存策略和相关参数,如缓存有效期、缓存目录等。
安全和访问控制配置块:安全和访问控制配置块用于设置访问权限、身份验证、IP过滤等。
日志配置块:日志配置块用于设置日志记录的相关参数,如日志级别、日志格式、日志路径等。
首先,将以下脚本内容复制并保存为/tmp/install_nginx.sh文件。
#!/bin/bash
# 安装工具包
yum -y install yum-utils
if [ $? -eq 0 ]; then
echo "yum-utils 安装成功"
else
echo "yum-utils 安装失败,请重试"
exit 1
fi
# 设置 yum 存储库
nginxrepo='[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'
echo "$nginxrepo" > /etc/yum.repos.d/nginx.repo
# 默认情况下,使用稳定的 nginx 包的存储库。 如果你想使用主线 nginx 包, 请去掉下面一行命令的注释
#yum-config-manager --enable nginx-mainline
# 安装 nginx
yum -y install nginx
if [ $? -eq 0 ]; then
echo "nginx 安装成功"
else
echo "nginx 安装失败,请重试"
exit 1
fi
# 启动Nginx服务
systemctl start nginx
if [ $? -eq 0 ]; then
echo "启动 Nginx 服务成功"
else
echo "启动 Nginx 服务失败,请重试"
exit 1
fi
# 配置nginx开机自启动
systemctl enable nginx
if [ $? -eq 0 ]; then
echo "配置 nginx 开机自启动成功"
else
echo "配置 nginx 开机自启动失败,请重试"
exit 1
fi
exit 0
在终端中执行以下命令,为脚本添加执行权限。
chmod a+x /tmp/install_nginx.sh
执行以下命令,运行脚本开始下载、安装nginx。
/tmp/install_nginx.sh
请等待安装完成,如有异常会有提示。
安装完成后,浏览器访问服务器的IP地址,如下图所示:
systemctl start nginx
systemctl enable nginx
systemctl status nginx
systemctl stop nginx
systemctl restart nginx
nginx [-?hvVtTq] [-s signal] [-p prefix] [-e filename] [-c filename] [-g directives]
nginx -h
nginx -v
nginx -V
nginx -t
nginx -T
nginx -q
nginx -s quit
nginx -s stop
nginx -s reload
nginx -s reopen
在反向代理中,Nginx充当客户端与后端服务器之间的中间人。当客户端发送请求时,Nginx接收到请求并将其转发给后端服务器处理,并将响应返回给客户端。这种架构隐藏了真实的后台服务,并提供了一些重要功能和优势:
负载均衡:通过使用多个后台服务器并分配流量到它们之间,可以实现负载均衡来提高系统性能和可伸缩性。
缓存加速:Nginx可以缓存经常访问的资源(如图片、CSS文件等),从而减轻后台服务的压力并提升用户体验。
安全保护:作为前置代理,在传递请求之前,Nginx可以执行各种安全策略,例如防火墙规则、DDoS攻击防护等。
SSL终止/SSL握手优化:通过在 Nginx 上进行 SSL 终止(即解密 HTTPS 请求)或者进行 SSL 握手优化(利用 Ngnix 的事件驱动模型),可以减轻应用程序对 SSL 处理的负担。
URL重写和请求转发:Nginx提供了强大的URL重写功能,可以根据特定规则修改URL,并将请求转发到不同的后端服务器上。
Nginx的反向代理功能可以通过配置文件来实现。下面是一个简单的示例:
假设有两个后端服务器,IP地址分别为192.168.1.101和192.168.1.102,并且我们希望使用Nginx作为反向代理将请求转发到这两个服务器上。
首先,需要在Nginx配置文件中添加以下内容:
http {
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
# 其他服务器IP
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 可选:设置其他HTTP头部信息
}
}
}
解释一下以上配置的关键部分:
upstream
块定义了后端服务器组(backend),其中列出了要转发请求到的各个服务器。server
块监听80端口,并且在根路径(/)下进行处理。location
块指定了匹配规则,在本例中是所有路径都会被匹配。proxy_pass
指令将请求转发给名为"backend" 的上游组。这里使用http://前缀表示使用HTTP协议进行通信。
负载均衡是指将网络流量合理地分配到多台服务器上,以避免单一节点过载,并提供更好的服务响应时间。Nginx通过使用不同类型的负载均衡算法来实现这一目标。
以下是几种常见的Nginx负载均衡算法:
Nginx还支持会话保持(Session Persistence),这意味着对于同一个客户端的多个请求,它们将被路由到相同的后端服务器上。这在需要维护用户状态或会话数据时非常有用。
以下示例在nginx配置文件(/etc/nginx/nginx.conf
)设置。
轮询是nginx的默认算法。
以下是一个简单的Nginx负载均衡配置示例:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
在上述配置中,upstream
块定义了后端服务器的列表。您可以根据需要添加或删除服务器,并调整它们之间的权重。
在 server
块中,我们使用 listen 80
指令来监听 HTTP 请求。然后,在 /location/
配置块内部,我们使用 proxy_pass http://backend;
将请求代理到名为 “backend” 的上游服务器组。
此外,通过设置一些代理头信息(例如:Host、X-Real-IP、X-Forwarded-for),Nginx将这些信息传递给后端服务器以进行正确处理和日志记录。
要使用Nginx的IP哈希算法进行负载均衡,可以确保同一客户端的请求始终被发送到相同的后端服务器。这对于某些应用程序可能很重要,例如需要在多个请求之间保持会话状态或缓存数据。
以下是一个示例配置,演示如何使用Nginx IP哈希算法进行负载均衡:
http {
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
# 其他配置...
}
在上述示例中,我们通过在 upstream
块内部添加 ip_hash;
指令来启用IP哈希算法。这将使得每个客户端根据其源IP地址被分配到特定的后端服务器。
请注意,在此配置中,并不需要为每个后端服务器指定权重值(weight),因为所有具有相同源 IP 的请求都将路由到相同的服务器。
当启用了IP哈希时,请记住以下几点:
要使用Nginx的最少连接算法进行负载均衡,可以确保将请求发送到当前具有最少活跃连接数的后端服务器。这样可以实现负载均衡,并尽量平衡每个后端服务器上的连接数量。
以下是一个示例配置,演示如何使用Nginx最少连接算法进行负载均衡:
http {
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
# 其他配置...
}
在上述示例中,我们通过在 upstream
块内部添加 least_conn;
指令来启用最少连接算法。这将使得每个新请求都被路由到当前具有最小活跃连接数的后端服务器。
请注意,在此配置中,并不需要为每个后端服务器指定权重值(weight),因为根据活跃连接数自动选择了合适的目标。
当使用“least_conn”时,请记住以下几点:
要使用Nginx的加权轮询算法进行负载均衡,可以根据后端服务器的性能和处理能力为每个服务器分配不同的权重值。这样可以实现按照权重比例分配请求,从而更好地利用资源。
以下是一个示例配置,演示如何使用Nginx加权轮询算法进行负载均衡:
http {
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
}
# 其他配置...
}
在上述示例中,我们为每个后端服务器指定了不同的 weight
值。较高的 weight
值表示该服务器将获得更多请求。
在此配置中,默认情况下会采用简单轮询(round-robin)算法来选择目标。即使设置了不同的权重值,在一段时间内仍然会平等地向所有后端发送相应数量的请求,并且只有当所有具有较高权重的后端服务器处理完所分配到的请求后,才将新请求发送给较低权重的后端服务器。
请注意,在此配置中:
Nginx不提供直接的加权最小连接数算法。然而,您可以结合使用least_conn
和ip_hash
指令来实现近似的加权最小连接数负载均衡。
以下是一个示例配置,演示如何使用Nginx结合 least_conn
和 ip_hash
来实现近似的加权最小连接数算法:
http {
upstream backend {
ip_hash;
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
}
# 其他配置...
}
在上述示例中,我们首先启用了 ip_hash;
指令来根据客户端IP地址进行哈希,并将同一客户端请求路由到相同后端服务器。这样可以确保每个客户端始终与相同的后端服务器建立连接。
然后,在每个后端服务器上设置了不同的 weight
(权重) 值以表示它们之间处理能力或性能差异。较高的权重值表示该服务器将获得更多的请求。
通过结合使用这两种指令,当有新请求到达时:
这样,相对较强的服务器将处理更多请求,并且每个客户端始终与同一台后端服务器建立连接。
请注意,在此配置中:
要设置备份服务器,以便在主服务器不可用时提供冗余和故障转移能力,您可以使用Nginx的backup
关键字。这将允许您指定一个或多个备份服务器,在主服务器不可用时自动切换到备份。
以下是一个示例配置,演示如何设置备份服务器:
http {
upstream backend {
server backend1.example.com;
server backup_backend.example.com backup;
}
# 其他配置...
}
在上述示例中:
backend1.example.com
是主要的后端服务。backup_backend.example.com
是作为备份的后端服务,并通过添加 backup;
关键字来标识它是一个备份。当 Nginx 发现主要的后端服务 (backend1.example.com
) 不可用时(例如连接超时或错误),它会自动将请求发送到标记为 “backup” 的后端服务(backup_backend.example.com
)上。一旦原始主服务器再次可用,Nginx就会自动切回到主要后端服务器。
stream {}
是 Nginx 配置文件中的一个块,用于配置 Nginx 的流代理功能。与 HTTP 代理不同,流代理主要用于 TCP 和 UDP 协议的转发和负载均衡。
stream {
server {
listen 12345;
proxy_pass backend_servers;
}
server {
listen 12346;
proxy_pass backend.example.com:12346;
}
server {
listen 53 udp;
proxy_pass dns_servers;
}
# ...
}
server {}
块内部设置监听端口号(例如:12345)。proxy_pass
指令将请求转发给名为 “backend_servers” 的上游组或后端服务器。Nginx可以用于TCP和UDP负载均衡,以将传入的TCP或UDP流量分发到多个后端服务器上。下面是关于如何配置TCP和UDP负载均衡的示例:
stream {
upstream backend {
server backend1.example.com:8000;
server backend2.example.com:8000;
}
server {
listen 80;
proxy_pass backend;
}
}
由于 TCP 是上下文的默认协议,因此该指令没有参数
在上述示例中,我们使用stream
模块来配置TCP级别的代理。通过定义一个名为 backend
的upstream组,并指定多个后端服务器及其相应的地址和端口。
然后,在 server
块中监听指定的端口(例如80),并使用 proxy_pass
将流量转发给定义好 的 后 端 服 务器 组 (backend
)。
请注意,在此配置中:
backend1.example.com
, backend2.example.com
)、地址和端口。stream {
upstream udp_backend {
hash $remote_addr consistent;
server udp_backend1.example.com:5000 weight=3 max_fails=3 fail_timeout=30s;
server udp_backend2.example.com:5000 weight=4 max_fails=3 fail_timeout=30s;
}
server {
listen 12345 udp;
proxy_pass udp_backend;
# 其他相关指令
}
}
使用UDP,应包括 udp 参数
在上述示例中,我们使用stream
模块来配置UDP级别的代理。通过定义一个名为 udp_backend
的upstream组,并指定多个后端服务器及其相应的地址和端口。
在这种情况下,我们使用了哈希算法(hash $remote_addr consistent
)来根据客户机IP地址进行负载均衡,并设置了不同权重值 (weight
) 来表示每个后端服务器处理能力或性能差异。
请注意,在此配置中:
udp_backend1.example.com
, udp_backend2.example.com
)、地址和端口。max_fails
) 和失败超时时间 (fail_timeout
) 等。stream {
# 后台SSL证书密钥文件路径
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
server {
listen 443;
proxy_pass backend_servers;
# 其他SSL/TLS相关指令
}
}
stream {}
块中配置 SSL/TLS 支持,包括设置证书和私钥文件路径。需要注意的是,stream {}
块中只能使用一些特定于流代理功能的指令,并不支持所有 HTTP 模块相关功能。
在 Nginx 配置中启用 PROXY 协议有以下作用:
保留客户端真实IP地址:当 Nginx 位于代理服务器后面时,通常会将客户端的请求转发给后端服务器。但是,默认情况下,Nginx 将使用自己与后端服务器之间建立的连接IP地址作为来源IP地址。通过启用 PROXY 协议,在代理请求头部添加了PROXY protocol
的信息,可以让 Nginx 获取到原始客户端的真实IP地址。
支持透明地传递其他协议层信息:PROXY 协议不仅可以包含源 IP 地址还可包含其他协议层(如TCP、SSL)相关信息。这些额外的协议层信息可以被后端服务器利用来进行更多的定制化处理,如 SSL 握手相关设置或者其他应该根据客户端提供的信息进行处理。
要在 Nginx 中接受并解析 PROXY 协议,需要在配置文件中添加相应指令,并确保前段负载均衡设备或反向代理也发送了符合规范格式(如HAProxy)的PROXY protocol
请求头部。
以下是一个示例配置,展示了如何启用代理协议:
http {
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
#...
server {
server_name localhost;
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/public.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/public.example.com.key;
location /app/ {
proxy_pass http://backend1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
}
}
stream {
log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
#...
server {
listen 12345 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
proxy_pass backend.example.com:12345;
proxy_protocol on;
}
}
知道客户端的原始 IP 地址后,可以配置正确的日志记录:
对于 HTTP,使用 $proxy_protocol_addr 变量和 proxy_set_header 指令将 NGINX 配置为将客户端 IP 地址传递给上游服务器:
http {
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
将 $proxy_protocol_addr 变量添加到指令(HTTP 或 Stream)log_format 中:
在 http 块中:
http {
#...
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
}
在 stream 块中:
stream {
#...
log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
}
对于TCP流,可以为 NGINX 和上游服务器之间的连接启用 PROXY 协议。要启用 PROXY 协议,请将 proxy_protocol 指令包含在以下级别的 serverstream {} 块中:
stream {
log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
#...
server {
listen 12345 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
proxy_pass backend.example.com:12345;
proxy_protocol on;
}
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#...
}
listen 443 ssl
:指定服务器监听443端口,并使用SSL协议。server_name www.example.com
:设置服务器的主机名为www.example.com。ssl_certificate www.example.com.crt
:指定SSL证书文件的位置,该文件用于验证服务器身份。ssl_certificate_key www.example.com.key
:指定SSL私钥文件的位置,用于加密和服务器身份验证。ssl_protocols TLSv1 TLSv1.1 TLSv1.2
:指定服务器支持的最高TLS版本为TLSv1.2。ssl_ciphers HIGH:!aNULL:!MD5
:指定服务器使用的加密套接字,优先使用高强度加密算法,禁用aNULL和MD5算法。服务器证书是公共实体。它被发送到连接到 NGINX 或 NGINX Plus 服务器的每个客户端。私钥是一个安全的实体,应存储在访问受限的文件中。
NGINX 可以配置为使用联机证书状态协议 (OCSP) 来检查 X.509 客户端证书的有效性。客户端证书状态的 OCSP 请求将发送到 OCSP 响应程序,该响应程序检查证书有效性并返回包含证书状态的响应:
启用 SSL 客户端证书的 OCSP 验证:
server {
listen 443 ssl;
ssl_certificate /etc/ssl/foo.example.com.crt;
ssl_certificate_key /etc/ssl/foo.example.com.key;
ssl_verify_client on;
ssl_trusted_certificate /etc/ssl/cachain.pem;
ssl_ocsp on; # Enable OCSP validation
#...
}
ssl_verify_client on
:启用客户端证书验证,这将要求客户端提供有效的客户端证书以进行连接。
ssl_trusted_certificate /etc/ssl/cachain.pem
:指定用于验证客户端证书的证书颁发机构(CA)证书链文件的位置。
ssl_ocsp on
:启用OCSP验证,这将允许服务器在客户端证书验证过程中检查证书的在线状态。
要在 Nginx 中使用 HTTP 基本身份验证限制访问,您可以按照以下步骤进行配置:
首先,需要创建一个包含用户名和密码的文件。可以使用 htpasswd
工具来生成该文件。运行以下命令以生成密码文件:
htpasswd -c /etc/nginx/.htpasswd username
将 “username” 替换为您想要用于身份验证的实际用户名。系统会提示您输入并确认用户的密码。
打开 Nginx 的配置文件/etc/nginx/nginx.conf
。找到需要添加基本身份验证的位置或块,并在其中添加以下代码:
location / {
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
此示例中,我们将基本身份验证应用于根路径 (“/”) 下所有请求。如果只想对特定目录或 URL 进行限制,请相应地修改 location
指令。
保存更改后,请确保语法正确性,并重新加载 Nginx 配置以使更改生效。
nginx -t # 检查语法错误
systemctl reload nginx # 重新加载Nginx服务
nginx -s reload # 重新加载nginx配置文件
现在,在尝试访问受限内容时,浏览器会弹出一个对话框要求输入用户名和密码。输入正确的凭据后,才能访问受限内容。
请注意,基本身份验证是一种简单的身份验证方法,并且传输过程中的凭据以明文形式发送。因此,请确保使用 HTTPS 进行加密通信以提供更高级别的安全性。
通过阅读本教程,您应该对Nginx有一个初步的认识,并且能够进行基础配置和使用一些常用功能。请记住,在实际应用中,可能会涉及更复杂的场景和配置选项,请参考官方文档以获取更详细的信息。
希望本教程对您有所帮助!如有任何疑问或问题,请随时在评论区留言。感谢阅读!
参考链接: