代理主机

silky微服务定义了三种类型的代理主机,开发者可以根据需要选择合适的silky代理主机托管微服务应用。代理主机定义了一个Startup模块,该模块给出了使用该种类型主机所必须依赖的模块。

通用代理主机

该类型的主机一般用于托管业务应用,服务内部之间通过rpc进行通信,不支持与微服务集群与外部进行通信,web代理主机可以通过引用该类型的微服务的应用接口,通过应用接口生成的代理与该微服务进行通信。该类型的微服务使用.net的通用主机进行托管引用。定义的Startup模块如下所示:

  [DependsOn(typeof(ZookeeperModule),
typeof(DotNettyTcpModule),
typeof(RpcProxyModule),
typeof(TransactionTccModule),
typeof(ValidationModule),
typeof(FluentValidationModule),
typeof(RedisCachingModule),
typeof(TransactionRepositoryRedisModule)
)]
public abstract class GeneralHostModule : StartUpModule
{
}

开发者如果需要创建一个微服务应用,只需要在创建一个控制台应用,通过nuget包管理工具安装Silky.Agent.GeneralHost包,在主函数中注册SilkyServices,并指定启动模块即可。


public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
} private static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.RegisterSilkyServices<AccountHostModule>()
;
}

开发者通过继承GeneralHostModule模块定义启动模块。可以通过DependsOn依赖自定义的模块或是Silky提供的模块。

启动模块如下所示:

//
// [DependsOn(typeof(SilkySkyApmAgentModule),
// typeof(JwtModule),
// typeof(MessagePackModule))]
public class AccountHostModule : GeneralHostModule
{ }

web代理主机

该类型的主机可以通过http端口与外部通过http协议进行通信,通过引用其他业务微服务应用的应用接口,根据路由模版生成restful风格的webapi,开发者可以通过配置生成在线的swagger文档。直观的看到在线api文档和进行调试。生成的swagger文档可以根据引用的应用接口进行分组。

web代理主机预定义的Startup模块指定了web代理主机必须依赖的silky模块,如下所示:

    [DependsOn(typeof(RpcProxyModule),
typeof(ZookeeperModule),
typeof(SilkyHttpCoreModule),
typeof(DotNettyModule),
typeof(ValidationModule),
typeof(FluentValidationModule),
typeof(RedisCachingModule)
)]
public abstract class WebHostModule : StartUpModule
{ }

该类型的主机一般用于网关,提供了外部与微服务集群进行通信的桥梁,该类型的主机使用.net的web主机进行托管应用。开发者可以创建一个aspnetcore项目,通过安装Silky.Agent.WebHost包即可创建web代理主机,需要同时指定启动模块和Startup类。

    public async static Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
} public static IHostBuilder CreateHostBuilder(string[] args)
{
var hostBuilder = Host.CreateDefaultBuilder(args)
.RegisterSilkyServices<GatewayHostModule>()
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); return hostBuilder;
}

web代理主机的启动模块需要继承WebHostModule,启动模块GatewayHostModule如下所示:

public class GatewayHostModule : WebHostModule
{ }

需要在Startup类注册Silky请求管道,Startup类如下所示:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{ } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment() || env.EnvironmentName == "ContainerDev")
{
app.UseDeveloperExceptionPage();
}
app.ConfigureSilkyRequestPipeline();
}
}

websocket代理主机

websocket代理主机与通用代理主机基本一致,websocket代理主机具体提供ws服务的能力,web主机可以通过ws代理与websocket代理主机的ws服务进行通信。

websocket代理主机的启动模块如下所示:

    [DependsOn(typeof(ZookeeperModule),
typeof(DotNettyTcpModule),
typeof(RpcProxyModule),
typeof(TransactionTccModule),
typeof(WebSocketModule),
typeof(ValidationModule),
typeof(FluentValidationModule),
typeof(RedisCachingModule),
typeof(TransactionRepositoryRedisModule)
)]
public abstract class WebSocketHostModule : StartUpModule
{
}

开发者可以通过WebSocket配置节点对ws服务进行配置,ws服务的默认端口为3000,但是一般地,与ws服务建立握手时,不应该与ws服务直接进行握手,而是应该通过web代理主机的代理中间件进行握手,所以如果开发者使用ws服务,必须要在web代理主机安装Silky.WebSocket.Middleware

