個人解讀《ABP微服務解決方案示例》


參考:

ABP官網中文文檔

abp官網的文檔:微服務解決方案示例 (注意,要配合文檔去運行項目,然后反復、認真看文檔,文檔中已經把項目的細節講得足夠清楚的了,包含:項目引用、依賴、遠程調用過程、通信、網關等等)

有大佬為abp的微服務項目進行了講解和擴展:[Abp vNext微服務實踐] - 文章目錄----一曲肝腸斷錄

下載ABP全部示例代碼

ABP示例github下載地址,默認是master,也可以選擇最新的版本

 

ABP微服務架構簡略圖

 

 

問題

MongoDb

問題:BloggingService.Host(博客服務)運行失敗,提示MongoDb單台服務器不支持事務,目前我下載的是abp3.2.1版本。說明文檔中的MongoDB中提到新版本好像已經解決這個問題,不過微服務示例還沒有升級到最新版。

雖然有個服務運行失敗,而且我也沒安裝ElasticSearch、Kibana,但項目還是能夠運行起來演示products的效果。

RabbitMQ

問題:目前使用的是3.2.1版本的,發現停止RabbitMQ服務和注釋RabbitMQ代碼都能正常演示

結論:這個ABP微服務示根本就沒有使用RabbitMQ進行消息通信,只不過是有幾個項目有引入RabbitMQ模塊但是沒有使用,微服務示例文檔中居然說是使用RabbitMQ通信的,有點誤導人。

應該是使用 動態 C# API 客戶端 來通信的

項目結構

調用順序:applications(應用層),項目引用:modules(模塊層)、shared(共享層) =》gateways(網關 / 前端后端層)  =》microservices(微服務層)

applications(應用層):控制台應用程序 + UI + 身份認證

這些是具有用戶界面以與用戶交互並使用系統的實際應用程序.

  • AuthServer.Host  44399: 托管IdentityServer4以向其他服務和應用程序提供身份驗證服務. 它是一個單點登錄服務器,包含登錄頁面.
  • BackendAdminApp.Host  44354: 這是一個后端管理應用程序,用於托管身份和產品管理模塊的UI.

  • PublicWebSite.Host  44335: 作為包含簡單產品列表頁面和博客模塊UI的公共網站.

  • ConsoleClientDemo: 一個簡單的控制台應用程序,用於演示C#應用程序中使用服務.

 

gateways(網關 / 前端后端層):控制台應用程序 + 網關 + 通信

網關用於為應用程序提供單一入口點.它還可以用於速率限制,負載平衡等. 使用Ocelot類庫.

  • BackendAdminAppGateway.Host  44315: 由BackendAdminApp.Host應用程序用作后端.
  • PublicWebSiteGateway.Host  44397: 由PublicWebSite.Host應用程序用作后端.

  • InternalGateway.Host  44329: 用於服務間通信(微服務之間的通信).

 

microservices(微服務層):控制台應用程序 RabbitMQ + 身份認證 + EFCore

微服務沒有UI,但暴露了一些REST API.

  • IdentityService.Host  44368: 托管用於管理用戶和角色的ABP Identity模塊. 它沒有其他服務,僅托管Identity模塊的API.
  • TenantManagementService.Host  44336: 托管用於管理角色的ABP租戶管理模塊. 它沒有其他服務,僅托管租戶管理模塊的API.

  • BloggingService.Host  44357: 托管ABP博客模塊,該模塊用於管理博客和帖子(典型的博客應用程序). 它沒有其他服務,僅托管Blogging模塊的API.

  • ProductService.Host  44344: 托管用於管理產品的產品模塊(位於解決方案內). 它還包含用於創建/更新產品管理數據庫架構的EF Core遷移.

 

modules(模塊層):類庫 + DDD + DTO + 實體類 

項目名稱都是帶有 Management 字眼的

包含基於DDD原則分層的實際模塊:

