NGINX - 高级负载均衡器、Web服务器、反向代理
一、概述
Nginx
是一个高性能的开源Web服务器,也可以用作反向代理服务器、负载均衡器和HTTP缓存。它的设计目标是提供高并发、低内存消耗和高度可伸缩性,使其成为处理大量并发连接的理想选择。以下是关于Nginx的一些关键特点和功能:
-
高性能:
Nginx
的事件驱动架构和高效的内存使用使其能够处理大量并发连接,而不会消耗过多的系统资源。它被广泛用于构建高性能的Web服务器和应用程序。 -
反向代理:
Nginx
可以作为反向代理服务器,将客户端的请求转发给后端的应用服务器。这对于提高应用的安全性、可伸缩性和灵活性非常有用。 -
负载均衡:
Nginx
提供了负载均衡功能,可以平均分配流量到多个后端服务器,从而提高系统的稳定性和性能。负载均衡可以通过不同的算法进行配置,例如轮询、IP哈希、最小连接数等。 -
静态文件服务和缓存:
Nginx
可以高效地提供静态文件服务,并支持HTTP
缓存,减轻后端服务器的压力。它还能够通过gzip
压缩来减小传输的数据量,提高网站的加载速度。 -
SSL/TLS支持:
Nginx
支持SSL/TLS
协议,可以用于安全地加密传输数据。这对于保护用户隐私和确保数据完整性非常重要。 -
模块化架构:
Nginx
的模块化架构允许用户根据需要添加或移除功能。它支持丰富的第三方模块,使得用户可以自定义和扩展Nginx
的功能。 -
日志记录:
Nginx
提供详细的访问日志和错误日志,方便管理员进行故障排除和性能调优。 -
易于配置:
Nginx
的配置文件采用简洁而直观的语法,易于理解和维护。同时,它支持热加载配置,不需要重启即可生效配置更改。 -
支持多协议:除了
HTTP/HTTPS
,Nginx
还支持其他网络协议,如SMTP
、IMAP
、POP3
等,使其具备更广泛的应用领域。 -
活跃的社区和广泛的采用:
Nginx
是一个开源项目,拥有庞大的社区支持。由于其高性能和稳定性,它被广泛采用作为Web服务器和反向代理服务器。
总体而言,Nginx
是一个强大、灵活且高性能的Web服务器,适用于处理各种规模的网络流量和应用场景。
二、正向代理与反向代理解读
1)正向代理
正向代理是代理服务器位于客户端和目标服务器之间,代理服务器代表客户端向目标服务器发出请求。目标服务器不知道实际发起请求的是客户端,而是以为是代理服务器发起的。
使用场景:
- 访问受限资源: 当客户端无法直接访问某些资源,但代理服务器可以访问,这时可以通过正向代理来获取目标资源。
- 隐私保护: 客户端通过正向代理访问目标服务器,目标服务器无法直接识别客户端,从而保护了客户端的隐私。
客户端 --> 正向代理服务器 --> 目标服务器
【总结】正向代理可以通俗的理解就是需要客户端设置,面向用户的,对用户是感知的,例如:访问国外的网站,Google等,就需要配置代理。这个代理就是属于正向代理了。
2)反向代理
反向代理是代理服务器位于目标服务器和客户端之间,代理服务器代表目标服务器向客户端提供服务。客户端不知道实际提供服务的是目标服务器,而是以为是代理服务器提供的。
使用场景:
- 负载均衡: 多个目标服务器提供相同服务,反向代理可以根据负载均衡算法将请求分发到不同的服务器,以提高系统性能和可用性。
- 隐藏目标服务器: 反向代理可以隐藏后端的真实服务器,提高安全性。
客户端 --> 反向代理服务器 --> 目标服务器
【总结】反向代理跟正向代理正好相反,反向代理是代理后端服务器的,面向服务器端的,对用户是无感知的。例如:使用反向代理来实现负载均衡,将客户端的请求分发到多个服务器上,提高系统的性能和可扩展性。
三、NGINX 四层与七层代理
Nginx 可以作为四层(Layer 4)和七层(Layer 7)代理,这指的是它在 OSI 模型中的不同层次上提供代理服务的能力。
1)NGINX 四层代理
四层代理工作在 OSI 模型的传输层,主要基于网络协议信息(IP地址和端口号)来进行转发。
功能:
- 基于 IP 地址和端口号: 四层代理根据源 IP 地址、目标 IP 地址、源端口号和目标端口号等信息进行转发决策。
- 负载均衡: 可以进行四层的负载均衡,将请求分发到多个后端服务器,以提高系统的性能和可用性。
应用场景: 适用于需要基于传输层信息进行转发的场景,如负载均衡、TCP代理等。
示例配置如下:
2)NGINX 七层代理
七层代理工作在 OSI 模型的应用层,可以理解为能够读取和理解 HTTP/HTTPS 协议的代理。
功能:
- 基于应用层代理: 七层代理不仅考虑网络协议信息,还能够读取和理解 HTTP 头部等应用层信息,以进行更精细的处理。
- 反向代理: 可以用于反向代理,根据请求的 URL、域名、Cookie 等信息进行转发决策。
应用场景: 适用于需要深度理解和处理应用层协议信息的场景,如反向代理、内容缓存等。
示例配置如下:
四、NGINX 安装
1)yum 安装
# 安装EPEL的源
yum -y install epel-release
# 安装nginx
yum -y install nginx
# 默认路径
/usr/sbin/nginx
/etc/nginx/nginx.conf
/usr/share/nginx/html
2)源码编译安装
1、下载源码包
官方地址:http://nginx.org
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -xf nginx-1.24.0.tar.gz
2、编译
yum install -y gcc pcre-devel openssl-devel
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
make
make install
3)access 与 error 日志配置
1、log_format 字段讲解
在 Nginx 中,log_format
用于定义日志的格式,可以根据实际需求自定义日志的内容。以下是一些常见的 log_format
字段及其含义:
常用字段:
-
$remote_addr
: 客户端的 IP 地址。 -
$remote_user
: 通过 HTTP 基本认证的用户名,如果没有认证则为空。 -
$time_local
: 本地时间,日志记录的时间。 -
$request
: 客户端的请求行,包括请求方法、请求路径、HTTP 协议版本。 -
$status
: HTTP 状态码,表示请求的处理结果。 -
$body_bytes_sent
: 发送给客户端的响应正文的字节数。 -
$http_referer
: 表示从哪个 URL 链接访问过来的。 -
$http_user_agent
: 客户端浏览器的相关信息。 -
$http_x_forwarded_for
: 客户端的真实 IP 地址,如果通过代理,则该字段表示真实的客户端 IP。 -
$request_time
: 请求处理的总时间,单位为秒。 -
$upstream_response_time
: 从发起请求到收到上游服务器响应的时间,用于反向代理的场景。 -
$host
: 请求中的主机头字段。 -
$server_addr
: 服务器 IP 地址。 -
$server_port
: 服务器端口号。
以下是一个常见的 log_format
示例:
# log_format 的默认输出格式不是 JSON。Nginx 的默认日志格式是一种非 JSON 的格式,通常是一个由空格分隔的字符串。
# 示例一:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 希望将日志格式设置为 JSON,你需要显式地使用 log_format 指令并定义 JSON 格式,同时可以使用 escape=json 参数来确保特殊字符得到适当的转义,以便生成有效的 JSON。
# 示例二(json 格式):
log_format json escape=json
'{"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"}';
此配置定义了一个名为 main
的日志格式,包含了常见的访问信息,可以在 access_log
中引用这个格式:
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
# log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
# access_log /var/log/nginx/access.log main;
log_format json escape=json
'{"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"}';
access_log /var/log/nginx/access.log json;
}
在特殊字符处理中,escape
参数有以下几个选项:
-
none
: 默认选项,不进行特殊字符转义。 -
json
: 将特殊字符进行 JSON 转义,确保日志是有效的 JSON。 -
default
: 使用默认的转义规则,对一些特殊字符进行转义。
2、配置访问日志(Access Log)
访问日志用于记录客户端请求的详细信息,如访问时间、客户端 IP、请求方法、请求路径、HTTP 状态码等。
在 server
或 location
块中,使用 access_log
指令配置访问日志。
access_log
指令的基本语法如下:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
其中:
path
是指定访问日志文件的路径。format
是可选的参数,用于指定日志的格式。- 其他参数如
buffer
、gzip
、flush
等是一些进一步的配置选项,用于控制日志的缓冲、压缩、刷新等行为。
示例配置:
server {
listen 80;
server_name example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
log_format json escape=json
'{"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"}';
access_log /var/log/nginx/access.log json;
}
注意:在 Nginx 中,
access_log
指令不涉及日志级别的概念,因为它主要用于配置访问日志的输出方式和格式,而不是定义不同级别的日志记录。而error_log
有日志级别配置。
3、配置错误日志(Error Log)
在 Nginx 配置文件中,error_log
可以在全局级别(http
块)和 server
块级别进行配置。配置在 server
块中的 error_log
会覆盖全局配置。
在 Nginx 中,error_log
指令用于配置错误日志的输出。它的基本语法如下:
error_log file [level];
其中:
file
是指定错误日志文件的路径。level
是可选参数,用于指定错误日志的级别。如果不指定级别,默认是error
。
Nginx 支持以下几个错误日志级别:
-
debug: 详细的调试信息,用于排查问题,但在生产环境中通常不建议启用,因为会产生大量日志。
-
info
: 提供一般性的信息,用于记录一些关键事件。 -
notice
: 用于记录一些需要注意的信息,但不是错误。 -
warn
: 记录警告信息。 -
error
: 记录错误信息,这是默认级别。 -
crit
: 记录关键性错误信息,通常表示发生了严重的问题。 -
alert
: 记录需要立即采取行动的问题,通常需要管理员干预。 -
emerg
: 紧急情况,系统无法继续运行,通常需要立即采取行动。
http {
# 其他配置...
error_log /var/log/nginx/error.log;
}
4)nginx.conf 配置
Nginx 的主要配置文件是 nginx.conf
,该文件包含了全局配置、HTTP 模块配置以及一些其他模块的配置。以下是一个简单的 nginx.conf 配置文件,并对其中的各部分进行了说明:
# 创建七层与四层配置目录
mkdir vhosts tcp_proxy
nginx.conf
配置
user nginx; # Nginx worker 进程的运行用户
worker_processes auto; # 根据 CPU 核数自动设置 worker 进程数
pid /usr/local/nginx/logs/nginx.pid; # 进程 ID 文件路径
events {
worker_connections 1024; # 每个 worker 进程允许的最大连接数
}
http {
include /usr/local/nginx/conf/mime.types; # 包含 MIME 类型配置文件
default_type application/octet-stream; # 默认 MIME 类型
sendfile on; # 启用 sendfile,提高文件传输性能
tcp_nopush on; # 启用 tcp_nopush 优化
tcp_nodelay on; # 启用 tcp_nodelay 优化
keepalive_timeout 65; # 客户端与服务器连接的超时时间
types_hash_max_size 2048; # MIME 类型哈希表大小
log_format json escape=json
'{"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for"}';
access_log /usr/local/nginx/logs/access.log json; # 访问日志文件路径
error_log /usr/local/nginx/logs/error.log error; # 错误日志文件路径
server {
listen 80; # 监听端口号
server_name example.com; # 服务器名称
location / {
root /usr/local/nginx/html; # 网站根目录
index index.html; # 默认首页文件
}
# 可以添加更多的 server 块配置,用于定义不同的虚拟主机
}
# 可以添加更多的 server 块配置,用于定义不同的虚拟主机
}
include /usr/local/nginx/conf/vhosts/*.conf; # 七层代理配置文件
include /usr/local/nginx/conf/tcp_proxy/*.conf; # 七层代理配置文件
上述配置文件中的说明如下:
user
:指定 Nginx worker 进程的运行用户。worker_processes
:指定 Nginx 启动的 worker 进程数,使用 auto 表示自动根据 CPU 核数设置。error_log
:指定错误日志文件的路径。pid
:指定 Nginx 进程 ID 文件的路径。events
:定义全局事件模块的配置,如 worker 进程的连接数等。http
:定义全局 HTTP 模块的配置,包括 MIME 类型、默认类型等。include
:包含其他配置文件,通常用于将配置分散到多个文件中以便管理。server
:定义虚拟主机的配置,包括监听的端口号、服务器名称、根目录等。location
:定义请求匹配的位置和处理规则,通常用于配置 URL 路由和反向代理。
5)启动nginx
# 检测nginx语法
nginx
# 查看nginx进程
ps -ef|grep nginx
6)配置启动脚本 nginx.service
# /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动
# 先把上面启动的nginx停掉
pkill -9 nginx
# 从新加载脚本配置
systemctl daemon-reload
# 开机自启
systemctl enable nginx
#
systemctl start nginx
systemctl stop nginx
7)从新加载nginx配置
# 检测配置是否正常
nginx -t
# 重新加载配置
nginx -s reload
8)nginx 日志滚动切割
在 Nginx
中,日志切割和滚动是通过外部工具来完成的,常见的工具包括 logrotate
。logrotate
是一个用于管理日志文件的工具,它可以定期滚动、压缩和删除日志文件,以避免日志文件无限增长。
以下是一个简单的示例,演示如何使用 logrotate
配合 Nginx
进行日志切割和滚动:
1、安装 logrotate
# CentOS/RHEL
sudo yum -y install logrotate
2、创建 logrotate 配置文件
创建一个 logrotate
配置文件,例如 /etc/logrotate.d/nginx
:
sudo vi /etc/logrotate.d/nginx
在文件中添加以下内容:
/usr/local/nginx/logs/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
if [ -f /usr/local/nginx/logs/nginx.pid ]; then
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
fi
endscript
}
这个配置文件指示 logrotate 对 /var/log/nginx/ 目录下的所有 .log 文件进行日志切割。配置中的一些关键选项包括:
daily
:每天滚动一次日志。rotate 7
:保留过去7
天的日志文件。compress
:使用gzip
压缩旧的日志文件。delaycompress
:延迟压缩,直到下一次滚动时再进行压缩。postrotate
和endscript
:在滚动后执行的命令块,用于通知Nginx
重新打开日志文件。size
:如果你使用了size
选项来指定日志文件大小,logrotate
只有在达到指定大小时才会滚动。如果当前日志文件大小未达到设定的阈值,就不会滚动。
3、测试 logrotate
可以手动运行 logrotate
进行测试,查看是否能够正确地滚动和压缩日志文件。
# 没达到要求就不会滚动
sudo logrotate -d /etc/logrotate.d/nginx
# 如果你确实希望手动强制执行一次日志滚动,你可以使用以下命令:
sudo logrotate -f /etc/logrotate.d/nginx
# 这里的 -f 选项表示强制执行,即使认为不需要滚动也进行滚动。注意,手动滚动日志时,可能会打断正在运行的 Nginx 进程,所以最好在低流量时执行。
-d
选项用于调试模式,实际执行时可以去掉该选项。
logrotate
将在每天的指定时间运行,默认情况下,它通常是系统的日志轮询时间(通常是凌晨)。这样,你就可以使用 logrotate
来定期维护和管理 Nginx
的日志文件,避免日志文件不断增大导致磁盘空间耗尽。
五、四层与七层代理配置
1)四层代理配置
cd /usr/local/nginx/conf/tcp_proxy/
# vi tcp_proxy.conf
stream {
upstream backend {
server backend1.example.com:8080;;
server backend2.example.com:8080;;
# Add more backend servers as needed
}
server {
listen 8080;
proxy_pass backend;
}
}
解释一下这个配置:
stream
模块用于配置四层代理。upstream
块定义了后端服务器的地址和端口,你可以根据需要添加更多的后端服务器。server
块定义了监听的端口(在这里是 80),并通过 proxy_pass 将流量代理到定义的后端服务器上。
重新加载配置
nginx -t
nginx -s reload
如果报错:
nginx: [emerg] unknown directive "stream" in /usr/local/nginx/conf/tcp_proxy/tcp_proxy.conf:1 nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
安装stream模块
yum -y install epel-release
yum -y install nginx-all-modules.noarch
重新编译nginx,加入stream模块
# --with-stream=dynamic
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-stream=dynamic
# 重新编译
make
make install
nginx.conf
最顶部加入:
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;
如果还是报错,则直接拷贝nginx
源码objs
中的文件
cp ./objs/ngx_stream_module.so /usr/lib64/nginx/modules/
2)七层代理配置
在 Nginx 中进行七层代理,通常指的是 HTTP 代理,它能够理解和操作 HTTP 协议,能够进行更精细的请求分发和处理。以下是一个简单的七层代理配置示例:
cd /usr/local/nginx/conf/vhosts
vi http_proxy.conf
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
# Add more backend servers as needed
}
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
块定义了后端服务器的地址。在这里,backend1.example.com
和backend2.example.com
是代理请求的后端服务器。你可以根据需要添加更多的后端服务器。 -
server
块定义了监听的端口(在这里是 80),并配置了一个基本的请求代理。 -
location
/ 块指定了代理的路径,即所有路径。你可以根据需要修改这个路径。 -
proxy_pass
指令将请求代理到定义的后端服务器。 -
proxy_set_header
指令用于设置转发给后端服务器的一些 HTTP 头信息,以确保后端服务器能够正确获取客户端的真实信息。
这个配置允许 Nginx 接收来自客户端的 HTTP 请求,然后将这些请求代理到后端服务器上,并在代理过程中保留了一些原始的 HTTP 头信息。
NGINX - 高级负载均衡器、Web服务器、反向代理简单讲解就先到这里了,上面的内存只是nginx的最基础的部分,后部分更精彩,有任何疑问也可关注我公众号:大数据与云原生技术分享,进行技术交流,如本篇文章对您有所帮助,麻烦帮忙一键三连(点赞、转发、收藏)~