n>>();
builder.Services.AddSingleton<IOcelotCache<InternalConfiguration>, CzarMemoryCache<InternalConfiguration>>();
builder.Services.AddSingleton<IOcelotCache<CachedResponse>, CzarMemoryCache<CachedResponse>>();
builder.Services.AddSingleton<IInternalConfigurationRepository, RedisInternalConfigurationRepository>();
builder.Services.AddSingleton<IOcelotCache<ClientRoleModel>, CzarMemoryCache<ClientRoleModel>>();
builder.Services.AddSingleton<IOcelotCache<RateLimitRuleModel>, CzarMemoryCache<RateLimitRuleModel>>();
builder.Services.AddSingleton<IOcelotCache<RemoteInvokeMessage>, CzarMemoryCache<RemoteInvokeMessage>>();
builder.Services.AddSingleton<IOcelotCache<CzarClientRateLimitCounter?>, CzarMemoryCache<CzarClientRateLimitCounter?>>();
现在需要实现redis
订阅来更新本地的缓存信息,在项目启动时判断是否开启集群模式,如果开启就启动订阅,实现代码如下:
public static async Task<IApplicationBuilder> UseCzarOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
{
//重写创建配置方法
var configuration = await CreateConfiguration(builder);
ConfigureDiagnosticListener(builder);
CacheChangeListener(builder);
return CreateOcelotPipeline(builder, pipelineConfiguration);
}
/// <summary>
/// 金焰的世界
/// 2019-03-03
/// 添加缓存数据变更订阅
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
private static void CacheChangeListener(IApplicationBuilder builder)
{
var config= builder.ApplicationServices.GetService<CzarOcelotConfiguration>();
var _cache= builder.ApplicationServices.GetService<IMemoryCache>();
if (config.ClusterEnvironment)
{
//订阅满足条件的所有事件
RedisHelper.PSubscribe(new[] { config.RedisOcelotKeyPrefix + "*" }, message =>
{
var key = message.Channel;
_cache.Remove(key); //直接移除,如果有请求从redis里取
//或者直接判断本地缓存是否存在,如果存在更新,可自行实现。
});
}
}
使用的是从配置文件提取的正则匹配的所有KEY
都进行订阅,由于本地缓存增加了定时过期策略,所以为了实现方便,当发现redis
数据发生变化,所有订阅端直接移除本地缓存即可,如果有新的请求直接从redis
取,然后再次缓存,防止集群客户端缓存信息不一致。
为了区分不同的缓存实体,便于在原始数据发送变更时进行更新,定义CzarCacheRegion
类。
namespace Czar.Gateway.Configuration
{
/// <summary>
/// 缓存所属区域
/// </summary>
public class CzarCacheRegion
{
/// <summary>
/// 授权
/// </summary>
public const string AuthenticationRegion = "CacheClientAuthentication";
/// <summary>
/// 路由配置
/// </summary>
public const string FileConfigurationRegion = "CacheFileConfiguration";
/// <summary>
/// 内部配置
/// </summary>
public const string InternalConfigurationRegion = "CacheInternalConfiguration";
/// <summary>
/// 客户端权限
/// </summary>
public const string ClientRoleModelRegion = "CacheClientRoleModel";
/// <summary>
/// 限流规则
/// </summary>
public const string RateLimitRuleModelRegion = "CacheRateLimitRuleModel";
/// <summary>
/// Rpc远程调用
/// </summary>
public const string RemoteInvokeMessageRegion = "CacheRemoteInvokeMessage";
/// <summary>
/// 客户端限流
/// </summary>
public const string Cza