背景html
在《咱們的應用系統是如何支撐千萬級別用戶的》隨筆中已經從「宏觀」角度去介紹了整個應用系統的佈局。組件化是整個系統由頭到尾都始終堅持的一個設計原則,其中「SOA組件化容器」也是咱們應用系統比較特別的一點。好東西確定要分享,固然,這個好還只停留在自戀當中。安全
主題session
上圖爲整個SOA容器(即WEB容器)的透析圖。其中各個(黃色)組件的執行流程就是整條業務線程的執行流程。例如在咱們應用系統中主要包括會話組件、安全攔截組件、業務驗證組件、業務解析組件、業務服務組件、業務響應組件、日誌組件等。也就是這些組件組成了整個業務線程的生命週期。接下來對SOA容器的各個組成部分進行一一介紹。oop
SOA組件配置文件組件化
配置文件就是組件執行引擎的依賴,有點相似於Spring配置文件的概念,下面是配置文件的一個例子:佈局
<?xml version="1.0" encoding="UTF-8"?>性能
<soabean id=」session」 class=」com.soa.session」 order=」1」/>spa
<soabean id=」security」 class=」com.soa. security」 order=」2」/>線程
<soabean id=」validate」 class=」com.soa.validate」 order=」3」/>設計
<soabean id=」analysis」 class=」com.soa.analysis」 order=」4」/>
<soabean id=」service」 class=」com.soa.service」 order=」5」/>
<soabean id=」response」 class=」com.soa.response」 order=」6」/>
<soabean id=」logger」 class=」com.soa.logger」 order=」7」/>
其中soabean爲SOA容器組件,id爲組件的惟一標識,class爲組件的類路徑,order爲組件的執行順序。
SOA組件執行引擎
執行引擎就是整個SOA組件容器的發動機,容器初始化時須要加載SOA組件配置文件信息並經過反射生成各組件實例根據序號(order)依序存放在SOA組件單例隊列容器裏。當業務請求到達SOA容器時,執行引擎循環執行單例隊列容器裏面的組件。
/*僞代碼*/
Loop singleSOABeanList: //循環組件單例隊列容器
SOABean.handle(); //組件執行
SOA組件單例隊列容器
這是一個存放着SOA組件實例的單例隊列容器,隊列的順序依賴於配置文件的order值,按隊列容器按order值升序排序,order值越小的組件越優先執行。
ThreadLoal(線程本地變量)
這是整個線程生命週期的本地變量,主要存儲的是會話信息,而這個會話信息就是各組件解耦的關鍵所在,貫穿了全部組件的執行。會話信息主要包含着如下字段:
Class Session{
serssionId //會話標識
seviceName //請求服務標識,如SOA_001_001,可自定義業務規則
retCode //業務響應標識
retDesc //業務響應描述
isGone=true //線程主流程執行信號(true/false)
soaLogger //SOA容器組件日誌跟蹤器
reqJson //請求參數報文
respJson //響應參數報文
HTTPRequest實例
HTTPRespone實例
Userinfo //用戶信息
……
}
此會話跟HTTP會話的做用是同樣的,主要是維護用戶不一樣請求的關聯關係,同時仍是各組件的解耦的關鍵所在。
SOA組件
上圖中的黃色組件爲各SOA容器的業務組件,業務組件須要實現SOA組件接口。
public interface SOAInterface {
public void handle();
}
組件是一個獨立體,必須管理好本身因此異常信息,可經過會話實體記錄和跟蹤會話的運行狀況。組件又分爲主流程組件和輔助組件,主流程組件是經過會話的線程主流程執行信號(isGone)來跟蹤主業務流程的執行狀況,若是某主業務流程組件發生異常或業務失敗,則經過session.setIsGone = false告訴後續的主流程組件不須要執行了:
/*主流程組件僞代碼*/
Class SubGroup implement SOAInterface(){
try{
If(session.isGone){
operations
…
If(operation false){
session.setIsGone = false;
}
}
}catch(Exception e){
session.setExceptionLog;
session.setIsGone = false;
}
}
在咱們應用中,主流程組件有會話組件、請求解析組件、業務處理組件、請求業務響應組件等。而輔助組件有黑名單攔截組件,日誌組件等。輔助組件的異常不會致使整條業務線程的奔潰,遇到異常,不會對主線程的運行標識(isGone)進行干預,以避免影響整條主業務線程的正常服務。例如黑名單攔截,若是就由於黑名單組件異常失敗,而中止系統全部業務對外提供服務,那有點說不過去。其實說白了,仍是根據本身業務而定。對於一些比較敏感的系統組件,能夠經過實時異常監控組件去跟蹤來彌補日誌異常信息監控緩慢的缺點。例如能夠利用「發佈訂閱系統」:
/*會話記錄組件異常信息僞代碼*/
session.setExceptionLog(){
ExceptionLog;
PubSubMonitor.publish(exceptioninfo); //經過發佈訂閱監控組件實時監控
}
總結
不難理解,各個組件就是線程棧的組成部分。SOA組件化容器把整個業務請求流程的各個組成部分都封裝成組件化形式執行,例如會話解析、請求參數解析、業務邏輯處理、請求業務響應、日誌記錄等業務主要流程。有利於系統往後的擴展性和維護性。這個SOA容器其實有點相似於企業服務總線(ESB)的概念,也一樣支持相似Spring的AOP功能,畢竟在一條垂直的業務線程上,可經過組件配置文件在隨意一個橫切面插入其餘操做組件。不管SOA容器組件仍是服務層(SOA容器業務邏輯處理組件)的業務服務組件,都是經過反射實現生產單例使用,也有點相似於Spring的IOC概念。在這裏我主要仍是提供想法和思路,只有思路是通用的,仍是建議思路+具體業務的實現才能發揮系統的最大性能。DIY過程最好不要脫離組件化和簡單化的設計原則,固然,定義=限制,不一樣人都有不一樣的可能,歡迎評論交流。