发布网友 发布时间:2024-09-24 18:34
共1个回答
热心网友 时间:2024-09-24 21:04
本文是Nginx负载均衡实验的一些笔记。
概述前面已经完成了转发的程序,也尝试了一些负载均衡算法,本文对 nginx 的负载均衡做一些简单的测试,有部分实验是为了解答笔者与同事交流时产生的疑惑。
程序本文所用程序,为笔者之前实现的转发程序,实际上任何能响应 post 请求的程序均可。
环境本文实验环境如下: 虚拟机 Linux 运行容器。 虚拟机 Windows 发送 POST 请求。
本文使用镜像centos/nginx-116-centos7进行测试。 启动命令如下:
#$PWD/bin保存了后端的服务,故挂载之dockerrun-itd--namenginx-p8080:8080-v$PWD/bin:/home/latelee/bincentos/nginx-116-centos7nginx-g"daemonoff;"为了配置 nginx,需 root 权限,故使用如下命令进入容器:
sudodockerexec-uroot-itnginxbash后端服务运行命令如下:
/home/latelee/bin/httpforward_back.exe-p9001-i"helloin9001"/home/latelee/bin/httpforward_back.exe-p9002-i"helloin9002"/home/latelee/bin/httpforward_back.exe-p9003-i"helloin9003"重启 nginx 命令如下:
nginx-sreloadnginx 配置文件如下:
cat>/etc/nginx/nginx.conf<<-EOFworker_processesauto;error_log/var/opt/rh/rh-nginx116/log/nginx/error.log;pid/var/opt/rh/rh-nginx116/run/nginx/nginx.pid;#Loaddynamicmodules.See/opt/rh/rh-nginx116/root/usr/share/doc/README.dynamic.include/opt/rh/rh-nginx116/root/usr/share/nginx/modules/*.conf;events{worker_connections1024;}http{log_formatmain'[$time_local]$remote_addr:"$request"''$status"$http_referer"''"$http_user_agent"[$upstream_addr$upstream_status$upstream_response_timems$request_timems]';access_log/var/opt/rh/rh-nginx116/log/nginx/access.logmain;sendfileon;tcp_nopushon;tcp_nodelayon;keepalive_timeout65;types_hash_max_size2048;proxy_connect_timeout10;include/etc/opt/rh/rh-nginx116/nginx/mime.types;default_typeapplication/octet-stream;#Loadmodularconfigurationfilesfromthe/etc/nginx/conf.ddirectory.#Seehttp://nginx.org/en/docs/ngx_core_module.html#include#formoreinformation.include/opt/app-root/etc/nginx.d/*.conf;server{listen8080default_server;listen[::]:8080default_server;server_name_;root/opt/app-root/src;#Loadconfigurationfilesforthedefaultserverblock.include/opt/app-root/etc/nginx.default.d/*.conf;location/{proxy_passhttp://foobar;proxy_set_headerHost$proxy_host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;}location/fee/sleep{proxy_passhttp://foobar;}}upstreamfoobar{server127.0.0.1:9001;server127.0.0.1:9002;}#upstreamfoobar{#server127.0.0.1:9001weight=3;#server127.0.0.1:9002weight=1;#}#upstreamfoobar{#ip_hash;#server127.0.0.1:9001;#server127.0.0.1:9002;#server127.0.0.1:9003;#}}EOF该配置文件主要设置了上游服务foobar的IP和端口。再进行具体 URL 的映射,如下:
location/{proxy_passhttp://foobar;]location/fee/sleep{proxy_passhttp://foobar;]下面主要针对upstream foobar部分进行修改,达到使用不同算法的实验目的。
实验为了进行实验,需启动若干个终端进入容器,如:修改配置并重启 nginx,执行程序,观察日志,等等。 查看访问日志:
tail-f/var/opt/rh/rh-nginx116/log/nginx/access.log在另一终端(可在Windows或虚拟机中)执行如下请求命令:
curlhttp://192.168.28.11:8080/-XPOST-F"file=@sample.json"下面给出配置和相应的日志和观察到的现象。
基础的实验默认轮询配置:
upstreamfoobar{server127.0.0.1:9001;server127.0.0.1:9002;}日志:
[18/Nov/2021:10:23:15+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90022000.000ms0.001ms][18/Nov/2021:10:23:16+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90012000.001ms0.001ms][18/Nov/2021:10:23:18+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90012000.002ms0.003ms][18/Nov/2021:10:23:21+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90022000.001ms0.001ms][18/Nov/2021:10:23:24+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90022000.001ms0.001ms][18/Nov/2021:10:23:25+0000]192.168.28.5:"POST/HTTP/1.1"200"-""curl/7.73.0"[127.0.0.1:90012000.001ms0.001ms]结论: 9001 和 9002 依次出现。
加权轮询配置:
sudodockerexec-uroot-itnginxbash0日志:
sudodockerexec-uroot-itnginxbash1结论: 9001 和 9002 依次出现 4 次和 1 次。 注:经测试发现,nginx 加权轮询本身就是平滑加权轮询,此处为了演示,特意将权重值扩大。
平滑加权轮询配置:
sudodockerexec-uroot-itnginxbash2日志:
sudodockerexec-uroot-itnginxbash3结论: 从权重上看,9001、9002 和 9003 保持配置中的值,即依次出现 2、5、3 次。从顺序上看,权重大的服务器并没有集中出现,三者轮询相对较均匀。从2轮实验结果看,每一次的轮询,某个服务器出现的顺序并不相同。
与前面自实现平滑算法对比如下:
sudodockerexec-uroot-itnginxbash4可以看到,二者还是有区别的。
ip_hash 轮询配置:
sudodockerexec-uroot-itnginxbash5为模拟不同的 IP 访问,在虚拟机、物理机以及其它的容器中发送 POST 请求,观察日志。如下:
sudodockerexec-uroot-itnginxbash6结论:其中127.0.0.1为 nginx 所在容器的本地 IP,172.17.0.3是另一容器,192.168.28.5是物理机,192.168.28.11是虚拟机。从日志中看,每个源 IP 均由相同端口的服务响应。但不知为何,9001 端口服务没有被轮询到。
自定义的实验下面是一些笔者一直想做的实验。
后端服务未启动访问-返回502模拟场合:所有的后端服务均未启动,但在 nginx 配置文件中指定了后端服务。 nginx 访问日志:
sudodockerexec-uroot-itnginxbash7curl 请求返回:
$curlhttp://192.168.28.11:8080/-XPOST-F"file=@sample.json"%Total%Received%XferdAverageSpeedTimeTimeTimeCurrentDloadUploadTotalSpentLeftSpeed10049310015710033678500164k--:--:----:--:----:--:--481k<html><head><title>502BadGateway</title></head><body><center><h1>502BadGateway</h1></center><hr><center>nginx/1.16.1</center></body></html>结论:返回 502,注意,访问日志中提示了所有的后端服务均返回 502,猜测 nginx已经做了一次轮询。
服务处理中突然-返回502,当次服务失败模拟场合:某服务在处理请求中突然停止服务(如出现段错误或断电)。 为了模拟该情况,特意实现一个 sleep 请求,该请求中延时 4 秒,以方便停止服务。 nginx 访问日志:
sudodockerexec-uroot-itnginxbash9可以看到,其响应处理耗时 3 秒多,因为笔者在大概 3 秒时才停止后端服务。
curl 请求返回:
/home/latelee/bin/httpforward_back.exe-p9001-i"helloin9001"/home/latelee/bin/httpforward_back.exe-p9002-i"helloin9002"/home/latelee/bin/httpforward_back.exe-p9003-i"helloin9003"0结论:对于请求者而言,返回信息与上一实验相同,但在访问日志看到,只有 9001 才提示 502,但还有其它后端服务在运行,因此,再请求时,能返回正常,此时 nginx 会找正常工作的机器。
在处理中重新配置 nginx-会等待该处理完成模拟场合:在多台后端服务中,需停止部分并升级,再启动,再升级其它的服务。 先将两台服务器权重扩大,如 9001 为 10, 9002 为 1,保证请求大部分转发到 9001 端口。在请求处理中,修改 nginx 配置,去掉 9001 服务,再重启 nginx。观察。
结论:nginx 等待 9001 服务处理完请求,后续请求不再转发该服务。因此确保在处理中的请求一定能处理完毕。
设置超时响应时间配置:
/home/latelee/bin/httpforward_back.exe-p9001-i"helloin9001"/home/latelee/bin/httpforward_back.exe-p9002-i"helloin9002"/home/latelee/bin/httpforward_back.exe-p9003-i"helloin9003"1注: 不知如何实验。因为是来 gin 框架实现,有对应的响应函数,一旦进入,就认为响应了,直接用前面 sleep 模式的,也不行。
知识不能在upstream里面的 IP 地址加上 URL 后缀。否则提示
/home/latelee/bin/httpforward_back.exe-p9001-i"helloin9001"/home/latelee/bin/httpforward_back.exe-p9002-i"helloin9002"/home/latelee/bin/httpforward_back.exe-p9003-i"helloin9003"2可以在location地址添加对应的 URL,如location /foobar。
为方便观察请求日志,需要设置 nginx 日志,本文配置如下:
/home/latelee/bin/httpforward_back.exe-p9001-i"helloin9001"/home/latelee/bin/httpforward_back.exe-p9002-i"helloin9002"/home/latelee/bin/httpforward_back.exe-p9003-i"helloin9003"3备忘是否可以用 nginx 屏蔽客户端对真实Web服务器的直接访问?好像网上还没有相关方案。
小结许久前,在看分布式的视频时,里面介绍了负载均衡,雪花算法,一致性哈希算法,等,让笔者大开眼界,趁着中秋佳节无法外出,集中夜晚时间研究研究,从自实现的基于请求内容的转发工具,到 nginx 的负载均衡算法,基本过了一次。至于其它的知识,暂时未有计划。
2021.9月下旬初稿 11月中旬稍作修改