Java 高併發,大流量解決方案

對於我們所研發的網站,若網站的訪問量非常大,那麼我們必須考慮相關的併發訪問問題,而併發問題是絕大部分的程序員頭疼的問題。本 Chat 帶你領略一下相關概念和解決方案:

概念類:

  • 什麼是 QPS、PV、UV、QPS 不等於併發連接數?
  • 大中小三種類型網站的 QPS 一般是多少?
  • 具體解決方案:數據庫層面、Web 負載層面、IP Hash 策略、Nginx 負載均衡策略......

第一章 哪些必須掌握的常用概念

1.1 什麼是 QPS?

QPS:

每秒查詢率(Query Per Second),每秒的響應請求數,也即是最大吞吐能力。

QPS = req / sec = 請求數 / 秒。

QPS 統計方式 (一般使用 http _ load 進行統計)。

QPS = 總請求數 / ( 進程總數 * 請求時間 )。

QPS:單個進程每秒請求服務器的成功次數。

峰值QPS:

原理:每天 80% 的訪問集中在 20 % 的時間裡,這 20 % 時間叫做峰值時間。

單臺服務器每天 PV 計算

公式1:每天總 PV = QPS * 3600 * 6 。 公式2:每天總 PV = QPS * 3600 * 8。

集群服務器計算

服務器數量 = ceil(每天總 PV / 單臺服務器每天總 PV) 峰值 QPS 和機器計算公式

  • 原理:每天 80 % 的訪問集中在 20 % 的時間裡,這 20 % 時間叫做峰值時間 。
  • 公式:( 總 PV 數 * 80 % ) / ( 每天秒數 * 20 % ) = 峰值時間每秒請求數(QPS)
  • 機器:峰值時間每秒 QPS / 單臺機器的 QPS = 需要的機器

舉例 1:

每天 600 w PV 的在單臺機器上,這臺機器需要多少 QPS? ( 6000000 * 0.8 ) / (86400 * 0.2 ) = 278 (QPS)

舉例 2:

如果一臺服務器機器的 QPS 是 58,需要幾臺機器來支持? 278 / 65 = 4.3 採用進 1 算法,需要 5 臺機器支持。

以上 數據僅供 chat 講解知識,參考,勿要對應自己服務器,請以自己服務器的性能為準。

1.2 什麼是 PV?

PV 是 page view 的縮寫,即頁面瀏覽量,或點擊量;通常是衡量一個媒體頻道或網站甚至一條網絡文章的主要指標。

控制 PV 的網站:24 小時算一次 PV 。 例子:點我查看,24 小時只算一次 PV。

普通的 PV 的網站:每訪問一次 PV 增加一次。例子:點我查看,刷新看看人數,沒刷新增加1人。

Array 老師提醒: 針對大併發和大流量的網站,一定要做好這個,否則,黑客利用 PV 漏洞,及其容易刷 PV,導致服務器崩潰。

PV:一個網站的 PV,從某種程度上已成為投資者衡量商業網站表現的最重要尺度,可以通過專業的工具查詢和計算。

第三方查詢工具: http://www.alexa.cn/ 這個可以查詢或者搜索 alexa 的工具。

1.3 什麼是UV ?

UV:

獨立訪客即 Unique Visitor,訪問您網站的一臺電腦客戶端為一個訪客。00:00 - 24:00 內相同的客戶端只被計算一次,指訪問某個站點或點擊某條新聞的不同 IP 地址的人數。

在同一天內,uv 只記錄第一次進入網站的具有獨立 IP 的訪問者,在同一天內再次訪問該網站則無效。獨立 IP 訪問者提供了一定時間內不同觀眾數量的統計指標,而沒有反應出網站的全面活動狀況。

分析:PV 和 UV 各有各的用途,但是往往 UV 更為準確,但是 PV 更能查看活動值。

1.4 什麼是 PR 值

PR 值,即 PageRank,網頁的級別技術。取自 Google 的創始人 Larry Page,它是 * 運算法則(排名公式)的一部分,用來標識網頁的等級 / 重要性。級別從 1 到 10 級,10 級為滿分。PR 值越高說明該網頁越受歡迎(越重要)。

一個 PR 值為 1 的網站表明這個網站不太具有流行度,而 PR 值為 7 到 10 則表明這個網站非常受歡迎。

我們可以這樣說:一個網站的外部鏈接數越多其 PR 值就越高;外部鏈接站點的級別越高,網站的 PR 值就 越高。

例如:如果 https://edu.csdn.net/course/detail/8566 網站上有一個 www.ugaoxin.com 網站的鏈接,那為 CSDN 網站必須提供一些乾貨,搜索引擎認為來自 ugaoxin.com 的友情鏈接,從而對 CSDN 的網站增加PR值。

1.5 QPS 不等於併發連接數

通過前面的計算公式和各自概念的關係:我們得出結論 QPS 不等於併發連接數。

QPS 是每秒 HTTP 請求數量,併發連接數是系統同時處理的請求數量。

(總 PV 數 80 %)/(6小時秒數 20 %)= 峰值每秒請求數(QPS) 80 % 的訪問量集中在 20 % 的時間。

