新普金娱乐网址


地理外喜爱您的时候,你早干嘛去矣?

永不因此实绩定义孩子

《小王子》你曾是个少年:永远年轻,永远热泪盈眶

  • 九月 18, 2018
  • 地理
  • 没有评论

如若您爱上了一样枚生长于平等发星星上的费,那么夜间,你看在天空就觉得幸福愉快,所有的有限上都类似开在花。

ABP入门系列目录——学习Abp框架的实操演练
源码路径:Github-LearningMpaAbp

                                                          ——小王子


图片 1

1. 引言

缔造任务时我们用指定分配给哪个,Demo中我们利用一个下拉列表用来显示当前系的备用户,以供用户挑选。我们各创建一个职责时都使错过数据库取一次等用户列表,然后绑定到用户下拉列表显示。如果就单单对一个demo来说,这样实现为无可厚非,但是以正式项目面临,显然是无成立之,浪费程序性能,有待优化。
说交优化,你必马上就想开了下缓存。是的,缓存是增强程序性能的速方式之一。
即时等同省咱们尽管针对当时无异案例来拘禁无异扣押Abp中安使缓存来提高程序性能。

《小王子》是法国作家安托万·德·圣·埃克苏佩里为1942年写成的知名儿童文学短篇小说。虽然是儿童文学,但就并无阻止它们变成具备人数的童话,初读时懵懵懂懂,再念常热泪盈眶。当你怀大人的心气来读就仍开常常,它会展示格外无聊,不过还吓,我们都曾经是独少年。

2. Abp的缓存机制

以直采用缓存之前,我们或来概括梳理下Abp的缓存机制。
Abp之所以能变成一个上佳的DDD框架,我思以及笔者详细的文档有非常特别关系,
作者既当ABP官方文档介绍了什么样行使Caching,英文水准好之就算径直看官方的吧。

Abp对缓存进行抽象概念了ICache接口,位于Abp.Runtime.Caching取名空间。
并对ICache提供了默认的落实AbpMemoryCacheAbpMemoryCache是基于MemoryCache.aspx?f=255&MSPPError=-2147217396)的同等种实现方式。MemoryCache凡是微软的一模一样效仿缓存机制,定义在System.Runtime.Caching取名空间,顾名思义
,在内存中开展高速缓存。我们由此品种因图来拘禁下Abp对Cache的兑现:

图片 2

起图备受可见见要不外乎四单部分:

  • ICache->CacheBase->AbpMemoryCache:对缓存的纸上谈兵和落实;
  • ITypedCache:缓存的泛型实现;
  • ICacheManager->CacheManagerBase->AbpMemoryCacheManager:缓存管理类的泛和落实,代码中好由此注入ICacheManager来获取缓存;
  • ICachingConfiguration->CachingConfiguration:用来安排使用啊种缓存。

  • Abp缓存实操演练

《小王子》是为一个叙述者的口气开始的,叙述者是一个孤寂之飞行员,因为他于上下的社会风气里索不交可并行倾诉的人数,大人们还极实在了。直到发生相同上,他因为飞机故障被迫降落撒哈拉沙漠,在那里,他遭遇见了来其他一个星星的稍王子。小王子讲述了投机的故事,他离开了团结之星斗,在抵地之前看了六个星球,他遭受见了喝着统治整个的天王,爱慕虚荣的“绅士”,酒鬼,商人,为星球点灯的人头,未曾探索地理的地理学家,空虚的玫瑰园,和互驯化的狐狸……最关键之是叙了属于自己无比的玫瑰之故事。

3.1. 永恒优化点

稳定及我们的TasksController,其中起个别种创建Task的Action,代码如下:

public PartialViewResult RemoteCreate() {
    var userList = _userAppService.GetUsers();
    ViewBag.AssignedPersonId = new SelectList(userList.Items, "Id", "Name");
    return PartialView("_CreateTaskPartial");
}

[ChildActionOnly] 
public PartialViewResult Create() {
    var userList = _userAppService.GetUsers();
    ViewBag.AssignedPersonId = new SelectList(userList.Items, "Id", "Name");
    return PartialView("_CreateTask");
}

好看来零星只艺术还需调用_userAppService.GetUsers();来博用户列表。
现行咱们来行使缓存技术对该优化。首先我们应想到了Asp.net
mvc自带的同法缓存机制,OutputCache。