ws服务的创建与通用代理主机的创建一致,只需要将启动模块继承的基类修改为WebSocketHostModule即可。

ws服务的定义如下:

    public class WsTestAppService : WsAppServiceBase, IWsTestAppService
{
public async Task Echo(string businessId, string msg)
{
if (BusinessSessionIds.TryGetValue(businessId, out var sessionIds))
{
foreach (var sessionId in sessionIds)
{
SessionManager.SendTo($"message:{msg},sessionId:{sessionId}", sessionId);
}
}
else
{
throw new BusinessException($"不存在businessId为{businessId}的会话");
}
}
}

需要注意的时,在建立握手过程中,必须要指定hashkey从而保证每次回话的微服务实例都是同一个,更多关于ws服务请查看

分布式事务

silky微服务使用拦截器和filter实现了TCC分布式事务,在tcc分布式事务过程中,将事务参与者的调用参数作为undolog日志保存到数据仓库中(当前实现了redis作为undo日志的数据存储器),并在后台执行作业检查分布式事务的执行情况,从而保证数据的最终一致性。

分布式事务的使用

  1. 在应用接口中通过[Transaction]特性进行标识该接口是一个分布式应用方法。
[Transaction]
Task<GetOrderOutput> Create(CreateOrderInput input);
  1. 应用服务实现通过[TccTransaction]特性标识,并指定ConfirmMethod方法和CancelMethod,指定实现的ConfirmMethod方法和CancelMethod必须为public,方法参数与应用实现方法的保持一致。try方法如果需要向ConfirmMethod方法和CancelMethod传递参数通过RpcContext.Context进行。
        [TccTransaction(ConfirmMethod = "OrderCreateConfirm", CancelMethod = "OrderCreateCancel")]
[UnitOfWork]
public async Task<GetOrderOutput> Create(CreateOrderInput input)
{
var orderOutput = await _orderDomainService.Create(input);
return orderOutput;
} [UnitOfWork]
public async Task<GetOrderOutput> OrderCreateConfirm(CreateOrderInput input)
{
var orderId = RpcContext.Context.GetAttachment("orderId");
var order = await _orderDomainService.GetById(orderId.To<long>());
order.Status = OrderStatus.Payed;
order.UpdateTime = DateTime.Now;
order = await _orderDomainService.Update(order);
return order.Adapt<GetOrderOutput>();
} [UnitOfWork]
public async Task OrderCreateCancel(CreateOrderInput input)
{
var orderId = RpcContext.Context.GetAttachment("orderId");
if (orderId != null)
{
// await _orderDomainService.Delete(orderId.To<long>());
var order = await _orderDomainService.GetById(orderId.To<long>());
order.Status = OrderStatus.UnPay;
await _orderDomainService.Update(order);
}
}

服务定义与RPC通信

应用接口的定义

silky的服务定义非常简单,在这里的服务指的是应用服务,与传统MVC的Controller的概念一致。

您只需要在一个业务微服务应用中,新增应用接口层,一般地,我们可以命名为Project.IApplication或是Project.Application.Contracts,并新增应用接口,在应用接口中通过[ServiceRoute]特性进行标识,并在Project.Application项目中实现该接口。

您可以通过[ServiceRoute]指定该应用服务的路由模板, 以及是否允许多个实现。

例如:


namespace Silky.Account.Application.Contracts.Accounts
{
/// <summary>
/// 账号服务
/// </summary>
[ServiceRoute]
public interface IAccountAppService
{
/// <summary>
/// 新增账号
/// </summary>
/// <param name="input">账号信息</param>
/// <returns></returns>
Task<GetAccountOutput> Create(CreateAccountInput input);
}
}

在应用层中实现该接口:

namespace Silky.Account.Application.Accounts
{
public class AccountAppService : IAccountAppService
{
private readonly IAccountDomainService _accountDomainService; public AccountAppService(IAccountDomainService accountDomainService)
{
_accountDomainService = accountDomainService;
} public async Task<GetAccountOutput> Create(CreateAccountInput input)
{
var account = await _accountDomainService.Create(input);
return account.Adapt<GetAccountOutput>();
}
}
}

RPC通信

