haproxy+keepalived實現高可用負載均衡

来源:http://www.cnblogs.com/daixiang/archive/2016/06/12/5575477.html
-Advertisement-
Play Games

haproxy+keepalived實現高可用,負載均衡,動靜分離 ...


---恢復內容開始---

一、haproxy介紹:

  HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機。HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在時下的硬體上,完全可以支持數以萬計的併發連接。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web伺服器不被暴露到網路上。HAProxy實現了一種事件驅動、單一進程模型,此模型支持非常大的併發連接數。多進程或多線程模型受記憶體限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千併發連接。事件驅動模型因為在有更好的資源和時間管理的用戶端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴展性較差。這就是為什麼他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。

  在linux內核版本為2.6或打了epoll補丁的linux2.4上運行haproxy能獲得其最好的性能。

 

二、keepalived介紹:  

  keepalived理論工作原理

      keepalived可提供vrrp以及health-check功能,可以只用它提供雙機浮動的vip(vrrp虛擬路由功能),這樣可以簡單實現一個雙機熱備高可用功能。

      keepalived是一個類似於layer3, 4 & 5交換機制的軟體,也就是我們平時說的第3層、第4層和第5層交換。Keepalived的作用是檢測web 伺服器的狀態。 Layer3,4&5工作在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別如下:

      Layer3:Keepalived使用Layer3的方式工作式時,Keepalived會定期向伺服器群中的伺服器 發送一個ICMP的數據包(既我們平時用的Ping程式),如果發現某台服務的IP地址沒有激活,Keepalived便報告這台伺服器失效,並將它從伺服器群中剔除,這種情況的典型例子是某台伺服器被非法關機。Layer3的方式是以伺服器的IP地址是否有效作為伺服器工作正常與否的標準。在本文中將採用這種方式。

 

      Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP埠的狀態來決定伺服器工作正常與否。如web server的服務埠一般是80,如果Keepalived檢測到80埠沒有啟動,則Keepalived將把這台伺服器從伺服器群中剔除。

 

      Layer5:Layer5就是工作在具體的應用層了,比Layer3,Layer4要複雜一點,在網路上占用的帶寬也要大一些。Keepalived將根據用戶的設定檢查伺服器程式的運行是否正常,如果與用戶的設定不相符,則Keepalived將把伺服器從伺服器群中剔除。

 

         vip即虛擬ip,是附在主機網卡上的,即對主機網卡進行虛擬,此IP仍然是占用了此網段的某個IP。

 

  keepalived的用途:

      Keepalived是一個基於VRRP協議來實現的WEB 服務高可用方案,可以利用其來避免單點故障。一個WEB服務至少會有2台伺服器運行Keepalived,一臺為主伺服器(MASTER),一臺為備份伺服器(BACKUP),但是對外表現為一個虛擬IP,主伺服器會發送特定的消息給備份伺服器,當備份伺服器收不到這個消息的時候,即主伺服器宕機的時候,備份伺服器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。

      在lvs+keepalived高可用負載均衡架構中,lvs本身不支持對後端real server進行健康狀態檢測,而keepalived的誕生不僅能是lvs均衡器實現了高可用,而且還能對lvs後端的real server進行健康狀態檢測。如果有一臺web伺服器死機,或工作出現故障,Keepalived將檢測到,並將有故障的web伺服器從系統中剔除,當web伺服器工作正常後Keepalived自動將web伺服器加入到伺服器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修複故障的web伺服器。

 

 

 

 

 

配置過程:

在配置之前,先將HA中個節點進行時間同步,主機名之間相互解析,以及配置雙機互信。

在haproxy1.daixiang.com上配置:

[root@haproxy1 ~]# vim /etc/hosts
    172.16.0.1 haproxy1.daixiang.com haproxy1
    172.16.0.2 haproxy2.daixiang.com haproxy2
[root@haproxy1 ~]# ssh-keygen -t rsa -P '' [root@haproxy1 ~]# ssh-copy-id haproxy2 [root@haproxy1 ~]# ntpdate s2c.time.edu.cn

在haproxy2.daixiang.com上配置:

[root@haproxy2 ~]# vim /etc/hosts
    172.16.0.1 haproxy1.daixiang.com haproxy1
    172.16.0.2 haproxy2.daixiang.com haproxy2

