.Net微服務實戰之負載均衡(上)

系列文章

 相關源碼:https://github.com/SkyChenSky/Sikironginx

PS:最近開始在找工做,若是在廣州地區須要技術管理崗的(.Net架構師、技術經理)能夠隨時聯繫我,微信:SkyChen_Gong。git

分佈式?集羣?負載均衡?

  我曾經面試過一家企業,當時描述完我在老東家完成的微服務架構後,面試官問了我一個問題:github

  面試官:您有作過度布式系統嗎?面試

  我:有,剛剛我描述的微服務架構就是分佈式的……算法

  面試官:不不不,我意思是你有沒有嘗試過把一個站點部署到多臺服務器上?vim

  我:哦……你意思是我有沒有用過相似nginx這些工具作負載均衡是吧?有,如今咱們就這麼作的。可是我對分佈式理解是工做方式,可是你描述的更多具體稱之爲集羣或者負載均衡。後端

  面試官:對對,你們的站在的觀點不同因此理解的不同(尷尬的笑了笑)

PS:首先我申明下我沒有對該面試官有任何貶低嘲諷之意,也沒刻意突出誰對誰錯,面試完了後我回去回想了下個人回答並找到些資料作出如下總結。

分佈式

  分佈式計算是指系統的工做方式,主要分爲數據分佈式任務分佈式:

  數據分佈式也稱爲數據並行,把數據拆分後,利用多臺計算機並行執行多個相同任務。優勢是縮短全部任務整體執行時間,缺點是沒法減小單個任務的執行時間。

  任務分佈式也稱爲任務並行,單個串行的任務拆分紅多個可並行子任務。優勢是提升性能、可擴展性、可維護性,缺點是增長設計複雜性。

負載均衡

  負載均衡(Load Balance),簡稱LB,就是將併發的用戶請求經過規則後平衡、分攤到多臺服務器上進行執行,以此達到壓力分攤數據並行的效果。

集羣

  集羣是系統在負載均衡結果後的物理表現,系統(服務)經過部署到多臺服務器以達到共同提供相同的功能,能夠稱這一組服務爲某某集羣,例如Redis集羣,某Web站點集羣。

負載均衡器

做用

  負載均衡器的分類有不少,而他們的做用主要體現於架構要素的其中三個:可用性、性能、安全

  可用性,多臺服務器的部署避免了單點故障。

  性能,一臺Web站點能提供每秒4000次的併發請求,5臺服務器構成的一個集羣就能夠達到20000。

  安全,經過反向代理到真實服務器,避免直接路由到高危Web服務,避免開放危險端口。

算法

  經常使用的負載均衡算法主要如下4個:

  • 加權輪詢
  • 隨機
  • 最少連接數
  • 哈希

分類

  從製造上主要分爲軟件負載硬件負載:

  軟負載,包含了Nginx、LVS、HAProxy等。

  硬負載,包含了F五、Array等。

  從量級上主要分爲:百萬級數十萬級、萬級

  百萬級,硬負載,例如F五、Array。

  數十萬級,第四層負載,LVS、HAProxy。

  萬級,第七層負載,Nginx。

  固然從成本上,硬負載絕對是土豪公司的工具,便宜的十來萬RMB,貴則上百萬RMB。而軟負載只須要一臺Linux服務器的錢就足夠了。此外LVS的部署複雜度相比於Nginx會高那麼一點,可是Nginx的七層負載的靈活性是四層負載的沒法比擬的。

  在實際工做中你們更多會接觸到上圖的架構模型,從功能職責上又能夠劃分地域級、集羣級和應用級的負載:

  地域級的負載均衡使用的是DNS的智能解析來完成的DNS全稱Domain Name System,中文叫域名系統(服務)協議,通常都會採用雲服務廠商的DNS系統,咱們知道域名是須要花錢購買的,而廠商會附帶一個免費的域名解析套餐,若是須要對域名進行域名智能解析,就須要付費給廠商獲取相應的服務。

  Nginx做爲應用級負載也有本身的併發處理上限,若是超過上限了那麼只能經過再上一層加一個更高處理性能的負載均衡器做爲解決,而LVS能夠很好擔任集羣級的負載重任。若是是土豪公司能夠在本身選擇使用硬負載來代替LVS,硬負載雖然貴也有本身的優點,例如防火牆、加密、高性能處理等。

Nginx

  Nginx是一個高性能的反向代理服務器,也是穩定且高效的基於七層的負載均衡器。Nginx能夠根據以隨機、加權輪詢,IP哈希、URL哈希等方式調度後端真是服務器,Nginx也支持對後端服務器的健康檢查功能。

