基於surging的木舟平臺如何構建起微服務

fanly11發表於2024-11-12

一、概述

木舟平臺分為微服務平臺和物聯網平臺, 上面幾篇都是介紹如何透過網路元件接入裝置,那麼此篇文章就細緻介紹下在木舟平臺下如何構建微服務。

木舟 (Kayak) 是什麼?

木舟(Kayak)是基於.NET6.0軟體環境下的surging微服務引擎進行開發的, 平臺包含了微服務和物聯網平臺。支援非同步和響應式程式設計開發,功能包含了物模型,裝置,產品,網路元件的統一管理和微服務平臺下的註冊中心,服務路由,模組,中間服務等管理。還有多協議適配(TCP,MQTT,UDP,CoAP,HTTP,Grpc,websocket,rtmp,httpflv,webservice,等),透過靈活多樣的配置適配能夠接入不同廠家不同協議等裝置。並且透過裝置告警,訊息通知,資料視覺化等功能。能夠讓你能快速建立起微服務物聯網平臺系統。

那麼下面就為大家介紹如何從建立元件、協議、裝置閘道器,裝置到裝置閘道器接入,再到裝置資料上報,把整個流程透過此篇文章進行闡述。

二、構建服務

建立服務介面,繼承IServiceKey,新增特性[ServiceBundle("api/{Service}/{Method}")] 配置routepath,程式碼如下:

   [ServiceBundle("api/{Service}/{Method}")]
   public interface ITestApiService:IServiceKey
   { 
       public Task<string> SayHello(string name);
   }

建立服務例項,繼承ProxyServiceBase, ITestApiService, ISingleInstance,如果只是業務處理只需繼承ProxyServiceBase,繼承ISingleInstance表示注入的生命週期 為單例模式,新增特性ModuleName標識一個服務多個例項,可以在呼叫的時候傳入ServiceKey

    [ModuleName("Test")]
    public class TestService : ProxyServiceBase, ITestApiService, ISingleInstance
    {
        public Task<string> SayHello(string name)
        {
            return Task.FromResult($"{name} say:hello world");
        }
    }

二、身份鑑權

webapi呼叫必然會牽涉到身份鑑權,使用者登入問題,而surging 已經整合了一套jwt驗證機制

然後在Stage配置節上配置ApiGetWay

   "ApiGetWay": {
     "AccessTokenExpireTimeSpan": "240",
     "AuthorizationRoutePath": "api/sysuser/authentication",//身份鑑權服務的routepath
     "AuthorizationServiceKey": null,
     "TokenEndpointPath": "api/oauth2/token",//對映呼叫的routepath
     "CacheMode": "MemoryCache" //MemoryCache or  gateway.Redis save token
   }

然後在介面方法上加上 [Authorization(AuthType = AuthorizationType.JWT)] 特性,服務呼叫就要進行身份鑑權

    public interface IModuleService : IServiceKey
    {
        [Authorization(AuthType = AuthorizationType.JWT)]
        Task<ApiResult<bool>> Add(ModuleModel model);

        [Authorization(AuthType = AuthorizationType.JWT)]      
        Task<ApiResult<bool>> Modify(ModuleModel model);

        [Authorization(AuthType = AuthorizationType.JWT)]
        Task<ApiResult<Page<ModuleModel>>> GetPageAsync(ModuleQuery query);

    }

三、快取攔截

surging 可以支援攔截快取,可以透過ServiceCacheIntercept特性進行配置,獲取快取可以透過CachingMethod.Get, 刪除快取可以透過CachingMethod.Remove,可以支援MemoryCache,Redis, 可以支援一,二級快取,

啟用EnableStageCache表示閘道器呼叫也可以走快取攔截(注:不支援模型引數)

 [ServiceBundle("api/{Service}/{Method}")]
 public interface IProductService : IServiceKey
 {
     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts", CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
     Task<ApiResult<bool>> Add(ProductModel model);

     [Authorization(AuthType = AuthorizationType.JWT)]
     Task<ApiResult<ProductModel>> GetProduct(int id);

     [Authorization(AuthType = AuthorizationType.JWT)]
     Task<ApiResult<Page<ProductModel>>> GetPageAsync(ProductQuery query);

     [Authorization(AuthType = AuthorizationType.JWT)]
     Task<ApiResult<List<ProductModel>>> GetProductByCondition(ProductQuery query);

     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts", CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
     [ServiceLogIntercept]
     Task<ApiResult<bool>> DeleteById(List<int> ids);

     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts", CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
     Task<ApiResult<bool>> Modify(ProductModel model);


     [Authorization(AuthType = AuthorizationType.JWT)]
     Task<ApiResult<bool>> Validate(ProductModel model);

     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts",  CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
     Task<ApiResult<bool>> Stop(List<int> ids);

     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Remove, "GetProducts", CacheSectionType = "ddlCache", Mode = CacheTargetType.MemoryCache, EnableStageCache = true)]
     Task<ApiResult<bool>> Open(List<int> ids);

     [Authorization(AuthType = AuthorizationType.JWT)]
     [ServiceCacheIntercept(CachingMethod.Get, Key = "GetProducts", CacheSectionType = "ddlCache", EnableL2Cache = false, Mode = CacheTargetType.MemoryCache, Time = 480, EnableStageCache = true)]
     Task<ApiResult<List<ProductModel>>> GetProducts();


 }

引數如果是非模型集合型別的引數,快取key 會取第一個引數值,如果是模型引數就需要新增CacheKey特性,程式碼如下:

    public class PropertyThresholdQuery
    {
        [CacheKey(1)]
        public string PropertyCode {  get; set; }
        [CacheKey(2)]
        public string ProductCode { get; set; }
        [CacheKey(3)]
        public string DeviceCode { get; set; }
    }

四、服務管理

1.平臺是支援服務路由管理,此項功能除了可以檢視後設資料,服務節點,服務規則外,還可以在權重輪詢負載演算法情況下,改變權重可以讓更多的訪問呼叫到此服務節點上,還有可以優雅的移除服務節點

選擇權重輪詢負載分流演算法,程式碼如下:

    [ServiceBundle("api/{Service}/{Method}")]
    public interface ITestApiService:IServiceKey
    {
        // [Authorization(AuthType = AuthorizationType.JWT)]
        [Command(ShuntStrategy =AddressSelectorMode.RoundRobin)]
        public Task<string> SayHello(string name);
    }

以下是編輯權重

2. 熱部署中間服務

3. 黑白名單,新增IP地址或者IP段就能限制相關IP訪問

就比如訪問api/testapi,結果如下:

4.支援swagger API文件

五、分散式鏈路追蹤

支援skywalking 分散式鏈路追蹤

六 、構建釋出

1. 微服務釋出:

釋出微服務的時候,需要引用的是微服務,不要引用stage, 如下圖

2. 閘道器釋出, 引用服務介面和聚合服務(中間服務)模組,還有stage 模組

七、總結

以上是木舟平臺如何構建服務,平臺定於11月20日釋出1.0社群版本。也請大家到時候關注捧場。

相關文章