湖州网站设计,吉林网站建设哪家好,学做预算有网站吗,网站建设公司专业的建站优化公司高并发数据采集场景下#xff0c;要优化Nginx反向代理来支持多个Netty数采服务并保证稳定的性能#xff0c;可以从以下几个方面对Nginx进行优化配置。 直连模式#xff08;直接通过 Nginx 处理与后端 Netty 服务的连接#xff0c;而不作为反向代理#xff09;#xff0c;…高并发数据采集场景下要优化Nginx反向代理来支持多个Netty数采服务并保证稳定的性能可以从以下几个方面对Nginx进行优化配置。 直连模式直接通过 Nginx 处理与后端 Netty 服务的连接而不作为反向代理很多配置将无法使用。以下是一些无法应用于直连模式的配置和原因 proxy_* 配置 直连模式下Nginx 直接处理客户端请求并与后端服务建立连接因此 proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout、proxy_buffers、proxy_buffer_size 等 proxy_* 相关配置将不再适用。这些配置是针对代理模式设计的用于调整 Nginx 转发请求到后端时的行为。proxy_request_buffering off 和 tcp_nodelay proxy_request_buffering off 主要用于避免缓冲请求体在反向代理模式下用于优化实时性。但在直连模式下Nginx 会直接处理客户端与后端服务的连接因此不需要该配置。tcp_nodelay on 仍然有效它禁用 Nagle 算法有助于减少小数据包的延迟但这个配置本身不依赖于代理模式。 accept_mutex accept_mutex on 配置用于避免多个工作进程同时接受连接即避免“惊群效应”在直连模式下如果 Nginx 不作为反向代理而直接与后端建立连接这个配置也通常不需要因为连接接入和处理模式不同。 upstream 和健康检查 健康检查配置如 nginx_upstream_check_module是针对 Nginx 作为反向代理时用于检查后端服务健康状态的配置。直连模式下如果没有进行负载均衡或使用代理服务器这些配置将无法使用。 keepalive_timeout 和 keepalive_requests 这些配置在直连模式下仍然可能需要但其意义略有不同。keepalive_timeout 会影响连接在空闲时的保持时间keepalive_requests 限制了每个连接的最大请求数。虽然这些配置不完全依赖于代理模式它们在直连模式中依然重要特别是在长连接场景下。 worker_processes 和 worker_cpu_affinity 这些配置用于调整 Nginx 的多进程并行处理能力对于直连模式下的高并发连接优化仍然适用。 适用于直连模式的配置
worker_processes 和 worker_cpu_affinity对于高并发场景仍然需要调整工作进程和 CPU 核心绑定。worker_connections调整每个工作进程能够处理的最大连接数适用于高并发的直连模式。keepalive_timeout 和 keepalive_requests优化连接的保持时间和请求数。tcp_nodelay on减少数据包的延迟适用于实时性要求高的场景。epoll 和 multi_accept优化事件处理机制适用于高并发的 Linux 系统。
1. 调整Nginx工作进程与CPU绑定 默认情况下Nginx的worker_processes数量通常与CPU核心数一致。对于4核CPU可以设置为4 worker_processes 4;同时可以通过worker_cpu_affinity来将每个worker进程与一个CPU核心绑定减少上下文切换的开销提高CPU缓存命中率 worker_cpu_affinity 0001 0010 0100 1000; 这些数字分别对应CPU 0、CPU 1、CPU 2、CPU 3 这4个CPU核心。
2. 调整Nginx连接数与并发处理能力 通过worker_connections设置每个worker的最大连接数。由于每秒有大量数据流入适当调高这个值很重要。假设每秒有数千连接可以设置一个较大的值比如 events {worker_connections 4096;
}这意味着每个worker可以处理最多4096个连接结合4个worker理论最大连接数可达16384。 当前场景下每秒有3000条消息上报但这并不意味着总的连接数是固定的。每个采集点可能保持一个长连接来持续发送数据连接数相对较少也可能每次都建立新的连接连接数会更高。worker_connections设置的目的是保证每个Nginx worker可以处理足够多的并发连接。
3. 优化Nginx网络模型使用epoll 在Linux系统下epoll是高效的I/O多路复用模型适合高并发环境。确保在events块中使用epoll events {use epoll;multi_accept on;
}4. 增加请求缓存与队列能力 由于数据量大可以通过设置accept_mutex为on来避免惊群效应确保请求在多个worker之间合理分发 accept_mutex on; **惊群效应THP**是指当多个进程或线程等待同一个事件发生时事件触发时所有进程或线程都被唤醒争夺资源导致性能下降。在Nginx的上下文 中如果多个worker进程同时被唤醒来处理一个新的连接请求而实际上只有一个worker能够成功处理这个请求其它worker被唤醒但不能工作就会造成 资源浪费。通过启用accept_mutex可以确保每次只有一个worker被唤醒来接受新的连接请求减少不必要的竞争和浪费从而避免惊群效应。
5. 避免缓存 默认情况下Nginx 会在接收到客户端的完整请求后先将请求体缓存在内存或磁盘中然后再将整个请求一次性发送给后端服务。对于数据采集的场景一般要求实时性较高我们需要立即将数据转发给后端服务而不需要等待整个请求完成对于半包粘包问题由后端服务处理。 proxy_request_buffering off;启用 TCP_NODELAY 选项禁用 Nagle 算法。这可以减少数据包传输的延迟有助于实时性要求较高的数据采集场景。 tcp_nodelay on;6. 优化缓冲区与响应处理 根据1KB的数据大小可以优化Nginx的缓冲区设置确保它能高效处理数据。 调整客户端请求体缓冲区大小 (client_body_buffer_size) 和代理缓冲区大小 (proxy_buffers) client_body_buffer_size 16k;
proxy_buffer_size 16k;
proxy_buffers 8 32k;
proxy_busy_buffers_size 64k; Nginx是流式处理的Nginx在接收客户端请求时会分批处理数据而不是将整个流量积攒到缓冲区里。即使每秒钟传输的数据总量是3MB3000 X 1KB ≈ 3MBNginx会在接收到数据时直接转发给后端而不是缓存所有数据。Nginx在处理每个连接时会根据流入的数据流量和后端响应的速度进行动态处理不会把所有数据一次性存入缓冲区。
缓冲区的作用是处理单次请求的流量client_body_buffer_size和 proxy_buffers 的大小主要是为了处理单次请求的数据1KB确保不会频繁写入磁盘。client_body_buffer_size应该设置为略大于单条数据的大小一般为16KB或者其倍数这将允许Nginx在不写入临时文件的情况下处理单个或多个小型数据块。
下面是这几个参数的详细解释
client_body_buffer_size定义客户端请求体的内存缓冲区大小。当客户端向Nginx发送数据时Nginx会把请求体缓存在内存里直到数据达到一定大小。如果请求体超过这个配置的大小Nginx就会将超出的部分写入磁盘的临时文件中。在这次的场景中每条消息大约1KB大小设置 client_body_buffer_size 为 16KB 的意义在于可以有效地处理客户端发送的数据而不需要频繁地写入磁盘。如果单条数据小于这个值所有数据都可以暂存在内存中加快处理速度并减少磁盘I/O。写入磁盘会影响性能。
如果应用对消息的QoS要求较高的话下面的配置会比较有用但是一般情况下不是特别重要的实时数据是不会用到的。如果没有后端响应要回传客户端的话建议使用**proxy_buffering off;**关闭对代理数据的缓存处理。
proxy_buffer_size这是 Nginx 读取后端服务器响应时的单次读取缓冲区。每次从后端获取响应时Nginx会先将响应暂时放在这个缓冲区中。例如proxy_buffer_size 设置为 16kNginx每次从后端服务器读取16KB的数据存放在这个缓冲区。proxy_buffers是一组缓冲区用来暂时存储从后端读取的数据等待发送到客户端。proxy_buffers 8 32k 表示 Nginx 分配了 8 个 32KB 大小的缓冲区来存储从后端获取的数据。也就是说Nginx 可以在内存中临时存储最多 8 * 32KB 256KB 的响应数据。从 proxy_buffer_size 中读取的数据会被进一步存放到 proxy_buffers 中。当 proxy_buffers 中的数据准备好后Nginx开始将这些数据发送给客户端。proxy_busy_buffers_size主要控制当Nginx在向客户端发送数据时仍然处于“繁忙状态”的缓冲区大小。 繁忙状态 是指缓冲区中的数据已经开始发送到客户端但还没有完全发送出去。Nginx会在后台继续读取后端服务器的数据并将这些数据存放到缓冲区中而同时Nginx会在前台将已经读取到的数据发送给客户端。这个过程中proxy_busy_buffers_size 用来限制这个前台数据传输过程中仍在被使用的缓冲区繁忙缓冲区的最大大小。如果 proxy_busy_buffers_size 设置为 64k则表示在发送给客户端的过程中Nginx最多允许 64KB 的缓冲区数据仍然处于忙碌状态即正在被发送或等待发送。当繁忙缓冲区超过这个值时Nginx会停止从后端读取更多数据直到客户端接收完这些数据从而避免前后端的流量不平衡。
7. 增加客户端连接保持与超时时间 在数据采集场景中客户端可能会持续发送数据。因此可以增加客户端连接的保持时间减少重复建立连接的开销 keepalive_timeout 60;
keepalive_requests 0;keepalive_timeout这是Nginx 在关闭这个连接之前等待的时间。当客户端发送完数据后连接会被保持一段时间而不是立即关闭。如果在 keepalive_timeout 的时间内有新的数据发送Nginx 会继续使用这个连接从而避免了重新建立连接的开销。 keepalive_requests是为了防止单个连接持续占用资源过久限制在同一个保持连接Keep-Alive连接中客户端最多可以发送的请求数量而对于现在的数据采集场景不需要限制每个长连接的请求数。
8. 优化反向代理配置 Nginx作为反向代理负责将请求转发给后端Netty服务配置时需要确保Nginx可以高效转发大流量的数据。 设置合适的proxy_connect_timeout和proxy_read_timeout来保证大数据传输 proxy_connect_timeout 5s;
proxy_read_timeout 120s;
proxy_send_timeout 120s; 这三个参数主要用于控制Nginx与后端服务器Netty服务之间的连接和数据传输。proxy_connect_timeout定义了Nginx与后端服务器建立连接的超时时间proxy_read_timeout定义了Nginx从后端服务器读取响应的超时时间proxy_send_timeout设置了Nginx发送请求到后端服务器的超时时间。
多网卡支持海量长连接
在反向代理过程中NGINX 作为客户端与后端采集服务节点建立连接。在这种情况下单个 IP 地址最多能够创建约 6 万个长连接。为了支持更多的连接可以选择部署多个 NGINX 服务器或者配置多个 IP 地址。
配置多个 IP需要使用 NGINX 内置的 split_clients 模块来定义一个变量 $multi_ip根据客户端的 IP 地址和端口号进行请求分流需要确保所使用的 IP 地址在本地可用。
stream {split_clients $remote_addr$remote_port $multi_ip { 20% 192.168.0.105; 20% 192.168.0.106; 20% 192.168.0.107; 20% 192.168.0.108; * 192.168.0.109; }upstream netty_servers {server 192.168.0.211:8083;server 192.168.0.212:8083;}server {listen 8083;proxy_pass netty_servers;proxy_bind $multi_ip;}
}9. 内核参数优化 可以调整Linux内核参数来配合Nginx尤其是针对高并发场景的网络连接与文件描述符限制 sysctl -w net.core.somaxconn65535
sysctl -w net.core.netdev_max_backlog65535
sysctl -w net.ipv4.tcp_max_syn_backlog65535
ulimit -n 6553510. SSL 缓存和复用 因为需要交换密钥等操作SSL 握手过程很耗时如果使用SSL可以考虑开启SSL缓存和复用来优化SSL连接处理。通过启用 SSL Session 缓存Nginx 可以将每个 SSL 会话的状态保存起来在后续的连接中直接使用之前的会话状态避免重复的 SSL 握手过程。 ssl_session_cache shared:SSL:10m; # 共享内存中缓存SSL会话大小为10MB
ssl_session_timeout 10m; # SSL会话缓存的超时时间为10分钟
ssl_protocols TLSv1.2 TLSv1.3; # 使用现代的安全协议
ssl_prefer_server_ciphers on; # 优先使用服务器指定的加密套件当客户端与服务器第一次建立连接后服务器会生成一个 Session ID 并保存在缓存中。后续相同客户端与服务器的连接可以重用这个会话 ID跳过完整的握手过程只需要进行快速的重新协商。 通过 ssl_session_timeout 保证了在复用的时间窗口内10分钟内可以重用会话。过了这个时间后必须重新进行完整握手这样可以确保长期会话不会被滥用。
11. 添加健康检查机制 Nginx 可以通过配置来定期检测后端服务的健康状况主动健康检查。健康检查机制有助于及时发现并隔离故障的服务实例防止请求被路由到不可用的服务上。nginx_upstream_check_module 模块不是 Nginx 的默认模块需要单独编译或安装。 upstream backend {server netty1.example.com:8080;server netty2.example.com:8080;server netty3.example.com:8080;# 健康检查配置check interval3000 rise2 fall3 timeout1000 typehttp;# 指定健康检查的路径check_http_send HEAD /health HTTP/1.0\r\nHost: $host\r\n\r\n;check_http_expect http_200;
}参数详解 interval3000表示 Nginx 每隔 3000 毫秒即 3 秒检查一次后端服务器的健康状态。rise2表示后端服务器被认为健康之前必须连续成功响应两次健康检查请求。fall3表示后端服务器被认为不健康之前连续失败三次健康检查请求。timeout1000表示健康检查请求的超时时间为 1000 毫秒即 1 秒。如果在这段时间内没有得到响应健康检查就会认为失败。typehttp表示健康检查采用 HTTP 协议默认情况下 Nginx 会发送一个 HEAD 请求到后端服务器的默认监听地址。check_http_send 指令用于定义 Nginx 向后端服务器发送的健康检查请求的具体内容。 HEAD表示这是一个 HTTP HEAD 请求HEAD 请求与 GET 请求类似但不会返回请求体的内容只返回响应头。/health这是请求的路径通常用于健康检查。Netty 服务应该监听这个路径并在收到请求时返回相应的健康状态。HTTP/1.0这是请求使用的 HTTP 版本。虽然现在常用的是 HTTP/1.1但由于 HEAD 请求通常不需要响应体使用 HTTP/1.0 也是常见的做法。Host: $host这是请求中的 Host 头部字段用于指示请求的目标主机。$host 是一个变量它会被替换为实际请求的目标主机名。\r\n这是换行符用于分隔不同的 HTTP 请求头字段最后一个是请求的结束标志。 check_http_expect指的是望收到 200 OK 状态码。 SpringBoot工程定义健康检查的接口 import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;RestController
public class HealthController {/*** 处理 HEAD 请求。** return ResponseEntity 表示响应的状态码*/RequestMapping(value /health, method RequestMethod.HEAD)public ResponseEntityVoid health() {return ResponseEntity.ok().build();}
}虽然使用Nginx的请求超时和重试机制可以减少不健康服务的影响但最佳实践仍然是显式配置健康检查以确保请求只被转发到健康的后端服务。 被动健康检查是 Nginx 的内置功能无需额外安装模块或配置复杂的健康检查逻辑。对于一般的反向代理需求这种机制已经足够应对常见的故障情况。 upstream backend {server 192.168.0.211:8083 weight3 max_fails3 fail_timeout30s slow_start30s;server 192.168.0.212:8083 weight1 max_fails3 fail_timeout30s slow_start30s;server 192.168.0.213:8083 backup;server 192.168.0.214:8083 down;
}max_fails3 表示如果一个服务器在 fail_timeout 时间内连续失败 3 次则认为该服务器不可用。fail_timeout30s 表示在这个时间段内如果某个服务器连续失败达到 max_fails 次数即 3 次则该服务器会被标记为不可用。 自动切换机制如下 当 Nginx 尝试向 192.168.0.211:8083 发送请求但未能成功时例如连接超时、读写错误等它不会立即停止尝试而是继续在同一时间窗口内重试。如果 192.168.0.211:8083 在接下来的 30 秒内连续失败 3 次Nginx 会将其标记为不可用并暂时不再向其发送新的请求。一旦某个服务器被标记为不可用Nginx 会根据配置的负载均衡算法默认为轮询选择其他可用的服务器来处理请求。在这个例子中它会尝试将请求发送到 192.168.0.212:8083。被标记为不可用的服务器会在 fail_timeout 时间30 秒结束后重新参与请求分配周而复始直到服务恢复正常。对于刚刚恢复的服务器Nginx会在接下来的 slow_start30s 内逐渐增加其接收的请求数量而不是立即恢复正常负载。
12. 错误处理与重试策略
当出现网络异常或后端服务故障时可以配置 Nginx 来自动重试请求或者根据返回的状态码执行特定的操作如重定向到另一个 URL 或返回特定的错误页面。
location / {proxy_pass http://backend;# 自动重试策略proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;proxy_next_upstream_tries 2;proxy_next_upstream_timeout 10s;# 错误处理error_page 500 502 503 504 /50x.html;location /50x.html {root /usr/share/nginx/html;}
} proxy_next_upstream 指令定义了当遇到哪些类型的错误时 Nginx 将尝试切换到下一个可用的后端服务器。error指与后端服务器的连接失败timeout指与后端服务器连接超时invalid_header指当从后端服务器接收到无效的响应头其他就是后端服务响应的状态码。
proxy_next_upstream_tries 则定义了在切换到下一个后端之前尝试的次数。error_page 指令用于定义当出现特定错误码时返回的页面。
这些配置不仅保护了站点免受常见攻击还提高了系统的整体安全性。在实际部署时可以根据具体需求调整配置项确保既提高了安全性又不影响正常的服务运作。
需要说明的是即便没有额外配置Nginx 会对特定的错误如 error、timeout、http_500 等尝试自动重试。但是默认重试的次数没有明确的数值而是由后端服务器的数量决定因为重试行为与 upstream 中定义的后端服务器列表紧密相关。Nginx 默认会尝试将请求转发到 upstream 配置中的其他服务器直到尝试过所有健康的服务器或没有可用服务器为止。如果只有一个后端服务器即使失败了也不会重试。如果有多个后端服务器Nginx 会按配置的负载均衡算法逐个尝试。
默认情况下重试不限制具体次数而是受每个后端服务器响应超时时间proxy_connect_timeout 和 proxy_read_timeout 参考优化反向代理配置中关于此参数的说明以及 proxy_next_upstream_timeout 的影响。如果没有设置 proxy_next_upstream_timeoutNginx 会继续重试直到用尽后端服务器或客户端连接超时。