NGINX - 高级负载均衡器、Web服务器、反向代理

一、概述

Nginx 是一个高性能的开源Web服务器,也可以用作反向代理服务器、负载均衡器和HTTP缓存。它的设计目标是提供高并发、低内存消耗和高度可伸缩性,使其成为处理大量并发连接的理想选择。以下是关于Nginx的一些关键特点和功能:

  • 高性能Nginx 的事件驱动架构和高效的内存使用使其能够处理大量并发连接,而不会消耗过多的系统资源。它被广泛用于构建高性能的Web服务器和应用程序。

  • 反向代理Nginx 可以作为反向代理服务器,将客户端的请求转发给后端的应用服务器。这对于提高应用的安全性、可伸缩性和灵活性非常有用。

  • 负载均衡Nginx 提供了负载均衡功能,可以平均分配流量到多个后端服务器,从而提高系统的稳定性和性能。负载均衡可以通过不同的算法进行配置,例如轮询、IP哈希、最小连接数等。

  • 静态文件服务和缓存Nginx 可以高效地提供静态文件服务,并支持HTTP缓存,减轻后端服务器的压力。它还能够通过gzip压缩来减小传输的数据量,提高网站的加载速度。

  • SSL/TLS支持Nginx 支持SSL/TLS协议,可以用于安全地加密传输数据。这对于保护用户隐私和确保数据完整性非常重要。

  • 模块化架构Nginx 的模块化架构允许用户根据需要添加或移除功能。它支持丰富的第三方模块,使得用户可以自定义和扩展Nginx的功能。

  • 日志记录Nginx 提供详细的访问日志和错误日志,方便管理员进行故障排除和性能调优。

  • 易于配置Nginx 的配置文件采用简洁而直观的语法,易于理解和维护。同时,它支持热加载配置,不需要重启即可生效配置更改。

  • 支持多协议 :除了HTTP/HTTPSNginx 还支持其他网络协议,如SMTPIMAPPOP3等,使其具备更广泛的应用领域。

  • 活跃的社区和广泛的采用Nginx 是一个开源项目,拥有庞大的社区支持。由于其高性能和稳定性,它被广泛采用作为Web服务器和反向代理服务器。

总体而言,Nginx 是一个强大、灵活且高性能的Web服务器,适用于处理各种规模的网络流量和应用场景。

二、正向代理与反向代理解读

1)正向代理

正向代理是代理服务器位于客户端和目标服务器之间,代理服务器代表客户端向目标服务器发出请求。目标服务器不知道实际发起请求的是客户端,而是以为是代理服务器发起的。

使用场景:

  • 访问受限资源: 当客户端无法直接访问某些资源,但代理服务器可以访问,这时可以通过正向代理来获取目标资源。
  • 隐私保护: 客户端通过正向代理访问目标服务器,目标服务器无法直接识别客户端,从而保护了客户端的隐私。
bash 复制代码
客户端 --> 正向代理服务器 --> 目标服务器

【总结】正向代理可以通俗的理解就是需要客户端设置,面向用户的,对用户是感知的,例如:访问国外的网站,Google等,就需要配置代理。这个代理就是属于正向代理了。

2)反向代理

反向代理是代理服务器位于目标服务器和客户端之间,代理服务器代表目标服务器向客户端提供服务。客户端不知道实际提供服务的是目标服务器,而是以为是代理服务器提供的。

使用场景:

  • 负载均衡: 多个目标服务器提供相同服务,反向代理可以根据负载均衡算法将请求分发到不同的服务器,以提高系统性能和可用性。
  • 隐藏目标服务器: 反向代理可以隐藏后端的真实服务器,提高安全性。
bash 复制代码
客户端 --> 反向代理服务器 --> 目标服务器

【总结】反向代理跟正向代理正好相反,反向代理是代理后端服务器的,面向服务器端的,对用户是无感知的。例如:使用反向代理来实现负载均衡,将客户端的请求分发到多个服务器上,提高系统的性能和可扩展性。

