天天看點

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

秒殺購物商城業務服務-分布式架構介紹

  • 基于MySQL資料庫叢集技術實作服務的高可用
  • 基于Tomcat的叢集負載機制實作Tomcat伺服器的高可用
  • 基于Nginx負載均衡機制實作負載均衡(介紹和配置)
  • 基于Redis緩存服務實作資料緩存控制相關介紹和技術點分析
  • 對未來的分布式技術架構擴充和延伸介紹(包含雲原生部分)
基于MySQL資料庫叢集技術實作服務的高可用

高可用架構對于網際網路服務基本是标配,無論是應用服務還是資料庫服務都需要做到高可用。對于一個系統而言,可能包含很多子產品,比如前端應用,緩存,資料庫,搜尋,消息隊列等,每個子產品都需要做到高可用,才能保證整個系統的高可用。對于資料庫服務而言,高可用可能更複雜,對使用者的服務可用,不僅僅是能通路,還需要有正确性保證,是以資料庫的高可用需要更加認證對待。

MySQL高可用架構分類
  • MySQL實作高可用之MMM
  • MySQL實作高可用之MHA
  • MySQL實作高可用之主從架構
  • MySQL實作高可用之Cluster模式

MMM的技術分析

MMM(Master-Master replication manager for MySQL)是一套支援雙主故障切換和雙主日常管理的腳本程式。

MMM的基礎元件分析

  • mmm_mond:監控程序,負責所有的監控工作,決定和處理所有節點角色活動。是以,腳本需要在監管上運作。
  • mmm_agentd:運作在每個msql伺服器上的代理程序,完成監控的探針工作和執行簡單的遠端服務設定。此腳本需要在被監管機上運作。
  • mmm_control:一個簡單的腳本,提供管理mmm_mond進行的指令。

MMM實作基本實作原理

MMM提供了自動和手動兩種方式移除一組伺服器中複制延遲較高的伺服器的虛拟ip,同時它還可以備份資料,實作兩節點之間的資料同步等。

MySQL本身沒有提供replication failover的解決方案,通過MMM方案能實作伺服器的故障轉移,進而實作mysql的高可用。

MHA簡介

MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司的youshimaton(現就職于Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟體。

MHA的基礎元件

MHA由兩部分組成:MHA Manager(管理節點)和MHA Node(資料節點)。

MHA Manager可以單獨部署在獨立的機器上管理多個master-slave叢集,也可以部署在一台slave節點上。

MHA的實作原理

  • MHA Node運作在每台MySQL伺服器上,MHA Manager會定時探測叢集中的master節點,當master出現故障時,它可以自動将最新資料的slave提升為新的master,然後将所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。
MySQL主從架構

此種架構,一般初創企業比較常用,也便于後面步步的擴充

此架構特點

  1. 成本低,布署快速、友善
  2. 讀寫分離
  3. 還能通過及時增加從庫來減少讀庫壓力
  4. 主庫單點故障
  5. 資料一緻性問題(同步延遲造成)

MySQL Cluster基本概念

MySQL Cluster簡單地講是一種MySQL叢集的技術,是由一組計算機構成,每台計算機可以存放一個或者多個節點,其中包括MySQL伺服器,DNB Cluster的資料節點,管理其他節點,以及專門的資料通路程式,這些節點組合在一起,就可以為應用提高可高性能、高可用性和可縮放性的Cluster資料管理;

基于Tomcat的叢集負載機制實作Tomcat伺服器的高可用

Tomcat叢集原理

通過Nginx負載均衡進行請求轉發

Tomcat叢集能帶來什麼

  • 提高服務的性能, 并發能力, 以及高可用性
  • 提供項目架構的橫向擴充能力

Tomcat叢集産生什麼問題

  • Session登入資訊存儲以及讀取的問題
  • 伺服器定時任務并發的問題
Tomcat 單服務體系架構

在這個架構圖中,一層Nginx,首先Nginx主要職責給Tomcat一層反向代理。

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

此外,Nginx還可以FTPServer指定的目錄再做一層目錄轉發,保證上傳上去的圖檔實時可以通過http協定通路到。單服務架構先不用考慮叢集碰到的各種問題

Tomcat叢集"簡單版"
【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

比如,我們的登入的時候登入了A伺服器,session資訊存儲到A伺服器上了,假設我們使用的負載均衡政策是ip hash,那麼登入資訊還可以從A伺服器上通路,但是這個有可能造成某些伺服器壓力過大,某些伺服器又沒有什麼壓力,這個時候壓力過大的機器(包括網卡帶寬)有可能成為瓶頸,并且請求不夠分散。

首先要解決Session共享的問題

這時候我們使用輪詢或者最小連接配接負載均衡政策,就導緻了,第一次通路A伺服器,第二次可能通路到B伺服器,這個時候存儲在A伺服器上的session資訊在B伺服器上讀取不到。

典型負載均衡政策分析

打個比方,我們有輪詢,權重,位址散列,位址散列又分為原ip位址散列hash,目标ip位址散列hash,最少連接配接,權重最少連接配接,還有繼續更新的很多種政策

  • 輪詢:優點:實作簡單,缺點:不考慮每台伺服器處理能力
  • 權重:優點:考慮了伺服器處理能力的不同
  • 位址散列:優點:能實作同一個使用者通路同一個伺服器
  • 最少連接配接:優點:使叢集中各個伺服器負載更加均勻
  • 權重最少連接配接:在最少連接配接的基礎上,為每台伺服器加上權值。算法為(活動連接配接數*256+非活動連接配接數)/權重,計算出來的值小的伺服器優先被選擇。

Session管理-Session Sticky粘滞會話:

對于同一個連接配接中的資料包,負載均衡會将其轉發至後端固定的伺服器進行處理。

解決了我們session共享的問題,但是它有什麼缺點呢?

  • 一台伺服器運作的服務挂掉,或者重新開機,上面的 session 都沒了
  • 負載均衡器成了有狀态的機器,為以後實作容災造成了羁絆

Session管理-Session 複制

就是每一個Tomcat都存儲我們的Session,不同的tomcat之間進行拷貝複制。

解決了我們session共享的問題,但是它有什麼缺點呢?

  • 應用伺服器間帶寬問題,因為需要不斷同步session資料
  • 大量使用者線上時,伺服器占用記憶體過多

Session管理-基于Cookie

主要用于我們将session會話如同token一般存儲在我們的前端

解決了我們session共享的問題,但是它有什麼缺點呢?

  • cookie 的長度限制
  • cookie存于浏覽器,安全性是一個問題

Session管理-Session 伺服器

就是通過一個專門管理session會話的管理器服務,進行集中化存儲和管理session

解決了我們session共享的問題,這種方案需要思考哪些問題呢?保證 session 伺服器的可用性,session伺服器單點如何解決?

  • 我們在寫應用時需要做調整存儲session的業務邏輯
  • 打個比方,我們為了提高session server的可用性,可以繼續給session server做叢集
Tomcat單機部署多應用
  1. 解壓2個tomcat, 分别命名為tomcatA和tomcatB
  2. 分别設定2個tomcat的URIEncoding, 将tomcat的conf/server.xml裡的port修改為兩個不同端口。
【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析
【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

設定tomcat的環境變量

tomcatA的環境變量和以往一樣, 不做改變

設定tomcat的環境變量

​sudo vim /ect/profile​

在profile檔案裡新增

export CATALINA_BASE=/Users/tomcat/apache-tomcat-9.0.21
export CATALINA_HOME=/Users/tomcat/apache-tomcat-9.0.21
export TOMCAT_HOME=/Users/tomcat/apache-tomcat-9.0.21      
export CATALINA_2_BASE=/Users/tomcat/tomcat2
export CATALINA_2_HOME=/Users/tomcat/tomcat2
export TOMCAT_2_HOME=/Users/tomcat/tomcat2      

強制儲存退出

繼續配置tomcatB下的catalina.sh裡的内容,

cd tomcat目錄,在# OS specific support. $var must be set to either true or false.下加入。

sudo vi catalina.sh
export CATALINA_BASE=$CATALINA_2_BASE
export CATALINA_HOME=$CATALINA_2_HOME      

執行重新整理環境變量

​source /etc/profile​

使環境變量生效, 執行

​echo $CATALINA_2_BASE​

如果有輸出, 即環境變量已經生效

​/Users/tomcat/tomcat2​

分别進入兩個tomcat下的bin目錄啟動tomcat, 正常即可

配置nginx

修改host

​sudo vim /etc/hosts​

所謂tomcat叢集,就是可以向外提供并行服務的多台機器,任何一台伺服器當機,其它伺服器可以替代它向外提供服務,而不影響使用者通路。

nginx是一個常用的反向代理服務,可自定義子產品,實作請求轉發及負載均衡(根具體采用政策有關)。為了tomcat叢集的高可用性,還需要實作nginx的雙機熱備。

一,如果僅是對外提供一個頁面通路,不用區分單一使用者(不區分每個通路session,不涉及使用者權限,使用者資料等内容),僅僅配置nginx負載均衡政策即可。

nginx負載均衡政策主要分一下四種:

1)、輪詢(預設)每個請求按時間順序逐一配置設定到不同的後端伺服器,如果後端伺服器當機,能自動剔除。

