開源|ns4_frame分散式服務框架開發指南

宜信技術學院發表於2019-04-18

導語:宜信於2019年3月29日正式開源nextsystem4(以下簡稱“NS4”)系列模組。此次開源的NS4系列模組是圍繞當前支付系統笨重、程式碼耦合度高、維護成本高而產生的分散式業務系統解決方案。NS4系列框架允許建立複雜的流程/業務流,對於業務服務節點的實現可串聯,可分散式。其精簡、輕量,實現了“脫容器”(不依賴tomcat、jetty等容器)獨立執行。NS4系列框架的設計理念是將業務和邏輯進行分離,開發人員只需通過簡單的配置和業務實現就可以實現邏輯複雜、效能高效、功能穩定的業務系統。【點選檢視框架整體介紹】

NS4系列包括4個開源模組,分別是:ns4_frame分散式服務框架、ns4_gear_idgen ID 生成器元件(NS4框架Demo示例)、ns4_gear_watchdog 監控系統元件(服務守護、應用效能監控、資料採集、自動化報警系統)和ns4_chatbot通訊元件。本文將詳細介紹ns4_frame分散式服務框架開發指南。

專案開源地址:github.com/newsettle/n…

一、框架介紹

ns4_frame本質上是兩個應用加三套開發框架組合起來的分散式業務框架。

1.1 使用範圍

ns4_frame分散式框架主要適用於業務型別為訊息流或者業務核心模型為流式業務的業務系統。它支援訊息分發、傳遞、追蹤,支援分步驟、分批次的訊息處理,對於資訊流、資料流等訊息驅動型的業務尤為契合。

1.2 專案結構

ns4_frame框架是一套MAVEN父子專案,由五個專案組成:

  • NS_MQ :負責和底層訊息佇列進行通訊,提供了對訊息佇列進行操作的API。
  • NS_TRANSPORTER:通過呼叫NS_MQ提供的API,對業務訊息進行收取、處理、轉發。
  • NS_CHAIN :一個可選開發框架,負責對同一個jvm中的業務處理步驟進行鏈條式的整合,組成當前業務模組的業務處理流程。
  • NS_CONTROLLER:一個業務訊息轉發應用,負責將接收到的訊息轉給對應的業務模組進行處理,同時負責將業務模組根據整體業務進行關聯。NS_CONTROLLER本質是一個獨立的應用系統,構建於 NS_TRANPORTOR和NS_CHAIN之上。
  • NS_DISPATCHER :ns4_frame架構規定的訊息入口,通過提供的http服務接受業務系統邊界外的http請求,並將請求轉化成業務系統內部通訊使用的訊息協議格式。

二、基礎入⻔

2.1 開發環境配置

開發語言:JAVA

JDK版本:JDK1.7

MAVEN版本:3.3以上

REDIS版本:3.0以上

以上是開發環境必備的元件和配置,其中java為開發語言,maven為專案編譯打包部署必備, redis作為訊息中介軟體使用。

2.2 執行

ns4_frame執行至少需要啟動三個jvm專案才能完整執行。啟動整個專案分為如下三步:

  • 第一步: ns4_frame訊息入口是一個http介面,http服務是由NS_DISPATCHER專案提供的,所以我們第一件事情就是要把NS_DISPATCHER執行起來。要執行NS_DISPATCHER,直接執行Bootstrap類的main方法即可。 預設的NS_DISPATCHER會在本機(127.0.0.1)的8027埠上監聽http請求,如果收到http請求,預設會將http請求轉換成內部通訊訊息,並儲存到本機(127.0.0.1)的 redis中,預設訪問的redis埠號是6379。

  • 第二步: NS_CONTROLLER負責接收NS_DISPATCHER傳入的訊息,並根據配置進行訊息分發。 所以我們隨後需要執行NS_CONTROLLER專案(為了方便,以下簡稱“CONTROLLER”) 。 在CONTROLLER專案中我們不能直接執行,需要配置一些東⻄。CONTROLLER要執行至少需要指定一個配置檔案位置。這個配置檔案需要通過java命令引數來指定。假設我現在指定java執行引數 -Dconfigfile=nscontroller.xml 這個引數本質上是給CONTROLLER底層的NS_TRANSPORTER使用的,它指明瞭 NS_TRANSPORTER必須得配置檔案位置,使得CONTROLLER能順利利用 NS_TRANSPORTER進行訊息收發。 預設情況下,CONTROLLER還會到classpath下去找關於NS_CHAIN需要的配置檔案, 預設路徑是classpath下的nschainconfig目錄,在這個目錄下所有的xml檔案會被認作是NS_CHAIN需要的配置檔案集合。 當配置檔案配置好後,可以通過呼叫 com.creditease.ns.transporter.context.XmlAppTransporterContext的 main方法來啟動NS_CONTROLLER 。

  • 第三步: 在這個步驟中我們需要啟動自己的業務專案,在這個業務專案中,必須有以下三個前置條件:

    • 業務專案需要建立在NS_TRANSPORTER框架之上。
    • 業務專案的訊息佇列名稱必須和CONTROLLER專案中配置的佇列名一致。
    • 業務啟動必須通過 com.creditease.ns.transporter.context.XmlAppTransporterContext的 main方法來啟動。

