天津市网站建站制作,登录建筑培训网,举报的网站是国外的域名和空间,网站开发需求文档案例注#xff1a;此处的微服务只考虑服务部分#xff0c;不考虑内外层网关、认证等。ABP VNext从单体切换到微服务#xff0c;提供了相当大的便利性#xff0c;对于各模块内部不要做任何调整#xff0c;仅需要调整承载体即可。ABP can help you in that point by offerring a… 注此处的微服务只考虑服务部分不考虑内外层网关、认证等。ABP VNext从单体切换到微服务提供了相当大的便利性对于各模块内部不要做任何调整仅需要调整承载体即可。ABP can help you in that point by offerring a microservice-compatible, strict module architecture where your module is splitted into multiple layers/projects and developed in its own VS solution completely isolated and independent from other modules. Such a developed module is a natural microservice yet it can be easily plugged-in a monolithic application.分层架构ABP VNext自身提供的分层方式如下图核心部分是Application、Domain与EntityFrameworkCore层至于HttpApi.Client与HttpApi都是属于将应用去承载到其他系统之上的。Controller层在ABP VNext中被削弱了VNext提供了将Application提供动态Controller所以可能习惯了将部分逻辑写在控制器中的会有些唐突但理解就行。规划层次结构新建空文件夹取名随意(本次取名GravelService)用于存放整体项目。在上一步的空文件夹内新建空白解决方案可以用VS去生成或是按照dotnet的命令生成。习惯上按照ABP VNext给定的微服务Demo中的格式创建三个文件夹思路清晰。当然提供的微服务Demo还有更多文件夹但是这次只关注这三个。增加三个模块设计三个限界上下文并绘制上下文映射。依照常见的订单、产品与客户划分成三个限界上下文。并规划好订单作为下游依赖产品与客户作为的上游。从官网直接下载三个模块或是按照命令行去生成(前提是已经安装了ABP CLI)无论哪种方式确保准备好就行依照模块化思想将其存到modules文件夹下。如本次准备了三个模块ProductOrderCustomer依照实际需要可以去精简一下内部文件此处各模块内部我只留着src和test文件夹。对于customer模块的src内部具体生成的文件夹如下对于其中的HttpApi、HttpApi.Client及MongoDB我采取了剔除无需这部分(在稍后的承载体中有同等功能)。清理之后变得简简单单的。对于test内部同样采取剔除无需的HttpApi.CLient、MongoDB文件夹(注此处的无需只是针对我而言如果有需要还是留着吧)。清理之后层次划分变得简简单单的。改造下各模块内给定的Sample案例改造成各模块命名开头方便加以区分。以Customer模块为例将自带的Sample案例更名成Customer仅作该项改动。模拟服务调用对于Order与Product模块内增加一个下游访问上游服务的链路方便验证从单体跨越到微服务底层服务的无需任何改动。对于下游访问上游服务的调用形式了解到的有两种方式。当前上下文的应用层直接依赖其他上下文的应用服务当前上下文设定出防腐层(在限界上下文间增加一层隔离方便保证依赖限界上下文存在变动时只需更改隔离层)在防腐层的实现中去依赖或远程调用其他上下文的应用服务我个人倾向于增加防腐层虽然在VNext中并无相关说法。具体使用时在领域层或应用层增加防腐层接口及在EF Core层给与防腐层实现此时的EF Core层更应该更名为基础设施层而不单单是作为资源库的形式。在Order中Domain层增加ServiceClients文件夹用于存放防腐层接口而在EntityFrameworkCore层增加ServiceClients文件夹用于存放防腐层实现。在防腐层接口中增加IProductServiceClient。public interface IProductServiceClient : ITransientDependency
{Taskint GetProductId();
}
在防腐层实现中增加ProductServiceClient。在Order中的EntityFrameworkCore层引用Product模块内的Application.Contracts层。依赖ProductAppService并完成调用。public class ProductServiceClient : IProductServiceClient
{private readonly IProductAppService _productAppService;public ProductServiceClient(IProductAppService productAppService){_productAppService productAppService;}public async Taskint GetProductId(){var productDto await _productAppService.GetAsync();return productDto.Value;}
}
在OrderAppService中依赖防腐层接口并完成调用。public class OrderAppService : OrderManagementAppService, IOrderAppService
{private readonly IProductServiceClient _productServiceClient;public OrderAppService(IProductServiceClient productServiceClient){_productServiceClient productServiceClient;}public async TaskOrderDto GetAsync(){var productId await _productServiceClient.GetProductId();...}
}
这样一来在防腐层实现中便可以使用到Product上下文的应用服务了对于这个应用服务的请求是当前进程内的还是进程间的由具体的承载方式而决定。大单体承载将依照如下图将三个模块承载到GravelService.Host上。新建一个GravelService.Host的项目,采用WebApi类型即可。存放到microservices文件夹下这样方便理解整个层级划分。其次依赖一些基本的Nuget包诸如ABP自身的及方便展示Api的Swagger。本次不考虑实体的创建也就不考虑EF Core包的依赖了。Volo.AbpVolo.Abp.AspNetCore.MultiTenancyVolo.Abp.AspNetCore.MvcVolo.Abp.AutofacSwashbuckle.AspNetCore引用各模块内的Application层及EntityFrameworkCore层。模仿着给定的微服务Demo完成一波CV操作。增加一个类出来承担着服务与中间件的配置。在其中依赖引用的各Application层及EntityFrameworkCore层中的Module这样一来模块依赖就搞定了。[DependsOn(typeof(AbpAutofacModule),typeof(AbpAspNetCoreMvcModule),typeof(AbpAspNetCoreMultiTenancyModule),typeof(CustomerManagementApplicationModule),typeof(CustomerManagementEntityFrameworkCoreModule),typeof(OrderManagementApplicationModule),typeof(OrderManagementEntityFrameworkCoreModule),typeof(ProductManagementApplicationModule),typeof(ProductManagementEntityFrameworkCoreModule))]
public class GravelServiceHostModule : AbpModule
{...
}
增加服务配置将各模块中的应用服务动态转换成Api控制器。ConfigureAbpAspNetCoreMvcOptions(options
{options.ConventionalControllers.Create(typeof(CustomerManagementApplicationModule).Assembly, opts {opts.RootPath CustomerManagement;}).Create(typeof(OrderManagementApplicationModule).Assembly, opts {opts.RootPath OrderManagement;}).Create(typeof(ProductManagementApplicationModule).Assembly, opts {opts.RootPath ProductManagement;});
});
然后启动即可所有模块中的接口都承载到了该承载体中。通过访问Order的api/OrderManagement/order接口获得返回的9527也就验证了防腐层内去访问Product上下文的应用服务。此时是在同一进程内使用到的是ProductAppService的具体实现断点查看也可看出当前进程内的请求依赖其他上下文服务的应用服务为ApplicationServiceProxy。多服务承载依照如下图开始切换承载模式只更改承载体将一个大的承载体切分成各上下文独自承载体。新建三个和GravelService.Host同等的WebApi项目。在GravelService.Host上裁剪即可每个独立的承载体只拥有自身的上下文。依据上下文映射关系对处于下游的Order承载体增加对上游Product的依赖在Order承载体中增加对Product模块中Application.Contracts层的依赖。并在服务配置中完成依赖(第7行)。[DependsOn(typeof(AbpAutofacModule),typeof(AbpAspNetCoreMvcModule),typeof(AbpAspNetCoreMultiTenancyModule),typeof(OrderManagementApplicationModule),typeof(OrderManagementEntityFrameworkCoreModule),typeof(ProductManagementApplicationContractsModule))]
public class OrderServiceHostModule : AbpModule
{
...
}
配置远程服务代理在服务配置中设置从Order承载体到Product承载体的远程服务请求。在Order承载体中增加Volo.Abp.Http.Client包并在服务配置中完成依赖。[DependsOn(...typeof(AbpHttpClientModule),...)]
public class OrderServiceHostModule : AbpModule
{public override void ConfigureServices(ServiceConfigurationContext context){var configuration context.Services.GetConfiguration();... context.Services.AddHttpClientProxies( typeof(ProductManagementApplicationContractsModule).Assembly);...}
}
在配置源appsettings文件中加入对Product承载体的远程调用地址 {RemoteServices: {Default: {BaseUrl: http://localhost:57687}
}
更改项目配置启动多个文件一并启动三个独立承载体再次调用Order中的Get请求同样获得了从Product上下文的应用服务中的数据这次采用的不同进程间的承载方式通过防腐层然后经ABP提供的Http代理服务调用Product承载体可以断点查看当前在防腐层中的AppService类型已经不再是直接使用ProductAppService了。真香从大单体承载切换多服务承载Modules部分不需要做任何更改着实方便。至于内部的远程调用本身ABP VNext还存在一些问题像类似集合的Get请求在3.1的版本中才做了修复但是这丝毫不影响这一巨人的前行。