应用接口可以被其他微服务应用或是被网关应用引用。其他微服务可以通过应用接口生成代理,并通过内部实现的rpc框架与该微服务进行通信。silky的rpc通信支持tcc方式的分布式事务,详情见上节。

应用接口被网关引用,web host主机可以通过该应用服务接口生成相应的webapi,并可以生成swagger在线文档。通过http请求,从而实现服务与集群外部进行通信,当http请求到达webhost主机后,silky中间件通过webapi和请求方法路由到服务条目,然后通过内部实现的rpc通信与微服务应用进行通信。

RPC的过滤器: rpc通信支持两种类型的过滤器,在客户端发起请求过程中,会依次调用开发者定义的IClientFilter过滤器,服务端收到请求后,会依次调用IServerFilter然后再执行应用方法本身。

RpcContext: 可以通过RpcContext.Context添加或是获取本次rpc调用的Attachments参数。当然,开发者也可以通过注入IRpcContextAccessor获取本次通信的上线文参数RpcContext

获取当前登录用户: 开发者可以通过NullSession.Instance获取当前登录用户,如果您已经登录系统,那么通过该接口可以获取到当前登录用户的userIduserName等信息。

服务治理

针对每个服务条目(应用服务接口方法),都实现了服务治理,开发者可以通过governance或是[Governance()]特性对服务的最大并发量、负载均衡算法、执行超时时间、是否使用缓存拦截、失败回调接口、接口是否对外网屏蔽等等属性进行配置。

以下描述了以服务条目为治理单位的属性表单:

属性 说明 缺省值 备注
AddressSelectorMode 负载均衡策略 Polling(轮询) 负载均衡算法支持:Polling(轮询)、Random(随机)、HashAlgorithm(哈希一致性,根据rpc参数的第一个参数值)
ExecutionTimeout 执行超时时间 3000(ms) 单位为(ms),超时时发生熔断,-1表示在rpc通信过程中不会超时
CacheEnabled 是否启用缓存拦截 true rpc通信中是否启用缓存拦截
MaxConcurrent 允许的最大并发量 100
FuseProtection 是否开启熔断保护 true
FuseSleepDuration 熔断休眠时长 60(s) 发生熔断后,多少时长后再次重试该服务实例
FuseTimes 服务提供者允许的熔断次数 3 服务实例连续n次发生熔断端,服务实例将被标识为不健康
FailoverCount 故障转移次数 0 rpc通信异常情况下,允许的重新路由服务实例的次数,0表示有几个服务实例就转移几次
ProhibitExtranet 是否禁止外网访问 false 该属性只允许通过GovernanceAttribute特性进行设置
FallBackType 失败回调指定的类型 null 类型为Type,如果指定了失败回调类型,那么在服务执行失败,则会执行该类型的Invoke方法,该类型,必须要继承IFallbackInvoker该接口

开发者还可以通过[Governance()]特性对某个服务方法进行标识,被该特性标识的治理属性将覆盖微服务的配置/缺省值。

缓存拦截

为提高应用的响应,silky支持缓存拦截。缓存拦截在应用服务接口方法上通过缓存拦截特性进行设置,在silky框架中,存在如下三中类型的缓存特性,分别对数据缓存进行新增、更新、删除。

  1. 设置缓存特性--GetCachingInterceptAttribute

  2. 更新缓存特性--UpdateCachingInterceptAttribute

  3. 删除缓存特性--RemoveCachingInterceptAttribute

使用缓存拦截,必须要保证缓存一致性。在rpc通信过程中,使用缓存拦截,同一数据的缓存依据可能会不同(设置的KeyTemplate,例如:缓存依据可能会根据IdNameCode分别进行缓存),从而产生不同的缓存数据,但是在对数据进行更新、删除操作时,由于无法通过RemoveCachingInterceptAttribute特性一次性删除该类型数据的所有缓存数据,这个时候,在实现业务代码过程中,就需要通过分布式缓存接口IDistributedCache<T>实现缓存数据的更新、删除操作。

服务注册中心

silky使用zookeeper作为默认服务的注册中心。当前还未扩展支持其他的服务注册中心。

silky支持为微服务集群配置多个服务注册中心,您只需要在配置服务注册中心的链接字符串registrycenter:connectionStrings中,使用分号;就可以指定微服务框架的多个服务注册中心。

