一、集群

一堆服务器做一件事情
特点:

  • 高性能 单台机器及时性能在强也有可能达到瓶颈;对于复杂的计算或者业务时,可以使用集群技术共同分担完成。
  • 价格有效性 单台高性能机器价格太高了,还不是多买几台便宜的搭建集群系统
  • 可伸缩性 当服务负载,压力增长时,针对集群系统进行较简单的扩展即可满足需求,且不会降低品质。
  • 透明性 多台独立的计算机组成的松藕合集群集群系统构成一个虚拟服务器。用户和客户端在访问的时候就像在访问一台服务器,集群中一部分服务器的上线和下线不会中断整个系统服务,这对用户也是透明度。

计算机集群系统按照功能可以分为如下几类:

  • 负载均衡集群

负载均衡把很多客户的访问请求压力,平均的分给后面的多个计算机,也解决单点服务器压力问题
每个节点承担一定的流量压力,并且实现请求在多个节点之间动态的分配

  • 高可用集群

高可用性集群作用是集群中任意一个节点宕机,该节点上的数据资源、任务,会自动的切换到另一台提前准备好的备用服务器上,继续提供业务,并且不影响整个服务器系统,对用户来说是无感知的。

  • 高性能计算集群

高性能计算集群也称为并行计算,该集群系统用于解决复杂的科学问题;该集群由很多台小型服务器组成

  • 网格计算

常见的集群硬件、软件设备:
软件:nginx、lvs、haproxy、keepalived、heartbeat
硬件:f5、netscaler、radware、A10

二、Nginx负载均衡

Nginx负载均衡的优势:

  • Nginx负载均衡配置简单
  • 使用方便、安全稳定
  • 社区活跃、在淘宝得到了验证

使用Keepalive实现高可用性,选择Keepalive也是因为配置简单、使用方便
严格的来说,Nginx仅仅是作为Proxy反向代理的作用,因为这个反向代理的效果正是负载均衡的作用,所以称之为Nginx负载均衡

负载均衡和反向代理的区别:

  • 普通的负载均衡软件、例如LVS、仅仅对数据包进行转发
  • Nginx是接受到用户的请求之后,重新的向后台的负载均衡节点发出请求,此时真实服务器上看到的请求IP地址是Nginx的(LVS的负载均衡,在真实的服务器上看到的IP地址就是用户自己的IP地址)

    1、Nginx负载均衡部署

    Nginx提供负载均衡的模块是:

  • ngx_http_proxy_module proxy请求代理模块,用于把请求抛给后端的服务器节点或者upstream服务器池

  • ngx_http_upstream_module 负载均衡模块,实现服务器的负载均衡节点配置,已经健康检查
    1. 环境准备:两台负载均衡设备(loadbalance LB)、两台服务器
    2. lb01 主负载均衡节点 lb02
    3. web01 web节点 web02
    1. 1.分别准备web01web02的静态网页;
    2. 2.准备lb01lb02暂时只配置负载均衡,不考虑高可用性
    3. [root@lb01 ~]# cat /opt/nginx/conf/nginx.conf |grep -Ev ' *#|^$'
    4. worker_processes 1;
    5. events {
    6. worker_connections 1024;
    7. }
    8. http {
    9. include mime.types;
    10. default_type application/octet-stream;
    11. #通过关键字upstream定义负载均衡地址池,请求分发给地址池中的节点
    12. upstream my_web {
    13. server 192.168.43.177;
    14. server 192.168.43.8;
    15. }
    16. sendfile on;
    17. keepalive_timeout 65;
    18. #此时虚拟主机就不在是静态页面的作用,而是做请求转发,给负载均衡地址池;默认是轮训算法转发
    19. server {
    20. listen 80;
    21. server_name localhost;
    22. location / {
    23. #写法如下
    24. proxy_pass http://my_web;
    25. }
    26. error_page 500 502 503 504 /50x.html;
    27. location = /50x.html {
    28. root html;
    29. }
    30. }
    31. }
    32. 3.此时访问lb01IP地址,即可轮训访问后端的真实服务器。

2、upstream转发原理