完成以上的三個步驟,一個基本的ns4_frame系統就搭建好並執行起來了。

三、專案架構

3.1 層次劃分

開源|ns4_frame分散式服務框架開發指南

上圖展示了ns4_frame每個系統的層次結構。

  • 底層是以redis作為訊息中介軟體,對訊息中介軟體的操作被封裝入了NS_MQ專案,它向上層提供了對訊息佇列的操作API介面。
  • 在NS_MQ的上層是NS_TRANSPORTER,它本質是一套訊息收發處理框架,它負責接收訊息後反向回撥業務程式碼,並將訊息交給業務層處理。當業務層處理完畢後,它負責將處理後的訊息返回到redis中。
  • NS_CHAINS是一套開發輔助框架,它負責將一個模組的業務處理步驟解耦成一個個零散的任務,並可以隨意以任何順序做關聯。
  • NS_CONTROLLER是一個專案,它本質上是一個獨立的應用,它負責將整體業務分解成一個個節點,並通過配置將他們以一定的順序關聯起來,並通過訊息機制,將這些節點結合起來 形成一套業務系統。
  • NS_DISPATCHER也是一個專案,它是以NETTY框架作為基礎,開發出的一個能提供基本的 http服務的獨立應用。同時它也是業務系統和外部通訊的唯一邊界。

3.2 執行流程

ns4_frame整套系統本質上其實就是一套訊息中介軟體服務加開發框架,整體的結構圖如下:

開源|ns4_frame分散式服務框架開發指南

上圖顯示了一個ns4_frame整體分散式專案的執行流程,一個訊息的運轉流程按如下順序:

  • NS_DISPATCHER收到http請求,並將http請求轉化為內部訊息協議放入指定的訊息佇列中(根據配置檔案)。
  • NS_CONTORLLER從步驟1指定的佇列接收到訊息,並根據配置的服務編排開始按照順序將訊息傳送到每個服務步驟對應的訊息佇列中。
  • 業務系統收到步驟2中NS_CONTROLLER指定的訊息佇列接收到訊息並開始處理,處理完畢後,將結果返回。
  • NS_CONTROLLER收到業務系統的響應,開始根據配置好的服務,將返回的訊息結果傳送到下一個服務對應的訊息佇列中。

四、NS_MQ框架介紹

4.1 核心類和介面

  • RedisMQTemplate類:封裝了所有和訊息佇列的操作相關的API
  • MQConfig:儲存了所有和底層訊息中介軟體相關的配置。

4.2 配置方案

預設的,在沒有做任何配置的情況下,NS_MQ會自動訪問本機(127.0.0.1)的6379埠的redis,如果沒有,則會報異常。通常,NS_MQ會去找classpath下一個名為ns_mq.properties的配置檔案,這個配置檔案中儲存著所有和底層訊息中介軟體相關的屬性。

列舉一些關鍵的配置元素:

  • redis.type 1 代表redis單機 2 代表redis叢集 預設為1
  • redis.single/cluster.host redis單機或者叢集的主機地址(包含埠)
  • redis.single/cluster.maxTotal redis單機或者叢集的最大連線數
  • redis.single/cluster.miniIdle redis單機或者叢集的最小閒置連線數
  • redis.single/cluster.maxIdle redis單機或者叢集的最大閒置連線數
  • redis.single/cluster.connectionTimeout redis單機或者叢集的嘗試連線的超時時間(尚未連線到服務需要等待的時間)
  • redis.single/cluster.socketTimeout redis單機或者叢集連線後socket閒置的超時時間

五、NS_TRANSPORTER框架介紹

5.1 框架架構

開源|ns4_frame分散式服務框架開發指南