为微服务配置服务注册中心如下所示:

registrycenter: // 服务注册中心配置节点
connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 // 服务配置中心链接
registryCenterType: Zookeeper // 注册中心类型
connectionTimeout: 1000 // 链接超时时间(单位:ms)
sessionTimeout: 2000 // 会话超时时间(单位:ms)
operatingTimeout: 4000 // 操作超时时间(单位:ms)
routePath: /services/serviceroutes

模块化管理

silky框架存在两种类型的模块:

  1. 开发者通过继承SilkyModule就可以定义一个普通模块类;
  2. 也可以通过继承StartUpModule定义一个服务注册启动模块类;开发者也可以通过继承StartUpModule,选择合适的依赖包,实现自己的代理主机。

模块的依赖关系: silky框架的模块通过DependsOn特性指定模块的依赖关系,silky框架支持通过直接或是间接的依赖模块。

依赖注入(服务注册与解析)

  1. 通过继承依赖注入标识接口实现服务的注册(推荐)

    silky框架提供了三个依赖注册的相关标识接口:ISingletonDependency(单例模式)、IScopedDependency(区域模式)、ITransientDependency(瞬态模式)。在微服务应用启动时,会扫描继承了这些标识接口的类(服务),并将其自身和继承的接口注册到Ioc容器中。

  2. 定义模块,并在模块中通过RegisterServices()方法的ContainerBuilder注册服务(autofac),或是通过ConfigureServices()方法的IServiceCollection注册服务(微软官方自带的ioc容器)

  3. 通过继承IConfigureService或是ISilkyStartup,通过Configure()方法的IServiceCollection注册服务

Silky因为支持通过IServiceCollection进行服务注册,所以可以很方便的与第三方服务(组件)进行整合,例如:CAP或是MassTransit等分布式事件框架。

使用Serilog作为日志记录器

silky框架提供了serilog作为日志记录器。只需要在构建主机时,增加UseSerilogDefault(),并添加Serilog相关配置即可。

代码:

public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
} private static IHostBuilder CreateHostBuilder(string[] args)
{
var hostBuilder = Host.CreateDefaultBuilder(args)
.RegisterSilkyServices<OrderHostModule>()
.UseSerilogDefault();
return hostBuilder;
}

配置:

serilog:
minimumLevel:
default: Information
override:
Microsoft: Warning
Microsoft.Hosting.Lifetime: Information
Silky: Debug
writeTo:
- name: File
args:
path: "./logs/log-.log"
rollingInterval: Day
- name: Console
args:
outputTemplate: "[{Timestamp:yyyy/MM/dd HH:mm:ss} {Level:u11}] {Message:lj} {NewLine}{Exception}{NewLine}"
theme: "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console"

使用Miniprofile对http请求进行性能监控

要求必须在web主机项目(一般为网关项目)安装Silky.Http.MiniProfiler包,并将swaggerDocument:injectMiniProfiler配置项的属性设置为true

swaggerDocument:
injectMiniProfiler: true

使用skywalking查看链路跟踪

要求微服务在启动模块依赖SilkySkyApmAgentModule模块,并配置skyWalking相关属性。

 [DependsOn(typeof(SilkySkyApmAgentModule))]
public class AccountHostModule : GeneralHostModule
{
}
skyWalking:
serviceName: AccountHost
headerVersions:
- sw8
sampling:
samplePer3Secs: -1
percentage: -1.0
logging:
level: Debug
filePath: "logs/skyapm-{Date}.log"
transport:
interval: 3000
protocolVersion: v8
queueSize: 30000
batchSize: 3000
gRPC:
servers: "127.0.0.1:11800"
timeout: 10000
connectTimeout: 10000
reportTimeout: 600000

在silky的实例项目中,提供了skyWalking通过docker-compose快速启动的服务编排文件samples\docker-compose\infrastr\docker-compose.skywalking.yml,开发者只需要进入到samples\docker-compose\infrastr目录中,通过如下命令即可开始的启动一个skyWalking服务。

cd samples\docker-compose\infrastr
docker-compose -f docker-compose.skywalking.yml

打开http://127.0.0.1:8180即可看到微服务集群的运行情况:

网络拓扑图:

