关于当前后台服务器之中使用缓存的一点思考

前言

本文章只是个人心路历程,只是给予个人的思考思路。并不是绝对的正确答案。

例如

是的主要事情发生在今天,本在百无聊赖之际,想完善一下过去的写的一个小工具类。@Cache与@CacheClear注解。

//主要作用与方法上,简单来说就是将某个方法迅速的写入Redis缓存之中
public @interface Cache{
	//内部怎样实现并不是重要的
}

// 主要作用与方法上,当方法成功运行之中,便会清空某个记录在Redis缓存之中的数据
public @interface CacheClear{
	//内部怎么样实现并不是重要的
}

比如我今天有一个业务,显示某个商品的详情页,详情页上需要商品的名称,点赞数,评论数,库存数等等。

因此我创建了一个接口显示详情数,并且将我的缓存@Cache 加入

	@RequestMapping("details")
	@Cache
	public Object details( String goodsId ){
		//处理过程不重要;
		return details;
	}

这样我们就可以轻松实现了一个缓存操作。
但是缓存数据存在风险,例如每次商品的购买都会左右着购买的数量,如果我在购买完成之后不清除掉缓存,因此我们就在购买数量的接口上另写一个接口

	@RequestMapping("buy")
	@CacheClear
	public Object buy( String goodsId , Long userId ){
		//执行的过程不重要
		return result;
	}

这样我们就完成了我们的缓存失效功能。
但是我又很快发现,这并不是问题的解决,而是问题的开始。
我们发现,会影响数据的接口并不单单只是这一个方面。还有许许多多的方面。

  1. 例如,点赞数,评论数,甚至可能出现的点击数。这些都是导致缓存失效的因素,这样我们就不得不在与这些想得到的,想不到的所有相关接口上都加上@CacheClear,杂!
  2. 其次这些接口可能不单单只是跟获取奖品详情的缓存所相关,将来,我们不难想象这些接口上面可能会有长长一排的@CacheClear,乱!
  3. 会影响库存数量的因素,可能不单单来自于APP端的后台服务器。商户端以及管理端随时都可能给键盘添加库存,你就需要将这一套代码逻辑迁移到其他平台的服务器,烦!

最后哪怕我们不嫌杂,不嫌乱,不嫌烦。处理完这些,我们就发现我们的代码就是一片雷区,在后期的修改之中哪怕一个小错误都会导致BUG的出现。
因此,最后无奈的我,只能将前面花了一个多小时写的代码,全部回滚。

另外提一嘴,我觉得给商品数,点赞数有关的因素加缓存的确挺扯淡的。

思考

在经历了失败之后,我便开始了思考。
我认为《三体》之中有一个思考问题方式挺不错的,叫做给一个事件下定理。
因此我也模仿了这个规则,给缓存下了定义

  1. 被缓存的数据,应该是需要一个相对高的性价比去得到的
  2. 被缓存的数据,应该要有请求压力

最明显的例子,就在于我们对于APP端与后台管理端使用缓存的普遍出发点。
主要就是因为从这两点出发
客户端由于用户多,因此存在请求压力
后台管理端,由于需要对当前的数据进行处理分析,满足第一条

缓存数据也不单单只有一种,它也主要因为缓存的数据需不需要同步处理,而“动”数据与“静”数据。
“动”数据:被缓存的数据由于业务的原因需要进行被动或者主动的修改。
“静”数据: 被缓存的数据,无需进行手动的修改。被缓存的数据存在一个周期性的失效时间。

如何实现呢?

定义完概念之后,我们回来实际一点的按例之中。
就比如说,我们团队要做一个上文之中说到的物品购买的电商系统。
那么我们现在就要考虑,我们如何实现我们的功能呢?

对于静缓存来说 , 这很简单。可以简简单单的通过一个缓存操作便可以完成。
剩下的便是大难题,动缓存。
对于动缓存如何解决,相信不少看过其他文章的人都知道,主要概念就是数据库Redis保持同步的架构理念。大家如果想知道详细内容与理念可以去搜索一下,阿里社区与腾讯社区等一系列社区几乎都有文章讲解实际理论。
那不讲理论,我们就讲讲如何实现吧。
相信看到上文的同学都知道,我们不可能吧实现“同步”的理念分散到各个业务接口里面去。这非常难以管理我们的代码。
那么既然接口不能管理,那么我们就只能把代码写在一个Service里吧

	@Service
	public class GoodStockSerivce{
		//获取数量
		public Integer getNumber( String goodId ){
		}

		//修改数量的方法

		public boolean add( Good good ){}

		public boolean reduce( String goodIds ){}
		
	}

当然上面只是一个展示而已,实际操作大家可以看看实际情况。
但是理念都是一样的,任何需要修改库存的操作 , 最后都要调用这个 GoodStockService 内部的方法。
用代码的强规定,来保证缓存的强一致。
那么假设自己的分为不同的服务呢?
那么方法也有两个

  1. 将库存修改的操作,也变为一个服务。提供给不同的服务调用
  2. 代码复制到各个不同的平台

我们不难看出,对于动缓存的操作概念。他是需要一个专门设计的架构与开发约定的。
要完成这个需要一定的开发量。
其次,这个也不是一个人的事(当然除非你们的任务分配是一个人完成一个功能点的所有开发),动缓存的制定,他可能不是一个接口,一个模块,一个服务,一个系统的共同努力。他就像一个社区 , 需要这个社区的所有参与者都要努力,才能保证这个社区的正常运作。不然,自己在那里再努力的埋头开发,结果其他人没有引入你的概念。哪怕是一个人,你的动缓存在理论上,也会出错。【那时候,满地图找错误的感觉真的让人上瘾】

这种规约的设立,基本上是需要目标缓存业务开始之初就引入的。一般来说越早越好。当然,如果项目初期,你们所在的团队或公司,没有这方面的技术沉淀。并且,似乎也还没有这方面的意识,以及需求的话。这种就是要晚到底了,等到业务有对应的需求,或者线上有这方面的压力的时候。团队这时候再制定计划。
当然,如果你自告奋勇要提出这个理念,那是另外一回事。

那么对于我来说

简单说,他不是一个人的事,需要让团队内的人达成共知。
这种规约的设立,基本上是需要目标缓存业务开始之初就引入的。一般来说越早越好,而对我来说,只能说由于各种的不可抗力,我最后只能在当前项目之中放弃了对动缓存的概念。
因此,我将我的视野投入在了静缓存上。
然而我很失望的发现,对于当前项目来说,静缓存的可用之处是并不多的。
当前的项目前后端通讯方式,都已经是RESTFUL API了,简单来说,就是最基础的通讯原子数据。
对于这类型的数据,静缓存能使用的场景就很少了。
(说实话,我引入谁?引入商品的详情嘛?靠唯一索引查的东西,我实在想不出理由给他造一个缓存)
能引入的场景,似乎也只剩下了主页与查询页,热门商品评论等等**“不太好查”并且“实时性”**要求不高的数据了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值