Nginx的负载均衡功能是来自于nginx_http_upstream_module,该模块的作用是允许定义一组或者多组的服务器节点,在Nginx接收到请求的时候,可以通过porxy_pass等代理方式,把用户的请求发送到预先定义好的upstream地址池中,该模块还支持如下功能:

  • proxy_pass 转发http请求
  • uwsgi_pass 和Python结合使用
  • Fastcgi_pass、memcached_pass ```

    基本写法如下:

    upstream my_web { server x.x.x.x weight=1 max_fails=1 fail_time out=0s backup; server www.x.x.x.x } server 关键字,后面可以跟服务器的IP、主机名、域名、socket套接字(本地进程转发时使用)、端口、转发方式等 weight 权重 基于权重比例进行转发 max_fails nginx尝试连接该节点的失败次数 backup 当其他非backup的机器挂掉或者繁忙时,请求转发给backup机器,相当于备份机器 down 剔除、暂停当前节点的请求解析,不参与负载均衡

upstream定义在nginx.conf的http标签内,默认算法为轮训

  1. <a name="fKv6Q"></a>
  2. #### 3、Nginx负载均衡算法
  3. 第一类是静态调度算法:负载均衡设备根据自身设定的规则进行分配,不考虑后端节点的健康情况(坏了也会发);例如:轮询、加权轮询、哈希类型调度算法<br />第二类是动态调度算法:负载均衡设备会先判断后端节点的当前状况,来决定是否分配。例如:链接数最少的优先分配、响应时间短的优先分发,如least_conn、fail等都是动态调度算法。<br />算法如下:
  4. - rr轮询(round-robin) 按照请求顺序逐一分配给后端的节点服务器,如果后端服务器宕机,宕机的服务器会被自动的从地址池中剔除,新的请求会发给正常的服务器。
  5. - wrr权重轮询 根据配置的权重。数值越大,优先获得客户端请求;可以配置权重比例还进行分发
  6. - ip_hash 每个请求结果按照客户端的IP hash结果进行分配,将客户端IP通过hash算法得到一个唯一值;在随后的请求中,如果客户短的IPhash数值相等,该请求会发送给固定的一台服务器。该调度算法可以解决动态网页中session共享的问题;配置ip_hash后不再使用weight、backup参数,易冲突;即使配置了也不会生效。
  7. - fail 该算法根据后端服务器节点的响应时间来分配,响应时间短的优先分配,该算法根据页面大小和加载时间长短进行负载均衡,Nginx本身不支持fail形式,如果要支持该算法,需要加载upstream_fail模块
  8. - least_conn 该算法根据后端节点的链接数决定分配请求,少的来
  9. - url_hash 和ip_hash类似,该算法根据客户请求的URL信息进行hash得到唯一值,让某一个URL固定发给同一个后端服务器,后端服务器为缓存服务器效果最佳。需要安装hash模块。

upstream web { ip_hash; server x.x.x.x; server y.t.t.t; }


<a name="HNCBo"></a>
### 三、Nginx负载均衡实践
<a name="u5nIH"></a>
#### 1、多虚拟主机+负载均衡 (proxy_set_header)

1.在web01、02配置基于域名的多虚拟主机

修改Nginx.conf配置文件,通过include语法进入server配置,参考如下:

[root@web01 server_conf]# cat server1.conf server { listen 80; server_name x.ylin.com; charset utf-8;

location / { root html/server1; index index.html; }

} 2.需要修改本地hosts,做dns解析
如果访问IP地址,Nginx自上而下默认加载server主机配置。 [root@web01 server_conf]# tail -2 /etc/hosts 192.168.43.177 x.ylin.com 192.168.43.177 y.ylin.com

3.配置lb01负载均衡 [root@lb01 ~]# cat /opt/nginx/conf/nginx.conf |grep -Ev ‘^$|.*#’ workerprocesses 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; upstream my_web { server 192.168.43.177; server 192.168.43.8; } sendfile on; keepalive_timeout 65; server { listen 80; server_name ;
location / { proxy_pass http://my_web; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }

4.修改本地域名解析关系测试

出现问题,只能查看到第一个虚拟主机的解析页面(两台轮训但都只是第一个虚拟机页面);看不到第二个虚拟主机的web页面

5.配置基于多域名的请求分发,修改如下,在转发请求时添加头部信息 location / { proxy_pass http://my_web; proxy_set_header Host $host; }

<a name="ylese"></a>
#### 2、正向IP代理(x-Forwarded-For)
nginx的日志记录功能access.log能记录异常访问的用户IP地址,进行封禁;但是他们又通过了代理IP的方式来接着爬,<br />正向代理:代理访问服务器的源IP地址,真实IP地址针对服务器而言隐藏

1.配置日志显示 [root@web02 ~]# cat /opt/nginx/conf/server_conf/server1.conf #在两台web和lb设备上都进行配置 server { listen 80; server_name x.ylin.com; charset utf-8; access_log logs/access_ylin.log main;

location / { root html/server1; index index.html; } }

2.测试访问lb01地址发现,在访问地址时,真实服务器收到的日志信息为lb01发起的请求访问。 192.168.0.173 - - [01/Mar/2021:11:42:00 +0800] “GET / HTTP/1.0” 200 17 “-“ “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36” 192.168.0.173 - - [01/Mar/2021:11:42:00 +0800] “GET /favicon.ico HTTP/1.0” 404 555 “http://192.168.0.173/“ “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36”

![image.png](https://cdn.nlark.com/yuque/0/2021/png/1443280/1614570256490-c6d931da-2bd2-4347-aae9-760d59f9b458.png#align=left&display=inline&height=120&margin=%5Bobject%20Object%5D&name=image.png&originHeight=160&originWidth=996&size=89335&status=done&style=stroke&width=747)<br />x-Forwarded-For参数,在反向代理请求后端节点服务器中,在请求头中添加获取客户端IP的字段信息,然后在后端节点上可以再次通过程序接受x-Forwarded-for参数传来的真实IP信息。

背景:由于在真实的服务器上查看到的IP地址是lb01代理之后的,如果想要看到客户端的真实IP还需要如下操作一把。 1.修改lb01反向代理机器的配置,添加如下参数;在请求转发时,添加头部信息(客户端真实的IP信息)。 location / { proxy_pass http://my_web; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; #这行 }

2.真实服务器端,修改参数如下 log_format main ‘$remote_addr - $remote_user [$time_local] “$request” ‘ ‘$status $body_bytes_sent “$http_referer” ‘ ‘“$http_user_agent” “$http_x_forwarded_for”‘; #添加此字段即可

3.测试

```