lms微服務框架介紹

lms 框架簡介

Lms是一個旨在通過.net平台快速構建微服務開發的框架。具有穩定、安全、高性能、易擴展、使用方便的特點。lms內部通過dotnetty實現高性能的rpc通訊,使用zookeeper作為服務註冊中心。RPC通訊支援隨機輪詢、哈希一致性、隨機路由等負載均衡演算法。

您還可以很方便的與CAP或是MassTransit集成,使用事件匯流排進行內部通訊。

開源地址

//github.com/liuhll/lms

該框架現在還正在開發過程中,如果您也認可該框架,您可以給個star,或是提交pr參與貢獻,如果遇到問題,您也可以通過issues需求幫助。

快速開始

LMS框架集成與服務託管

使用通用主機註冊和託管LMS服務

使用LMS框架非常簡單,您只需要使用.net提供的通用主機註冊LMS框架,同時指定啟動的模組,在啟動的模組中,通過DependsOn特性依賴必要的組件。

通用主機註冊LMS框架主要用於一般情況下對服務的託管,配置的token保證的集群通訊的安全性,避免用戶直接通過RPC埠訪問集群內部,

(1) 只有請求來源於網關,才被認為是合法的請求。集群外部無法通過rpc埠與主機直接通訊。

(2) 服務內部通訊過程中,同一個集群只有配置的token一致, 通訊才會被被認為是合法的。

  1. 註冊LMS服務
    public class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                    .RegisterLmsServices<NormModule>() //註冊lms服務,並指定啟動的模組
                ;

        }
    }
  1. 指定啟動模組
    [DependsOn(typeof(ZookeeperModule), 
      typeof(DotNettyTcpModule), 
      typeof(RpcProxyModule),
      typeof(MessagePackModule))]
    public class NormModule : LmsModule
    {
        
    }

啟動模組必須要繼承LmsModule基類,通過DependsOn特性指定依賴的模組組件,一般的,您需要依賴服務註冊中心組件(ZookeeperModule)、和通訊框架組件(DotNettyTcpModule)、Rpc通訊代理組件(RpcProxyModule),也可以指定編解碼組件(MessagePackModule或是ProtoBufferModule),如果未指定編解碼組件,則默認使用json作為rpc內部的通訊編解碼格式。同一個集群內部,必須要保證使用的編解碼一致。

在啟動模組中,您也可以通過重寫RegisterServices來註冊需要注入ioc的類,通過重寫Initialize方法在應用啟動時執行初始化方法,重寫Shutdown方法在應用結束時執行釋放資源的方法。

  1. 配置

您可以使用json或是yml格式對服務進行配置。如下所示,列舉了lms服務必要的最少配置。

rpc:
    host: 0.0.0.0 # 主機地址
    rpcPort: 2201 # rpc通訊埠號
    token: ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW # token令牌
registrycenter:
    connectionStrings: 127.0.0.1:2181 # 服務註冊中心地址
    registryCenterType: Zookeeper # 服務註冊中心類型
  
  1. 完成主機構建後,您可以引用各個微服務模組的應用介面,或是託管服務自身的應用服務。集群內部使用dotntty實現的RPC框架進行通訊。

使用Web主機註冊和託管LMS服務

您可以使用.net的web主機來註冊和託管lms服務,通過這種形式構建的服務主機,可以通過引用各個微服務模組的應用介面,通過web主機指定的http埠對外提供訪問。web主機可以通過應用介面生成的代理與微服務集群內部各個服務主機進行通訊。

通過web主機註冊LMS服務時,一般不需要實現應用介面(即,不需要託管應用服務),只需要引用各個微服務模組的應用介面,通過HTTP埠提供一個與集群外部通訊的方式。

  1. 註冊LMS服務
    public class Program
    {
        public async static Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .RegisterLmsServices<GatewayModule>()
                .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
  1. 啟動模組
    [DependsOn(typeof(RpcProxyModule),
        typeof(ZookeeperModule),
        typeof(HttpServerModule),
        typeof(DotNettyModule),
        typeof(MessagePackModule)
        )]
    public class GatewayModule : LmsModule
    {
    }

與通用主機的指定的啟動模組相比,需要額外依賴HttpServerModule模組。

  1. StartUp類

在StartUp類中,您可以通過ConfigureServices配置服務的注入,以及在Configure方法中配置Http請求中間件。例如: 您可以在StartUp類中配置mvc路由、SwaggerAPI穩定等。

需要注意的是必須在Configure中必須要配置app.ConfigureLmsRequestPipeline(),只有這樣Http請求才可以通過lms框架預先設置的中間件。

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {Title = "Lms Gateway", Version = "v1"});
                c.MultipleServiceKey();
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Lms Gateway Demo v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

            app.ConfigureLmsRequestPipeline();
        }
    }

應用介面與服務條目

在一個微服務模組中,您可以通過定義應用介面來提供相應的服務條目,應用介面只需要通過ServiceRoute特性進行描述。每個應用介面定義的方法都會生成一個服務條目,應用介面就相當於MVC的Controller,服務條目相當於Action。

