前言
目前接觸的一個服務,它的7層負載均衡使用Nginx,4層使用的是我司自研的彈性負載均衡ELB。
而本文介紹和實戰的是工作在4層負載均衡之一的LVS(Linux Virtual Server),權當拋磚引玉,實戰是從工作中簡化而來。
概念
章文嵩博士在 1998 年 5 月成立了 Linux Virtual Server 的自由軟件項目,進行Linux服務器集群的開發工作,並且在 Linux2.4 以后的版本中,直接將 LVS 加入內核中,不用在重新自行編譯進內核。
看到這里很汗顏,這是人家98年,也就是20年前就搗鼓的技術……
因為單台服務器並不能滿足大部分的線上需求,而高端服務器又太貴,效果也不咋地,由此大部分線上服務都會使用多台服務器同時提供服務,而這樣的多台服務器就是大家俗稱的(服務器)集群。而LVS是一個開源軟件,它是專門進行Linux服務器集群開發的。
為什么要實現服務器集群?
實現服務器集群主要就是為了負載均衡(Load Balance)——有兩台或者以上的服務器或者站點提供服務,服務將來自客戶端的請求,靠某種算法,去盡量平分請求到集群的機器中,從而避免一台服務器因為負載太高而出現故障,而即使其中某個機器出現故障,負載均衡會自動規避選擇,使得用戶也能正常訪問服務。
web服務端架構的發展史
當然不會說全面,也可能會有謬誤,拋磚引玉!
單機部署
這是web服務最初的狀態,一台機器同時部署了服務器和數據庫。
我記得我之前搭建個人網站,還有我們在學校里搗鼓的一些教學項目,一般就是用的這種模式。
程序&數據庫服務器分離
后來,隨着業務量變大,類型增多,原始方案愈來愈成為了項目開發階段進行自測的一個選擇。等自測完畢,域名備案后,真正上線的往往是采用了數據庫和服務器單獨部署的模式。
好處是:服務器的壓力變小,而且當程序服務器被攻擊的時候 ,數據庫不會被連累。
壞處是:數據遠程傳輸性能無法保證,除非是將兩者放在同一機房節點下,或者同一台交換機下。
動&靜資源分離
網站有很多資源。其中有靜態資源和動態資源之分。
靜態資源,比如HTML,JavaScript,CSS,img等文件,也就是可以直接呈現給用戶的頁面資源;
動態資源,是不能直接在頁面呈現,而是需要在后台進行某種轉換的資源,即動態資源要轉換為靜態資源。
對於Java 的 Web程序,JSP/Servlet 容器的基本功能是把動態資源轉換成靜態資源,當然JSP/Servlet容器不只這些功能。
動靜分離就是把靜態資源與后台應用分開部署,提高用戶訪問靜態代碼的速度,降低對后台應用的訪問速度。
好處
比如,在目前我接手的這個網絡服務中,采用動靜分離之后,后端只需要提供restful API 即可,其他模塊或者前端只需要訪問我的API接口即可。也就是說,如此一來,我的服務,可以同時被多個外部模塊甚至是多平台去調用,邏輯清晰,便於維護。
另外,提到了前端調用后端的restful API,這樣可以使得前端和后端的開發&測試進度互不影響,它們之間只需要關注接口的協議即可。
這樣搞的最終目的,無非就是為了減輕后端服務器的壓力,提高靜態資源訪問速度,因為后端程序不需要在使用模板去渲染頁面。
壞處
首先要明白什么是SEO,以國內的百度為例,百度的爬蟲會根據網站的URL去抓取頁面進行分析,一份分析的都是文本內容,也就是說會過濾掉js代碼,而動靜分離后,前端一般需要實時同后端進行異步請求和響應,這個異步請求的實現一般都是js來做。而常規的爬蟲一般不能抓取異步加載的內容,也就是說爬蟲抓取下來的前端的頁面里,包含了大量異步加載的操作,但是爬蟲無法執行也無法獲得其內容,這樣會導致網站的SEO受影響。
目前我聽說的解決方案,是可以采用前端緩存技術來解決,把不經常變的數據緩存起來。
負載均衡+服務水平擴展
負載均衡不再多說,談下下服務擴展。
服務的垂直擴展
垂直擴展意思就是努力提高后端服務的服務能力,如何優化業務邏輯?如何提高代碼質量?使用多線程(進程)?能否從單機硬件着手,比如增加服務器內存,磁盤容量,購買更好的CPU……以期能提高服務的負載能力。
但是這樣搞,明顯成本是很高的,死活薅一個羊的毛,其實意義不是很大。於是,就有了水平擴展。
服務的水平擴展
在水平擴展中,不追求增加單個服務器的負載能力,而是簡單的通過部署更多的廉價服務器,去分攤負載。
數據庫性能瓶頸
搞了那么多的服務器,在結合LB,雖然負載被分攤,但是數據庫的性能又跟不上了。主要還是I/O瓶頸,那么這時候就出現了NoSQL緩存。
NoSQL緩存
主流的有memcached以及Redis。
當然,數據庫方面也有水平擴展,同時還有庫表水平和垂直拆分。
庫表水平和垂直拆分
垂直拆分:當網絡服務不斷壯大的時候,數據庫也會變成多個子系統來支撐,這時就有按業務把表划分出來的需求,即就是把業務聯系緊密的數據表划分到同一個數據庫中,這樣整個服務的多張表會分配到不同的數據庫,原則是不破壞第三范式。
但是垂直拆分依然存在問題,如果拆分之后的單表數據小,數據增速緩慢,一般會維持現狀。否則進行水平拆分。
水平拆分:把一個表按照約定的規則,將數據划分到不同表或者數據庫。
大白話解釋就是:庫表的水平拆分對應的行,把行數據拆分到不同表中, 而垂直拆分對應的列,把表數據拆分到不同表中。
因為后續還涉及到了篩選合並。
總之,比較復雜……
引入SOA架構
SOA,即面向服務的體系結構(Service-Oriented Architecture,SOA),它是一個組件模型,官方的解釋是:
它將應用程序的不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯系起來。
接口是采用中立的方式進行定義的,它應該獨立於實現服務的硬件平台、操作系統和編程語言。這使得構建在各種各樣的系統中的服務可以使用一種統一和通用的方式進行交互。
SOA,本質上是一種業務和技術完全分離,業務和技術又能自由組合的思想。
SOA架構,達到了目前軟件設計思想的最高境界。
引入CDN鏡像
大數據平台
防火牆——防DDos
當然接下來的東西還有很多
容器部署
……
多機房容災機制
……
虛擬化雲計算
一切都在雲上,雲存儲,雲主機等等。
四層負載均衡
本圖的7層負載均衡使用了Nginx,4層使用了LVS,緩存服務使用Memcached,隊列服務使用Redis,文件服務器使用NFS,數據庫是MySQL主從集群。
可以看到,用戶的請求先經過防火牆,然后到LVS負載均衡主服務器,然后按照靜態和動態內容,分發到Nginx的負載均衡服務器,如果是靜態內容,那么直接從靜態web節點集群讀取數據返回給用戶,如果是動態內容,那么Nginx會把請求分發到Tomcat集群,也就是動態web節點。
Tomcat集群獲得請求后,會做一系列業務判斷,比如是否有緩存,如果緩存沒有,要去直接訪問MySQL主從集群。如果對於一些memcached應付不了的,需要持久化的資源,就會被送到Redis隊列服務器。
對於Nginx和Tomcat,都會共享文件,這里就可以用NFS文件服務器解決。
額外的,海量數據的處理,比如日志分析,目前都是使用的Hadoop。
……
其中,本篇文章重點說的是4層負載均衡 LVS。
負載均衡的發展史
硬件時代
硬件負載均衡解決方案是直接在服務器和外部網絡間,安裝負載均衡設備,由專門的設備完成專門的任務,獨立於操作系統,再加上多樣化的負載均衡算法,智能化的流量管理,使得服務的整體性能得到大量提高。但是相對來說硬件的成本較高。
軟件時代
因為硬件的成本貴,互聯網公司肯定不會首選的,那么軟件負載均衡就應運而生。也是目前使用的最為廣泛的。一是它的效果很牛B,二是不需要很大的成本,甚至可以近乎0成本!
其中常用的軟件實現方式有:
- LVS
- Nginx
- HAProxy
LVS 主要工作在第四層,Nginx 主要工作在第七層,HAProxy 是一款提供高可用性、負載均衡以及基於TCP和HTTP應用的代理軟件,也支持虛擬主機。
歡迎關注
dashuai的博客是終身學習踐行者,大廠程序員,且專注於工作經驗、學習筆記的分享和日常吐槽,包括但不限於互聯網行業,附帶分享一些PDF電子書,資料,幫忙內推,歡迎拍磚!