三、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 安装

bash 复制代码
# 安装EPEL的源
yum -y install epel-release
# 安装nginx
yum -y install nginx

# 默认路径
/usr/sbin/nginx
/etc/nginx/nginx.conf
/usr/share/nginx/html

2)源码编译安装

1、下载源码包

官方地址:nginx.org

bash 复制代码
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -xf nginx-1.24.0.tar.gz

2、编译

bash 复制代码
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 示例:

bash 复制代码
#  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 中引用这个格式:

bash 复制代码
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 状态码等。

serverlocation 块中,使用 access_log 指令配置访问日志。

access_log 指令的基本语法如下:

bash 复制代码
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

其中:

  • path 是指定访问日志文件的路径。
  • format 是可选的参数,用于指定日志的格式。
  • 其他参数如 buffergzipflush 等是一些进一步的配置选项,用于控制日志的缓冲、压缩、刷新等行为。

示例配置:

bash 复制代码
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 指令用于配置错误日志的输出。它的基本语法如下:

bash 复制代码
error_log file [level];

其中:

  • file 是指定错误日志文件的路径。
  • level 是可选参数,用于指定错误日志的级别。如果不指定级别,默认是 error

Nginx 支持以下几个错误日志级别:

  • debug: 详细的调试信息,用于排查问题,但在生产环境中通常不建议启用,因为会产生大量日志。

  • info: 提供一般性的信息,用于记录一些关键事件。

  • notice: 用于记录一些需要注意的信息,但不是错误。

  • warn: 记录警告信息。

  • error: 记录错误信息,这是默认级别。

  • crit: 记录关键性错误信息,通常表示发生了严重的问题。

  • alert: 记录需要立即采取行动的问题,通常需要管理员干预。

  • emerg: 紧急情况,系统无法继续运行,通常需要立即采取行动。

bash 复制代码
http {
    # 其他配置...

    error_log /var/log/nginx/error.log;
}

4)nginx.conf 配置

Nginx 的主要配置文件是 nginx.conf,该文件包含了全局配置、HTTP 模块配置以及一些其他模块的配置。以下是一个简单的 nginx.conf 配置文件,并对其中的各部分进行了说明:

bash 复制代码
# 创建七层与四层配置目录
mkdir vhosts tcp_proxy

nginx.conf 配置

bash 复制代码
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

bash 复制代码
# 检测nginx语法
nginx
# 查看nginx进程
ps -ef|grep nginx

6)配置启动脚本 nginx.service

bash 复制代码
# /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

启动

bash 复制代码
# 先把上面启动的nginx停掉
pkill -9 nginx
# 从新加载脚本配置
systemctl daemon-reload
# 开机自启
systemctl  enable nginx
# 
systemctl  start nginx
systemctl  stop nginx

7)从新加载nginx配置

bash 复制代码
# 检测配置是否正常
nginx -t
# 重新加载配置
nginx -s reload

8)nginx 日志滚动切割

Nginx 中,日志切割和滚动是通过外部工具来完成的,常见的工具包括 logrotatelogrotate 是一个用于管理日志文件的工具,它可以定期滚动、压缩和删除日志文件,以避免日志文件无限增长。

以下是一个简单的示例,演示如何使用 logrotate 配合 Nginx 进行日志切割和滚动:

1、安装 logrotate

bash 复制代码
# CentOS/RHEL
sudo yum -y install logrotate

2、创建 logrotate 配置文件

创建一个 logrotate 配置文件,例如 /etc/logrotate.d/nginx

bash 复制代码
sudo vi /etc/logrotate.d/nginx

在文件中添加以下内容:

bash 复制代码
/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:延迟压缩,直到下一次滚动时再进行压缩。
  • postrotateendscript:在滚动后执行的命令块,用于通知 Nginx 重新打开日志文件。
  • size :如果你使用了 size 选项来指定日志文件大小,logrotate 只有在达到指定大小时才会滚动。如果当前日志文件大小未达到设定的阈值,就不会滚动。