[root@haproxy2 ~]# ssh-keygen -t rsa -P ''
[root@haproxy2 ~]# ssh-copy-id haproxy1
[root@haproxy2 ~]# ntpdate s2c.time.edu.cn

 

安裝haproxy和keepalived:

  在haproxy1和haproxy2節點上進行同樣的操作:

[root@haproxy1 ~]# yum install keepalived haproxy -y
[root@haproxy1 ~]# cd /etc/keepalived/
[root@haproxy1 keepalived]# cp keepalived.conf{,.bak}

 

配置keepalived:雙主模型

[root@haproxy1 keepalived]# vim keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {         #定義收件人郵箱
     root@localhost
   }
   notification_email_from root@localhost      #定義發件人郵箱
   smtp_server 127.0.0.1                              #定義郵件伺服器地址
   smtp_connect_timeout 30                         #定有郵件伺服器連接超時時長為30秒
   router_id LVS_DEVEL                                 #運行keepalive的機器的標識
}

vrrp_instance VI_1 {                      #定義VRRP實例,實例名自定義
    state MASTER                             #指定當前節點的角色,master為主,backup為從
    interface eth1                             #直接HA監測的介面
    virtual_router_id 51                    #虛擬路由標識,在同一VRRP實例中,主備伺服器ID必須一樣
    priority 100                                 #定義節點優先順序,數字越大越優先,主伺服器優先順序高於從伺服器
    advert_int 1                                #設置主備之間永不檢查時間間隔,單位為秒
    authentication {                          設置主從之間驗證類型和密碼
        auth_type PASS
        auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e

    }
    virtual_ipaddress {
        192.168.80.200                      #定義虛擬ip地址
    }
}    

vrrp_instance VI_2 {
    state BACKUP
    interface eth1
    virtual_router_id 52
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 56f7663077966379d4106e8ee30eb1a5

    }
    virtual_ipaddress {
        192.168.80.201
    }
}
View Code

  將此配置文件同步到另一個haproxy2.daixiang.com上:

[root@haproxy1 keepalived]# scp keepalived.conf haproxy2:/etc/keepalived/

  在haproxy2.daixiang.com上修改keepalived.conf配置文件:

[root@haproxy2 keepalived]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from root@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass a23c7f32dfb519d6a5dc67a4b2ff8f5e

    }
    virtual_ipaddress {
        192.168.80.200
    }
}

vrrp_instance VI_2 {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 56f7663077966379d4106e8ee30eb1a5

    }
    virtual_ipaddress {
        192.168.80.201
    }
}
View Code

  重啟keepalived:

[root@haproxy1 keepalived]# service keepalived restart
[root@haproxy1 keepalived]# ssh haproxy2 'service keepalived restart'

 

 

配置haproxy:

先將原始配置文件進行備份:

[root@haproxy1 ~]# cd /etc/haproxy/
[root@haproxy1 haproxy]# cp haproxy.cfg{,.bak}

##節點2也進行同樣的操作

編輯其配置文件修改其內容如下:

[root@haproxy1 haproxy]# vim haproxy.cfg

