silky微服務業務主機簡介


主機的概念

silky的主機與.net的主機概念一致。是封裝應用資源的對象,用於托管應用和管理應用的生命周期。

通用主機

如果用於托管普通的業務應用,該微服務模塊本身並不需要對直接對集群外部提供訪問入口。那么,您可以使用.net的通用主機注冊silky服務框架。.net的通用主機無法提供http請求,也無法配置http的請求管道(即:中間件)。

在注冊silky框架后,silky框架會注冊dotnetty的服務監聽者,並會暴露rpc端口號。但是由於silky框架的安全機制,集群外部並不允許通過tcp協議通過rpc端口號直接訪問該微服務模塊的應用接口。

web主機

如果您需要訪問該服務模塊的應用接口,您必須要通過.net的web主機注冊silky框架,並配置silky框架的請求管道。這樣,web構建的主機通過引用某個微服務的應用接口項目(包),通過應用接口的代理與微服務集群內部實現rpc通信。

業務主機類型

silky微服務框架提供了多種類型的業務主機,開發者可以選擇合適的主機來托管應用服務。

使用web主機構建微服務應用

使用web主機構建的silky應用具有如下特性:

  1. 提供http服務和RPC服務,暴露http端口和RPC端口
  2. 可以作為外部流量的入口,集群外部通過http服務訪問微服務應用集群
  3. 作為RPC服務提供者,通過RPC框架與其他微服務進行通信

一般地,如果我們希望該服務應用既可以作為RPC服務提供者,也希望外部能夠直接通過http協議訪問應用,那么我們就可以通過web主機構建微服務應用。這樣的方式適用於將微服務應用拆分給不同的團隊進行開發,開發者也無需要額外的構建網關,就可以訪問微服務應用服務。

使用web主機構建Silky微服務應用只需要開發者安裝Silky.Agent.Host包后,在Main()方法中通過Host提供的APIConfigureSilkyWebHostDefaults即可。開發者需要指定Startup類,在Startup中注冊服務和配置http中間件。

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                    .ConfigureSilkyWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
               
        }
    }
}

當然,我們也可以在構建主機的時候,另外指定啟動模塊:

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                    .ConfigureSilkyWebHost<DemoModule>(webBuilder => webBuilder.UseStartup<Startup>());
               
        }
    }
}

自定義的啟動模塊DemoModule需要繼承WebHostModule,開發者可以在自定義的啟動模塊中,定義應用啟動和停止需要執行的業務方法和配置服務注冊,也可以依賴開發者擴展的自定義模塊。

    // 依賴開發者自定義的模塊
    // [DependsOn(typeof("UserDefinedModule"))]
    public class DemoModule : WebHostModule
    {
        public override Task Initialize(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序啟動時執行的業務方法
            return Task.CompletedTask;
        }

        public override Task Shutdown(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序停止時執行的業務方法
            return Task.CompletedTask;d
        }

        public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            // 開發者可以配置服務注冊,作用與Startup類ConfigureServices一致
            
        }

        protected override void RegisterServices(ContainerBuilder builder)
        {
            // 開發者可以通過 Autofac 的ContainerBuilder注冊服務,
            // 例如: IServiceCollection無法注冊命名服務,ContainerBuilder支持注冊命名服務
        }
    }

在啟動類Startup類中配置服務注冊和中間件:

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services) 
        {
            services
                .AddSilkyHttpCore()
                .AddResponseCaching()
                .AddHttpContextAccessor()
                .AddRouting()
                .AddSilkyIdentity()
                .AddSilkyMiniProfiler()
                .AddSwaggerDocuments();
            
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwaggerDocuments();
                app.UseMiniProfiler();
            }
            app.UseRouting();
            app.UseResponseCaching();
            app.UseSilkyWebSocketsProxy();
            app.UseSilkyIdentity();
            app.UseSilkyHttpServer();           
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapSilkyRpcServices();
            });
        }
    }

這樣,我們就可以得到一個既可以提供http服務,也作為rpc服務提供者的應用。

使用通用主機構建微服務應用

使用通用主機構建的silky應用具有如下特性:

  1. 只提供RPC服務,不提供http服務,微服務集群外部無法直接訪問應用
  2. 可以通過網關或是具有http服務的應用間接的訪問該微服務提供的服務

一般地,如果只是作為普通的業務應用,只需要作為RPC服務提供者,服務內部通過RPC框架進行通信,並不需要對外提供http服務,在這樣的情況下,我們考慮使用通用主機構建微服務應用。

開發者在安裝Silky.Agent.Host包后,在Main()方法中通過Host提供的APIConfigureSilkyGeneralHostDefaults即可通過通用主機構建silky微服務應用。

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyGeneralHostDefaults();
    }
}

同樣地,我們也可以在構建主機的時候,另外指定啟動模塊:

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyGeneralHost<DemoModule>();
    }
}

在這里,我們需要自定義的啟動模塊DemoModule需要繼承GeneralHostModule,開發者可以在自定義的啟動模塊中,定義應用啟動和停止需要執行的業務方法和配置服務注冊,也可以依賴開發者擴展的自定義模塊。

  // [DependsOn(typeof("UserDefinedModule"))]
    public class DemoModule : GeneralHostModule
    {
        public override Task Initialize(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序啟動時執行的業務方法
            return Task.CompletedTask;
        }

        public override Task Shutdown(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序停止時執行的業務方法
            return Task.CompletedTask;
        }

        public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            // 開發者可以配置服務注冊,作用與Startup類ConfigureServices一致
            
        }

        protected override void RegisterServices(ContainerBuilder builder)
        {
            // 開發者可以通過 Autofac 的ContainerBuilder注冊服務,
            // 例如: IServiceCollection無法注冊命名服務,ContainerBuilder支持注冊命名服務
        }
    }