3、测试 logrotate

可以手动运行 logrotate 进行测试,查看是否能够正确地滚动和压缩日志文件。

bash 复制代码
# 没达到要求就不会滚动
sudo logrotate -d /etc/logrotate.d/nginx

#  如果你确实希望手动强制执行一次日志滚动,你可以使用以下命令:
sudo logrotate -f /etc/logrotate.d/nginx
# 这里的 -f 选项表示强制执行,即使认为不需要滚动也进行滚动。注意,手动滚动日志时,可能会打断正在运行的 Nginx 进程,所以最好在低流量时执行。
  • -d 选项用于调试模式,实际执行时可以去掉该选项。

logrotate 将在每天的指定时间运行,默认情况下,它通常是系统的日志轮询时间(通常是凌晨)。这样,你就可以使用 logrotate 来定期维护和管理 Nginx 的日志文件,避免日志文件不断增大导致磁盘空间耗尽。

五、四层与七层代理配置

1)四层代理配置

bash 复制代码
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 将流量代理到定义的后端服务器上。

重新加载配置

bash 复制代码
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模块

bash 复制代码
yum -y install epel-release
yum -y install nginx-all-modules.noarch

重新编译nginx,加入stream模块

bash 复制代码
# --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 最顶部加入:

bash 复制代码
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;

如果还是报错,则直接拷贝nginx源码objs中的文件

bash 复制代码
cp ./objs/ngx_stream_module.so /usr/lib64/nginx/modules/

2)七层代理配置

在 Nginx 中进行七层代理,通常指的是 HTTP 代理,它能够理解和操作 HTTP 协议,能够进行更精细的请求分发和处理。以下是一个简单的七层代理配置示例:

bash 复制代码
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.combackend2.example.com 是代理请求的后端服务器。你可以根据需要添加更多的后端服务器。

  • server 块定义了监听的端口(在这里是 80),并配置了一个基本的请求代理。

  • location / 块指定了代理的路径,即所有路径。你可以根据需要修改这个路径。

  • proxy_pass 指令将请求代理到定义的后端服务器。

  • proxy_set_header 指令用于设置转发给后端服务器的一些 HTTP 头信息,以确保后端服务器能够正确获取客户端的真实信息。

这个配置允许 Nginx 接收来自客户端的 HTTP 请求,然后将这些请求代理到后端服务器上,并在代理过程中保留了一些原始的 HTTP 头信息。


NGINX - 高级负载均衡器、Web服务器、反向代理简单讲解就先到这里了,上面的内存只是nginx的最基础的部分,后部分更精彩,有任何疑问也可关注我公众号:大数据与云原生技术分享,进行技术交流,如本篇文章对您有所帮助,麻烦帮忙一键三连(点赞、转发、收藏)~

相关推荐
xujiangyan_1 天前
nginx的反向代理和负载均衡
服务器·网络·nginx
viqecel1 天前
网站改版html页面 NGINX 借用伪静态和PHP脚本 实现301重定向跳转
nginx·php·nginx重定向·301重定向·html页面重定向
硪就是硪2 天前
内网环境将nginx的http改完https访问
nginx·http·https
ak啊2 天前
Nginx 安全加固详细配置指南
nginx
沐土Arvin2 天前
Nginx 核心配置详解与性能优化最佳实践
运维·开发语言·前端·nginx·性能优化
haoranyyy3 天前
mac环境中Nginx安装使用 反向代理
linux·服务器·nginx
ak啊3 天前
Nginx 高级缓存配置与优化
nginx
再学一丢丢3 天前
Keepalived+LVS+nginx高可用架构
nginx·架构·lvs
xujiangyan_3 天前
nginx的自动跳转https
服务器·nginx·https
tingting01194 天前
k8s 1.30 安装ingress-nginx
nginx·容器·kubernetes