链路跟踪:

仪表盘:

使用Apollo作为服务配置中心

部署Apollo服务

必要前提是开发者已经部署了一套Apollo服务。开发者可以参考Apollo部署节点,部署一套Apollo服务。

在开发过程中,更简单的做法是使用silky实例项目中使用docker-compose已经编排好的文件 docker-compose.apollo.yml

进入到samples\docker-compose\infrastr目录,将.env设置的环境变量EUREKA_INSTANCE_IP_ADDRESS修改为您当前本机的IP地址,不允许为127.0.0.1

运行如下命令,等待1~2分钟即可启动apollo配置服务。

docker-compose -f docker-compose.apollo.yml up -d

使用Apollo作为微服务的配置中心

  1. 在主机项目通过nuget安装Silky.Apollo包。(这是一个空包,您也可以直接安装Com.Ctrip.Framework.Apollo.AspNetCoreHostingCom.Ctrip.Framework.Apollo.Configuration包)

  2. 在服务注册时,添加对Appo服务配置中心的支持

private static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.RegisterSilkyServices<AccountHostModule>()
.AddApollo();
}

如果您您想在指定的运行环境中使用Apollo作为微服务的配置中心,而在另外其他运行环境中使用本地配置,那么您也可以通过如下当时处理:

private static IHostBuilder CreateHostBuilder(string[] args)
{
var hostBuilder = Host.CreateDefaultBuilder(args)
.RegisterSilkyServices<AccountHostModule>()
.UseSerilogDefault();
if (EngineContext.Current.IsEnvironment("Apollo"))
{
hostBuilder.AddApollo();
} return hostBuilder;
}

备注

运行环境您可以通过修改Properties\launchSettings.jsonDOTNET_ENVIRONMENT变量(本地开发模式)

或是通过.env环境变量文件指定DOTNET_ENVIRONMENT变量(docker-compose开发模式)

  1. 在Apollo服务配置中心新建相关的应用,并新增相关的配置

打开地址:http://127.0.0.1:8070 (Applo服务的web管理工具:portal),新建相关的应用。如下图:

为应用添加相应的配置:

普通业务微服务的配置如下:

# Application
rpc:port = 2201
connectionStrings:default = server=127.0.0.1;port=3306;database=order;uid=root;pwd=qwe!P4ss;
jwtSettings:secret = jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW # TEST1.silky.sample
registrycenter:registryCenterType = Zookeeper
registrycenter:connectionStrings = 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 distributedCache:redis:isEnabled = true
distributedCache:redis:configuration = 127.0.0.1:6379,defaultDatabase=0 rpc:token = ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW governance:executionTimeout = -1 cap:rabbitmq:hostName = 127.0.0.1
cap:rabbitmq:userName = rabbitmq
cap:rabbitmq:password = rabbitmq

web网关的配置如下:


# TEST1.silky.sample.gateway
gateway:injectMiniProfiler = true
gateway:enableSwaggerDoc = true
gateway:wrapResult = true
gateway:jwtSecret = jaoaNPA1fo1rcPfK23iNufsQKkhTy8eh
swaggerDocument:organizationMode = Group
swaggerDocument:injectMiniProfiler = true
swaggerDocument:termsOfService = https://www.github.com/liuhll/silky # TEST1.silky.sample
registrycenter:registryCenterType = Zookeeper
registrycenter:connectionStrings = 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 distributedCache:redis:isEnabled = true
distributedCache:redis:configuration = 127.0.0.1:6379,defaultDatabase=0 rpc:token = ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW governance:executionTimeout = -1
  1. 增加Apollo配置中心相关配置(默认读取appsettings.yml),如果指定运行环境变量则读取appsettings.{Environment}.yml中的配置

例如:

apollo:
appId: "silky-stock-host"
cluster: default
metaServer: "http://127.0.0.1:8080/"
# secret: "ffd9d01130ee4329875ac3441c0bedda"
namespaces:
- application
- TEST1.silky.sample
env: DEV
meta:
DEV: "http://127.0.0.1:8080/"
PRO: "http://127.0.0.1:8080/"

分布式锁

silky使用DistributedLock作为分布式锁,在服务路由注册和分布式事务作业中均使用了分布式锁.

身份认证与授权

