阿里云服务器ECS    
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新 [咨询更多]
阿里云存储OSS
简单易用、多重冗余、数据备份高可靠、多层次安全防护安全性更强、低成本 [咨询更多]
阿里云数据库RDS
稳定可靠、可弹性伸缩、更拥有容灾、备份、恢复、监控、迁移等方面的全套解决方案 [咨询更多]
阿里云安全产品
DDoS高防IP、web应用防火墙、安骑士、sll证书、态势感知众多阿里云安全产品热销中 [咨询更多]
阿里云折扣优惠    
云服务器ECS、数据库、负载均衡等产品新购、续费、升级联系客服获取更多专属折扣 [咨询更多]
.Net微服务实战之负载均衡(上)
2020-7-20    点击量:
    分布式?集群?负载均衡?
    我曾经面试过一家企业,当时描述完我在老东家完成的微服务架构后,面试官问了我一个问题:
    面试官:您有做过分布式系统吗?
    我:有,刚刚我描述的微服务架构就是分布式的……
    面试官:不不不,我意思是你有没有尝试过把一个站点部署到多台服务器上?
    我:哦……你意思是我有没有用过类似nginx这些工具做负载均衡是吧?有,现在我们就这么做的。但是我对分布式理解是工作方式,但是你描述的更多具体称之为集群或者负载均衡。
    面试官:对对,大家的站在的观点不一样所以理解的不一样(尴尬的笑了笑)
    PS:首先我申明下我没有对该面试官有任何贬低嘲讽之意,也没刻意突出谁对谁错,面试完了后我回去回想了下我的回答并找到些资料做出以下总结。
    分布式
    分布式计算是指系统的工作方式,主要分为数据分布式和任务分布式:
    数据分布式也称为数据并行,把数据拆分后,利用多台计算机并行执行多个相同任务。优点是缩短所有任务总体执行时间,缺点是无法减少单个任务的执行时间。
    任务分布式也称为任务并行,单个串行的任务拆分成多个可并行子任务。优点是提高性能、可扩展性、可维护性,缺点是增加设计复杂性。
    负载均衡
    负载均衡(LoadBalance),简称LR,就是将并发的用户请求通过规则后平衡、分摊到多台服务器上进行执行,以此达到压力分摊、数据并行的效果。
    集群
    集群是系统在负载均衡结果后的物理表现,系统(服务)通过部署到多台服务器以达到共同提供相同的功能,可以称这一组服务为某某集群,例如Redis集群,某Web站点集群。
    负载均衡器
    作用
    负载均衡器的分类有很多,而他们的作用主要体现于架构要素的其中三个:可用性、性能、安全。
    可用性,多台服务器的部署避免了单点故障。
    性能,一台Web站点能提供每秒4000次的并发请求,5台服务器构成的一个集群就可以达到20000。
    安全,通过反向代理到真实服务器,避免直接路由到高危Web服务,避免开放危险端口。
    算法
    常用的负载均衡算法主要以下4个:
    加权轮询
    随机
    最少链接数
    哈希
    分类
    从制造上主要分为软件负载和硬件负载:
    软负载,包含了Nginx、LVS、HAProxy等。
    硬负载,包含了F5、Array等。
    从量级上主要分为:百万级、数十万级、万级:
    百万级,硬负载,例如F5、Array。
    数十万级,第四层负载,LVS、HAProxy。
    万级,第七层负载,Nginx。

    当然从成本上,硬负载绝对是土豪公司的工具,便宜的十来万RMB,贵则上百万RMB。而软负载只需要一台Linux服务器的钱就足够了。此外LVS的部署复杂度相比于Nginx会高那么一点,但是Nginx的七层负载的灵活性是四层负载的无法比拟的。

硬负载绝对是土豪公司的工具

    在实际工作中大家更多会接触到上图的架构模型,从功能职责上又可以划分地域级、集群级和应用级的负载:
    地域级的负载均衡使用的是DNS的智能解析来完成的,DNS全称DomainNameSystem,中文叫域名系统(服务)协议,一般都会采用云服务厂商的DNS系统,我们知道域名是需要花钱购买的,而厂商会附带一个免费的域名解析套餐,如果需要对域名进行域名智能解析,就需要付费给厂商获取相应的服务。

