博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单的幂等工具类实现
阅读量:6844 次
发布时间:2019-06-26

本文共 3133 字,大约阅读时间需要 10 分钟。

一个简单的幂等工具类

在日常的工作中,业务的去重幂等场景属于比较常见的需求,一般来讲简单的幂等工具类可以基于内存或者基于redis进行,本篇简单介绍下,如何使用Guava的缓存来实现一个幂等工具类

I. 基本思路与实现

利用Guava的内存缓存来缓存,如果执行完毕,则在缓存中添加一个标识,每次执行之前,判断是否执行过,从而实现简单的幂等逻辑

1. 基本实现

基于此,一个简单的工具来就出炉了

public static final String NOT_HIT_TAG = "UNHIT_TAG";private static LoadingCache
idempotentCache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).build(new CacheLoader
() { @Override public Object load(String key) throws Exception { return NOT_HIT_TAG; }});public static Object getObject(String uuid) { return idempotentCache.getUnchecked(uuid);}复制代码

上面的代码比较简单,这个幂等工具类,key为唯一标识,value为上次计算的结果,因此在下次再次执行时,直接拿这个结果即可,适用于需要获取计算结果作为他用的业务场景中。那么在实际使用中,直接这么用是否可行?

答案却是不行,在实际使用的时候,有几个地方需要注意

  • 如果某次计算结果返回的null怎么办?
  • 内存是否会爆掉?

2. null值问题

针对返回结果为null的场景,也好解决,就是利用一个符号来代替null,简单的变形如下

public static final String NOT_HIT_TAG = "UNHIT_TAG";public static final String NULL_TAG = "NULL_TAG";private static LoadingCache
idempotentCache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).build(new CacheLoader
() { @Override public Object load(String key) throws Exception { return NOT_HIT_TAG; } });public static Object getObject(String uuid) { Object obj = idempotentCache.getUnchecked(uuid); if (obj instanceof String) { if (NULL_TAG.equals(obj)) { return null; } } return obj;}public static void putObject(String uuid, Object val) { if (val == null) { val = NULL_TAG; } idempotentCache.put(uuid, val);}复制代码

在上面使用中,有一点需要注意,在取出数据之后,首先判断下是否为未命中状态?为什么未命中要这么干?而言看博文

3. 内存问题

虽然上面设置了失效时间为3min,但在jdk8的场景下,很容易发现内存疯狂上涨,不见到有回收? why?这块可能与gauva的内存回收机制有关系,因为jdk8取消了永久代,使用了元空间,当没有设最大值时,会一直上涨,使用系统的内存

简单的解决方案就是主动回收掉无效的数据

public static final String NOT_HIT_TAG = "UNHIT_TAG";public static final String NULL_TAG = "NULL_TAG";private static LoadingCache
idempotentCache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).build(new CacheLoader
() { @Override public Object load(String key) throws Exception { return NOT_HIT_TAG; } });public static Object getObject(String uuid) { Object obj = idempotentCache.getUnchecked(uuid); if (obj instanceof String) { if (NULL_TAG.equals(obj)) { return null; } } return obj;}public static void putObject(String uuid, Object val) { if (val == null) { val = NULL_TAG; } idempotentCache.put(uuid, val);}public static void remove(String uuid) { idempotentCache.invalidate(uuid);}public static void registerScheduleClearTask() { ScheduledExecutorService task = Executors.newSingleThreadScheduledExecutor(new DefaultThreadFactory("idempotent")); task.scheduleAtFixedRate(() -> idempotentCache.cleanUp(), 1, 1, TimeUnit.MINUTES);}复制代码

II. 其他

1. : https://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

  • 微博地址:
  • QQ: 一灰灰/3302797840

3. 扫描关注

转载地址:http://ovdul.baihongyu.com/

你可能感兴趣的文章
Exchange2003 反垃圾邮件之一
查看>>
The page cannot be displayed
查看>>
三层交换VLAN配置
查看>>
监控运维系统实施方案--监控对象信息收集阶段
查看>>
WINDOWS和LINUX下带时间的PING包监控脚本
查看>>
RHEL6入门系列之九,常用命令2
查看>>
Exchange数据保护最佳实践
查看>>
突破360防黑加固添加用户
查看>>
数据仓库建模方法初步
查看>>
Active Directory 回收站配置篇
查看>>
ubuntu 11.10 体验
查看>>
MS UC 2013-0-虚拟机-标准化-部署-2-模板机-制作-5
查看>>
隐藏nginx、apache与php版本号
查看>>
【STM32 .Net MF开发板学习-08】远程PLC读写控制
查看>>
Lync 小技巧-12-同台服务器删除Lync Server 2010安装Lync Server 2013
查看>>
【STM32 .Net MF开发板学习-17】Wifi遥控智能小车
查看>>
做程序,要“专注”和“客观”
查看>>
运维常用表格
查看>>
6.VMware View 4.6安装与部署-view桌面克隆与分配
查看>>
Azure恢复服务-DPM联机备份SQL数据库
查看>>