2)、ip_hash 每個請求按通路ip的hash結果配置設定,這樣每個訪客固定通路一個後端伺服器。

3)、fair 按後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定。

4)、url_hash 按通路url的hash結果來配置設定請求,使每個url定向到同一個後端伺服器,後端伺服器為緩存時比較有效。

二,如果涉及到使用者session,做一些鑒權緩存、存放臨時資訊時,就必須做tomcat的session共享。

目前可參考到的session共享方式主要分為兩種。

1)利用tomcat自帶的多點傳播機制,實作session複制。

對tomcat及應用的若幹配置檔案進行配置即可實作,網上有很多資料可參考。但這種方式些弊端,看過一些資料,不建議用session複制的方式。在實際使用過程中,也發現有存在session莫名失蹤的現象。

2)利用第三方機制存儲session。

比較常見的是tomcat內建memcached伺服器來存儲session。實際項目中,我們采用過利用redis實作session存儲,redis高效的存取性能為高效的通路提供了保障,但是目前redis的叢集功能似乎沒有釋出,如何解決redis的單點故障需要研究。

小結:是否實作session共享與nginx的負載政策有很大關系。比如采用輪詢政策,就必須實作session共享,因為用戶端會通路到每台伺服器;而如果采用ip_hash政策,就可以不用考慮session共享的問題了,但是ip_hash有些缺陷使它不能随便使用(如多台pc使用同一個外網ip)。

最近發現一個nginx的粘連子產品(類似session粘連),可以看做nginx的第5種均衡政策。它利用用戶端cookie,對其寫入一個route參數,每次通路可以根據route的值,固定的通路一台伺服器,解決的session共享的問題。

Nginx是什麼?

Nginx(發音同 engine x)是一款輕量級的Web 伺服器/反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器,并在一個BSD-like 協定下發行。由俄羅斯的程式設計師Igor Sysoev(伊戈爾·西索夫)所開發,供俄國大型的入口網站及搜尋引擎Rambler(漫步者)(俄文:Рамблер)使用。其特點是占有記憶體少,并發能力強,事實上nginx的并發能力确實在同類型的網頁伺服器中表現較好,中國大陸使用nginx網站使用者有:新浪、網易、 騰訊等。

優點
  1. 可運作linux,并有 Windows移植版。
  2. 在高連接配接并發的情況下,Nginx是Apache伺服器不錯的替代品Nginx在美國是做虛拟主機生意的老闆們經常選擇的軟體平台之一。能夠支援高達50,000個并發連接配接數的響應
負載均衡的功能
  • 轉發
  • 故障移除
  • 恢複添加
  • 高可用 Ha

我們想要使用Nginx那麼就必須滿足上面的四個條件.