LVS

  LVS即Linux Virtual Server,翻譯中文爲 Linux虛擬服務器,目前LVS是已經被集成到Linux內核模塊中,LVS的工做模式分爲NAT模式、TUN模式以及DR模式。那麼在實戰中,更多會Keepalived + LVS一塊兒集成使用,Keepalived能夠自動將LVS備用調度器升級爲主調度器,最終實現整個集羣系統的高負載、高可用。

  本篇的重點主要講解Keepalive + LVS + Nginx + .Net Core的搭建與使用。

效果圖

  PS:上圖是我完成搭建後錄製的視頻轉gif,由於中間有等待的一分鐘,爲了觀看效果剪斷了。

  Web1與Web2是同一個Nginx,Web3和Web4是同爲另外的一個Nginx。在圖裏可見須要過一段時間才能從一個Nginx切換到另一個Nginx,緣由主要是LVS會根據訪問客戶端的IP+端口在會話時間內重複的轉發到同一個目標服務器。而控制這個會話時間的能夠經過設置ipvsadm --persistent 與--set這兩個參數決定。

LVS的三種工做模式

NAT(Network Address Translation)-網絡地址轉換模式。

首先,外部請求會通過LVS的VIP(Virtual IP Address);接着,LVS會根據預設的調度算法選擇一臺真實的服務器進行數據請求包轉發,轉發前會把原數據包的目標地址與目標端口修改成真實服務器的地址與端口;最後,LVS在獲得響應數據包後會把源地址與源端口改成VIP及調度器相應的端口。由於因爲全部的請求與響應都會通過LVS調度器轉發,所以容易成爲集羣的瓶頸。

TUN-隧道模式

由於NAT會的瓶頸問題,所以TUN模式採用用了請求與響應數據分離的思路,讓調度器僅處理數據請求,讓真實服務器響應數據包直接返回給客戶端,須要注意的是該模式下的真實服務器須要與外部網絡鏈接。另外TUN模式下須要在LVS調度器與真實服務器之間建立隧道鏈接,一樣會增長服務器的負擔。

DR(Direct Routing)-直接路由模式

DR模式也是採用請求與響應分離的思路,由真實服務器直接響應客戶端,可是它的報文轉發方法有所不一樣,在不修改數據報文的狀況下,將數據幀的MAC地址修改成須要轉發到的真實服務器MAC地址,免去了TUN中的IP隧道開銷。這種方式是三種負載調度機制中性能最高最好的,可是LVS調度器與真實後端服務器必須在一個局域網內。

LVS的部署

  

  接下來的部署操做將實現上圖Keepalived + LVS +Nginx的多層負載均衡,LVS將是以DR模式實現。

兩臺LVS服務器(主從)

基礎依賴安裝
yum install gcc
yum -y install openssl-devel
yum -y install libnl libnl-devel
yum install -y libnfnetlink-devel
yum -y install net-tools
yum install vim -y

安裝keepalived 和 ipvsadm

yum install -y keepalived ipvsadm

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
systemctl restart network

那麼以上關於LVS部分就搭建好了。

Nginx的部署

在兩臺Nginx服務器都執行如下指令

添加源並安裝
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

yum install -y nginx
 
填寫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;    
        }
    }
    #結束
}
設置開機啓動
systemctl start nginx.service
systemctl enable nginx.service
重啓防火牆
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall
-cmd --reload

 以上關於Nginx的部分就完成了搭建。能夠經過如下指令查看LVS的調度與鏈接信息。

查看LVS調度信息

ipvsadm -Ln

查看LVS鏈接信息

ipvsadm -Lnc

.Net Core部署

添加下載源:

rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

下載安裝:

sudo yum install aspnetcore-runtime-2.2

經過FTP把Web站點文件複製兩份並上傳到服務器,而後啓動後臺進程:

nohup dotnet Test1.dll --server.urls "http://*:5001" &
nohup dotnet Test1.dll --server.urls "http://*:5002" &

FTP服務器的部署

安裝FTP服務器:
yum install -y vsftpd
修改配置:
vim /etc/vsftpd/vsftpd.conf

把已有的三項配置修改了:

anonymous_enable=NO
listen=YES
#listen_ipv6=YES
啓動
systemctl start vsftpd
systemctl enable vsftpd 
重啓防火牆
firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload
容許root登陸,把如下兩個文件的root註釋了
vim /etc/vsftpd/user_list
vim /etc/vsftpd/ftpusers
#root
關掉selinux,會影響上傳
setenforce 0
vim /etc/selinux/config
#將SELINUX=enforcing改成SELINUX=permissive
FTP客戶端—FileZilla下載地址

https://filezilla-project.org/download.php?type=client

結束

  以上爲本篇的全部內容了,負載均衡在實際工做中涉及的地方挺多的,所以我將分爲上下兩篇,該篇爲負載均衡的上篇主要從大方向DNS、LVS、Nginx進行了分享,下篇會從微服務架構裏使用到的組件API網關和註冊中心進行探討,若是你們在實踐上遇到任何問題,或者有更好的建議能夠到評論反饋給我。

相關文章
相關標籤/搜索