Ocelot中使用 CacheManager 來(lái)支持緩存蒲跨,官方文檔中強(qiáng)烈建議使用該包作為緩存工具译断。
以下介紹通過(guò)使用CacheManager來(lái)實(shí)現(xiàn)Ocelot緩存授翻。
1、通過(guò)Nuget添加 Ocelot.Cache.CacheManager
包
在OcelotGetway項(xiàng)目中添加引用:
2、修改 Startup
中的 ConfigureServices
方法
修改如下:
services
.AddOcelot(new ConfigurationBuilder()
.AddJsonFile("configuration.json")
.Build())
.AddConsul()
.AddCacheManager(x => x.WithDictionaryHandle())
.AddAdministration("/administration", "secret");
3堪唐、修改 WebApiA 添加一個(gè) TimeController
并添加如下代碼:
using System;
using Microsoft.AspNetCore.Mvc;
namespace WebApiA.Controllers
{
[Produces("application/json")]
[Route("api/[controller]/[action]")]
public class TimeController : Controller
{
[HttpGet]
public string GetNow()
{
return DateTime.Now.ToString("hh:mm:ss");
}
}
}
啟動(dòng)WebApiA項(xiàng)目并使用Postman多次請(qǐng)求 http://localhost:5000/api/Time/GetNow
可以看到每次返回的時(shí)間不同巡语。
4、修改OcelotGetway項(xiàng)目中的 configuration.json
淮菠,在 ReRoutes
中添加如下配置:
{
"DownstreamPathTemplate": "/api/Time/GetNow",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/Now",
"UpstreamHttpMethod": [ "Get" ],
"FileCacheOptions": {
"TtlSeconds": 60,
"Region": "somename"
}
}
對(duì) FileCacheOptions
配置做下解釋:
- TtlSeconds: 緩存時(shí)間(秒)
- Region: 緩存區(qū)男公,表示改配置緩存放到哪個(gè)區(qū)域,可以在配置管理中進(jìn)行維護(hù)合陵,后邊將做詳細(xì)介紹
用一句話解釋改配置:對(duì)鏈接http://localhost:5000/Now使用somename緩存區(qū)進(jìn)行60秒緩存枢赔。
然后啟動(dòng)OcelotGetway項(xiàng)目,使用Postman請(qǐng)求如下:
Now from cache.gif
多次請(qǐng)求在一分鐘之內(nèi)得到的返回?cái)?shù)據(jù)并未發(fā)生變化拥知。
至此踏拜,緩存配置完成。
5低剔、使用配置管理清除緩存
在配置管理篇中并沒(méi)有介紹清除緩存api的使用速梗,而是留到了本片來(lái)進(jìn)行介紹。要使用配置管理需要先按照之前的文章進(jìn)行配置襟齿。
以下介紹清除緩存的方法姻锁。
使用Postman post請(qǐng)求http://localhost:5000/administration/connect/token如下:
得到token。
使用Postman delete請(qǐng)求http://localhost:5000/administration/outputcache/somename并bearer上述得到的token如下:
再次請(qǐng)求http://localhost:5000/Now猜欺,可以發(fā)現(xiàn)與上次請(qǐng)求的返回時(shí)間不同位隶。
注意:兩次請(qǐng)求http://localhost:5000/Now的時(shí)間間隔要控制在60s之內(nèi)才能看出效果。
6开皿、實(shí)現(xiàn)自己的緩存
Ocelot提供了接口可以讓我們自己實(shí)現(xiàn)緩存處理類(lèi)钓试,該類(lèi)要實(shí)現(xiàn) IOcelotCache<CachedResponse>
,并且要在 Startup中的 ConfigureServices
方法中的 AddOcelot
之后添加 services.AddSingleton<IOcelotCache<CachedResponse>, MyCache>();
來(lái)注入自己的緩存處理類(lèi)覆蓋Ocelot中默認(rèn)的緩存處理副瀑。
如果需要實(shí)現(xiàn)文件緩存需要實(shí)現(xiàn) IOcelotCache<FileConfiguration>
接口并添加相應(yīng)注入弓熏。
提供一個(gè)簡(jiǎn)單版本的緩存處理類(lèi)(非常不建議生產(chǎn)環(huán)境使用):
using System;
using System.Collections.Generic;
using System.Linq;
using Ocelot.Cache;
namespace OcelotGetway
{
public class MyCache : IOcelotCache<CachedResponse>
{
private static Dictionary<string, CacheObj> _cacheObjs = new Dictionary<string, CacheObj>();
public void Add(string key, CachedResponse value, TimeSpan ttl, string region)
{
if (!_cacheObjs.ContainsKey($"{region}_{key}"))
{
_cacheObjs.Add($"{region}_{key}", new CacheObj()
{
ExpireTime = DateTime.Now.Add(ttl),
Response = value
});
}
}
public CachedResponse Get(string key, string region)
{
if (!_cacheObjs.ContainsKey($"{region}_{key}")) return null;
var cacheObj = _cacheObjs[$"{region}_{key}"];
if (cacheObj != null && cacheObj.ExpireTime >= DateTime.Now)
{
return cacheObj.Response;
}
_cacheObjs.Remove($"{region}_{key}");
return null;
}
public void ClearRegion(string region)
{
var keysToRemove = _cacheObjs.Where(c => c.Key.StartsWith($"{region}_"))
.Select(c => c.Key)
.ToList();
foreach (var key in keysToRemove)
{
_cacheObjs.Remove(key);
}
}
public void AddAndDelete(string key, CachedResponse value, TimeSpan ttl, string region)
{
if (_cacheObjs.ContainsKey($"{region}_{key}"))
{
_cacheObjs.Remove($"{region}_{key}");
}
_cacheObjs.Add($"{region}_{key}", new CacheObj()
{
ExpireTime = DateTime.Now.Add(ttl),
Response = value
});
}
}
public class CacheObj
{
public DateTime ExpireTime { get; set; }
public CachedResponse Response { get; set; }
}
}