在使用redisson消息订阅时,我针对门店商品库存减扣进行订阅的操作(在这里一个商品一个监听队列),当正式投入生产时,发现一直再报Subscribe timeout: (" + timeout + "ms). Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.的错误,索性根据提示翻了翻源码看看原因:

在redisson里先关注一个类:RedisPubSubConnection该类继承自RedisConnection,根据名字我们可知它是一个典型的发布与订阅的类。那么在redisson使用时,会使用PubSubConnectionEntry进行一次包装:

    public class PubSubConnectionEntry {private final AtomicInteger subscribedChannelsAmount;private final RedisPubSubConnection conn;private final ConcurrentMap<ChannelName, SubscribeListener> subscribeChannelListeners = new ConcurrentHashMap<ChannelName, SubscribeListener>();private final ConcurrentMap<ChannelName, Queue<RedisPubSubListener<?>>> channelListeners = new ConcurrentHashMap<ChannelName, Queue<RedisPubSubListener<?>>>();public PubSubConnectionEntry(RedisPubSubConnection conn, int subscriptionsPerConnection) {super();this.conn = conn;this.subscribedChannelsAmount = new AtomicInteger(subscriptionsPerConnection);}//.....省略其他代码 }

在这里我们可以看到其有一个比较重要的属性 subscribedChannelsAmount,而这个值就是通过PublishSubscribeService进行调用的:

        private void connect(final Codec codec, final ChannelName channelName,final RPromise<PubSubConnectionEntry> promise, final PubSubType type, final AsyncSemaphore lock, final RedisPubSubListener<?>... listeners) {//....RedisPubSubConnection conn = future.getNow();final PubSubConnectionEntry entry = new PubSubConnectionEntry(conn, config.getSubscriptionsPerConnection());entry.tryAcquire();//....}

那么此属性就是根据config的subscriptionsPerConnection里设置的,那么此值就代表了每个连接的最大订阅数。当tryAcqcurie的时候会减少这个数量:

      public int tryAcquire() {while (true) {int value = subscribedChannelsAmount.get();if (value == 0) {return -1;}if (subscribedChannelsAmount.compareAndSet(value, value - 1)) {return value - 1;}}}

如果当此值为0时,那么会重新获取一个可用的连接,代码如下:

     int remainFreeAmount = freeEntry.tryAcquire();if (remainFreeAmount == -1) {throw new IllegalStateException();}final PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, freeEntry);if (oldEntry != null) {freeEntry.release();freePubSubLock.release();subscribe(channelName, promise, type, lock, oldEntry, listeners);return;}if (remainFreeAmount == 0) {freePubSubConnections.poll();}freePubSubLock.release();

如果此时没有可用的连接的话,恐怕此次操作就会等待新的连接直至超时,超时了就报上述的错误了,不过根据提示。我们此时的解决办法是增大subscriptionsPerConnection或者subscriptionConnectionPoolSize的值。当我们使用springboot时可以通过设置spring.redis.redisson.config(具体设置请参考官网)来指定redisson的配置文件或者重新创建RedissonClient:

            @Bean(destroyMethod = "shutdown")public RedissonClient redisson(RedissonProperties redissonProperties, RedisProperties redisProperties) throws IOException {Config config = new Config();String prefix = "redis://";Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");if (method != null && (Boolean) ReflectionUtils.invokeMethod(method, redisProperties)) {prefix = "rediss://";}config.useSingleServer().setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()).setConnectTimeout(30000).setSubscriptionsPerConnection(5000) //在这里指定数目.setDatabase(redisProperties.getDatabase()).setPassword(redisProperties.getPassword());return Redisson.create(config);}

转载于:https://www.cnblogs.com/niechen/p/10845459.html

使用redisson时关于订阅数的问题相关推荐

  1. 英特尔核显运行opengl时的帧数过高或过低问题,opengl帧数问题

    我相信不止我一个人在学习OpenGL时遇到了这些问题,国内外的相关资料或解决方法很难找,也仅在glfw论坛里找到了几个提出这个问题的人,并摸索到了莫名其妙的解决方法,具体原因也没弄清楚. 这里也希望如 ...

  2. redisson究极爽文-手把手带你实现redisson的发布订阅,消息队列,延迟队列(死信队列),(模仿)分布式线程池

    参考资料 :分布式中间件实战:java版 (书籍), 多线程视频教程(视频)- 项目启动环境 导入依赖 <parent><groupId>org.springframework ...

  3. mysql分页时获得行数_MySQL分页取得总行数新法

    SELECT语句中经常用到LIMIT限制返回行数有时候可能想要知道如果没有LIMIT会返回多少行,比如做分页的时候,但又不想再执行一次相同语句. 我们要怎么做呢? 如下 在SELECT查询中包含 SQ ...

  4. Hive 观看时长秒数、毫秒数转化为时分秒格式

    程序的计时元年是1970-01-01 08:00:00,为了方便截取时间,采用1970-01-01 01:00:00, 时间戳毫秒数为-28800000,秒数为-28800 在hive中转化为时间格式 ...

  5. python两个数相加时_两数相加 leetcode Python

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  6. python计算区间内偶数和_Python 计算当真因子个数为偶数个时为幸运数,计算区间内幸运数之和...

    晚饭后朋友发来个问题,正好无事做,动手写了一下 若一个正整数有偶数个不同的真因子,则称该数为幸运数.如4含有2个真因子为 1 和 2 .故4是幸运数.求[2,100]之间的全部幸运数之和. 常规思路 ...

  7. js 效果显示 时分秒 进行 数秒 主要是逻辑处理

    var InterTimeValObj; var time_id_ss = 0; var time_id_mm = 0; var time_id_HH = 0; //启动 function showT ...

  8. php时分获取秒数,javascript与php时/分/秒与秒数互转

    javascript: /* 时间转换成秒 */ function time_to_second(time){ var arr = time.split(':') var hour = arr[0]? ...

  9. 为什么SQL用UPDATE语句更新时更新行数会多3行有触发器有触发器有触发器有触发器有触发器有触发器...

    update明显更新就一行,但是结果显示更新多行. 原因是有触发器有触发器有触发器有触发器有触发器有触发器有触发器有触发器有触发器 转载于:https://www.cnblogs.com/qqhfen ...

最新文章

  1. jsp截取字符串前几位_7. Python3轻食丨丛林里的野蛮生长:无处不在的字符串(一)
  2. python的工资为什么这么低-你拿着3k的工资,不明白为什么别人年薪 200万
  3. 我为NET狂-----大前端专帖
  4. 干货!各国圣诞放假时刻表!
  5. SpringCloud学习之运行第一个Eureka程序
  6. ASP.NET中实现模版的动态加载
  7. SPOJ4487(Splay树)
  8. java ee 8 api_Java EE 8安全性API:概述
  9. 【转】VS2005 CTP 版本这个CTP是什么意思
  10. 用 toto 3分钟建轻量级博客
  11. python 反射机制
  12. VC2010 MFC文档类菜单快捷键无法加载问题
  13. Access、Trunk、Hybrid三种端口收发规则以及tagged端口和untagged端口的区别
  14. AUTOCAD——拉伸
  15. 2021年起重机司机(限桥式起重机)考试题及起重机司机(限桥式起重机)免费试题
  16. mp4播放器下载android,MP4视频播放器最新版下载_MP4视频播放器正式版_MP4视频播放器9.3-华军软件园...
  17. storm源码分析研究(五)
  18. mysql中dateformat用法,MySQL date_format()函数
  19. 关于RAID1的读写问题
  20. FL Studio水果编曲软件V20.0.3.542密钥序列号版

热门文章

  1. WPF:Documents文档--Annomation批注(3)
  2. [Usaco2009 Open]工作安排Job
  3. 关于整合spring+mybatis 第三种方式-使用注解
  4. linux 下查mac
  5. Duanxx的图像处理学习: 透视变换(一)
  6. Windows/Linux下引用jar包,并用javac/java编译运行
  7. 重启服务才可连接BOOT服务器
  8. Java代码使用Spark on Yarn 方式提交任务到带Kerberos认证的Hadoop集群
  9. ospf和pat及nat的配置
  10. 69.2. wget - retrieves files from the web