很久没有更新dapr系列了。今天带来的是一个小的组件集成,通过多级缓存框架来实现对服务的缓存保护,依旧是一个简易的演示以及对其设计原理思路的讲解,欢迎大家转发留言和star

目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统

二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

五、通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

六、通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

七、通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

八、通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

九、通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权 && 百度版Oauth2

十、通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

十一、通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

十二、通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

十三、通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

十四、通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧

十五、通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

十六、通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护

十七、通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

十八、通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存

十九、通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址

二、通讯框架地址

  今天我们演示一下,在创建订单的时候,订单服务会通过rpc拉取用户服务获取一个随机用户来模拟下订单。这个随机用户的接口接下来我会尝试使用多级缓存来保护。首先我们需要在AccountService的Infrastructure层通过nuget引入多级缓存的包:

Install-Package Oxygen-MultilevelCache

  接着我们需要注入两个具体的多级缓存实现,这里我们的一级缓存采用.netcore自带的memcache,二级缓存我们选用dapr的statemanager来实现,当然这两种实现你都可以替换成任意其他你熟知的缓存实现,并不影响最终效果。代码如下:

  一级缓存实现:

    public class L1Cache : IL1CacheServiceFactory
{
private readonly IMemoryCache memoryCache;
public L1Cache(IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
}
public T Get<T>(string key)
{
Console.WriteLine($"L1缓存被调用,KEY={key},value{(memoryCache.Get<T>(key) == null ? "不存在" : "存在")}");
return memoryCache.Get<T>(key);
} public bool Set<T>(string key, T value, int expireTimeSecond = 0)
{
return memoryCache.Set(key, value, DateTimeOffset.Now.AddSeconds(expireTimeSecond)) != null;
}
}

  二级缓存实现:

    public class L2Cache : IL2CacheServiceFactory
{
private readonly IStateManager stateManager;
public L2Cache(IStateManager stateManager)
{
this.stateManager = stateManager;
}
public async Task<T> GetAsync<T>(string key)
{
var cache = await stateManager.GetState(new L2CacheStore(key),typeof(T));
Console.WriteLine($"L2缓存被调用,KEY={key},value{(cache == null ? "不存在" : "存在")}");
if (cache != null)
return (T)cache;
return default(T);
} public async Task<bool> SetAsync<T>(string key, T value, int expireTimeSecond = 0)
{
var resp = await stateManager.SetState(new L2CacheStore(key, value, expireTimeSecond));
return resp != null;
}
}
internal class L2CacheStore : StateStore
{
public L2CacheStore(string key, object data, int expireTimeSecond = 0)
{
Key = $"DarpEshopL2CacheStore_{key}";
this.Data = data;
this.TtlInSeconds = expireTimeSecond;
}
public L2CacheStore(string key)
{
Key = $"DarpEshopL2CacheStore_{key}";
}
public override string Key { get; set; }
public override object Data { get; set; }
}

  接着我们将这两个实现注入到我们的webapplication里并在middleware里通过use启动它:

builder.Services.AddMemoryCache();
builder.Services.InjectionCached<L1Cache, L2Cache>();
//......
var app = builder.Build();
app.UseCached();
//......
await app.RunAsync();

  最后我们在AccountQueryService.cs里对GetMockAccount添加对应的缓存注解:

        [SystemCached]