這點謹防在面試中誤入陷阱,面試中該部分是拔高的部分,很多人被面試官帶篇。Array 老師在做面試官期間,問過很多次,如果面試者打不上了你自己做的系統是 QPS 和併發連接數,或者誤認為是一個的話,在以後的談薪資等容易被動,甚至讓你回家等消息了,因為這是實際項目經驗不可或缺的一部分,要不你不上心。

那麼如果被面試官問道你做的網站的 QPS 是多了?你該怎麼回答?尤其是對這方面缺乏或者沒有實戰經驗的同學,請查看下面的章節。

第二章 大中小三種類型網站的 QPS 一般是多少?

隨著 QPS 的增長,每個階段需要根據實際情況來進行優化,優化的方案也與服務器等硬件、網絡帶寬等現實的物理條件息息相關。

2.1網站的大小標準

一個網站的“大小”,所採用的架構不同,用到的技術也大相徑庭,眾多種衡量的方法 。對於併發業界的,存在爭議,這裡從數量級層面總結歸納一下。

網站的熱度:日均 PV,同時在線人數、註冊用戶數,活躍用戶等運營數據。

互聯網的“3 秒定律”,大型網站要求 1.5 秒以內加載整頁,或者至少可以達到瀏覽。

2.2 分類

2.2.1 平均值 < 50QPS

小型網站,一般的服務器就可以應付,可以用最簡單的方法快速搭建,短期沒有太多的技術瓶頸,只要服務器穩定即可,網絡通暢即可。

2.2.2 50QPS < 平均值 < 100QPS

DB 數據庫極限型:常用的關係型數據庫的每次請求大多都能控制在 0.01 秒左右,就算你研發的 Web 網站每頁面只有一次數據庫請求,那麼頁面請求無法保證在 1 秒鐘內完成 100 個請求,這個階段要考慮做 Cache 或者多 DB 負載。

2.2.3 300QPS

帶寬極限型

服務器常用 IDC 提供的“百兆帶寬”,這意味著網站出口的實際帶寬是 8 M Byte左右。假定每個頁面只有 10 K Byte,在這個併發條件下,百兆帶寬已經快速的佔用資源完畢。

這要就可能考慮優化的技術如同:CDN 加速 & 異地緩存,集群負載等技術。

2.2.4 500QPS < 平均值 < 1000QPS

內網帶寬極限+緩存極限型

由於 Key/value 的特性,每個頁面對緩存技術的請求遠大於直接對 DB 的請求。

例:Memcache 的悲觀併發數在 2w 左右,現在的實際項目,可能在大併發之前內網的帶寬就已經吃光。

Array 老師當初做電商項目的時候,用的也是 memcached,但是壓力測試的時候,在 7991QPS 的時候,memcached 已經不穩定,存在各種無法預知的程序問題,這是壓力迅速到到 mysql 的數據庫上了,整個系統性能迅速下降,這樣就會出現網站訪問變慢,甚至無法訪問的 404 等情況,我們當時做的是 wait.xxxxx.com,跳轉到等待界面,這樣提示更加的友好。

2.2.5 1000QPS < 平均值 < 2000QPS

FORK / SELECT,鎖模式極限型

線程模型決定吞吐量。不管你係統中最常見的鎖是什麼鎖,這個級別下,文件系統訪問鎖都成為了災難。這就要求系統中不能存在中央節點,所有的數據都必須分佈存儲,數據需要分佈處理。總之, 分佈

Array 老師提醒:這個是常說的是否需要做分佈式的標準,如果達到了這個標準,必須做分佈式。

2.2.6 2000 QPS < 平均值

C10K 極限 現在阿里的技術以及實現了 C25K,但熟悉 java 的短板理論,木桶原理很明顯我們能得出, 網站整體併發的永遠是最慢的那個。在阿里巴巴的雙 11 的晚上 24 點的時候,肯定超過這個值。

第三章 具體的解決方案

以下內容都是在實際項目中遇到的各種瓶頸或者問題,經過了團隊討論,前輩的請教,閉關的修煉,查閱大量技術官網或者文檔,最後的總結,結合市面上的各種成熟方案,聯繫當下硬件,寬帶等多方面的侷限,經過了研發團隊的打磨和麵試中,面試高工或者架構師的門檻,總結如下:供大家在日常業務中參考和麵試中升職加薪。

3.1 數據庫層面

數據庫緩存層的優化:數據庫集群、庫表散列 自從去 IOE 之後,大批量的軟件研發團隊和企業都開始研究使用 Mysql,緩存等作為存儲設備。本 chat 以 mysql 的數據庫層面去探索優化的意義。

Java 高併發,大流量解決方案

下面具體給大家說一說

數據庫存儲引擎是數據庫底層軟件組織,數據庫管理系統使用數據引擎進行創建、查詢、更新和刪除數據。不同的存儲引擎提供不同的存儲機制、索引技巧、鎖定水平等功能,使用不同的存儲引擎,還可以 獲得特定的功能。現在許多不同的數據庫管理系統都支持多種不同的數據引擎。

MySql 的核心就是存儲引擎。

3.1.1 InnoDB 存儲引擎

InnoDB 是事務型數據庫的首選引擎,支持事務安全表(ACID),支持行鎖定和外鍵,上圖也看到了,InnoDB 是默認的 MySQL 引擎。InnoDB 主要特性有:

