如何基於surging跨網關跨語言進行緩存降級

概述

       surging是一款開源的微服務引擎,包含了rpc服務治理,中間件,以及多種外部協議來解決各個行業的業務問題,在日益發展的今天,業務的需求也更加複雜,單一語言也未必能抗下所有,所以在多語言行業解決方案優勢情況下,那麼就需要多語言的協同研發,而對於協同研發環境下,統一配置的網關,多語言訪問調用必然會涉及到需要數據緩存的問題,那麼怎麼做到跨網關跨語言緩存降級呢?那麼將在此篇文章中進行講解。

如何創建攔截器

繼承IInterceptor ,創建攔截,如下代碼所示

public class LogProviderInterceptor : IInterceptor
    {
        public async Task Intercept(IInvocation invocation)
        { 
            await invocation.Proceed();
            var result = invocation.ReturnValue;
        }
    }

服務引擎針對於IInterceptor 擴展了CacheInterceptor用來做緩存攔截,如以下代碼所示

 

  public class CacheProviderInterceptor : CacheInterceptor
    {
        public override async Task Intercept(ICacheInvocation invocation)
        { 
        }
}

如何使用緩存攔截器

通過設置特性Metadatas.ServiceCacheIntercept配置緩存攔截,如以下代碼所示

 [Metadatas.ServiceCacheIntercept(Metadatas.CachingMethod.Get, Key = "GetUser_{0}_{1}", L2Key = "GetUser_{0}_{1}",EnableL2Cache =true, CacheSectionType = "ddlCache", Mode = Metadatas.CacheTargetType.Redis, Time = 480)]

在處理業務的修改,刪除方法時候,需要移除依賴的緩存,那麼可以設置CorrespondingKeys,如以下代碼所示

 [Metadatas.ServiceCacheIntercept(CachingMethod.Remove, "GetUser_id_{0}", "GetUserName_name_{0}", CacheSectionType = SectionType.ddlCache, Mode = CacheTargetType.Redis)]

如何設置緩存Key

1.比如緩存設置爲GetUserById_{0}, 傳遞的參數是int 類型,值爲2199 ,那麼產生的key就是GetUserById_2199.

2.比如緩存設置爲GetUser_{0}_{1},傳遞的參數是UserModel類型,傳遞爲new UserModel{ UserId=2199,Name="Fanly" }值,那麼產生的Key就是GetUser_fanly_2199. 標識CacheKeyAttribute特性以生成緩存key, 並且設置SortIndex排序依次生成。

public class UserModel
    {
       [CacheKey(1)]
        public int UserId { get; set; }
        [CacheKey(2)]
public string Name { get; set; } public int Age { get; set; } }

創建攔截模塊

通過以下代碼,把攔截器注入到服務引擎中

 public class IntercepteModule : SystemModule
    {
        public override void Initialize(CPlatformContainer serviceProvider)
        {
            base.Initialize(serviceProvider);
        }

        /// <summary>
        /// Inject dependent third-party components
        /// </summary>
        /// <param name="builder"></param>
        protected override void RegisterBuilder(ContainerBuilderWrapper builder)
        {
            base.RegisterBuilder(builder);
            builder.AddClientIntercepted(typeof(CacheProviderInterceptor),typeof(LogProviderInterceptor));
        }
    }

 如何跨語言調用中開啓緩存攔截降級

在surging 是調用分爲二種

1.基於接口創建代理調用,可以作爲同一語言的互相調用,性能上比第二種基於routepath要快,但是具有高耦合性

  var userProxy = ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy<IUserService>("User");

 

2.基於routepath調用,可以作爲跨語言調用,性能上比第一種基於接口創建代理要慢,但是具有低耦合性

  Dictionary<string, object> model = new Dictionary<string, object>();
  model.Add("name", name);
  string path = "api/hello/say";
   string result =await _serviceProxyProvider.Invoke<object>(model, path, null);

而在服務調用下,因爲業務模型參數在基於routepath調用情況,做不到模型參數解析,只能支持單一參數和無參數的緩存攔截調用,而基於接口創建代理調用是可以支持業務模型緩存調用的,在以下特徵情況下就需要在Metadatas.ServiceCacheIntercept特性下開啓EnableStageCache,代碼如下

[Metadatas.ServiceCacheIntercept(Metadatas.CachingMethod.Get, Key = "GetDictionary", L2Key = "GetDictionary", EnableL2Cache = true, CacheSectionType = "ddlCache", Mode = Metadatas.CacheTargetType.Redis, Time = 480, EnableStageCache = true)]      

 

通過以上的代碼,運行後,在註冊中心註冊的服務路由下可以看到攔截器元數據,這樣在其它語言通過元數據可以構造服務消費者的緩存攔截降級。

 以下是基於二種調用的緩存結果存儲redis中

如何處理緩存K/V 中Value 過大

 

緩存中間件Redis是一種高性能的內存數據庫,用於存儲鍵值對的數據結構。當value的大小超過一定限制時,一般超過10K就會影響查詢的性能。這時候使用一二級緩存來解決,一級緩存用redis 存儲標記,標記緩存是否失效,二級緩存用本地緩存存儲,當標記失效不存在後,會遠程調用服務,返回結果添加一級緩存標記,返回結果添加到二級緩存。

提示:大家可以按照自己的業務需求,研發緩存攔截,不一定非要使用CacheProviderInterceptor,按照CacheProviderInterceptor一二級緩存進行構建研發

總結

      社區版:https://github.com/fanliang11/surging,如果需要其它版本,請聯繫作者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章