我們配置負載均衡的目的是在于當使用者通路我們的伺服器的時候, 首先會通過 Nginx伺服器來決定轉發到哪個Tomcat伺服器上去給使用者提供服務, 當然這個機率是我們通過權重來配置的. 經過Nginx指派之後, 我們就可以處理高并發的通路了, 這裡就能達到負載均衡的目的.

Nginx如何實作負載均衡

Nginx的負載均衡是通過upstream來實作的,在upstream中指定若幹個 server,格式如下:

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

myserver就是通過 upstream 定義的一組負載均衡模闆,其中:

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

在配置完upstream後,還要讓用戶端過來的請求反向代理到myserver,格式如下:

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

完成了負載均衡的配置,但是在實際需求中除了上面的設定外,還會增加一些額外設定:

負載均衡政策設定請求上遊伺服器攜帶請求頭資訊upstream子產品中其他參數設定

Nginx的負載均衡政策有5種方式:

【秒殺購物商城業務服務】「分布式架構服務」盤點中間件服務的高可用模式及叢集技術的方案分析

除以上5種,還有一種:least-connected — 下一個請求被配置設定到擁有最少活動連接配接數的伺服器。

編輯nginx配置檔案(例中為/usr/local/ngnix/conf/nginx.conf),找到http結點,

配置案例

http {
    upstream myapp1 {
        server 192.168.1.103:8080;
        server 192.168.1.104:8080;
   }
   server {
        listen 80;
        server_name  localhost;
        location /webautotest/ {
            proxy_buffering off;
            proxy_pass http://myapp1;
        }
    }
}      

重新加載配置檔案

[root@localhost nginx-1.10.0]# /usr/local/ngnix/sbin/nginx -s reload      

預設的負載均衡配置

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://myapp1;
        }
    }
}      

最少連接配接負載均衡

  • 另一個負載均衡原則為least-connected。當一些請求花費較長時間來完成時,least-connected更“公平”的控制應用程式執行個體上的負載。
  • 配置了least-connected的負載均衡機制的情況下,nginx會盡量不讓負載繁忙的應用伺服器上負載過多的請求,相反的,會把新的請求發送到比較不繁忙的伺服器。

配置示例:

upstream myapp1 {
        least_conn;
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
}      

會話持久性

注意,round-robin或least-connected負載均衡下,每個後續的用戶端可能被分發至不同伺服器,不保證相同用戶端的請求總是被發送到相同的伺服器。

如果有必要把用戶端綁定至特定伺服器,則可使用ip-hash負載均衡機制。

ip-hash機制

ip-hash機制下,用戶端ip位址被用作hash key來判斷用戶端請求應該發送到哪個伺服器,這種方法保證了來自相同用戶端的請求總是發送到相同伺服器(如果伺服器可用的話)

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}      
負載均衡權重

可通過配置伺服器權重來影響負載均衡機制。上面的例子中,都未配置伺服器權重,這意味着所有伺服器都擁有相同的權重。

針對round-robin負載機制,權重意味着更多或更少的請求傳送至伺服器---假設有足夠的請求,且按統一方式處理請求,且足夠快完成請求處理。

配置示例:

upstream myapp1 {
        server srv1.example.com weight=3;
        server srv2.example.com;
        server srv3.example.com;
}      

上例配置中,每發送至伺服器執行個體的5個新的請求中,有3個發送到srv1,1個發送到srv2,另1個發送到srv3。

注:目前版本似乎隻實作了round-robin機制下的權重設定

健康檢測

  • nginx反向代理實作包含伺服器健康檢查。如果來自特定伺服器的響應失敗,報錯,nginx将标記該伺服器為failed,一段時間内盡量避免選擇此伺服器作為随後請求的分發伺服器。
  • max_fails機制設定fail_timeout期間,和伺服器溝通失敗的連續重試次數,預設為1.當設定為0時,不做伺服器健康檢測。fail_timeout定義了伺服器被标記為failed的時長。fail_timeout時間間隔過後,nginx将開始使用活動用戶端請求來探測伺服器,如果探測成功則标記伺服器為活動伺服器。

Nginx負載均衡配置項介紹

下面我們将介紹一下proxy子產品的參數:

各個參數介紹: