如何基于surging跨网关跨语言进行缓存降级

news/2024/10/10 0:23:29

概述

       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,如果需要其它版本,请联系作者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/27839.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

AtCoder Grand Contest 001

D. Arrays and Palindrome 如果两个字符要求相同就给它们连边,对于一个长度为 \(x\) 的回文串,\(x\) 是偶数会连 \(x/2\) 条边,奇数会连 \(x/2 - 0.5\) 条边。 \(a\) 和 \(b\) 两个序列总和为 \(2n\),要让 \(n\) 个字符相同至少连 \(n - 1\) 条边,也就是奇数个数超过 \(2\…

AtCoder Beginner Contest 352题解

AtCoder Beginner Contest 352 Time : 2024-05-04(Sat) 20:00 - 2024-05-04(Sat) 21:40 A AtCoder Line 问题陈述 AtCoder 铁路线有 $N$ 个车站,编号为 $1, 2, \ldots, N$ 。 在这条线路上,有趟进站列车从 $1$ 站出发,依次停靠 $2, 3, \ldots, N$ 站,有趟出站列车从 $N$ 站…

windows安装ffmpeg

官网 https://ffmpeg.org/download.html这个是别人已经编译好的,不染源码还需要重新编译解压到一个目录,添加到环境变量

SpringBoot3.1.5对应新版本SpringCloud开发(2)-Eureka的负载均衡

Eureka的负载均衡 负载均衡原理负载均衡流程老版本流程介绍 当order-servic发起的请求进入Ribbon后会被LoadBalancerInterceptor负载均衡拦截器拦截,拦截器获取到请求中的服务名称,交给RibbonLoadBanlancerCient,然后RibbonLoadBanlancerCient会将服务名称当作服务id交给Dyn…

i-MES生产制造管理系统-设备点检

考虑到设备的分布区域比较分散,为了方便设备管理人员进行作业,设备点检模块通过安卓版的移动 PDA 完成,在此之前我们登录进入 MES 系统,创建点检项目,包括每一个点检项目的标准值以及上下限,如下图所示: 创建完点检项目之后,我们针对不同的设备类型,定义点检方案,在…

yum配置及仓库搭建

yum实现 YUM 是一个在 Linux 系统中用于管理软件包的工具,可以在服务器和客户端之间跨网络使用。在这种系统中,服务器上通常会存储软件包(RPM 包)和相应的元数据(repodata 文件夹中的内容)。RPM 包:这些是实际的软件包文件,它们包含了应用程序、库文件、配置文件等。这…

P3193 [HNOI2008] GT考试 题解

P3193 [HNOI2008] GT考试 题解之前学矩阵乘的时候做的题,当时因为不会\(kmp\)搜索一稀里糊涂过去了,现在填个坑。头图 是\(Logos\)!P3193 [HNOI2008] GT考试 题链:洛谷 题库 题目大意: 求有多少个长度为\(n\)的数字串的子串中不包含给出的长度为\(m\)位的串,范围 \(n &l…

一些贪心的解题报告

一些贪心的解题报告 贪心题一般来说都是观察结论远简单于严谨证明,所以不会过多的去证明。 1.Tree compass 题目来源 codeforces div1 934 C https://codeforces.com/problemset/problem/1943/C 题面翻译 给定一棵节点数为\(n\)的树(\(1\le n \le 2\cdot 10^3\)),一开始节点都…