1、InnoDB 給 MySQL 提供了具有提交、回滾和崩潰恢復能力的事物安全(ACID 兼容)存儲引擎。InnoDB 鎖定在行級並且也在 SELECT 語句中提供一個類似 Oracle 的非鎖定讀。這些功能增加了多用戶部署和性能。在 SQL 查詢中,可以自由地將 InnoDB 類型的表和其他 MySQL 的表類型混合起來,甚至在同一個查詢中也可以混合。

2、InnoDB 是為處理巨大數據量的最大性能設計。它的 CPU 效率可能是任何其他基於磁盤的關係型數據庫引擎鎖不能匹敵的。

3、InnoDB 存儲引擎完全與 MySQL 服務器整合,InnoDB 存儲引擎為在主內存中緩存數據和索引而維持它自己的緩衝池。InnoDB 將它的表和索引在一個邏輯表空間中,表空間可以包含數個文件(或原始磁盤文件)。這與 MyISAM 表不同,比如在 MyISAM 表中每個表被存放在分離的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制為 2 GB 的操作系統上。

4、InnoDB 支持外鍵完整性約束,存儲表中的數據時,每張表的存儲都按主鍵順序存放,如果沒有顯示在表定義時指定主鍵,InnoDB 會為每一行生成一個 6 字節的 ROWID,並以此作為主鍵。

5、InnoDB 被用在眾多需要高性能的大型數據庫站點上。

InnoDB 不創建目錄,使用 InnoDB 時,MySQL 將在 MySQL 數據目錄下創建一個名為 ibdata1 的 10 MB 大小的自動擴展數據文件,以及兩個名為 ib _ logfile0 和 ib _ logfile1 的 5 MB 大小的日誌文件。

3.1.2 MyISAM 存儲引擎

MyISAM 基於 ISAM 存儲引擎,並對其進行擴展。它是在 Web、數據倉儲和其他應用環境下最常使用的存儲引擎之一。MyISAM 擁有較高的插入、查詢速度,但不支持事物。

MyISAM 主要特性有:

1、大文件(達到 63 位文件長度)在支持大文件的文件系統和操作系統上被支持。

2、當把刪除和更新及插入操作混合使用的時候,動態尺寸的行產生更少碎片。這要通過合併相鄰被刪除的塊,以及若下一個塊被刪除,就擴展到下一塊自動完成。

3、每個 MyISAM 表最大索引數是 64,這可以通過重新編譯來改變。每個索引最大的列數是 16。

4、最大的鍵長度是 1000 字節,這也可以通過編譯來改變,對於鍵長度超過 250 字節的情況,一個超過 1024 字節的鍵將被用上。

5、BLOB 和 TEXT 列可以被索引。

6、NULL 被允許在索引的列中,這個值佔每個鍵的 0 ~ 1 個字節。

7、所有數字鍵值以高字節優先被存儲以允許一個更高的索引壓縮。

8、每個 MyISAM 類型的表都有一個 AUTO _ INCREMENT 的內部列,當 INSERT 和 UPDATE 操作的時候該列被更新,同時 AUTO _ INCREMENT 列將被刷新。所以說,MyISAM 類型表的 AUTO _ INCREMENT 列更新比 InnoDB 類型的 AUTO _ INCREMENT 更快。

9、可以把數據文件和索引文件放在不同目錄。

10、每個字符列可以有不同的字符集。

11、有 VARCHAR 的表可以固定或動態記錄長度。

12、VARCHAR 和 CHAR 列可以多達 64KB。

使用 MyISAM 引擎創建數據庫,將產生 3 個文件。文件的名字以表名字開始,擴展名之處文件類型:frm 文件存儲表定義、數據文件的擴展名為 .MYD(MYData)、索引文件的擴展名時 .MYI(MYIndex)。

3.1.3 MEMORY 存儲引擎(也叫 HEAP)堆內存

MEMORY 存儲引擎將表中的數據存儲到內存中,未查詢和引用其他表數據提供快速訪問。

MEMORY主要特性有:

1、MEMORY 表的每個表可以有多達 32 個索引,每個索引 16 列,以及 500 字節的最大鍵長度。

2、MEMORY 存儲引擎執行 HASH 和 BTREE 縮影。

3、可以在一個 MEMORY 表中有非唯一鍵值。

4、MEMORY 表使用一個固定的記錄長度格式。

5、MEMORY 不支持 BLOB 或 TEXT 列。

6、MEMORY 支持 AUTO _ INCREMENT 列和對可包含 NULL 值的列的索引。

7、MEMORY 表在所由客戶端之間共享(就像其他任何非 TEMPORARY 表)。

8、MEMORY 表內存被存儲在內存中,內存是 MEMORY 表和服務器在查詢處理時的空閒中,創建的內部表共享。

9、當不再需要 MEMORY 表的內容時,要釋放被 MEMORY 表使用的內存,應該執行 DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用 DROP TABLE)。

3.1.4 EXAMPLE 存儲引擎

是一個 “ 存根 ” 引擎,它不做什麼。你可以用這個引擎創建表,但沒有數據被存儲於其中或從其中檢索。這個引擎的目的是服務,在 MySQL 源代碼中的一個例子,它演示說明如何開始編寫新存儲引擎。同樣,它的主要興趣是對開發者。

3.1.5 NDB Cluster

是被 MySQL Cluster 用來實現分割到多臺計算機上的表的存儲引擎。