上圖展示了整個NS_TRANSPORTER的整體架構,整套框架收發處理訊息分為如下三個步驟:

  • 首先由接收訊息的執行緒(Fetcher執行緒)通過NS_MQ從底層訊息中介軟體獲取訊息並放入到本地訊息快取。
  • 訊息處理執行緒(Handler執行緒)從本地訊息快取中取出訊息,並呼叫業務層的方法實現對訊息進行處理,處理完畢後,將處理後的訊息放到本地傳送快取。
  • 傳送執行緒(Sender執行緒)從本地傳送快取取出訊息後,將訊息通過NS_MQ將訊息放入底層訊息中介軟體。

5.2 核心類和介面

  • ServiceMessage:對各個模組之間傳遞的訊息的java封裝,包含了模組間通訊需要知道的任何資訊;

  • Worker:業務層需要實現此介面的doWork方法,實現此介面的物件會被NS_TRANSPORTER的Handler執行緒回撥用來對ServiceMessage中的資訊進行處理。

  • ActionWorker:已經部分封裝好的抽象類,實現了Worker介面,業務層可以直接繼承這個抽象類,簡化開發。

5.3 配置方案

預設的,NS_TRANSPORTER會去找名為configfile的系統變數,這個系統變數的值就是NS_TRANSPOTER需要的配置檔案所在的路徑,NS_TRANSPORTER會找到這個xml配置檔案,並在解析相關的配置後啟動。

NS_TRANSPORTER相關的配置檔案模板如下:

<queues>
     <prefix></prefix>
     <launchers>
           <launcher>
<class name="類的全名" method="method方法名" property="" />
<class name="類的全名" static-method="method方法名" /> </launcher>
     </launchers>
       <inqueues>
           <queue>
               <name></name>
<fetchernum></fetchernum> <buffersize></buffersize> <handlersize></handlersize> <serviceClass></serviceClass> <sendernum></sendernum>
           </queue>
     </inqueues>
</queues>
複製程式碼

以上xml模板中有如下幾個關鍵元素需要注意:

  • Launcher:用來定義在整個框架完全執行之前需要執行的方法。
  • queue:在這個元素下 name元素表示需要監聽的底層訊息中介軟體的佇列名。
  • Fetchernum:表示監聽訊息佇列並獲取訊息的執行緒數,預設是1。
  • buffersize:表示本地接收/傳送訊息佇列的大小預設是100。
  • handlersize:表示處理訊息的執行緒數,預設是10。
  • Serviceclass:表示具體的處理訊息的業務類,這個類必須實現了Worker介面。
  • Sendernum:表示從本地傳送訊息佇列中獲取訊息後傳送到底層訊息中介軟體的執行緒數。

六、NS_CHAIN框架介紹

6.1 框架架構

由於NS_CHAIN本質是一個純開發框架,故暫時忽略此框架的框架架構。

6.2 核心類和介面

暫略

6.3 配置方案

本節將詳細介紹NS_CHAINS的配置。

NS_CHAINS啟動時會去找系統變數chainconfig,這個變數的值就是NS_CHAINS配置檔案所在的路徑。NS_CHAINS支援配置目錄(目錄下的所有xml格式檔案都被視作NS_CHAINS框架的配置檔案)和配置檔案。

對於NS_CHAINS的配置格式我們大致列舉出關鍵要素如下:

  • catalog:這個相當於一個完整的服務或者一個名稱空間,是NS_CHAINS對外服務的基本單位,NS_CHAINS外部系統只能看到catalog。
  • Command:這是NS_CHAINS任務執行的最小單位,所有執行任務都可以以command的形式被呼叫執行。
  • Chain:這是一個command的容器,可以將多個command的任務組合成一個執行鏈路。
  • Group:這個一個command的組合,它可以將多個command組合成一個整體,並按照配置順序執行。
  • 同時NS_CHAINS的配置具有完整的邏輯語法,支援if條件判斷,while迴圈結構和順序結構。

七、NS_DISPATCHER應用介紹

7.1 框架架構

NS_DISPATCHER本質是一個獨立的建立在Netty框架上的一個能提供http服務的獨立應用,所以框架結構此處從略。

7.2 核心類和介面

NS_DISPATCHER是以NETTY框架為基礎的,所以其核心類就是如下的幾個協議處理器:

  • HttpDispatcherServerHandler:主要負責解析傳入的http請求,並封裝成對應的java物件交給 HttpRPCHandler做進一步處理。
  • HttpRPCHandler:主要接收上一步封裝好的java物件,並取出對應的請求引數、請求內容等,封裝成系統內部傳輸用的協議物件,並可以以同步請求響應模式/非同步傳送模式將協議物件放入底層訊息中介軟體。

7.3 配置方案

