当前位置: 首页 > Linux

玩转Linux下nginx系列(五)---nginx实现负载均衡

时间:2023-04-06 02:13:49 Linux

Ngnix负载均衡有效的在多台服务器间分配客户端请求或网络负载通过只向普通服务器发送请求来保证高可用性和可靠性在业务不间断的情况下,按需弹性分配服务器资源使用nginx进行负载均衡三个模块:upstream定义负载节点池定位模块执行URL匹配代理模块向upstream定义节点池upstream模块解释nginx负载均衡功能依赖于ngx_http_upstream_module模块,以及支持的代理方式有proxy_pass(一般用于反向代理)、fastcgi_pass(一般用于动态程序交互)、memcached_pa??ss、proxy_next_upstream、fastcgi_next_pass、memcached_next_pass。上游模块应该放在http{}标签内。模块写法:upstreambackend{ip_hash;服务器backend1.example.com权重=5;服务器backend2.example.com:8080;服务器backup1.example.com:8080备份;serverbackup2.example.com:8080backup;}示例1:upstreamdynamic{zoneupstream_dynamic64k;服务器backend1.example.com权重=5;服务器backend2.example.com:8080fail_timeout=5sslow_start=30s;服务器192.168.199.18max_fails=3;服务器backend3.example.com解析;backup1.example.com:8080备份;serverbackup2.example.com:8080backup;}语法解释nginx默认支持四种调度算法roundrobin(rr),每个请求按照时间顺序一一分配到不同的后端服务器。如果后台服务器出现故障,故障系统会自动清除,不影响用户访问。轮询权重(weight),权重值越大,分配的访问概率越高,主要用于各个后端服务器性能参差不齐的情况ip_hash,每个请求根据访问IP的hash结果进行分配,这样从同一个IP固定访问一个后端服务器主要是解决动态网站session共享的问题。url_hash根据访问的URL的哈希结果分配请求,即每两个URL指向同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持。如果要使用需要安装nginx的hash包fair,这个算法可以根据页面大小和加载时间智能实现。负载均衡,即根据后端服务器的响应时间来分配请求。默认不支持对应短时间的优先级分配。如果要使用,需要安装upstream_fail模块文件ast_conn最小连接数,server模块的写法,如果机器连接数少,则分配当前服务器暂时不参与备用服务器,为负载均衡备份预留。当所有其他非备份服务器都发生故障或繁忙时,它们会请求备份机器,因为这个集群的压力最小。如果为1,当超过最大数量时,将返回proxy_next_upstream模块定义的错误。0表示禁用失败尝试。根据业务需要配置fail_timeout,在经历max_fails次失败后,暂停服务的时间。根据业务需求配置。例行业务2-3秒合理示例:如果max_fails为5,他会检查5次,如果这5次是502,那么他会根据fail_timeout的值等待10秒,然后检查。如果服务器连接的是域名,则需要内网的DNS服务器,或者在负载均衡器的hosts文件中做域名解析。服务器也可以直接连接IP或者IP加端口。长连接keepaliveupstream后端{serverbackend2.example.com:8080;服务器backup1.example.com:8080备份;keepalive100;}该指令配置每个工作进程和上游服务器之间的最大可缓存空闲连接数。当超过这个数字时,最近最少使用的连接将被关闭。keepalive指令不限制工作进程与上游服务器的总连接数。location/{#支持保活proxy_http_version1.1;proxy_set_header连接“”;proxy_passhttp://backup;}如果是http/1.0,需要配置发送“Connection:Keep-Alive”请求头。上游服务器不要忘记启用长连接支持连接池配置建议长连接总数为“空闲连接池”+“已释放连接池”中的长连接总数。另外连接池也要根据场景合理设置。1.空闲连接池太小,连接不够用,需要不断建立连接。2.空闲连接池太大,空闲连接太多,还没用就超时了。3、建议只对小包开启长连接。位置模块解释位置的作用:根据命令设置URI。基本语法:语法:location[=|~|?*|^~]uri{...}location@name{...}Default:—Context:server,location=完全匹配,如果找到符合符号=的内容,立即停止搜索,立即处理请求(最高优先级)~区分大小写~*不区分大小写^~只匹配字符串,不匹配正则表达式@指定命名位置,一般用于内部重定义请求,location@name{…}匹配有优先权,不根据nginx配置文件。官方示例:location=/{[配置A]}location/{[配置B]}location/documents/{[配置C]}location^~/images/{[配置D]}location~*\.(gif|jpg|jpeg)${[configurationE]}结论:/匹配A/index.html匹配B/documents/document.html匹配C/images/1.gif匹配D/documents/1.jpg匹配E测试示例:location/{返回401;}位置=/{返回402;}位置/文档/{返回403;}location^~/images/{return404;}位置~*\.(gif|jpg|jpeg)${返回500;}测试结果:[root@skylineconf]#curl-I-s-o/dev/null-w"%{http_code}\n"http://192.168.199.7/402[root@skylineconf]#curl-I-s-o/dev/null-w"%{http_code}\n"http://192.168.199.7/index.html401[root@skylineconf]#curl-I-s-o/dev/null-w"%{http_code}\n"http://192.168.199.7/documents/document.html403[root@sky行conf]#curl-I-s-o/dev/null-w"%{http_code}\n"http://192.168.199.7/images/1.gif404[root@skylineconf]#curl-I-s-o/dev/null-w"%{http_code}\n"http://192.168.199.7/dddd/1.gif500结果总结:匹配优先,=>^~(匹配固定字符串,忽略正则)>ExactEqual>~*>Empty>/尽量把'='放在作品前面。proxy_pass模块的解释proxy_pass指令属于ngx_http_proxy_module模块,可以将请求转发到另一个服务器。写法:proxy_passhttp://localhost:8000/uri/;示例1:upstreamproxy_real_servers{server192.168.199.9:80weight=5;服务器192.168.199.10:80权重=10;服务器192.168.199.19:82权重=15;}服务器{听80;服务器名称www.xxx.org;location/{proxy_passhttp://proxy_real_servers;proxy_set_header主机$host;proxy_set_headerX-Forwarded-For$remote_addr;}}proxy_set_header:当后端web服务器也配置了多个虚拟主机时,需要用这个Header来区分反向代理哪个主机名,proxy_set_headerhost$host;proxy_set_headerX-Forwarded-For:如果程序在后端Web服务器需要获取用户IP,从Header中获取。proxy_set_headerX-Forwarded-For$remote_addrproxy_pass相关优化参数client_max_body_size10m;client_body_buffer_sizeclient_body_buffer_size128k;客户端可以请求的单个文件的最大字节数;bufferproxy缓冲客户端请求的最大字节数,可以理解为保存在本地,然后传递给用户proxy_connect_timeout600;与后端server连接超时时间_发起握手等待响应超时时间proxy_read_timeout600;连接成功后_等待后台服务器响应时间_其实已经进入后台队列等待处理proxy_send_timeout600;backend服务器返回数据的时间是指后端服务器必须在指定时间内传输完所有数据。proxy_buffer_size8k;proxy请求缓存区,这个缓存区会保存用户的header信息,供Nginx处理规则,一般只要设置即可,保存以下信息proxy_buffers432k即可;告诉Nginx保存单个页面使用的空间,假设平均页面大小在32k以下,proxy_busy_buffers_size64k;如果系统很忙,可以申请更大的proxy_buffers官方推荐(proxy_buffers*2)proxy_max_temp_file_size1024m;当proxy_buffers无法容纳后端服务器的响应内容时,它会将其中的一部分保存到硬盘上的临时文件中。该值用于设置最大临时文件大小。默认为1024M,与proxy_cache无关。如果大于这个值,就会从上游服务器发回。设置为0禁用proxy_temp_file_write_size64k;proxy缓存临时文件的大小proxy_temp_path(可以在编译的时候)指定写入健康检查的目录Nginx提供health_check语句来提供加载时关键的健康检查机制(上游)(注意:这个语句需要被在位置上下文中设置)。支持的参数有:interval=time:设置两次健康检查的间隔值,默认为5秒fails=number:设置将服务器视为不健康的连续检查次数,默认为1passes=number:设置一次server认为健康的连续检查次数,默认为1次uri=uri:定义健康检查的请求URI,默认为"/"match=name:指定匹配的配置块的名称,用于测试响应是否通过健康检查。默认情况下,测试返回状态代码为2xx和3xx。一个简单的设置如下,将使用默认值:location/{proxy_passhttp://backend;health_check;}对于这个应用,我们可以定义一个专门用于健康检查的API:/api/health_check,只返回HTTP状态码200。并且设置检查间隔为1秒。这样health_check语句的配置如下:health_checkuri="/api/health_check"interval;匹配方法matchhttp{server{...location/{proxy_passhttp://backend;health_check匹配=欢迎;}}匹配欢迎{status200;headerContent-Type=text/html;身体?“欢迎使用nginx!”;}}匹配示例status200;:status等于200status!500;:status不是500status200204;:status是200或204status!301302;:status不是301或302status200-399;:status在200和399之间status!400-599;:status不在400和599之间status301-303307;:statusis301,302,303,Or307headerContent-Type=text/html;:"Content-Type"istext/htmlheaderContent-Type!=text/html;:"Content-Type"不是text/htmlheaderConnection~close;:"Connection"包含closeheaderConnection!~close;:“Connection”不包含closeheaderHost;:请求头包含“Host”头!X-Accel-Redirect;:请求头不包含“X-Accel-Redirect”主体~“欢迎使用nginx!”;:正文包含“Welcometonginx!”body!~"Welcometonginx!";:body不包含“Welcometonginx!”完整nginx实例[root@skylineconf]#catnginx.confworker_processes2;events{worker_connections65536;}http{includemime.types;default_type应用程序/八位字节流;发送文件;keepalive_timeout65;#upstreamupstreamproxy_real_servers{服务器192.168.199.9:80weight=1max_fails=1fail_timeout=10s;服务器192.168.199.10:80weight=1max_fails=2fail_timeout=20s;}服务器{听80;服务器名称www.xxx.org;location/{proxy_passhttp://proxy_real_servers;包括proxy.conf;}}}[root@skylineconf]#catproxy.confproxy_set_headerHost$host;proxy_set_headerX-Forwarded-For$remote_addr;proxy_connect_timeout90;代理发送超时90;proxy_read_timeout90;proxy_buffer_size4k;代理缓冲区432k;proxy_busy_buffers_size64k;proxy_temp_file_write_size64k;extendedsupplementonlyallowspecifiedmethodrequests(GET,HEAD,POST)##只允许这些请求方法##if($request_method!~^(GET|HEAD|POST)$){return444;}根据URI和location,最终实现动静分离:1、/static/的url全部访问到192.168.199.92。/dynamic/的url都访问到192.168.199.10。3.图片等静态文件访问到192.168.199.9.4./upload/的URL都访问到192.168.199.10。[root@skylineconf]#catnginx.confworker_processes1;events{worker_connections1024;}http{includemime.types;default_type应用程序/八位字节流;发送文件;keepalive_timeout65;上游静态池{服务器192.168.199.9:80;}upstreamdynamic_pools{服务器192.168.199.10:80;}upstreamupload_pools{服务器192.168.199.9:80;}服务器{听80;服务器名称www.xxx.com;位置/{proxy_passhttp://static_pools;包括proxy.conf;}location/static/{proxy_passhttp://static_pools;包括proxy.conf;}location~*\.(gif|jpg|jpeg)${proxy_passhttp://static_pools;包括proxy.conf;}location/dynamic/{proxy_passhttp://dynamic_pools;包括proxy.conf;}location/upload/{proxy_passhttp://upload_pools;包括proxy.conf;}}}实现苹果手机和安卓手机访问不同地址服务器{listen80;服务器名称www.xxxx.com;location/{if($http_user_agent~*"android"){proxy_passhttp://android_pools;}if($http_user_agent~*"iphone"){proxy_passhttp://iphone_pools;}proxy_passhttp://pc_pools;包括额外的/proxy.conf;}access_log关闭;示例配置