它在 MySQL - Max 5.1 二進制分發版裡提供。這個存儲引擎當前只被 Linux,Solaris,和 Mac OS X 支持。在未來的 MySQL 分發版中,我們想要添加其它平臺對這個引擎的支持,包括 Windows。

3.1.6 ARCHIVE 存儲引擎 被用來無索引地,非常小地覆蓋存儲的大量數據。

3.1.7 CSV 存儲引擎 把數據以逗號分隔的格式存儲在文本文件中。

3.1.8 BLACKHOLE 存儲引擎 接受但不存儲數據,並且檢索總是返回一個空集。

3.1.9 FEDERATED 存儲引擎

把數據存在遠程數據庫中,在 MySQL 5.1 中,它只和 MySQL 一起工作,使用 MySQL C Client API。在未來的分發版中,我們想要讓它使用其它驅動器或客戶端連接方法連接到另外的數據源。

在實際高併發項目中:

MySQL 等一些常見的關係型數據庫的數據都存儲在磁盤中,在高併發場景下,業務應用對 MySQL 產生的增、刪、改、查的操作造成巨大的 I/O 開銷和查詢壓力, 數據庫和服務器都是一種巨大的壓力,為了解決此類問題,緩存數據的概念應運而生。

緩存數據是為了讓客戶端很少甚至不訪問數據庫服務器進行數據的查詢,高併發下,能最大程度的降低對數據庫服務器的訪問壓力極大地解決數據庫服務器的壓力。

提高應用數據的響應速度

用戶請求 --> 數據查詢 --> 連接數據庫服務器並查詢數據-->將數據緩存起來(HTML、內存、JSON、序列化數據)--> 顯示給客戶端 用戶再次請求或者新用戶訪問 --> 數據查詢 --> 直接從緩存中獲取數據 --> 顯示給客戶端

3.2 聯姻的數據庫

引入緩存可以提高性能,但是數據會存在兩份,一份在數據庫中,一份在緩存中,如果更新其中任何一份會引起數據的不一致,數據的完整性被破壞了,因此,同步數據庫和緩存的這兩份數據就非常重要。本文介紹常見的緩存更新的同步策略。

1.預留緩存 Cache-aside

應用代碼能夠手工管理數據庫和緩存中數據,應用邏輯會在訪問數據庫之前檢查緩存,在數據庫更新以後再更新緩存。

通過手工編碼分別對數據庫 save() 和緩存 (put(key,entity)) 做更新,將這種瑣碎的緩存管理和更新夾雜在應用邏輯中並不是一種好方式,可以採取 AOP 面向方面攔截器等方式實現緩存操作,減輕緩存操作洩漏到應用代碼中,同時確保數據庫和緩存都能正確同步。

2.Read-through(同步讀取)

如果緩存中不存在某個項目,則對 DataCache.Get 的調用將會返回 null。

在緩存端編程模型中,調用方負責隨後從後端存儲中加載數據,然後將該數據放置於緩存中。緩存使用 read - through(同步讀取)提供程序檢測丟失的項目,並調用提供程序執行數據加載。項目隨後將無縫返回到緩存客戶端中。

相比上面同時管理數據庫和緩存,我們可以簡單委託數據庫同步給一個緩存提供者,所有數據交互通過這個緩存抽象層完成。確認緩存中是否有該數據,如果沒有,從數據庫加載,然後放入緩存,下次以後再訪問就可以直接從緩存中獲得。

3.Write - through

類似於 Read - through 的數據抓取策略,緩存能夠在其中數據變化時自動更新底層數據庫。

儘管數據庫和緩存同步更新了,但是我們也可以按照我們自己的業務要求選擇事務的邊界,如果需要強一致性,並且緩存提供者提供了 XAResource,這樣我們可以在一個全局事務中完成緩存和數據庫的更新,這樣數據庫和緩存更新是在一個原子單元:single atomic unit-of-work。 如果只需要弱一致性,我們可以先後更新緩存和數據庫,不必使用全局事務,這會讓我們提升快速響應性與性能,通常緩存首先被更新,如果數據庫更新失敗,緩存可以通過補償動作實現回滾當前事務所做的改變。

4.Write - behind(事後寫入)

如果強一致性不是必須的,我們可以簡單將緩存的更新放在隊列中,然後定期批量地去更新數據庫。打破了事務保證,但是性能要遠遠超過 write - through,因為數據庫能夠快速批量更新,事務機制不再需要。在 write - behind 緩存中,數據的讀取和更新通過緩存進行,與 write - through 緩存不同,更新的數據並不會立即傳到數據庫。相反,在緩存中一旦進行更新操作,緩存就會跟蹤髒記錄列表,並定期將當前的髒記錄集刷新到數據庫中。

作為額外的性能改善,緩存會合並這些髒記錄。合併意味著如果相同的記錄被更新,或者在緩衝區內被多次標記為髒數據,則只保證最後一次更新。對於那些值更新非常頻繁,例如金融市場中的股票價格等場景,這種方式能夠很大程度上改善性能。如果股票價格每秒鐘變化 100 次,則意味著在 30 秒內會發生 30 x 100 次更新。合併將其減少至只有一次。

3.2 Web 負載層面,IP Hash 策略,Nginx 負載均衡策略三者互相關聯

