# 硬件实现负载均衡 F5 硬件设备 A10硬件设备 #软件实现负载均衡 nginx(7层,19之后支持4层) LVS(4层) HAproxy(4层,7层) 负载均衡概念说明:1.对用户的访问请求进行调度管理 2.对用户的访问请求进行压力分担 反向代理概念说明:1.接受用户请求代替用户向后端访问 2.反向代理与数据转发概念区别说明
# 一、实现负载均衡的机器(10.0.0.5) cd /etc/nginx/ cp nginx.conf{,.bak} grep -Ev '^$|#' nginx.conf.bak > nginx.conf # 将 nginx.conf.bak文件中的空白行和以#开头的行过滤掉,把其它内容从定向到nginx.conf文件中 vim nginx.conf user www; # 用户最好统一 useradd www -u 1002 -s /sbin/nologin -M ,因为这个用户并不需要登录,所以这里创建的是一个虚拟用户 cd ./conf.d/ grep -Ev '^$|#' default.conf > lb.conf vim lb.conf upstream clobotics { server 10.0.0.7:80; # 使用内网ip,这里使用的是外网,为了抓包; server 10.0.0.8:80; server 10.0.0.9:80; } server { # 默认再conf.d目录中的.conf文件的server区块被包含在http区块中 listen 80; server_name www.clobotics.com; # 访问www.clobotics.com网站的请求负载均衡到内网的其它主机 location / { #root /usr/share/nginx/html; 因为不是web服务器,所以不需要有家目录和主页文件index.html # index index.html index.htm; proxy_pass http://clobotics; # 要与upstream中定义的名称一致,才能分配给upstream中定义的server中; } } vim /etc/hosts 10.0.0.7 www.clobotics.com 10.0.0.8 www.clobotics.com 10.0.0.9 www.clobotics.com # 二、被负载的机器 # 10.0.0.7机器 for name in www bbs blog;do echo "$name 192.168.1.102">/html/$name/clobo.html;done curl www.clobotics.com/clobo.html # 返回www 10.0.0.7 vim /etc/nginx/conf.d/web01.conf server { listen 80; server_name www.clobotics.com; location / { root /html/www; index index.html index.htm; } } vim /html/www/clobo.html <h1>clobotics 10.0.0.7</h1> vim /etc/hosts 10.0.0.7 www.clobotics.com # 10.0.0.8机器 for name in www bbs blog;do echo "$name 10.0.0.8">/html/$name/clobo.html;done curl www.clobotics.com/clobo.html # 返回www 10.0.0.8 vim /etc/nginx/conf.d/web01.conf server { listen 80; server_name www.clobotics.com; location / { root /html/www; index index.html index.htm; } } vim /html/www/clobo.html <h1>clobotics 10.0.0.8</h1> vim /etc/hosts 10.0.0.8 www.clobotics.com # 10.0.0.9机器 for name in www bbs blog;do echo "$name 10.0.0.9">/html/$name/clobo.html;done curl www.clobotics.com/clobo.html # 返回www 10.0.0.9 vim /etc/nginx/conf.d/web01.conf server { listen 80; server_name www.clobotics.com; location / { root /html/www; index index.html index.htm; } } vim /html/www/clobo.html <h1>clobotics 10.0.0.9</h1> vim /etc/hosts 10.0.0.9 www.clobotics.com # 修改windows解析文件 10.0.0.5 www.clobotics.com blog.clobotics.com bbs.clobotics.com # 3台被负载的机器nginx.conf配置 useradd www -u 1008 -s /sbin/nologin -M vim /etc/nginx/nginx.conf user www; worker_processes 2; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; 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; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/www.conf; # include /etc/nginx/conf.d/*.conf } systemctl start nginx # 10.0.0.5 10.0.0.7 10.0.0.8 10.0.0.9 # 测试: 在10.0.0.5机器: curl www.clobotics.com/clobo.html # 轮询被负载的7、8、9三台机器 在10.0.0.7机器: curl www.clobotics.com/clobo.html 在10.0.0.8机器: curl www.clobotics.com/clobo.html 在10.0.0.9机器: curl www.clobotics.com/clobo.html 在windows机器: curl www.clobotics.com/clobo.html 如果出现403 forbidden,可从以下几个方面查找原因: 1.selinux是否被禁用,修改/etc/selinux/config,SELINUX=disabled,然后重启机器 2.启动用户和nginx工作用户是否一致 ps aux | grep nginx: 如果不一致,修改/etc/nginx/nginx.conf的user为启动用户; 3.我们指定的web页面目录是否有index.html文件,或者我们访问具体的html文件是否有在此目录中; 4.nginx的worker进程是否有访问web页面目录及其内部html文件的权限; chown -R user:user /dir
1.负载均衡 测试后端web节点服务器是否能够正常访问 curl -H host:www.clobotics.com 10.0.0.7/clobo.html curl -H host:www.clobotics.com 10.0.0.8/clobo.html curl -H host:www.clobotics.com 10.0.0.9/clobo.html 2.负载均衡 利用curl命令访问负载均衡服务器 查看两个配置文件,一个主配置文件nginx.conf,一个负载均衡的配置文件lb.conf 3.打开一个xshell连接 ping www.clobotics.com 4.配置文件编写不正确
ngx_http_upstream_module -- upstream 实现不同的调度功能 1.轮询分配请求(平均) 2.权重分配请求(能力越强责任越重) vim /etc/nginx/conf.d/lb.conf upstream clobotics { server 192.168.1.102:10572 weight=2; server 192.168.1.105:10572 weight=1; } 3. 实现热备功能 # 如图1 upstream clobotics { server 192.168.1.102:10572; server 192.168.1.105:10572 backup; # 当其它被负载的机器服务进程不死掉,backup的这台机器就不会被负载均衡。 } 4.定义最大失败次数 max_fails=number 5.定义失败之后重发的间隔时间 fail_timeout=10s # 当10s时间到了的时候,会给失败的服务器一次机会(在这10s以内发给其它服务器),如果还不成,会再等10s再发,,,以此类推。 6. down # 这标志着服务器永远不可用,这个参数可配合ip_hash使用;类似注释效果。 upstream clobotics { server 192.168.1.102:10572 down; # 请求不再发往这个服务器,其实直接注释掉就行了,这里的down显得有些鸡肋 server 192.168.1.105:10572; } 实现不同调度算法: 1.rr 轮询 2.wrr 加权轮询 3.ip_hash 算法(静态调度算法, 出现反复登录的时候) 在负载均衡的场景中,登录web页面时,始终登录不进去?用户输入用户名和密码,被nginx负载到不同的机器上,在做登录和认证时不再同一台机器,导致重复输入登录名和密码。这是由两种解决方案: (1)session会话:使用一台缓存服务器(memcached),在用户登录输入用户名和密码时,不论用户的访问请求被调度到哪一台负载的机器上,该机器都要从缓存服务器上认证该用户是否已经登录(已登录,保存session会话),如果已经登录,不用再次输入用户名和密码; (2)ip_hash:每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一个节点服务器,从而导致请求分配不均。LVS负载均衡的-p参数、keepalived配置的persistence_timeout 50参数都类似这个nginx里的ip_hash参数,其功能都可以解决动态网页的session共享问题。 但是,ip_hash只识别公网地址,在中国的局域网内的无数台机器映射成一个公网地址,所以在私网内的用户都被负载到一台机器中,导致负载不均。 upstream clobotics { ip_hash; server 192.168.1.102:10572; server 192.168.1.105:10572; } upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; server backend4.example.com; } 注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能由weight和backup,即使有也不会生效。 4.fair(动态调度算法) 此算法会根据后端节点服务器的响应时间来分配请求,响应时间的优先分配。这是更加智能的调度算法。此种算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。nginx本身不支持fair调度算法,如果需要使用这种调度算法,必须下载nginx的相关模块upstream_fair. 示例: upstream clobotics { server 192.168.1.102:10572; server 192.168.1.105:10572; fair; } 5.least_conn least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。
图1:
ngx_http_proxy_module --proxy_pass 1.访问不同的网站地址,不能显示不同的网站页面 cat -n /etc/nginx/nginx.conf # 显示文本的行编号 sed -i "19s/include/#include/; 20s/#include/include/g" /etc/nginx/nginx.conf # 将19行注释掉,20行取消注释 curl -H host:www.clobotics.com 192.168.1.104/clobo.html curl -H host:blog.clobotics.com 192.168.1.104/clobo.html # 应该是 blog 192.168.1.102 blog 192.168.1.105 curl -H host:bbs.clobotics.com 192.168.1.104/clobo.html # # 应该是 bbs 192.168.1.102 bbs 192.168.1.105 但是,得到的返回值都是: ''' www 192.168.1.102 www 192.168.1.105 ''' 需要在server中添加此字段:# 如下图1 proxy_set_header Host $host; # 表示将用户访问的负载均衡的Host改成用户的$host 如下图2 2.访问网站用户地址信息无法进行分析统计 proxy_set_header X-Forwarded-For $remote_addr; # 需要与nginx.conf文件中定义日志的变量http_x_forwarded_for(表示获取http请求头你面的x_forwarded_for)保持一致 upstream clobotics { server 192.168.1.102; server 192.168.1.105; } server { listen 80; server_name www.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; # $remote_addr,可以在官方网站上查看变量,代表客户端IP,正常客户在浏览器访问我们站点负载均衡时的客户的公网IP。 } } server { listen 80; server_name bbs.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } } server { listen 80; server_name blog.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } systemctl restart nginx tail -f /var/log/nginx/access.log # 如下图3 3.访问负载均衡会出现错误页面,影响用户体验 比如:在定义的根目录下没有要寻找的.html文件,会报404错误 可以使用 proxy_next_upstream 字段 proxy_next_upstream error timeout http_404 http_502 http_403; # 当访问碰到这些错误时,会访问下一个正常的负载,从这个正常的负载中获得返回页面。 vim /etc/nginx/conf.d/lb.conf upstream clobotics { erver 192.168.1.102; server 192.168.1.105; } server { listen 80; server_name www.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } } server { listen 80; server_name bbs.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } } server { listen 80; server_name blog.clobotics.com; location / { proxy_pass http://clobotics; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } }
图1:
图2:
图3:
ngx_http_proxy_module ngx_http_upstream_module
# 负载均衡反向代理根据请求地址分配 1.静态请求资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置location /static/区块信息 (2)web服务器端配置 (1.1)创建static资源目录 (1.2)资源目录中创建页面文件 2.动态请求资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置location /upload/区块信息 (2)web服务器端配置 (1.1)创建upload资源目录 (1.2)资源目录中创建页面文件 3.默认请求资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置location /区块信息 (2)web服务器端配置 (1.1)创建默认资源目录 (1.2)资源目录中创建页面文件 # 负载均衡反向代理根据访问软件分配 1.谷歌浏览资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置if ($http_user_agent ~* "Chrome")区块信息 2.火狐浏览资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置if ($http_user_agent ~* "Firefox")区块信息 3.手机浏览资源 (1)负载服务器端配置 (1.1)配置upstream资源池 (1.2)配置if ($http_user_agent ~* "iphone")区块信息
1.根据用户访问的uri信息进行负载均衡 第一个历程:架构环境规划 /upload 集群-10.0.0.8:80 html/www/upload upload服务器集群 # web02 /static 集群-10.0.0.7:80 html/www/static static服务器集群 # web01 / 集群-10.0.0.9:80 html/www # web03 web02上进行环境部署: mkdir /html/www/upload echo "upload-web集群_10.0.0.8" >/html/www/upload/clobo.html web01上进行环境部署: mkdir /html/www/static echo "static-web集群_10.0.0.7" >/html/www/static/clobo.html web03上进行环境部署: echo "default-web集群_10.0.0.9" >/html/www/clobo.html 第二个历程,编写负载均衡配置文件 # 负载均衡服务器 10.0.0.5 vim /etc/nginx/conf.d/lb.conf upstream upload { server 10.0.0.8:80; } upstream static { server 10.0.0.7:80; } upstream default { server 10.0.0.9:80; } server { listen 80; server_name www.clobotics.com; location / { proxy_pass http://default; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } location /upload { proxy_pass http://upload; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } location /static { proxy_pass http://static; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } } # web03 10.0.0.8服务器 server { listen 80; server_name www.clobotics.com clobotics.com; access_log /var/log/nginx/www_access.log main; if ($host ~* "^clobotics.com$") { rewrite ^/(.*) http://www.clobotics.com/$1 permanent; } location / { root /html/www; index clobotics.html; #auth_basic "clobotics-sz-01"; #auth_basic_user_file password/htpasswd; #autoindex on; #charset utf-8; } } # web01 10.0.0.7服务器 server { listen 80; server_name www.clobotics.com clobotics.com; access_log /var/log/nginx/www_access.log main; if ($host ~* "^clobotics.com$") { rewrite ^/(.*) http://www.clobotics.com/$1 permanent; } location / { root /html/www; index clobotics.html; #auth_basic "clobotics-sz-01"; #auth_basic_user_file password/htpasswd; #autoindex on; #charset utf-8; } } # web03 10.0.0.9服务器 server { listen 80; server_name www.clobotics.com clobotics.com; access_log /var/log/nginx/www_access.log main; if ($host ~* "^clobotics.com$") { rewrite ^/(.*) http://www.clobotics.com/$1 permanent; } location / { root /html/www; index clobotics.html; #auth_basic "clobotics-sz-01"; #auth_basic_user_file password/htpasswd; #autoindex on; #charset utf-8; } } 总结:实现网站集群动静分离 (1).提高网站服务安全性 有效防止了单一部署动态页面无法访问,静态资源页无法访问; (2).管理操作工作简化,static和upload的机器只需要安装nginx即可,动态网页才需要安装对应项目的解释器 (3).可以换分不同人员管理不同集群服务器 2.根据用户访问的终端信息显示不同页面 iphone www.clobotics.com -- iphone_access 10.0.0.7:80 mobile移动端集群 谷歌 www.clobotics.com -- google_access 10.0.0.8:80 web端集群 IE 360 www.clobotics.com -- default_access 10.0.0.9:80 default端集群 编写负载均衡配置文件 vim /etc/nginx/conf.d/lb.conf upstream mobile { server 10.0.0.7:80; } upstream google { server 10.0.0.8:80; } upstream default { server 10.0.0.9:80; } server { listen 80; server_name www.clobotics.com; location / { if ($http_User-Agent ~* iphone) { proxy_pass http://mobile; } if ($http_User-Agent ~* Chrome) { proxy_pass http://google; } proxy_pass http://default; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_next_upstream error timeout http_404 http_502 http_403; } }