就需要付费给厂商获取相应的服务

    Nginx作为应用级负载也有自己的并发处理上限,如果超过上限了那么只能通过再上一层加一个更高处理性能的负载均衡器作为解决,而LVS可以很好担任集群级的负载重任。如果是土豪公司可以在自己选择使用硬负载来代替LVS,硬负载虽然贵也有自己的优势,例如防火墙、加密、高性能处理等。
    Nginx
    Nginx是一个高性能的反向代理服务器,也是稳定且高效的基于七层的负载均衡器。Nginx可以根据以随机、加权轮询,IP哈希、URL哈希等方式调度后端真是服务器,Nginx也支持对后端服务器的健康检查功能。
    LVS
    LVS即LinuxVirtualServer,翻译中文为Linux虚拟服务器,目前LVS是已经被集成到Linux内核模块中,LVS的工作模式分为NAT模式、TUN模式以及DR模式。那么在实战中,更多会Keepalived+LVS一起集成使用,Keepalived可以自动将LVS备用调度器升级为主调度器,最终实现整个集群系统的高负载、高可用。
    本篇的重点主要讲解Keepalive+LVS+Nginx+.NetCore的搭建与使用。
    效果图

效果图

    PS:上图是我完成搭建后录制的视频转gif,因为中间有等待的一分钟,为了观看效果剪断了。
    Web1与Web2是同一个Nginx,Web3和Web4是同为另外的一个Nginx。在图里可见需要过一段时间才能从一个Nginx切换到另外一个Nginx,原因主要是LVS会根据访问客户端的IP+端口在会话时间内重复的转发到同一个目标服务器。而控制这个会话时间的可以通过设置ipvsadm--persistent与--set这两个参数决定。
    LVS的三种工作模式
    NAT(NetworkAddressTranslation)-网络地址转换模式。
    首先,外部请求会经过LVS的VIP(VirtualIPAddress);接着,LVS会根据预设的调度算法选择一台真实的服务器进行数据请求包转发,转发前会把原数据包的目标地址与目标端口修改为真实服务器的地址与端口;最后,LVS在得到响应数据包后会把源地址与源端口改为VIP及调度器相应的端口。因为由于所有的请求与响应都会经过LVS调度器转发,因此容易成为集群的瓶颈。

因此容易成为集群的瓶颈

    TUN-隧道模式
    因为NAT会的瓶颈问题,因此TUN模式采用用了请求与响应数据分离的思路,让调度器仅处理数据请求,让真实服务器响应数据包直接返回给客户端,需要注意的是该模式下的真实服务器需要与外部网络连接。另外TUN模式下需要在LVS调度器与真实服务器之间创建隧道连接,同样会增加服务器的负担。

同样会增加服务器的负担

    DR(DirectRouting)-直接路由模式
    DR模式也是采用请求与响应分离的思路,由真实服务器直接响应客户端,但是它的报文转发方法有所不同,在不修改数据报文的情况下,将数据帧的MAC地址修改为需要转发到的真实服务器MAC地址,免去了TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是LVS调度器与真实后端服务器必须在一个局域网内。

LVS调度器与真实后端服务器必须在一个局域网内

    LVS的部署

LVS的部署

    接下来的部署操作将实现上图Keepalived+LVS+Nginx的多层负载均衡,LVS将是以DR模式实现。
    两台LVS服务器(主从)
    基础依赖安装

    yuminstallgcc
    yum-yinstallopenssl-devel
    yum-yinstalllibnllibnl-devel
    yuminstall-ylibnfnetlink-devel
    yum-yinstallnet-tools
  yuminstallvim-y
    安装keepalived和ipvsadm
    
yuminstall-ykeepalivedipvsadm

    LVS-Master服务器
    修改Keepalived配置:
    
vim/etc/keepalived/keepalived.conf

    复制以下配置覆盖进去
    注意:real_server填写的是Nginx服务器的IP地址

global_defs {
  router_id LVS_MASTER # 设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 {
  state MASTER #指定Keepalived的角色,MASTER为主,BACKUP为备 记得大写
  interface ens33 #网卡id 不同的电脑网卡id会有区别 可以使用:ip a查看
  virtual_router_id 51 #虚拟路由编号,主备要一致
  priority 100 #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
  advert_int 1 #检查间隔,默认为1s
  authentication {
    auth_type PASS
    auth_pass 12345678
  }
  virtual_ipaddress {
    192.168.174.128/24 #定义虚拟IP(VIP)为192.168.174.128,可多设,每行一个
  }
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.174.128 80 {
  delay_loop 6 # 设置健康检查时间,单位是秒
  lb_algo rr # 设置负载调度的算法为wlc
  lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
  nat_mask 255.255.255.0
  persistence_timeout 0
  protocol TCP
  real_server 192.168.88.137 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 10
      nb_get_retry 3
      delay_before_retry 3
      connect_port 80
    }
  }
  real_server 192.168.88.139 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 10
      nb_get_retry 3
      delay_before_retry 3
      connect_port 80
    }
  }
}
    LVS-BackUp服务器
    修改Keepalived配置:
    