public async Task<ApiResult> GetMockAccount()
{
Console.WriteLine("GetMockAccount被调用");
//......
}

  *默认注解参数为int expireSecond = 60, int timeOutMillisecond = 5000, SystemCachedType cachedType = SystemCachedType.Method。其中expireSecond代表你想要的缓存的时间,单位为秒,timeOutMillisecond是指在框架尝试请求二级缓存时的超时等待时长,单位毫秒。cachedType代表缓存类别,SystemCachedType.Method代表仅使用方法作为缓存key,SystemCachedType.MethodAndParams代表会根据方法名+参数来实现更加细化的缓存key

  最后启动我们的项目,现在通过postman来访问这个接口,打印日志如下:

  可以看到首先会尝试访问L1缓存实现,如果没有找到对应的key会尝试访问L2缓存实现,最终会访问原始服务并将缓存结果进行多级缓存,所以当再次请求这个接口时将不再产生对原始服务的调用:

  接下来我们停止掉这个pod,让k8s重启一个新的pod来模拟L1缓存失效时的情况,可以看到首次调用时L2缓存被调用并且会重新覆写到L1,后面再次调用都会命中L1的缓存:

  演示很简单,大家可以下载最新版本的代码rebuild通过调用创建订单并log accountservice来观察多级缓存是否起作用。

  下面来讲解一下多级缓存的实现思路:

  从流程图里看起来很简单,其实就是一个AOP原理的实现,通过systemcached注解为对应的方法体创建一个proxy代理并注入到IOC容器中。当方法被调用时被proxy拦截到请求后依次串行调用L1、L2、realservice实现。

  具体有兴趣的朋友可以看看github上的代码:https://github.com/sd797994/Oxygen-MultilevelCache

通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(二十)——Saga框架实现思路分享

    今天这篇博文的主要目的是分享一下我设计Saga的实现思路来抛砖引玉,其实Saga本身非常的类似于一个简单的工作流体系,相比工作流不一样的部分在于它没有工作流的复杂逻辑处理机制(比如会签),没有条件分支 ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

    之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统

    本来想在Dpar 1.0GA时发布这篇文章,由于其他事情耽搁了放到现在.时下微服务和云原生技术如何如荼,微软也不甘示弱的和阿里一起适时推出了Dapr(https://dapr.io/),园子里关于da ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

    首先感谢张队@geffzhang公众号转发了上一篇文章,希望广大.neter多多推广dapr,让云原生更快更好的在.net这片土地上落地生根. 目录:一.通过Dapr实现一个简单的基于.net的微服务 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

    目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

    状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

    我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

    在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...

随机推荐

  1. 基于CentOS6.5-Hadoop2.7.3-hive-2.1.1安装sqoop1.4.7

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6627736198431375879/ 系统版本,Hadoop已安装完成.链接<CentOS6.5下安装Had ...

  2. ES6随笔D1

    1.数值解构赋值 ES6 允许按照一定模式,可以从数组中提取值,按照对应位置,对变量赋值,这被称为解构. 解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象.由于undefined和n ...

  3. C# 基本控件使用练习

    自己设计并编写一个 Windows 应用程序,要求用到 TextBox.GroupBox.RadioButton.CheckBox.ComboBox.ListBox 控件. 代码如下: 页面1: us ...

  4. 0,NULL和nullpter

    #include <iostream> using namespace std; void f(int) { cout<<"f(int)"<<e ...

  5. golang中的标准库template

    html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用text/templa ...

  6. Android开发----开发工具的安装与TextView组件

    开发工具的安装 选择使用Android Studio进行开发,Android Studio 是谷歌推出的一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT, ...

  7. maven一键构造及常用命令

    maven一键构造及常用命令 1.maven的一键构建 我们不再使用本地的Tomcat对项目进行编译.测试.运行.打包.安装.部署等一系列过程,而是使用maven自身集成的Tomcat插件来完成这些操 ...

  8. ApacheCN PHP 译文集 20211101 更新

    PHP 入门指南 零.序言 一.PHP 入门 二.数组和循环 三.函数和类 四.数据操作 五.构建 PHP Web 应用 六.搭建 PHP 框架 七.认证与用户管理 八.建立联系人管理系统 使用 PH ...

  9. AT3913 XOR Tree

    经过长时间的思考,我发现直接考虑对一条链进行修改是很难做出本题的,可能需要换一个方向. 可以发现本题中有操作的存在,是没有可以反过来做的做法的,因此正难则反这条路应该走不通. 那么唯一的办法就是简化这 ...

  10. HBase安装教程

    一.版本介绍 linux : CentOS7 Hadoop : 2.7.6 zookeeper : 3.4.6 hbase : 1.4.6 jdk : jdk1.8.0_171 三个节点的主机名分别为 ...