silky身份认证与授权通过包Silky.Http.Identity,通过webhost在网关实现统一的身份认证和授权。

用户登陆与签发token

silky通过Silky.Jwt包提供的IJwtTokenGenerator实现jwt格式的token。签发token的微服务应用需要通过nuget安装Silky.Jwt包,并在启动模块中依赖JwtModule模块。开发者可以对签发的token的密钥、token有效期、Jwt签名算法、签发者、受众等属性通过配置节点jwtSettings进行配置。开发者至少需要对jwtSettings:secret进行配置。

配置如下:

jwtSettings:
secret: jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW

用户登陆接口如下:

        public async Task<string> Login(LoginInput input)
{
var userInfo = await _accountRepository.FirstOrDefaultAsync(p => p.UserName == input.Account
|| p.Email == input.Account);
if (userInfo == null)
{
throw new AuthenticationException($"不存在账号为{input.Account}的用户");
} if (!userInfo.Password.Equals(_passwordHelper.EncryptPassword(userInfo.UserName, input.Password)))
{
throw new AuthenticationException("密码不正确");
} var payload = new Dictionary<string, object>()
{
{ ClaimTypes.UserId, userInfo.Id },
{ ClaimTypes.UserName, userInfo.UserName },
{ ClaimTypes.Email, userInfo.Email },
};
return _jwtTokenGenerator.Generate(payload);
}

身份认证

  1. 网关项目(WebHost)的启动模块需要依赖IdentityModule模块
    [DependsOn(typeof(IdentityModule))]
public class GatewayHostModule : WebHostModule
{ }
  1. gateway:jwtSecret配置的属性必须与签发token的微服务应用配置的属性jwtSettings:secret的值保持一致。
gateway:
jwtSecret: jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW
  1. 匿名访问

开发者只需要在应用接口或是应用接口方法中标注[AllowAnonymous]特性即可,这样无需用户登陆,也可以访问该接口。

[AllowAnonymous]
Task<string> Login(LoginInput input);

授权

开发者可以在网关应用通过继承SilkyAuthorizationHandler基类,并重写PipelineAsync方法即可实现对自定义授权。

 public class TestAuthorizationHandler : SilkyAuthorizationHandler
{
private readonly ILogger<TestAuthorizationHandler> _logger;
private readonly IAuthorizationAppService _authorizationAppService; public TestAuthorizationHandler(ILogger<TestAuthorizationHandler> logger,
IAuthorizationAppService authorizationAppService)
{
_logger = logger;
_authorizationAppService = authorizationAppService;
} public async override Task<bool> PipelineAsync(AuthorizationHandlerContext context,
DefaultHttpContext httpContext)
{
// 获取访问的服务条目
var serviceEntry = httpContext.GetServiceEntry(); // 可以通过rpc调用IdentifyApp,实现自定义的授权
return _authorizationAppService.Authorization(sserviceEntry.ServiceDescriptor.Id); }
}

对象属性映射

silky实现了基于AutoMapperMapster的对象属性映射的包。实现的代理主机默认依赖MapsterModule包,使用Mapster作为对象映射的组件。

只需要通过Adapt方法即可实现对象属性映射。

使用efcore作为数据访问组件

efcore数据访问组件主要参考了furion的实现。提供了数据仓库、数据库定位器、多租户等实现方式。使用方式与其基本保持一致。

silky开源地址

github: https://github.com/liuhll/silky

gitee: https://gitee.com/liuhll2/silky

开发者文档: http://docs.silky-fk.com/