涉及高併發的時候,我們的 Nginx 這個是不可或缺的工具,那麼我們來看看這個軟件是什麼,他能幫助我們實際生產中解決什麼問題。

#3.2.1 Web 負載層面,Nginx 負載均衡策略

HTTP基礎功能:

處理靜態文件,索引文件以及自動索引; 反向代理加速(無緩存),簡單的負載均衡和容錯; FastCGI,簡單的負載均衡和容錯;

模塊化的結構:

過濾器包括:gzipping,byte ranges,chunked responses,以及 SSI - filter ; 在SSI過濾器中,到同一個 proxy 或者 FastCGI 的多個子請求併發處理; SSL 和 TLS SNI 支持。

IMAP/POP3 代理服務功能:

  • 使用外部 HTTP 認證服務器重定向用戶到 IMAP/POP3 後端;
  • 使用外部 HTTP 認證服務器認證用戶後連接重定向到內部的 SMTP 後端。

認證方法:

POP3:POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5; IMAP:IMAP LOGIN; SMTP:AUTH LOGIN PLAIN CRAM-MD5; SSL 支持; 在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持。

支持的操作系統:

FreeBSD 3.x,4.x,5.x,6.x i386; FreeBSD 5.x,6.x amd64; Linux 2.2,2.4,2.6 i386; Linux 2.6 amd64; Solaris 8 i386; Solaris 9 i386 and sun4u; Solaris 10 i386; MacOS X (10.4) PPC。

結構與擴展:

一個主進程和多個工作進程。工作進程是單線程的,且不需要特殊授權即可運行;

kqueue (FreeBSD 4.1+), epoll (Linux 2.6+), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), select, 以及 poll 支持;

kqueue 支持的不同功能包括EV_CLEAR, EV_DISABLE(臨時禁止事件),NOTE_LOWAT, EV_EOF,有效數據的數目,錯誤代碼;

sendfile (FreeBSD 3.1+),sendfile (Linux 2.2+),sendfile64 (Linux 2.4.21+),和 sendfilev (Solaris 8 7/01+) 支持;

輸入過濾(FreeBSD 4.1 +) 以及 TCP_DEFER_ACCEPT (Linux 2.4+) 支持;

10000 非活動的 HTTP keep-alive 連接僅需要 2.5 M 內存。 最小化的數據拷貝操作;

其他HTTP功能:

基於IP 和名稱的虛擬主機服務; Memcached 的 GET 接口; 支持 keep-alive 和管道連接; 靈活簡單的配置; 重新配置和在線升級而無須中斷客戶的工作進程; 可定製的訪問日誌,日誌寫入緩存,以及快捷的日誌回捲; 4xx - 5xx 錯誤代碼重定向; 基於 PCRE 的 rewrite 重寫模塊; 基於客戶端 IP 地址和 HTTP 基本認證的訪問控制; PUT,DELETE,和 MKCOL 方法; 支持 FLV (Flash 視頻); 帶寬限制;

3.2.2 高性能的服務器

Nginx 是一個高性能的 Web 和反向代理服務器, 它具有有很多非常優越的特性:

作為 Web 服務器:相比 Apache,Nginx 使用更少的資源,支持更多的併發連接,體現更高的效率,這點使 Nginx 尤其受到虛擬主機提供商的歡迎。能夠支持高達 50000 個併發連接數的響應,感謝 Nginx 為我們選擇了 epoll and kqueue 作為開發模型。

作為負載均衡服務器:Nginx 既可以在內部直接支持 Rails 和 PHP,也可以支持作為 HTTP代理服務器 對外進行服務。Nginx 用 C 編寫, 不論是系統資源開銷還是 CPU 使用效率都比 Perlbal 要好的多。

作為郵件代理服務器:Nginx 同時也是一個非常優秀的郵件代理服務器(最早開發這個產品的目的之一也是作為郵件代理服務器),Last.fm 描述了成功並且美妙的使用經驗。

Nginx 安裝非常的簡單,配置文件 非常簡潔(還能夠支持 perl 語法),Bugs 非常少的服務器:Nginx 啟動特別容易,並且幾乎可以做到 7 * 24 不間斷運行,即使運行數個月也不需要重新啟動。你還能夠在 不間斷服務的情況下進行軟件版本的升級。

總結:七層負載均衡的實現基於 Web 層面的 URL 等應用信息的負載均衡,Nginx 的 proxy 是它一個很強大的功能,實現了 7 層負載均衡。

3.2.3 nginx 負載均衡中 RR 和 IP Hash 策略分析

1、RR(默認)

每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器 down 掉,能自動剔除。

例如:

 upstream tomcats {
server 172.19.1.182:8888 max_fails=3 fail_timeout=3s weight=9;
server 172.19.1.152:8080 max_fails=3 fail_timeout=3s weight=9;
}

2、IP Hash 策略

每個請求按訪問 ip 的 hash 結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決 session 的問題。

例如:

 upstream tomcats {
ip_hash;
server 172.19.1.182:8888;
server 1172.19.1.152:8080 ;
}

3、fair(第三方)

按後端服務器的響應時間來分配請求,響應時間短的優先分配。

4、url_hash(第三方)

按訪問 url 的 hash 結果來分配請求,使每個 url 定向到同一個後端服務器,後端服務器為緩存時比較有效。