#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global                   #定義全局配置段
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2          #通過rsyslog將日誌進行歸檔記錄,在/etc/rsyslog.conf配置文件中,添加‘local2.*     /var/log/haproxy',並且啟用$ModLoad imudp,$UDPServerRun 514,$ModLoad imtcp,$InputTCPServerRun 514 此四項功能,最後重啟rsyslog進程。                           
    chroot      /var/lib/haproxy          #指定haproxy進程工作的目錄
    pidfile     /var/run/haproxy.pid      #指定pid文件
    maxconn     4000                      #最大併發連接數
    user        haproxy                   #運行haproxy的用戶
    group       haproxy                   #運行haproxy的組
    daemon                                #以守護進程的形式運行,即後臺運行

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults                                                #預設配置端
    mode                   http                         #工作模式,源碼包編譯預設為tcp
    log                       global                    #記錄全局日誌
    option                  httplog                     #詳細記錄http日誌
    option                  dontlognull                 #不記錄健康檢測的日誌信息
    option http-server-close                            #啟用伺服器端主動關閉功能
    option forwardfor       except 127.0.0.0/8          #傳遞client端IP至後端real server
    option                  redispatch                  #基於cookie做會話保持時,後端對應存放session的伺服器出現故障時,會話會被重定向至別的伺服器
    retries                 3                           #請求重傳次數
    timeout http-request    10s                         #斷開客戶端連接的時長
    timeout queue           1m                          #一個請求在隊列里的超時時長
    timeout connect         10s                         #設定在haproxy轉發至後端upstream server時等待的超時時長
    timeout client          1m                          #client的一次非活動狀態的超時時長
    timeout server          1m                          #等待伺服器端的非活動的超時時長
    timeout http-keep-alive 10s                         #持久連接超時時長
    timeout check           10s                         #檢查請求連接的超時時長
    maxconn                 3000                        #最大連接數

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  webserver *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets       #匹配path以/static,/images開始的,且不區分大小寫
    acl url_static       path_end       -i .jpg .gif .png .css .js .html
    acl url_static       hdr_beg(host)  -i img. video. download. ftp. imgs. image.

    acl url_dynamic      path_end       .php .jsp

    use_backend static          if url_static           #滿足名為url_static這條acl規則,則將請求轉發至後端名為static的real server組中去
    use_backend dynamic         if url_dynamic
    default_backend             static                  #如果上面所有acl規則都不滿足,將請求轉發到static組中

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static                              #定義後端real server組,組名為static
    balance     roundrobin                  #支持動態權重修改,支持慢啟動
    server      static_1 172.16.0.100:80 check inter 3000 fall 3 rise 1 maxconn 30000
    server      static_2 172.16.0.101:80 check inter 3000 fall 3 rise 1 maxconn 30000
    server      static_Error 172.16.0.1:8080 backup check         #當此組中的所有server全部不能提供服務,才將請求調度至此server上
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------


backend dynamic
    cookie cookie_name insert nocache   #使用cookie實現session綁定,且不記錄緩存
    balance     roundrobin
    server  dynamic1 172.16.0.200:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic1
    server  dynamic2 172.16.0.201:80 check inter 3000 fall 3 rise 1 maxconn 1000 cookie dynamic2      #定義dynamic組中的server,將此server命名為dynamic2,每隔3000ms檢測一個健康狀態,如果檢測3次都失敗,將此server剔除。在離線的狀態下,只要檢測1次成功,就讓其上線,此server支持最大的併發連接數為1000,cookie的值為dynamic2
     

listen state                                            # 使用單獨輸出,不需要frontedn調用:定義haproxy的狀態統計頁面
    bind *:8001                                         # 監聽的地址
    mode http                                           # http 7層工作模式:對應用層數據做深入分析,因此支持7層的過濾、處理、轉換等機制
    stats enable                                        # 開啟統計頁面輸出
    stats hide-version                                  # 隱藏狀態頁面版本號
    stats uri /haproxyadmin?stats                       # 指定狀態頁的訪問路徑
    stats auth admin:admin                              # 基於用戶名,密碼驗證。
    stats admin if TRUE                                 # 驗證通過時運行登錄。
    acl num1 src 192.168.80.0/24                        # 定義源地址為192.168.80.0/24網段的acl規則,將其命名為num1
    tcp-request content accept if num1                  # 如果滿足此規則,則允許訪問
    tcp-request content reject                          # 拒絕其他所有的訪問

將此配置文件同步當另一個haproxy節點上去: 

[root@haproxy1 haproxy]# scp haproxy.cfg haproxy2:/etc/haproxy/

重啟haproxy服務:

[root@haproxy1 haproxy]# service haproxy restart
[root@haproxy1 haproxy]# ssh haproxy2 'service haproxy restart'

 

查看這兩個節點獲取ip的情況:

haproxy1.daixiang.com:

