cond));
}
}
else
{
_cache.Set(key, result, TimeSpan.FromSeconds(_options.CzarCacheTime));
}
}
}
return result;
}
}
}
上面就段代码实现了本地缓存和Redis
缓存的支持,优先从本地提取,如果在集群环境使用,增加redis
缓存支持,但是此种方式不适用缓存变更非常频繁场景,比如客户端限流的实现,所以在代码中把客户端限流的缓存直接使用redis
缓存实现。
2.注入实现和订阅
有了实现代码后,发现还缺少添加缓存注入和配置信息修改。首先需要修改配置文件来满足是否开启集群判断,然后需要实现redis
的不同部署方式能够通过配置文件配置进行管理,避免硬编码导致的不可用问题。
配置文件CzarOcelotConfiguration.cs
修改代码如下:
namespace Czar.Gateway.Configuration
{
/// <summary>
/// 金焰的世界
/// 2018-11-11
/// 自定义配置信息
/// </summary>
public class CzarOcelotConfiguration
{
/// <summary>
/// 数据库连接字符串,使用不同数据库时自行修改,默认实现了SQLSERVER
/// </summary>
public string DbConnectionStrings { get; set; }
/// <summary>
/// 金焰的世界
/// 2018-11-12
/// 是否启用定时器,默认不启动
/// </summary>
public bool EnableTimer { get; set; } = false;
/// <summary>
/// 金焰的世界
/// 2018-11.12
/// 定时器周期,单位(毫秒),默认30分总自动更新一次
/// </summary>
public int TimerDelay { get; set; } = 30 * 60 * 1000;
/// <summary>
/// 金焰的世界
/// 2018-11-14
/// Redis连接字符串
/// </summary>
public string RedisConnectionString { get; set; }
/// <summary>
/// 金焰的世界
/// 2019-03-03
/// 配置哨兵或分区时使用
/// </summary>
public string[] RedisSentinelOrPartitionConStr { get; set; }
/// <summary>
/// 金焰的世界
/// 2019-03-03
/// Redis部署方式,默认使用普通方式
/// </summary>
public RedisStoreMode RedisStoreMode { get; set; } = RedisStoreMode.Normal;
/// <summary>
/// 金焰的计界
/// 2019-03-03
/// 做集群缓存同步时使用,会订阅所有正则匹配的事件
/// </summary>
public string RedisOcelotKeyPrefix { get; set; } = "CzarOcelot";
/// <summary>
/// 金焰的世界
/// 2019-03-03
/// 是否启用集群环境,如果非集群环境直接本地缓存+数据库即可
/// </summary>
public bool ClusterEnvironment { get; set; } = false;
/// <summary>
/// 金焰的世界
/// 2018-11-15
/// 是否启用客户端授权,默认不开启
/// </summary>
public bool ClientAuthorization { get; set; } = false;
/// <summary>
/// 金焰的世界
/// 2018-11-15
/// 服务器缓存时间,默认30分钟
/// </summary>
public int CzarCacheTime { get; set; } = 1800;
/// <summary>
/// 金焰的世界
/// 2018-11-15
/// 客户端标识,默认 client_id
/// </summary>
public string ClientKey { get; set; } = "client_id";
/// <summary>
/// 金焰的世界
/// 2018-11-18
/// 是否开启自定义限流,默认不开启
/// </summary>
public bool ClientRateLimit { get; set; } = false;
}
}
在配置文件中修改了redis
相关配置,支持使用redis
的普通模式、集群模式、哨兵模式、分区模式,配置方式可参考csrediscore开源项目。
然后修改ServiceCollectionExtensions.cs
代码,注入相关实现和redis
客户端。
builder.Services.AddMemoryCache(); //添加本地缓存
#region 启动Redis缓存,并支持普通模式 官方集群模式 哨兵模式 分区模式
if (options.ClusterEnvironment)
{
//默认使用普通模式
var csredis = new CSRedis.CSRedisClient(options.RedisConnectionString);
switch (options.RedisStoreMode)
{
case RedisStoreMode.Partition:
var NodesIndex = options.RedisSentinelOrPartitionConStr;
Func<string, string> nodeRule = null;
csredis = new CSRedis.CSRedisClient(nodeRule, options.RedisSentinelOrPartitionConStr);
break;
case RedisStoreMode.Sentinel:
csredis = new CSRedis.CSRedisClient(options.RedisConnectionString, options.RedisSentinelOrPartitionConStr);
break;
}
//初始化 RedisHelper
RedisHelper.Initialization(csredis);
}
#endregion
builder.Services.AddSingleton<IOcelotCache<FileConfiguration>, CzarMemoryCache<FileConfiguratio