vim/etc/keepalived/keepalived.conf

    复制以下配置覆盖进去
    注意:real_server填写的是Nginx服务器的IP地址,state改为BACKUP,priority改为比Master小。

global_defs {
  router_id LVS_SLAVE # 设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 {
  state BACKUP #指定Keepalived的角色,MASTER为主,BACKUP为备 记得大写
  interface ens33 #网卡id 不同的电脑网卡id会有区别 可以使用:ip a查看
  virtual_router_id 51 #虚拟路由编号,主备要一致
  priority 50 #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
  advert_int 1 #检查间隔,默认为1s
  authentication {
    auth_type PASS
    auth_pass 12345678
  }
  virtual_ipaddress {
    192.168.174.128/24 #定义虚拟IP(VIP)为192.168.174.128,可多设,每行一个
  }
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.174.128 80 {
  delay_loop 6 # 设置健康检查时间,单位是秒
  lb_algo rr # 设置负载调度的算法为wlc
  lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
  nat_mask 255.255.255.0
  persistence_timeout 0
  protocol TCP
  real_server 192.168.88.137 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 10
      nb_get_retry 3
      delay_before_retry 3
      connect_port 80
    }
  }
  real_server 192.168.88.139 80 {
    weight 1
    TCP_CHECK {
      connect_timeout 10
      nb_get_retry 3
      delay_before_retry 3
      connect_port 80
    }
  }
}
    两台Nginx服务器
    执行以下命令
   
 vim/etc/sysconfig/network-scripts/ifcfg-lo:0

    填写以下配置并保存
    DEVICE=lo:0
    IPADDR=192.168.88.128
    NETMASK=255.255.255.255
    BROADCAST=192.168.88.128
    ONBOOT=yes
    NAME=lvs_vip

    修改ARP
    
vim/etc/sysctl.conf

    填写配置并保存
    net.ipv4.conf.all.arp_ignore=1
    net.ipv4.conf.all.arp_announce=2
    net.ipv4.conf.lo.arp_ignore=1
    net.ipv4.conf.lo.arp_announce=2

    重启网卡
    sysctl-p
    systemctlrestartnetwork

    那么以上关于LVS部分就搭建好了。

    Nginx的部署
    在两台Nginx服务器都执行以下指令
    添加源并安装

    rpm-Uvhhttp://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    yuminstall-ynginx

    填写Nginx配置
    把http里【#开始】到【#结束】这段拷贝进去就可以了。

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    #开始
    upstream 192.168.88.139{
        server localhost:5001 weight=1;
        server localhost:5002 weight=1;
    }
    server {
        listen       80;
        server_name  192.168.88.139;
        charset utf8;
    
        client_max_body_size 50m;
        client_body_buffer_size 256k;
    
    location / {
        proxy_pass        http://192.168.88.139;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;    
        }
    }
    #结束
}

    设置开机启动
    systemctlstartnginx.service
    systemctlenablenginx.service

    重启防火墙
 
   firewall-cmd--permanent--zone=public--add-port=80/tcp
    firewall-cmd--reload

    以上关于Nginx的部分就完成了搭建。可以通过以下指令查看LVS的调度与连接信息。
    查看LVS调度信息
   
 ipvsadm-Ln

    查看LVS连接信息
   
 ipvsadm-Lnc

查看LVS调度信息
    .NetCore部署
    添加下载源:
    
rpm-Uvhhttps://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

    下载安装:
    
sudoyuminstallaspnetcore-runtime-2.2

    通过FTP把Web站点文件复制两份并上传到服务器,然后启动后台进程:
    nohupdotnetTest1.dll--server.urls"http://*:5001"&
    nohupdotnetTest1.dll--server.urls"http://*:5002"&

    FTP服务器的部署
    安装FTP服务器:
    
yuminstall-yvsftpd

    修改配置:
    
vim/etc/vsftpd/vsftpd.conf

    把已有的三项配置修改了:
   
 anonymous_enable=NO
    listen=YES
    #listen_ipv6=YES

    启动
    systemctlstartvsftpd
    systemctlenablevsftpd

    重启防火墙
    firewall-cmd--permanent--zone=public--add-service=ftp
    firewall-cmd--reload

    允许root登录,把以下两个文件的root注释了
    vim/etc/vsftpd/user_list
    vim/etc/vsftpd/ftpusers
    #root

    关掉selinux,会影响上传
    setenforce0
    vim/etc/selinux/config
    #将SELINUX=enforcing改为SELINUX=permissive

    FTP客户端—FileZilla下载地址
    https://filezilla-project.org/download.php?type=client

联系客服免费领取更多阿里云产品新购、续费升级折扣,叠加官网活动折上折更优惠