::: warning 注意

與web主機構建微服務應用自定義啟動模塊繼承的基類不同,但是作用和使用上一致

:::

通用主機構建的微服務應用,不提供HTTP服務,所有也無需(也沒有必要)配置http中間件。但是,開發者可以通過繼承IConfigureService來配置服務的注冊,從而自身服務注冊,或是引入第三方組件。

    public class ConfigureService : IConfigureService
    {
        public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            services.AddSilkyCaching()
                .AddSilkySkyApm()
                .AddMessagePackCodec();
             
            services.AddDatabaseAccessor(
                options => { options.AddDbPool<DefaultContext>(); },
                "Demo.Database.Migrations");

             // 可以通過服務注冊引入第三方組件,例如:CAP,MassTransit等
        }
    }

構建具有websocket能力的微服務應用

具有websocket服務能力的微服務應用除了能夠提供RPC服務,還可以提供websocket服務。

  1. 提供RPC服務,也提供WebSocket服務
  2. 可以通過網關的websocket代理中間件與該微服務的websocket服務進行握手

開發者在安裝Silky.Agent.Host包后,在Main()方法中通過Host提供的APIConfigureSilkyGeneralHostDefaults即可通過通用主機構建支持websocket服務的微服務應用。

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyWebSocketDefaults();
    }
}

同樣地,我們也可以在構建主機的時候,另外指定啟動模塊:

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyWebSocket<DemoModule>();
    }
}

在這里,我們需要自定義的啟動模塊DemoModule需要繼承WebSocketHostModule,開發者可以在自定義的啟動模塊中,定義應用啟動和停止需要執行的業務方法和配置服務注冊,也可以依賴開發者擴展的自定義模塊。

// [DependsOn(typeof("UserDefinedModule"))]
    public class DemoModule : WebSocketHostModule
    {
        public override Task Initialize(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序啟動時執行的業務方法
            return Task.CompletedTask;
        }

        public override Task Shutdown(ApplicationContext applicationContext)
        {
            // 開發者可以定義應用程序停止時執行的業務方法
            return Task.CompletedTask;
        }

        public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            // 開發者可以配置服務注冊,作用與Startup類ConfigureServices一致
            
        }

        protected override void RegisterServices(ContainerBuilder builder)
        {
            // 開發者可以通過 Autofac 的ContainerBuilder注冊服務,
            // 例如: IServiceCollection無法注冊命名服務,ContainerBuilder支持注冊命名服務
        }
    }

::: warning 注意

與web主機構建微服務應用自定義啟動模塊繼承的基類不同,但是作用和使用上一致

:::

構建具有websocket能力的服務,實現應用服務接口的類需要繼承WsAppServiceBase。在與前端建立會話后,就可以通過SessionManager向前端發送消息。

    public class TestAppService : WsAppServiceBase, ITestAppService
    {
        private readonly ILogger<TestAppService> _logger;

        public TestAppService(ILogger<TestAppService> logger)
        {
            _logger = logger;
        }

        protected override void OnOpen()
        {
            base.OnOpen();
            _logger.LogInformation("websocket established a session");
            
        }

        protected override void OnMessage(MessageEventArgs e)
        {
            _logger.LogInformation(e.Data);
        }

        protected override void OnClose(CloseEventArgs e)
        {
            base.OnClose(e);
            _logger.LogInformation("websocket disconnected");
        }
    }

前端需要通過網關的websocket代理中間件,與具體的websocket服務實例建立會話時,需要滿足如下要求:

  1. 需要通過請求頭或是qString參數指定bussinessId,通過該值使用哈希算法,路由到具體的websocket服務實例。
  2. 為保證每次都能夠路由到同一個websocket服務實例,websocket服務對應的網關實例只能有一個。
  3. 該網關必須要引用websocket服務代理中間件。
// 需要在網關的Configure()配置websocket代理中間件
app.UseSilkyWebSocketsProxy();

::: warning 注意

  1. 開發者可以考慮,普通業務服務對應一組網關應用(支持部署多個實例),websocket應用對應一組網關應用(只允許一個服務實例)

:::

構建網關

這里,網關的作用只是作為集群流量的入口,將http請求轉發到集群內部,交個各個微服務應用的服務進行處理,並不作為rpc服務提供者。也就是說,這里構建的網關只能作為服務消費者。

  1. 只提供http服務,作為集群流量入口
  2. 不提供RPC服務,不可以作為rpc服務提供者

::: warning 注意

網關與web主機構建業務主機的區別在於,網關只能作為服務消費者,轉發外部的http請求,而后者除了具有轉發http請求的能力之外,還能作為RPC服務提供者。

:::

開發者在安裝Silky.Agent.Host包后,在Main()方法中通過Host提供的APIConfigureSilkyGatewayDefaults即可通過通用主機構建支持websocket服務的微服務應用。

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

    private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyGatewayDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
}

當然,也可以自定義啟動模塊,只需要將自定義的啟動模塊DemoModule繼承的基類修改為GatewayHostModule:

namespace Silky.Sample
{
    using Microsoft.Extensions.Hosting;
    using System.Threading.Tasks;
    class Program
    {
        public static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

    private static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSilkyGateway<DemoModule>(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
}

開源地址

在線文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM