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

洛神灬殤發表於2022-12-12

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

  • 基於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模組的引數:

各個引數介紹:

設定proxy_connect_timeout 為2秒,縮短超時時間,使其不至於太慢。

相關文章