總結:Nginx 內置的另一個負載均衡的策略,流程和輪詢很類似,只是七種的算法和具體的策略有些變化 IP Hash 算法是一種變相的輪詢算法

3.3 頁面靜態化

現在提倡前後端分離,前端界面基本都是 HTML 網頁代碼,通過 Angular JS 或者 NodeJS 提供的路由向後端服務器發出請求獲取數據,然後在遊覽器對數據進行渲染,這樣在很大程度上降低了後端服務器的壓力。

還可以將這些靜態的 HTML、CSS、JS、圖片資源等放置在緩存服務器上或者 CDN 服務器上,一般使用最多的應該是 CDN 服務器或者 Nginx 服務器提供的靜態資源功能。

總結的規則如下:

Java 高併發,大流量解決方案

無論是 JSP,ASP,PHP 等等效率最高、消耗最小的就是純靜態化的 html 頁面,所以我們儘可能使我們的網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。因為這樣可以減少了和後臺等交互的步驟,尤其大量內容並且頻繁更新的網站,我們無法全部手動逐個實現。

所以就誕生了 CMS 的內容發佈系統,生成 HTML,Array 老師在電商系統的實戰項目,講到這這個 CTX 技術,像我們常訪問的各個門戶站點,甚至他們的其他頻道,都是通過信息發佈系統來管理和實現的,信息發佈系統可以實現最簡單的信息錄入自動生成靜態頁面,還能權限和爬蟲自動抓取等功能,對於一個大型門戶網站來說,擁有一套高效、可管理的 CMS 必須的。

哪些網站需要這些技術?

除了門戶和信息發佈類型的網站,對於交互性要求很高的社區類型網站來說,儘可能的靜態化也是提高性能的必要手段,將社區內的帖子、文章進行實時的靜態化、有更新的時候再重新靜態化也是大量使用的策略,像電商類使用了這樣的策略,網易社區等也是如此。

第四章 實戰分享

無論是淘寶的雙 11,還是京東的 618 都是高併發和大流量的王者,那麼我們通過網絡中的例子和電商的官方解析來看看他們如何將技術落地的。

4.1關係數據庫仍然不可或缺

當前主流的關係型數據庫有 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL 等。

非關係型數據庫有 NoSql、Cloudant。

nosql和關係型數據庫的比較

優點: 1)成本:nosql數據庫簡單易部署,基本都是開源軟件,不需要像使用oracle那樣花費大量成本購買使用,相比關係型數據庫價格便宜。 2)查詢速度:nosql數據庫將數據存儲於緩存之中,關係型數據庫將數據存儲在硬盤中,自然查詢速度遠不及nosql數據庫。 3)存儲數據的格式:nosql的存儲格式是key,value形式、文檔形式、圖片形式等等,所以可以存儲基礎類型以及對象或者是集合等各種格式,而數據庫則只支持基礎類型。 4)擴展性:關係型數據庫有類似join這樣的多表查詢機制的限制導致擴展很艱難。

缺點:

1)維護的工具和資料有限,因為 nosql 是屬於新的技術,不能和關係型數據庫 10 幾年的技術同日而語。

2)不提供對 sql 的支持,如果不支持 sql 這樣的工業標準,將產生一定用戶的學習和使用成本。

3)不提供關係型數據庫對事物的處理。

非關係型數據庫的優勢:

  1. 性能 NOSQL 是基於鍵值對的,可以想象成表中的主鍵和值的對應關係,而且不需要經過 SQL 層的解析,所以性能非常高。
  2. 可擴展性同樣也是因為基於鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。

關係型數據庫的優勢:

  1. 複雜查詢可以用 SQL 語句方便的在一個表以及多個表之間做非常複雜的數據查詢。
  2. 事務支持使得對於安全性能很高的數據訪問要求得以實現。對於這兩類數據庫,對方的優勢就是自己的弱勢,反之亦然。

關係型數據庫的優勢:

  1. 保持數據的一致性(事務處理)。
  2. 由於以標準化為前提,數據更新的開銷很小(相同的字段基本上都只有一處)。
  3. 可以進行 Join 等複雜查詢。

其中能夠保持數據的一致性是關係型數據庫的最大優勢。

關係型數據庫的不足

不擅長的處理:

  1. 大量數據的寫入處理。
  2. 為有數據更新的表做索引或表結構(schema)變更。
  3. 字段不固定時應用。
  4. 對簡單查詢需要快速返回結果的處理。

大量數據的寫入處理

讀寫集中在一個數據庫上讓數據庫不堪重負,大部分網站已使用主從複製技術實現讀寫分離,以提高讀寫性能和讀庫的可擴展性。

所以在進行大量數據操作時,會使用數據庫主從模式。數據的寫入由主數據庫負責,數據的讀入由從數據庫負責,可以比較簡單地通過增加從數據庫來實現規模化,但是數據的寫入卻完全沒有簡單的方法來解決規模化問題。

4.2 非關係型數據庫錦上添花

臨時性鍵值存儲(memcached、Redis)、永久性鍵值存儲(ROMA、Redis)、面向文檔的數據庫(MongoDB、CouchDB)、面向列的數據庫(Cassandra、HBase)

4.2.1 鍵值存儲

它的數據是以鍵值的形式存儲的,雖然它的速度非常快,但基本上只能通過鍵的完全一致查詢獲取數據,根據數據的保存方式可以分為臨時性、永久性和兩者兼具 三種。

(1)臨時性

所謂臨時性就是數據有可能丟失,memcached 把所有數據都保存在內存中,這樣保存和讀取的速度非常快,但是當 memcached 停止時,數據就不存在了。由於數據保存在內存中,所以無法操作超出內存容量的數據,舊數據會丟失。

總結來說:

  • 在內存中保存數據。
  • 可以進行非常快速的保存和讀取處理。
  • 數據有可能丟失。

(2)永久性

所謂永久性就是數據不會丟失,這裡的鍵值存儲是把數據保存在硬盤上,與臨時性比起來,由於必然要發生對硬盤的 IO 操作,所以性能上還是有差距的,但數據不會丟失是它最大的優勢。

總結來說:

  • 在硬盤上保存數據。
  • 可以進行非常快速的保存和讀取處理(但無法與 memcached 相比)。
  • 數據不會丟失。

(3) 兩者兼備

Redis 屬於這種類型。Redis 有些特殊,臨時性和永久性兼具。Redis 首先把數據保存在內存中,在滿足特定條件(默認是 15 分鐘一次以上,5 分鐘內 10 個以上,1 分鐘內 10000 個以上的鍵發生變更)的時候將數據寫入到硬盤中,這樣既確保了內存中數據的處理速度,又可以通過寫入硬盤來保證數據的永久性,這種類型的數據庫特別適合處理數組類型的數據。

總結來說:

  • 同時在內存和硬盤上保存數據。
  • 可以進行非常快速的保存和讀取處理。
  • 保存在硬盤上的數據不會消失(可以恢復)。
  • 適合於處理數組類型的數據。

4.2.2 面向文檔的數據庫

MongoDB、CouchDB 屬於這種類型,它們屬於 NoSQL 數據庫,但與鍵值存儲相異。

(1)不定義表結構

即使不定義表結構,也可以像定義了表結構一樣使用,還省去了變更表結構的麻煩。

(2)可以使用複雜的查詢條件

跟鍵值存儲不同的是,面向文檔的數據庫可以通過複雜的查詢條件來獲取數據,雖然不具備事務處理和 Join 這些關係型數據庫所具有的處理能力,但初次以外的其他處理基本上都能實現。

4.2.3 面向列的數據庫

Cassandra、HBae、HyperTable 屬於這種類型,由於近年來數據量出現爆發性增長,這種類型的 NoSQL 數據庫尤其引入注目。

普通的關係型數據庫都是以行為單位來存儲數據的,擅長以行為單位的讀入處理,比如特定條件數據的獲取。因此,關係型數據庫也被成為面向行的數據庫。相反,面向列的數據庫是以列為單位來存儲數據的,擅長以列為單位讀入數據。

面向列的數據庫具有搞擴展性,即使數據增加也不會降低相應的處理速度(特別是寫入速度),所以它主要應用於需要處理大量數據的情況。另外,把它作為批處理程序的存儲器來對大量數據進行更新也是非常有用的。

但由於面向列的數據庫跟現行數據庫存儲的思維方式有很大不同,故應用起來十分困難。

總結:關係型數據庫與NoSQL數據庫並非對立而是互補的關係,即通常情況下使用關係型數據庫,在適合使用NoSQL的時候使用NoSQL數據庫,讓NoSQL數據庫對關係型數據庫的不足進行彌補。

4.3 淘寶雙 11

2017 年雙 11 又創造了新紀錄,全天交易額 1682 億,交易峰值 32.5 萬筆/秒,支付峰值 25.6 W 筆/秒,狂歡的背後是極其複雜龐大的技術系統。那麼,這些技術在雙 11 的狂歡中又起了什麼作用呢?對大家的購物有什麼影響呢?

阿里雲網絡產品團隊的剖析

VPC - 安全的網絡容器

專有網絡 VPC(Virtual Private Cloud)是用戶在雲上的一個隔離,安全的網絡環境,就像是用戶在雲上的一個私有的網絡容器,這個容器和其它用戶邏輯上是徹底隔離的,有了這個網絡容器後,就可以在這個容器中“放置”需要的雲產品和資源,比如負載均衡 SLB,RDS 等等。

VPC 是用戶在雲上具備網絡管理能力的基礎,如選擇 IP 地址範圍、劃分子網、配置網關、實現多低於私網互通以及和雲下 IDC 的互通等,都需要依賴 VPC。

有了 VPC 後,用戶就能掌控自己的網絡。

公共雲平臺是很多用戶共享的平臺,雙 11 電商核心的交易、訂單、物流等都是在公共雲平臺上,為了保證雙 11 交易的安全,使用了專有網絡 VPC 進行租戶隔離。

如下圖所示,雙 11 使用了公共雲平臺上的一個 VPC,這個 VPC 和其它 VPC 都是隔離的,禁止通信的。

Java 高併發,大流量解決方案

專有網絡 VPC 使用隧道技術進行邏輯隔離,比經典網絡更安全。這麼說可能有點抽象,打個比方,VPC 使用的隧道技術就好比是在同一條公路上開闢不同的隧道,每個用戶有自己獨有的隧道,和其它用戶的隧道是完全隔離的,而經典網絡的安全隔離技術就好比是在同一條公路上有不同的車道,車道之間用隔離帶進行隔離,相比而言,沒有隧道隔離那麼安全。