NS_DISPATCHER啟動會去找ns_dispatcher.properties檔案,下面介紹配置的關鍵元素:

  • http.port:指定了http服務的監聽埠。
  • dispatcher.pool.num:指定了dispatcher的併發執行緒數,dispatcher的效能和這個引數有非常大的關係。
  • dispatcher.queuename:封裝好的內部協議訊息要放入的佇列的名字,NS_DISPATCHER也支援https,所以,如果在ns_dispatcher.properties檔案中有如下幾個選項,那麼NS_DISPATCHER也會啟動對應的https服務。
  • ca.path:指明瞭可信任證照的路徑。
  • key.path:指明瞭公鑰的路徑。
  • https.port:指明瞭https服務監聽的埠。

八、NS_CONTROLLER應用介紹

8.1 框架架構

NS_CONTROLLER本質是建立在NS_TRANSPORTER和NS_CHAINS上的獨立應用,核心就是 NS_TRANSPORTER的架構加NS_CHAINS的輔助,故不再重複列舉其架構。

8.2 核心類和介面

DefaultPublishCommand:這是NS_CONTROLLER對於NS_CHAINS的一個擴充套件,它支援同步傳送訊息,並等待訊息的響應,並可以設定等待響應的超時時間。同時,還支援非同步傳送訊息,不需要等待訊息的響應。

8.3 配置方案

遵循NS_TRANSPORTER和NS_CHAINS的配置規則,所以不再贅述。 注意:在NS_CONTROLLER中對於NS_CHAINS的配置做了一些功能擴充套件,主要是新增了publish的配置元素,這個隨後可以提供配置模板。

九、專案部署

9.1 部署方案

如果要部署整個ns4_frame專案,請按照以下步驟進行:

  • 部署NS_DISPATCHER專案:NS_DISPATCHER專案是一個Maven專案,首先需要通過mvn:package deploy將整個專案打成一個zip包上傳到伺服器,然後解壓成一個目錄。在這個目錄中,有如下幾個子目錄:bin、config、lib、logs。其中,bin目錄中包含了DISPATCHER的啟動指令碼;config目錄存放了NS_DISPATCHER必須的配置檔案;lib目錄存放了NS_DISPATCHER所需要的所有jar包;logs目錄存放了所有NS_DISPATCHER列印的日誌。
  • 部署NS_CONTROLLER專案:NS_CONTROLLER專案也是一個Maven專案,需要通過mvn:package deploy將整個專案打成一個zip包。目錄結構同NS_DISPATCHER專案,此處不再贅述。
  • 部署業務程式碼:業務程式碼請自行按照各個團隊的規則部署。

十、執行日誌

10.1 日誌分類

ns4_frame專案將日誌大致分成了四類:

  • *fram.log:系統日誌,屬於整個ns4_frame底層系統內部的日誌,包括系統的啟動,執行緒的啟動關閉等資訊。
  • *biz.log:業務日誌,所有業務相關的日誌統統會被導向到這裡。
  • *flow.log:訊息流日誌,這裡記錄了系統所有訊息的流轉資訊。
  • *mq.log:這裡記錄所有對底層訊息中介軟體進行操作的資訊。

10.2 如何檢視日誌

  • 業務報錯:如果業務報錯,基本所有的報錯資訊都會在*biz.log中查到。
  • 訊息流轉: 如果是訊息傳送響應的問題,基本上在*flow.log中可以查到或者推斷出相關的資訊。
  • 底層訊息中介軟體互動: 如果訊息流轉無法推斷出問題,或者無法查到對應的訊息,就需要轉到*mq.log中進行查詢。

十一、其他

11.1 常⻅問題

ns4_frame系統本質是一個以訊息為通訊機制的分散式系統,經常出現的問題分成以下兩部分:

  • 業務異常

由於業務本身是由底層NS_TRANSPORTER回撥來執行的,當業務出現異常的時候,很可能由於沒有合適的被catch到,從而被底層的NS_TRANSPOTER框架捕獲。 對於沒有在*biz.log和stdoout.log中查詢到的問題,可以去檢視下*flow.log的日誌,看是否出現了異常被底層NS_TRANSPOTER捕獲了。

  • 底層異常

有些情況,業務本身並沒有出現問題,但是由於訊息通訊出現了問題,會導致業務沒有執行,對於 這種情況我們需要首先從訊息入口處即NS_DISPATCHER的*flow.log中查詢到對應的 messageId,然後根據訊息流轉路徑,一步步去對應的部署機器上查詢。

內容來源:宜信技術學院

相關文章