3.2. 使用[OutputCache]进展缓存

设对OutputCache不了解,可以参考我之就篇文章Asp.net mvc
知多少(九)。

我们得以简简单单以Action上补偿加[OutputCache]特征即可。

[OutputCache(Duration = 1200, VaryByParam = "none")]
[ChildActionOnly] 
public PartialViewResult Create() {
    var userList = _userAppService.GetUsers();
    ViewBag.AssignedPersonId = new SelectList(userList.Items, "Id", "Name");
    return PartialView("_CreateTask");
}

[OutputCache(Duration = 1200, VaryByParam = "none")]就句代码的意是该action只缓存1200s。1200s后,ASP.NET
MVC会重新执行action并再缓存。因为凡以[ChildActionOnly]中使用[OutputCache],所以该缓存属于Donut
Hole caching。
当拖欠措施中由只断点,测试就发第一破调整用会进入艺术中,之后1200s内还未见面重上该方式,1200s后会还上,说明缓存成功!

柳暗花明,总有人理解你。

3.3. 采用ICacheManager进行缓存

依照上对Abp缓存机制的梳理,我们得于得以缓存的地方注入ICacheManager来进展缓存管理。
现在咱们尽管在TasksController中注入ICacheManager
说明私有变量,并以构造函数中流入,代码如下:

private readonly ITaskAppService _taskAppService;
private readonly IUserAppService _userAppService;
private readonly ICacheManager _cacheManager;

public TasksController(ITaskAppService taskAppService, IUserAppService userAppService, ICacheManager _cacheManager) {
    _taskAppService = taskAppService;
    _userAppService = userAppService;
    _cacheManager = cacheManager;
}

脚修改RemoteCreateaction如下:

public PartialViewResult RemoteCreate()
{   
    var userList = _cacheManager.GetCache("ControllerCache").Get("AllUsers", 
                          () => _userAppService.GetUsers()) as ListResultDto<UserListDto>;
    ViewBag.AssignedPersonId = new SelectList(userList.Items, "Id", "Name");
    return PartialView("_CreateTaskPartial");
}

分析代码发现我们于通过上面代码中取之缓存是亟需进行类型转换的。原来_cacheManager.GetCache回到的是ICache类型,而ICache定义key-value相应之是string-object类型,所以自然从缓存获取了数据后而拓展类型转换了(注:最新Abp版本为ICache提供了扩大方法,不再要展示进行类型转换)。那起没有起泛型版本?聪明而您,作者对ICache开展包装封装了只ITypedCache为落实种安全。代码种进行了5种实现,可以一样诈究竟:

public PartialViewResult RemoteCreate()
{
    //1.1 注释该段代码,使用下面缓存的方式
    //var userList = _userAppService.GetUsers();

    //1.2 同步调用异步解决方案(最新Abp创建的模板项目已经去掉该同步方法,所以可以通过下面这种方式获取用户列表)
    //var userList = AsyncHelper.RunSync(() => _userAppService.GetUsersAsync());

    //1.3 缓存版本
    var userList = _cacheManager.GetCache("ControllerCache").Get("AllUsers", () => _userAppService.GetUsers());

    //1.4 转换为泛型版本
    //var userList = _cacheManager.GetCache("ControllerCache").AsTyped<string, ListResultDto<UserListDto>>().Get("AllUsers", () => _userAppService.GetUsers());

    //1.5 泛型缓存版本
    //var userList = _cacheManager.GetCache<string, ListResultDto<UserListDto>>("ControllerCache").Get("AllUsers", () => _userAppService.GetUsers());

    ViewBag.AssignedPersonId = new SelectList(userList.Items, "Id", "Name");
    return PartialView("_CreateTaskPartial");
}

透过测试,用户列表正确缓存。

图片 3

与[OutputCache]对待,我们十分当然就是见面问Abp提供的复苏存怎么没配备缓存过期日,你想到的框架肯定吗想到了,Abp的默认缓存过期时是60mins,我们好透过当使用缓存项目之Module(模块)中从定义缓存时间。
为咱们是以Web项目蒙使用的Cache,所以一定及XxxWebModule.cs,在PreInitialize方式吃进行缓存配置。