一般的,我們會將應用介面單獨定義在一個獨立的程式集,應用介面的實現定義在另外一個單獨的程式集。應用介面程式集可以被其他微服務模組引用,在其他微服務模組中可以通過引用的應用介面生成代理,通過應用介面代理可以方便與服務提供者進行rpc通訊。

    [ServiceRoute]
    public interface ITestAppService
    {
       // 應用介面
       // 每個方法都會生成一個服務條目
        [HttpGet("{name:string}")]
        [Governance(ShuntStrategy = AddressSelectorMode.HashAlgorithm)]
        [GetCachingIntercept("ITestAppService.TestOut", "name:{0}")]
        Task<TestOut> Get([HashKey][CacheKey(0)] string name);
    }

更多應用介面的說明和配置請參考。

配置

Lms支援通過json或是yml格式的對框架進行配置。一般的,您可以通過appsettings.json或是appsettings.yml文件對系統進行配置,並且您可以通過appsettings.{Environment}.yml或是appsettings.{Environment}.json指定在不同的運行環境中載入相應的環境變數。有關詳細資訊,請參閱在 ASP.NET Core 中使用多個環境。

RPC通訊參數配置

配置項 名稱 預設值 備註
Host 主機地址 0.0.0.0 預設配置則自動獲取當前伺服器的IP為rpc服務IP
RpcPort Rpc通訊埠 2200 指定的rpc通訊埠號
MqttPort mqtt協議通訊埠 2300 當前暫未實現mqtt通訊協議
UseLibuv 使用libuv 2300 dotnetty通訊是否使用libuv網路庫,預設值為true
IsSsl 使用Ssl加密 false
SslCertificateName Ssl證書名稱 Ssl證書的相對路徑全名稱
SslCertificatePassword Ssl證書密碼
SoBacklog dotnetty SoBacklog 8192 過大或過小會影響性能
RemoveUnhealthServer 移除不健康服務 true 是否從服務註冊中心移除不健康的服務提供者

服務註冊中心配置

配置項 名稱 預設值 備註
RegistryCenterType 服務註冊中心類型 RegistryCenterType.Zookeepe 當前僅實現了zookeeper作為服務註冊中心
ConnectionTimeout 連接超時 20 單位(秒)
SessionTimeout session會話超時 30 單位(秒)
OperatingTimeout 操作超時 60 單位(秒)
ConnectionStrings 服務註冊中心地址 支援多服務註冊中心,通一個集群的地址使用逗號(,)分割,多個服務註冊中心使用(;)進行分割。例如:zookeeper1:2181,zookeeper1:2182,zookeeper1:2183;zookeeper2:2181,zookeeper2:2182,zookeeper2:2183
RoutePath 服務條目的路由地址 /services/serviceroutes 當服務啟動時會自動註冊路由資訊到服務註冊中心
MqttPtah Mqtt協議的服務條目的路由地址 /services/serviceroutes 暫未實現
HealthCheckInterval 暫未實現心跳檢查
服務治理相關配置

可以通過Governance配置節點統一的rpc通訊過程進行配置,但是該配置的可以被服務條目的GovernanceAttribute特性進行改寫。

配置項 名稱 預設值 備註
ShuntStrategy 負載分流策略 rpc通訊過程中的服務路由的地址選擇器
ExecutionTimeout 執行超時時間 -1 單位(ms),0或-1表示不會超時,建議值:1000
MaxConcurrent 允許的最大並發量 100 超過最大的並發量則會路由到其他的服務提供者實例,如果不存在則會發生熔斷保護
FuseSleepDuration 熔斷休眠時間 60 單位(s),熔斷期間不會被路由到服務提供者實例
FuseProtection 是否開啟熔斷保護 true 服務提供者無法到達時,開啟熔斷保護則不會立即將該服務提供者的實例標識為不健康,但是在熔斷休眠時間內該實例不會被路由
FuseTimes 熔斷幾次之後標識服務提供者實例不健康
FailoverCount 故障轉移次數 服務提供者不可達時,允許的重新路由的次數,預設值為0,則服務提供者實例有幾個,則會重試幾次

更對關於服務通訊的治理請查看服務治理節點相關文檔。

快取攔截

在rpc通訊過程中,您可以使用快取攔截。通過使用快取攔截,可以大大提升系統的性能。在一個應用介面方法配置了快取攔截,那麼在方法執行前,如果存在快取,則會從快取中取出數據。

您可以在服務條目的方法上通過如下特性對快取攔截進行配置。

  1. GetCachingInterceptAttribute 優先從快取中讀取快取數據,如果快取中不存在,才執行本地或是遠程方法。

  2. UpdateCachingInterceptAttribute 執行本地或遠程方法並更新快取數據。

  3. RemoveCachingInterceptAttribute 執行本地或遠程方法,並刪除相應的快取數據。

更對快取攔截的使用和配置請查看快取攔截文檔。