silky微服务简介的更多相关文章

  1. silky微服务业务主机简介

    目录 主机的概念 通用主机 web主机 业务主机类型 使用web主机构建微服务应用 使用通用主机构建微服务应用 构建具有websocket能力的微服务应用 构建网关 开源地址 在线文档 主机的概念 s ...

  2. silky微服务框架服务注册中心介绍

    目录 服务注册中心简介 服务元数据 主机名称(hostName) 服务列表(services) 终结点 时间戳 使用Zookeeper作为服务注册中心 使用Nacos作为服务注册中心 使用Consul ...

  3. Spring Cloud与微服务构建:微服务简介

    Spring Cloud与微服务构建:微服务简介 单体架构及其不足 1.单体架构简介 在软件设计中,经常提及和使用经典的3曾模型,即表示层.业务逻辑层和数据访问层. 表示层:用于直接和用户交互,也成为 ...

  4. silky微服务框架的服务治理介绍

    目录 服务治理的概念 服务注册与发现 负载均衡 超时 故障转移(失败重试) 熔断保护(断路器) 限流 RPC限流 HTTP限流 1. 添加配置 2. 注册服务 3.启用 AspNetCoreRateL ...

  5. Silky微服务框架之服务引擎

    构建服务引擎 在注册Silky微服务应用一节中,我们了解到在ConfigureServices阶段,通过IServiceCollection的扩展方法AddSilkyServices<T> ...

  6. SpringCloud微服务简介(一)

    Spring Cloud简单认识 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及部署,并通过 ...

  7. 1、Spring Cloud - 微服务简介

    前言: 业界大牛马丁.福勒(Martin Fowler) 这样描述微服务: 论文网址:https://martinfowler.com/articles/microservices.html 就目前而 ...

  8. java微服务简介与实战

    今年做了一段时间的可见光.ceph存储,后端开发微服务项目,在这记录点东西,也方便大家借鉴查找. springboot的项目实例:https://github.com/ityouknow/spring ...

  9. silky微服务快速开始

    项目介绍 Silky框架旨在帮助开发者在.net平台下,通过简单代码和配置快速构建一个微服务开发框架. Silky 通过 .net core的主机来托管微服务应用.通过 Asp.Net Core 提供 ...

随机推荐

  1. Zabbix5.0钉钉报警(centos7)

    2.1.到钉钉官网下载pc版钉钉,安装.注册.登陆: 钉钉下载地址:https://www.dingtalk.com/ 2.2.创建群聊和钉钉机器人: 1.创建群聊,把需要收到报警的人员都拉到这个群: ...

  2. 关于 C#的一些记录

    1, 注意: 使用Linq to Sql 查询数据库的时候,进行where 判断需要注意.我使用的EF,以下为我的记录使用Contain 需要 使用 *.Contains("" + ...

  3. elementui——表格的相同内容单元格合并

    在今天工作中遇到了相同单元格需要合并的一个需求,实现记录如下. 实现效果: 任务要求: 对表中体系这一列相同的体系进行合并. 思路:定义一个空数组:[]定义一个变量:0遍历数据如果有相同数据 在空数组 ...

  4. 在docker中使用nginx部署前端项目

    前言 部署了三个nginx用于前端项目, 并使用keepalived部署好热备, 所以总共有5个nginx 创建好nginx的文件和配置 根据上面的指令创建好目录 mkdir /home/web/ng ...

  5. Linux:jar服务部署

    1.进入jar包所在文件夹中 2.启动jar,将jar在后台运行,并且记录jar的pid 命令为 : nohup  java  -jar  test.jar (同jar包的配置文件要在jar包同级目录 ...

  6. springboot整合拦截器如何让其不拦截默认的访问路径

    1.注册自定义拦截器2.拦截器3.控制器4.其它说明:我想做控制拦截登陆,将所有的请求拦截下来判断如果当前的session里没有用户名则跳转到登陆页面.问题是目前可以拦截所有请求了,但第一次进入登陆页 ...

  7. 2020年MySQL数据库面试题总结(50道题含答案解析)

    1.MySQL 中有哪几种锁? (1)表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最 高,并发度最低. (2)行级锁:开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最 ...

  8. 关键字abstract和static总结

    1.  abstract:意为抽象,在Java中可以修饰方法或者类 (1)修饰方法,这个方法是抽象方法,无方法体,这个类一定是抽象类,这个类的子类必须实现这个抽象方法: (2)修饰类,这个类一定是抽象 ...

  9. Oracle_RAC共享存储

    <<ASM.sh>> 第2-3步可以使用"附件ASM.sh"脚本执行 此操作说明,此操作在2个节点都执行(可以复制) 编辑/etc/scsi_id.conf ...

  10. java基础---集合(1)

    一. 基本概念 集合.数组都是对多个数据进行存储操作的结构,简称Java容器 数组:长度确定,类型确定,对于添加.删除.插入等操作效率不高,元素有序可重复 Java中集合框架顶层框架是:java.ut ...