//配置所有Cache的默认过期时间为2小时
Configuration.Caching.ConfigureAll(cache =>
{
    cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2);
});

//配置指定的Cache过期时间为10分钟
Configuration.Caching.Configure("ControllerCache", cache =>
{
    cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(10);
});

飞行员原来的愿意是画家,他好画画自己想象着的别样事物,当他信心满满地将写在吞着大象的蟒蛇的绘画被家长看时,大人们也无视地告诉他,这仅仅是独罪名。同时告诫他放弃自己的绘画梦想与上下们并“忙正事”,飞行员虽真的开免动声色地举行一个大人了。直到外遭见了望外讨要小羊画的多少王子,他把画在帽子的描绘拿给他常,小王子却说“我毫不服用了大象的蟒蛇,我而同但有些羊。”

3.4. 用IEntityCache对实业进行缓存

当有着人都当繁忙正经事时,你是否上马扔真实的和睦,和豪门并做一个正经人。并且于其他人“不务正业”时,劝导外绝不发那些乱七八糟的想法,做一个正经人。在这个上,突然有人从怪圈子里跳出来鼓励公,支持你,心底的种子怕是会以转瞬始于起娇艳的花吧,小王子于丁信赖,柳暗花明,总有人会懂得你。

3.4.1. 缓存方式的思

方的片种植缓存方式,我们一般用来存储于定义缓存,但发生一个局限性,受到具体缓存过期时的范围。
琢磨一下,我们缓存的用户列表,它是一个实时会扭转的汇聚,而之实时是风雨飘摇时的,可能1mins以内就发生新用户注册,也发出或几龙无用户注册(比如我们以此Demo),这个上即便坏设置缓存过期(刷新)时间。
但出于我们是Demo性质只是为演示用法,所以我们设定缓存过期工夫也10mins也无可厚非。

那有无发雷同栽缓存机制,不待安装缓存过期时,当数码变动之时段就是会活动还缓存呢?
答案是大势所趋的,Abp为咱提供了IEntityCache,实体缓存机制。
当我们要经过ID获取实体数据而又未思经常去数据库查询时,我们不怕足以行使IEntityCache
改换句话说,IEntityCache支撑按实体Id进行动态缓存。

图片 4

3.4.2. IEntityCache缓存规律

于示范具体操作之前,我们事先来讲学下IEntityCache的缓存原理:

  • 第一它首先差从数据库中取实体,然后继续调用将会见从缓存获取。
  • 当实体更新或去时它自动将缓存的实业置为无效状态,因此其将会晤重复下同样蹩脚呼吁被起数据库被再次取得。
  • 其采取缓存的近乎的一体化类名作为缓存名称,可以由此也构造函数传参来改缓存名称。
  • 它们是线程安全的。
  • 其使IObjectMapper将实体映射到缓存项。
    IObjectMapper由AutoMapper模块实现。所以,如果你用她,你用AutoMapper模块。您可覆盖MapToCacheItem方法以手动将实体映射到缓存项。

刚好因你啊汝的玫瑰花费了时,这才使您的玫瑰变得如此重要。

3.4.3. IEntityCache达成手实战

既然是缓存实体,基于我们是demo,我们就是拿Task实体玩一下吧。
当这边我们先行使复习生什么是DTO,重申下DDD为什么引入DTO。
Data Transfer Objects(DTO)用来以应用层和表现层里传输数据。

DTO的必要性:

  1. 世界层的虚幻
  2. 数量隐藏
  3. 序列化和延期加载问题

这就是说是DTO跟要讲的实业缓存来什么关联吧?
免绕弯子了,就是说实体缓存不应允直接针对Entity进行缓存,以避免缓存时序列化了不拖欠序列化的对象与实业。
那现实怎么操作也?我们不怕直接上Demo吧。
咱定义一个TaskCacheItem,用来缓存Title、Description、State。并定义映射规则[AutoMapFrom(typeof(Task))]

namespace LearningMpaAbp.Tasks.Dtos
{
    [AutoMapFrom(typeof(Task))]
    public class TaskCacheItem
    {
        public string Title { get; set; }

        public string Description { get; set; }

        public TaskState State { get; set; }
    }
}

脚我们定义一个对TaskCacheItem的复苏存接口。