[root@haproxy1 ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:52:3b:c0 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.1/16 brd 172.16.255.255 scope global eth1
    inet 192.168.80.200/32 scope global eth1
    inet6 fe80::20c:29ff:fe52:3bc0/64 scope link 
       valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:52:3b:ca brd ff:ff:ff:ff:ff:ff
    inet 192.168.80.125/24 brd 192.168.80.255 scope global eth0
    inet6 fe80::20c:29ff:fe52:3bca/64 scope link 
       valid_lft forever preferred_lft forever
[root@haproxy1 ~]# 
View Code

haproxy2.daixiang.com:

[root@haproxy2 haproxy]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ae:5c:b3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.80.128/24 brd 192.168.80.255 scope global eth0
    inet6 fe80::20c:29ff:feae:5cb3/64 scope link 
       valid_lft forever preferred_lft forever
6: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 00:0c:29:ae:5c:a9 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.2/16 brd 172.16.255.255 scope global eth1
    inet 192.168.80.201/32 scope global eth1
    inet6 fe80::20c:29ff:feae:5ca9/64 scope link 
       valid_lft forever preferred_lft forever
View Code

 

在後端的real server提供測試頁面,測試的結果如下:

請求以.html結尾的文件,haproxy將請求代理至後端static組中的server處理:

請求以.php結尾的文件,haproxy將請求代理至後端dynamic組中server處理:

 

註意:本文在haproxy.cfg的配置文件中,將dynamic組中的server配置了基於cookie的session綁定,所以,用同一瀏覽器看不出負載均衡的效果來。換個瀏覽器再訪問一次或者清空瀏覽器的cookie記錄就能顯示效果,如下圖。

 

haproxy的統計頁面輸出效果:

 

       至此,實驗完結,但是對於haproxy的兩個節點,keepalived對於這兩節點是怎麼進行心跳檢測,其工作原理是什麼,此知識點比較模糊,求大神賜教。

 

 

  

  

 

  

  

 

  

 

  

---恢復內容結束---


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JS自動類型轉換 var a = 1; var b = true; "==" 表示 可以自動類型轉換,比較的是數值 " " 表示可以自動類型轉換,先比較數值,再比較類型 if (a == b) { alert("相等"); //列印 }else{ alert("不等"); } 三目運算 var c ...
  • 客戶端通過構建HTable對象來與HBase集群交互。 要創建HTable對象,首先要創建一個帶有HBase集群信息的配置對象Configuration conf,其一般創建方法如下: 在擁有了conf之後,可以通過HTable提供的如下兩種構造方法來創建HTable對象: (1)直接利用conf來 ...
  • 資料庫同步問題 1.有一臺主資料庫伺服器A和另外一臺資料庫伺服器B,客戶端首先訪問資料庫B,當B資料庫伺服器掛掉時就訪問A,當對資料庫B進行DML操作時,同時對A進行更新,如果A與B之間通訊失敗,則將更新後數據存入臨時表,當恢復通訊時,自動更新,並將臨時數據刪除,同樣當B不通時,將數據臨時存在A中, ...
  • 在資料庫的邏輯結構中,表空間將不同類型的數據分別組織在一起,如系統數據、用戶數據、臨時數據、回滾數據等。在同一個表空間中,數據以資料庫對象為單位組織在一起,一般情況下一個資料庫對象對應一個段,一個表空間中包含多個段。在段中存儲資料庫對象中的數據,數據所占用的存儲空間以區為單位進行分配和回收。 一個數 ...
  • 當我們對MySQL進行分表操作後,將不能依賴MySQL的自動增量來產生唯一ID了,因為數據已經分散到多個表中。 應儘量避免使用自增IP來做為主鍵,為資料庫分表操作帶來極大的不便。 在postgreSQL、oracle、db2資料庫中有一個特殊的特性 sequence。 任何時候資料庫可以根據當前表中 ...
  • ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) ERROR 1045 (28000): Access denied for user 'root'@'localhost' (usin... ...
  • 第一:用滑鼠右鍵單擊“電腦”,在彈出的下拉菜單中選擇“屬性”。 第二:在系統屬性中選擇“高級系統設置”。在系統屬性對話框中找到其上方的“高級”選項卡,裡面有一個“環境變數”按鈕,點擊進入 第三:在下方的系統變數區中找到變數“path”,點擊下方的編輯。如果path變數之前有內容,則需要在末尾添加一 ...
  • 今天,剛好碰到伺服器C盤空間滿的情況,首先處理了臨時文件和有關的日誌文件後空間還是不夠用,我知道清理C盤的方法有很多,但今天只分享一下如何在Windows Server 2008 R2沒有磁碟清理工具的情況下使用系統提供的磁碟清理工具。 一、在Windows Server 2008 R2,右擊C盤, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...