1. 程式人生 > >開源|ns4_frame分布式服務框架開發指南

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

最大 handler 支付系統 業務流 set 技術學 介紹 xml配置 封裝

導語:宜信於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分布式服務框架開發指南。

項目開源地址:https://github.com/newsettle/ns4_frame

一、框架介紹

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每個系統的層次結構。

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

3.2 運行流程

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 框架架構

技術分享圖片

上圖展示了整個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,然後根據消息流轉路徑,一步步去對應的部署機器上查詢。

內容來源:宜信技術學院

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