產品: 使用模塊開發最佳實踐開發的分層模塊. 它可以嵌入到單個應用程序中,也可以通過單獨部署API和UI作為微服務托管

  • ProductManagement.Domain.Shared: 包含所有層之間共享的常量和類型.
  • ProductManagement.Domain: 包含域邏輯並定義實體,域服務,域事件,業務/域異常.

  • ProductManagement.Application.Contracts: 包含應用程序服務接口和DTO.

  • ProductManagement.Application: 包含應用程序服務的實現.

  • ProductManagement.EntityFrameworkCore: 包含DbContext和其他與EF Core相關的類和配置.

  • ProductManagement.HttpApi: 包含API控制器.

  • ProductManagement.HttpApi.Client: 包含C#代理以遠程直接使用HTTP API. 使用ABP的Dynamic C#API客戶端功能.

  • ProductManagement.Web: 包含UI元素(頁面,腳本,樣式..等).

 

shared(共享層):類庫

  • MsDemo.Shared:多租戶

項目引用

從項目結構看項目引用

其他項目都項目引用modules(名稱帶有Management )、shared(名稱帶有shared)

 

modules內的product的項目引用關系

ProductManagement.Domain.Shared:沒有項目引用

ProductManagement.Domain:項目引用 ProductManagement.Domain.Shared

ProductManagement.EntityFrameworkCore:項目引用 ProductManagement.Domain

ProductManagement.Application.Contracts:項目引用 ProductManagement.Domain.Shared

ProductManagement.HttpApi.Client:項目引用 ProductManagement.Application.Contracts

ProductManagement.HttpApi:項目引用 ProductManagement.Application.Contracts

ProductManagement.Web:項目引用 ProductManagement.HttpApi

ProductManagement.Application:項目引用 ProductManagement.Domain、ProductManagement.Application.Contracts

通信方式

說明:消息和RabbitMQ

參考:[Abp vNext微服務實踐] - 服務通訊     [Abp vNext 源碼分析] - 13. 本地事件總線與分布式事件總線 (Rabbit MQ)

動態 C# API 客戶端

分布式 Event Bus--里面有說道ABP繼承RabbitMQ

所有示例--里面有2個RabbitMQ的示例的

 

ABP可以動態創建C#API客戶端代理來調用您的遠程HTTP服務(REST API)。這樣,您無需處理HttpClient其他低級詳細信息即可調用遠程服務並獲得結果。

動態C#代理會自動為您處理以下內容;

  • 通過考慮HTTP方法,路由,查詢字符串參數,請求有效負載和其他詳細信息,將C#方法調用映射到遠程服務器HTTP調用
  • 通過將訪問令牌添加到HTTP標頭來認證HTTP客戶端。
  • 從JSON序列化和反序列化
  • 處理HTTP API版本控制
  • 相關性ID,當前租戶ID和當前區域性添加到請求中。
  • 正確處理服務器發送的錯誤消息並引發適當的異常。

任何類型的.NET客戶端都可以使用此系統來使用您的HTTP API。

 

模塊層的ProductManagement.HttpApi.Client類庫中的模塊類ProductManagementHttpApiClientModule中

  • using Volo.Abp.Http.Client
  • 模塊依賴typeof(AbpHttpClientModule)
  • 使用添加Http客戶端代理方法:AddHttpClientProxies(typeof(ProductManagementApplicationContractsModule).Assembly, RemoteServiceName)

 

應用程序層

AuthServer.Host:登錄認證服務

  • appsettings.json
    • RabbitMQ
      • Connections
      • EventBus,備注:模塊類加載模塊的DependsOn(typeof(AbpEventBusRabbitMqModule))時,AbpEventBusRabbitMqModule類會默認加載配置文件中的RabbitMQ:EventBus信息,反編譯查看AbpEventBusRabbitMqModule的源碼如下:
        public class AbpEventBusRabbitMqModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {
                IConfiguration configuration = context.Services.GetConfiguration();
                Configure<AbpRabbitMqEventBusOptions>(configuration.GetSection("RabbitMQ:EventBus"));
            }
        
            public override void OnApplicationInitialization(ApplicationInitializationContext context)
            {
                context.ServiceProvider.GetRequiredService<RabbitMqDistributedEventBus>().Initialize();
            }
        }

         