如下圖所示,隧道 ID 100 和隧道 ID 200 就對用兩個不同用戶的 VPC,兩個 VPC 中分別有 VM1,VM3和VM2,VM4,這 2 個 VPC 的 VM 在各自的隧道上通信,和其它隧道的 VM 是隔離的。

Java 高併發,大流量解決方案

負載均衡 SLB - 流量洪峰的調度器

負載均衡 SLB 產品支持對多臺 ECS 進行流量分發,以提升應用系統的服務能力,長期以來都是關鍵業務系統的入口。

雙 11 億萬用戶訪問的流量洪峰需要大量的 ECS 服務器進行處理,而這些 ECS 的調度都需要依賴負載均衡 SLB,負載均衡 SLB 接收到用戶的請求,智能調度到後端的 ECS 進行處理,並將處理後的結果返回給用戶。如下圖所示:

Java 高併發,大流量解決方案

可以說,雙 11 的流量洪峰能不能扛住,用戶溝通體驗是不是流暢,負載均衡 SLB 是關鍵因素。對於負載均衡來說,網站大流量的指標通過本文前面章節的逐步解析:

雙 11 中負載均衡 SLB 使用了很多實例,其中我們拿出單獨的一個實例來賞析:

每秒峰值流量10G連接數CPS10萬最大併發300萬

ECS數 1000+

4.4 訂單層面

NAT 網關

NAT 網關產品支持 SNAT 和 DNAT 功能。SNAT 功能即為 VPC 內無公網 ECS 提供訪問 Internet 的能力,也支持通過 DNAT 將公網 IP 地址映射給 VPC ECS,使得 VPC ECS 可以面向 Internet 提供服務。

雙11中NAT網關主要提供的是 SNAT 服務,為什麼說 NAT 網關是雙 11 中支付成功的關鍵呢? 如下圖,當用戶選擇了自己看中的寶貝後,點擊 “ 提交訂單 ”:

Java 高併發,大流量解決方案

我們在提交訂單的時候其實後臺做了複雜的出力。

4.5 支付寶進行付款

NAT 網關去調用支付寶的

Java 高併發,大流量解決方案

雙 11 支付寶交易峰值達到 25.6 W 筆/秒,其中每一筆的支付都需要 NAT 網關,這就需要NAT網關具備超大規模的帶寬和超大併發連接,當然還需要具備超強的容災能力。整個雙 11 期間,其中一個 NAT 網關的最大連接數就高達 300 W。

4.6 高速的在線雲

全球最大混合雲的網絡通道

混合雲將公共雲和雲下數據中心通過專線互通,雲上雲下連成一體,這就是混合雲。混合雲既可以保護原有線下 IDC 的投資,又可以充分利用雲的彈性,尤其適合雙 11 這樣的促銷場景。

可以說,雙 11 發展到第九年,其意義早已超越消費和零售領域,更是史無前例的社會化大協同,成為商業、經濟、科技變革的最大實驗場,因此,雙 11 也是全球最大規模混合雲架構的極好實踐,在這朵雲上,商品瀏覽,訂單支付,客戶服務,物流查詢等等,很多系統調用頻繁在公共雲和雲下數據中心之間進行,已經成為一個緊密的整體,這些雲上雲下系統調用的背後都依賴混合雲網絡通道,這就是高速通道。

如下圖所示,高速通道有兩個重要的功能,一是專線,即將線下 IDC 和雲上 VPC 連接起來,二是 VPC 互聯,即將不同的 VPC[跨地域]連接起來。

Java 高併發,大流量解決方案

4.7 底層的網絡技術(我們在後面的 chat 專題講解) 例如:晚會直播

雙 11 晚會的視頻直播,再如說彈性計算 ECS 的網絡性能,更依賴存在於宿主機上的無名英雄-虛擬交換機。

網絡是雙11背後千百個系統的基礎,是基礎的基礎,核心的核心。網絡無處不在,但網絡之於雙 11 的最高境界是購物狂歡中感知不到網絡的存在,平穩,絲滑的購物體驗就是網絡的最大意義。

4.8 官方的技術架構(來自阿里的雲棲社區)

2017 天貓雙 11 的交易額定格在 1682 億。但對技術的追求,卻從未定格。11 秒交易額破億,28 秒破 10 億,3 分 01 秒破百億,40 分 12 秒破 500 億,9 小時破 1000 億 …… 2017 年 11 月 11 日的數據一定會銘記在歷史中。交易峰值 32.5 萬/秒,支付峰值 25.6 萬/秒,比去年增長超 1.1 倍,再次刷新全球紀錄。同時誕生的還有數據庫處理峰值,4200 萬次/秒。

要想詳細 高清 chat 後臺上傳該圖片都上傳了 2 分鐘。

不知道前臺能否展示高清,請查看或者點擊。

Java 高併發,大流量解決方案

後記

還有同步的解決策略,圖片服務器分離,CDN 加速技術等技術。

更多優秀的方案,伴隨著時代的高速步伐,在後廠村的道路上讓我們共同見證......

網絡中很多技術,善於整理歸納,學習到知道才是最終目的,技術知識手段,運用技術才是最終效果。


分享到:


相關文章: