一、接觸的服務化中間件
MQ
消息系統,使用多種方式來確保消息可靠的生產、投遞和消費,使得生產者和消費者有效解耦,降低了系統復雜性。
為什么要用消息系統?消息系統沒有提高系統性能(將消費者和生產者寫在一起豈不是更快?),也不是數據源(Redis更佳),而是實現了生產者和消費者的解耦。生產者和消費者各司其職,生產者把消息生產好,至于消息如何交付給消費者,這種交付方式是不是會丟失消息之類的可靠性問題一概不管(這也就是為什么消息隊列不僅是一個中間結果存放區的原因)。這個作為中間倉庫,負責與消費者打交道,同時保證后續交付可靠性的角色,就是消息隊列來擔當的。 3
那么如何設計一個完全可靠的消息系統呢?
(1)生產者將生產的消息保存在數據庫做持久化;
(2)消息broker接收到消息后也做持久化存儲;
(3)消費者請求消息后返回ack,如果請求失敗則retry.
RPC系統
對業務透明,提取公共服務。
Dubbo是一個典型的RPC分布式服務框架,致力于提供高性能和透明化的RPC遠程服務調用方案,是阿里巴巴SOA服務化治理方案的核心框架。
如何實現RPC的服務化呢?
(1)服務提供者在服務注冊中心注冊服務,提供對外接口;
(2)服務使用方從服務注冊中心訂閱感興趣的服務;
(3)當服務有變動時,服務注冊中心可通知使用方;
(4)服務使用方使用從注冊中心得到的接口信息使用服務。
Schedule
分布式任務調度
解決定時任務的單點,定時問題的集中監控,集中管理等問題。
原有的定時任務一般都是單點部署,可靠性不高,并且定時任務就像一個黑洞,要監控定時任務的狀態總是一遍遍的添加監控,維護監控。這些工作總是重復進行。
使用Schedule后,處理任務的worker可以多臺部署,在任務調度執行時只有一臺會參與執行,其中一臺離線后Schedule會選擇其他worker執行。并且可以通過Schedule提供的管理界面監控任務執行進度,任務執行過程中生成的日志,可以指定任務執行失敗后的恢復策略,可以人工介入任務的執行。
Config
配置中心
1、將配置和代碼相分離,集中管理所有的配置。配置中心會根據不同的環境下發不同的配置,配合最新的發布系統(QDR),我們可以實現打包一次部署到任意環境,不僅可以節約發布時間,更可以讓流程更順暢(經過測試的war包部署到線上)。
2、監控配置文件的發布流程。 將配置文件的修改和發布透明化;吸取我們之前在使用配置文件時的教訓,將使用配置文件的最佳實踐融合到發布流程中。
3、熱發布配置文件。 在配置中心后臺修改配置文件發布后應用會拿到最新的變更。
4、生產環境灰度測試. 修改配置后可以手動將改動推送到生產環境某臺機器進行線上測試. 待完全通過后再批量生效。
5、失敗回滾機制. 當配置文件解析失敗后會自動回滾到上個版本. 保證生產環境穩定運行.
Tracer
分布式鏈路追蹤系統用于在龐大的分布式集群系統的調用關系復雜的情況下,快速定位問題;
分布式鏈路跟蹤系統被廣為熟知源于Google Dapper論文,隨后Twitter開發了ZipKin,eBay開發了Centralized Activity Logging(CAL),淘寶開發了鷹眼(EagleEye)
ClientDB
分庫分表
二、互聯網高可用架構,為什么要服務化?
在服務化之前,互聯網的高可用架構大致是這樣一個架構:
( 1 )用戶端是瀏覽器 / APP 客戶端
( 2 )后端入口是高可用的 nginx 集群,用于做反向代理
( 3 )中間核心是高可用的 web-server 集群, 研發工程師主要編碼工作就是在這一層
( 4 )后端存儲是高可用的 db 集群,數據存儲在這一層
更典型的, web-server 層是通過 DAO/ORM 等技術來訪問數據庫的:
架構痛點一:代碼到處拷貝
舉一個最常見的業務的例子 -> 用戶數據的訪問,絕大部分公司都有一個數據庫存儲用戶數據,各個業務都有訪問用戶數據的需求:
在有用戶服務之前, 各個業務線都是自己通過 DAO 寫 SQL 訪問 user 庫來存取用戶數據,這無形中就導致了代碼的拷貝 。
架構痛點二:復雜性擴散
隨著并發量的越來越高,用戶數據的訪問數據庫成了瓶頸,需要加入緩存來降低數據庫的讀壓力,于是架構中引入了緩存,由于沒有統一的服務層, 各個業務線都需要關注緩存的引入導致的復雜性。
對于用戶數據的寫請求,所有業務線都要升級代碼: ( 1 )先淘汰 cache ( 2 )再寫數據
對于用戶數據的讀請求,所有業務線也都要升級代碼: ( 1 )先讀 cache ,命中則返回 ( 2 )沒命中則讀數據庫 ( 3 )再把數據放入 cache
這個復雜性是典型的“業務無關”的復雜性,業務方需要被迫升級。
架構痛點三:庫的復用與耦合
服務化并不是唯一的解決上述兩痛點的方法,抽象出統一的 “ 庫 ” 是最先容易想到的解決:
( 1 )代碼拷貝
( 2 )復雜性擴散
的方法。抽象出一個 user.so ,負責整個用戶數據的存取,從而避免代碼的拷貝。至于復雜性,也只有 user.so 這一個地方需要關注了。解決了舊的問題,會引入新的問題, 庫的版本維護與業務線之間代碼的耦合 :業務線 A 將 user.so 由版本 1 升級至版本 2 ,如果不兼容業務線 B 的代碼,會導致 B 業務出現問題;業務線 A 如果通知了業務線 B 升級,則是的業務線 B 會無故做一些“自身業務無關”的升級,非常郁悶。當然,如果各個業務線都是拷貝了一份代碼則不存在這個問題。
架構痛點四: SQL質量得不到保障,業務相互影響
業務線通過 DAO 訪問數據庫:
本質上 SQL 語句還是各個業務線拼裝的,資深的工程師寫出高質量的 SQL 沒啥問題,經驗沒有這么豐富的工程師可能會寫出一些低效的 SQL , 假如業務線 A 寫了一個全表掃描的 SQL ,導致數據庫的 CPU100% ,影響的不只是一個業務線,而是所有的業務線都會受影響 。
三、服務化解決了什么問題
為了解決上面的諸多問題,互聯網高可用分層架構演進的過程中,引入了“服務層”。
1、調用方友好
有服務層之前:業務方訪問用戶數據,需要通過 DAO 拼裝 SQL 訪問;有服務層之后: 業務方通過 RPC 訪問用戶數據,就像調用一個本地函數一樣,非常友好方便。
2、 提高復用性,防止代碼拷貝
3、 專注,屏蔽底層復雜度
4、SQL 質量得到保障
5、提供有限接口,無限性能\
在服務化之前,各業務線上游想怎么操縱數據庫都行,遇到了性能瓶頸,各業務線容易扯皮,相互推諉;服務化之后, 服務只提供有限的通用接口,理論上服務集群能夠提供無限性能,性能出現瓶頸,服務層一處集中優化 。