PublicWebSite.Hos:產品、博客展示服務

  • appsettings.json
    • 登錄服務:AuthServer:44399
    • 網關:RemoteServices:44397 PublicWebSiteGateway.Host(由PublicWebSite.Host應用程序用作后端)
  • AuthServerHostModule
    • options.Scope.Add("PublicWebSiteGateway");  //網關
    • options.Scope.Add("ProductService");  //產品微服務
    • options.Scope.Add("BloggingService"); //博客微服務

 

Program類讀取配置文件:

  • AddJsonFile("appsettings.json")加載配置文件
    using System;
    using System.IO;
    using System.Linq;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Hosting;
    using Serilog;
    using Serilog.Events;
    using Serilog.Sinks.Elasticsearch;
    
    namespace AuthServer.Host
    {
        public class Program
        {
            public static int Main(string[] args)
            {
                //TODO: Temporary: it's not good to read appsettings.json here just to configure logging
                var configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .AddEnvironmentVariables()
                    .Build();
    
                Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                    .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
                    .Enrich.WithProperty("Application", "AuthServer")
                    .Enrich.FromLogContext()
                    .WriteTo.File("Logs/logs.txt")
                    .WriteTo.Elasticsearch(
                        new ElasticsearchSinkOptions(new Uri(configuration["ElasticSearch:Url"]))
                        {
                            AutoRegisterTemplate = true,
                            AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6,
                            IndexFormat = "msdemo-log-{0:yyyy.MM}"
                        })
                    .CreateLogger();
    
                try
                {
                    Log.Information("Starting AuthServer.Host.");
                    CreateHostBuilder(args).Build().Run();
                    return 0;
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex, "AuthServer.Host terminated unexpectedly!");
                    return 1;
                }
                finally
                {
                    Log.CloseAndFlush();
                }
            }
    
            internal static IHostBuilder CreateHostBuilder(string[] args) =>
                Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    })
                    .UseAutofac()
                    .UseSerilog();
        }
    }
    View Code
  • 跟蹤調試查看configuration=》Providers=》[0]=>Data,發現Data是一個字典類型的集合:System.Collections.Generic.IDictionary<string, string> 

 

網關層

PublicWebSiteGateway.Host:產品、博客網關

  • appsettings.json
    • 登錄服務:AuthServer:44399 登錄頁
    • 路由:ReRoutes  
      • DownstreamPathTemplate(下游路徑模板):productManagement?模塊層?還是模板
      • DownstreamScheme(下游服務協議:http/https):
      • DownstreamHostAndPorts(下游服務地址):指定對應微服務
      • UpstreamPathTemplate(上游路徑模板):
      • UpstreamHttpMethod(上游HTTP方法):[ "Put", "Delete", "Get", "Post" ]
  • PublicWebSiteGatewayHostModule模塊類
    •  

                  //讀取appsettings.json文件的登錄配置   
                  context.Services.AddAuthentication("Bearer")
                      .AddIdentityServerAuthentication(options =>
                      {
                          options.Authority = configuration["AuthServer:Authority"];
                          options.ApiName = configuration["AuthServer:ApiName"];
                          options.RequireHttpsMetadata = false;
                      });    
      
                 //Ocelot網關
                  context.Services.AddOcelot(context.Services.GetConfiguration());
                  app.UseOcelot().Wait();

       

微服務層

ProductService.Host:產品微服務

  • appsettings.json
    • 登錄服務:AuthServer:44399 =》登錄頁

BloggingService.Host:博客微服務

  • appsettings.json
    • 登錄服務:AuthServer:44399 =》登錄頁
    • 網關:RemoteServices:44329  =》InternalGateway.Host  : 用於服務間通信(微服務之間的通信)
    • 認證:IdentityClients:4439 =》登錄頁


免責聲明!

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



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