namespace LearningMpaAbp.Tasks
{
    public interface ITaskCache:IEntityCache<TaskCacheItem>
    {
    }
}

实现ITaskCache缓存接口:

namespace LearningMpaAbp.Tasks
{
    public class TaskCache : EntityCache<Task, TaskCacheItem>, ITaskCache, ISingletonDependency
    {
        public TaskCache(ICacheManager cacheManager, IRepository<Task, int> repository, string cacheName = null) 
            : base(cacheManager, repository, cacheName)
        {
        }
    }
}

现,当我们用基于TaskId获取Title、Description、State,我们即便得经当待之近乎中流入注入ITaskCache,来起缓存中赢得。
下面我们于ITaskAppService中添加一个接口TaskCacheItem GetTaskFromCacheById(int taskId);
然后在TaskAppService吃实现其,申明变量并以构造函数注入ITaskCache,实现定义之接口:

private readonly ITaskCache _taskCache;

/// <summary>
///     In constructor, we can get needed classes/interfaces.
///     They are sent here by dependency injection system automatically.
/// </summary>
public TaskAppService(IRepository<Task> taskRepository, IRepository<User, long> userRepository,
    ISmtpEmailSenderConfiguration smtpEmialSenderConfigtion, INotificationPublisher notificationPublisher, ITaskCache taskCache)
{
    _taskRepository = taskRepository;
    _userRepository = userRepository;
    _smtpEmialSenderConfig = smtpEmialSenderConfigtion;
    _notificationPublisher = notificationPublisher;
    _taskCache = taskCache;
}

public TaskCacheItem GetTaskFromCacheById(int taskId)
{
    return _taskCache[taskId];
}

测试如下,直接以当时窗口调用方法,发现独发生同一条Sql查询生成,说明实体缓存成功。

图片 5

恐怕读到此,你也许会见问,说好之『Redis缓存用起来』,你开口了大体上上,跟Redis没有半毛钱关系啊。

Redis这么狠心的技能,当然要压轴登台啊,下面Redis开云。

些微王子有一棵独一无二的玫瑰花,他纯粹地,赤诚地爱着那枚玫瑰,尽管它自傲,虚荣。有同天他与他的玫瑰生了欺负,跑了出,却于地上发现了一个玫瑰园,原来他的玫瑰并无是绝无仅有的,她十分麻烦了。后来,他赶上了扳平只是狐狸,狐狸告诉他,小王子并无是独一无二的,狐狸也未是,但当她们竞相驯化,互相需要常,就都换的惟一了。玫瑰也是,正缘若吧而的玫瑰花费了光阴,这才设你的玫瑰变得这般重大。

4. Redis凡是什么玩意儿

Redis
是一个开源(BSD许可)的,内存中的数据结构存储系统,它可用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序聚集(sorted
sets)与范围查询、bitmaps、hyperloglogs和地理空间(geospatial)索引半径查询。

法定的解说就是是如此隐晦,对于初识Redis,我们得概括把它掌握为依据内存的进度好抢性能大棒的Key-Value数据库。

生一些欲验证,Redis官方仅支持Linux系统不支持Windows系统。
但是呢,微软特别法好什么,微软开始源技术团队(Microsoft Open Tech
group)开发暨保安了一个Win64
的版,我们好在https://github.com/MSOpenTech/redis上下载Win64版本来打同样游玩。

思念询问又多,请参见汉语官方文档或英文官方文档。

眼看吃自身想起了毛姆《面纱》中的句子:我理解您傻、轻佻、头脑空虚,然而我爱尔。我知道你的策划、你的名特优,你势利、庸俗,然而我容易而。我懂您是单坏货色,然而我容易君。

5. 动手试玩Redis

当有着人数实施着吃追求高速、高效的打响,做正面高尚的工作经常,却忘记了,成功用珍贵,是因它花费时间。人们连续为工作、为生存奔波,忙正经事,可谁而能够说,欣赏一朵小花,不是平等起正经事呢。我容易他,仅仅是坐自身爱他。

5.1. 安装Redis

开辟微软开始源技术集团维护的Redis
Github链接,找到Releases目录,下载最新版本的msi安装即可。

图片 6

下载后,一直下同样步安装即可。

出于麦子的原由,我要得了补。

5.2. 简便试玩

找到安装目录,打开cmd并登及安装目录,输入redis-server redis.windows.conf,即可启动Redis
服务。Redis服务默认启动于6379端口。

图片 7

双重开行一个cmd窗口,执行redis-cli.exe即可开始一个Redis客户端。
执行set一声令下进行缓存设置;
执行get命令进行缓存读取;
执行subscribe命进行频道监听;
执行publish令于指定频道发布消息;
具体步骤详参下图:

图片 8

狐狸渴望和微微王子相互驯化,他说:我无吃面包,麦子对自己的话,一点于是为无。我本着麦田无动于衷。而立即,真若人头扫兴。但是,你闹金黄色的毛发。那么,一旦你驯服了自身,这便会见怪美妙。麦子,是金黄色的,它就是见面要自身想起你。而且,我甚至会见爱那风吹麦浪的响动……

6. ABP上试玩Redis缓存

继自己的步子,对Redis也算有矣核心的认识,咱们下面就进去今天之压轴主题,介绍Abp下什么运用redis进行缓存。
首先我们若理解干什么要为此Redis进行缓存。
默认的缓存管理是当内存中(in-memory)进行缓存。当你生出不止一个并发web服务器需要周转与一个应用程序,默认的缓存管理虽不满足你的需求。你或用一个分布式/中央缓存服务器来拓展缓存管理,这时Redis就可以登台了。

狐狸与微王子分别时,狐狸哭了,小王子说:你啊便宜呢没有取。

6.1. Abp集成Redis

先是打开Web层,下载Abp.RedisCache Nuget包安装。
修改XxxWebModule.cs,在DependsOn特性上上加对AbpRedisCacheModule的赖,并以模块的PreInitialize方法被调用UseRedis扩张方法,代码如下:

[DependsOn(
        typeof(LearningMpaAbpDataModule),
        typeof(LearningMpaAbpApplicationModule),
        typeof(LearningMpaAbpWebApiModule),
        typeof(AbpWebSignalRModule),
        //typeof(AbpHangfireModule), - ENABLE TO USE HANGFIRE INSTEAD OF DEFAULT JOB MANAGER
        typeof(AbpWebMvcModule),
        typeof(AbpRedisCacheModule))]
    public class LearningMpaAbpWebModule : AbpModule
    {
        public override void PreInitialize()
        {
            //省略其他配置代码

            //配置使用Redis缓存
            Configuration.Caching.UseRedis();

            //配置所有Cache的默认过期时间为2小时
            Configuration.Caching.ConfigureAll(cache =>
            {
                cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2);
            });

            //配置指定的Cache过期时间为10分钟
            Configuration.Caching.Configure("ControllerCache", cache =>
            {
                cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(10);
            });            
        }
  ....
}

末段一步于Web.Config文件的【connectionStrings】节点也Abp.Redis.Cache加上连接字符串,如下:

  <connectionStrings>
    <add name="Default" connectionString="Server=.\sqlexpress; Database=LearningMpaAbp; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
    <add name="Abp.Redis.Cache" connectionString="localhost"/>
  </connectionStrings>

启航Redis
Server后,F5运转web项目,断点调试,发现早已成使Redis缓存。
假定不启动Redis
Server,会报Error:It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. SocketFailure on PING

图片 9

这么我们就算用Redis取而代之了默认的MemoryCache缓存方案,而未需要改变其它代码,Abp就是如此简单、灵活、松藕合!

狐狸说:由于麦子的缘故,我要么得了便宜。

7. 总结

旋即首文章被重要性梳理了Abp中安进行缓存管理,并简要介绍了Abp中的缓存机制,并同Asp.net
mvc自带的[Outputcache]缓存进行简单对比,并进行了缓存管理实战演练。最后对Redis进行了简易介绍,并介绍了哪些切换Redis缓存。

读到此处,大家该还深有令人感动,关于,友情、爱情、亲情,即使宇宙没有,即使情感消亡,我都欣过。在此间想推荐好妹妹的《风又吹走了》给大家听,虽然小小伤感,但我们仍然眷恋这来了并且动的歌谣。


精心读《小王子》你会意识多真诚而以珍贵的道理,关于善跟事,仪式、空虚……请你真诚且怀有丹心的诵读就本属您无比之《小王子》,永远年轻,永远热泪盈眶。

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图