前言:6月底 公司录单的人比较多,由于先前的系统用的同步锁 ,我们是多服务实例,导致出现重复单号的问题,我想到的解决办法有两种 ,第一种是 Redis锁 第二种是自增key,下面实现的是用第二种方法 自增key 。

不选择Redis锁的原因:

  • 它获取锁的方式简单粗暴,获取不到锁直接不断尝试获取锁,比较消耗性能。
  • 另外来说的话,Redis 的设计定位决定了它的数据并不是强一致性的,在某些极端情况下,可能会出现问题。锁的模型不够健壮。
  • 即便使用 Redlock 算法来实现,在某些复杂场景下,也无法保证其实现 100% 没有问题,关于 Redlock 的讨论可以看 How to do distributed locking。
  • Redis 分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能。

1.Redis自增key 的好处

  • 原子性(atomicity):一个事务是一个不可分割的最小工作单位,事务中包括的诸操作要么都做,要么都不做。
  • Redis所有单个命令的执行都是原子性的,这与它的单线程机制有关;
  • Redis命令的原子性使得我们不用考虑并发问题,可以方便的利用原子性自增操作
  • 简单解释就是你的服务即使是多机器多进程的,incr也能保证每次返回的结果不会出现相同的值.

2.逻辑梳理

  • Redis 获取Key自增次数 每次+1
  • 如果不存在key 默认值设置为30000
  • 截取数据 返回

3.代码实现:

    /*** 此方法只适用于************号和*****************号生成            * @param id 序列主键类型:BA/AJ等* @return*/@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)public synchronized String createNumberBAandAJ(String id) {//Redis 获取Key自增次数 每次+1String key="case:GenerateEnum:"+id;Long increment = redisTemplate.opsForValue().increment(key, 1);//如果不存在key  默认值设置为30000  方便区分与数据库字段不相同if(1 == increment ){increment = redisTemplate.opsForValue().increment(key, 30000);}//redisTemplate.boundValueOps("success").get(0, -1)//截取数据String s = "000000" + increment;s = s.substring(s.length() - 6);log.info("截取后的数据================>"+s);return s;}

4.总结:
在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试。这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量冲击而崩溃。对于系统崩溃带来的后果,显然还是拒绝一部分请求更能被维护者所接受。
而在各种限流中,除了系统自身设计的带锁机制的计数器外,利用Redis实现显然是一种既高效安全又便捷方便的方式。

5.redis 的incr原理

  • Redis Incr 命令将 key 中储存的数字值增一。
  • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
  • 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
  • 本操作的值限制在 64 位(bit)有符号数字表示之内。

计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令。

比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可。

比如用户名是 peter ,点击时间是 2012 年 3 月 22 日,那么执行命令 INCR peter::2012.3.22 。

可以用以下几种方式扩展这个简单的模式:

  1. 可以通过组合使用 INCR 和 EXPIRE ,来达到只在规定的生存时间内进行计数(counting)的目的。
  2. 客户端可以通过使用 GETSET 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 GETSET 命令。
  3. 使用其他自增/自减操作,比如 DECR 和 INCRBY ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。

学习如逆水行舟不进则退,记录问题,增加经历。

redis 的incr 高并发 原子性计数器相关推荐

  1. mysql点击计数器_MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能...

    MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: 5338 Date: 2014-03-29 23:30:42 Power By 李轩Lane TagMysql计数器高 ...

  2. 面试官:为什么单线程的Redis可以实现高并发访问

    背景 上回说到小枫在接受面试官的拷打,所幸第一个问题回答的还不错,因此面试官对于小枫的初步印象还行.我们接着来看看小枫是怎么和面试官继续过招的吧,他还能扛得住面试官几个连环炮呢? 面试官考察目的分析 ...

  3. 利用Redis锁解决高并发问题

    利用Redis锁解决高并发问题 参考文章: (1)利用Redis锁解决高并发问题 (2)https://www.cnblogs.com/yszr/p/11698696.html 备忘一下.

  4. SpringBoot+Redis+Cookies实现高并发的购物车

    案例实战:SpringBoot+Redis+Cookies实现高并发的购物车 步骤1:代码逻辑 /*** 添加购物车*/@PostMapping(value = "/addCart" ...

  5. java redis队列_redis队列实现高并发怎么用?Java如何使用redis队列解决高并发?

    小伙伴们大家好,不知道你们有没有在Java开发中遇到redis队列高并发,这个问题让你很头疼,今天小编就来讲解一下在Java中遇到redis队列高并发了,到底该怎么办. 高并发的业务场景: 我们做商品 ...

  6. Redis锁解决高并发问题

    Redis锁解决高并发问题 redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动. redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们 ...

  7. SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀

    SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀 提示:以下是本篇文章正文内容,下面案例可供参考 一.软件安装 1.安装RabbitMQ docker安装:docker安装R ...

  8. Redis多容器高并发场景 , 设置缓存的时候,要考虑多容器加锁的场景。(incr计数和redis分布式锁区别)

    1.设置缓存的时候,要考虑多容器加锁的场景. (1)场景,短信回执场景,会有二次回执的情况,但是我们只处理一次回执的消息体,如何不处理二次回执呢? // 队列中有数据且容量未达到100,可继续放入队列 ...

  9. 【高并发】Redis如何助力高并发秒杀系统?看完这篇我彻底懂了!!

    秒杀业务 在电商领域,存在着典型的秒杀业务场景,那何谓秒杀场景呢.简单的来说就是一件商品的购买人数远远大于这件商品的库存,而且这件商品在很短的时间内就会被抢购一空.比如每年的618.双11大促,小米新 ...

最新文章

  1. Windows性能分析器概述(一)
  2. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)...
  3. Python正则表达式的7个使用典范
  4. java 一个大事务下的新增、修改、查询_重新学习Mysql数据库8:MySQL的事务隔离级别实战...
  5. context:component-scan/和mvc:annotation-driven/的区别
  6. MAD huashi
  7. c ++明明的随机数_从列表C ++程序中随机建议电影
  8. SilverLight之我见
  9. Spring Boot文档阅读笔记-构建SOAP的web Service Client
  10. Android学习_ContentProvider和Uri
  11. win10QQ语音无法使用麦克风
  12. 液晶面板价格继续下跌,32英寸平板电视或跌破500元
  13. win7安装python3.8失败_Python3 | Win7系统下无法安装问题解决
  14. Mysql常见面试题(陆续更新中)...
  15. 大数据-什么是大数据?大数据的相关概念
  16. PHP设计模式(2) -创建型模式
  17. 星球前线 | Libra最大的竞争对手是什么?Calibra高管给出答案
  18. 毕业设计 - 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题
  19. 大地测量学转D3D第一篇博客
  20. 小米手机如何设置默认浏览器,这2个方法值得收藏

热门文章

  1. Elasticsearch 学习(二).实战使用
  2. java 最短遍历路径_凯文培根游戏的最短路径图遍历
  3. filament 5 Use IBL
  4. LTE学习笔记四:OFDM
  5. python conda安装与使用教程
  6. TIM定时器_CNT_ARR_PSC_CRR
  7. sse服务器推送性能,SSE 服务端向客户端推送
  8. MySQL中where 1=1真的会影响性能么?
  9. android WebView加载视频只有声音没有画面
  10. java 返回ro,错误retrofit rxjava优雅的处理服务器返回异常、错误