python守护进程 限制调用频率_解决推送每分钟六百次频率调用限制

1 packagecom.hsjry.plutus.customer.web;2

3 importlombok.extern.slf4j.Slf4j;4 importorg.springframework.scheduling.annotation.Scheduled;5 importorg.springframework.stereotype.Component;6 importorg.springframework.web.bind.annotation.RequestMapping;7 importorg.springframework.web.bind.annotation.RestController;8

9 importjava.util.Calendar;10 importjava.util.Date;11 importjava.util.concurrent.LinkedBlockingQueue;12 importjava.util.concurrent.atomic.AtomicInteger;13

14

15 /**

16 * 限流器 每分钟限制请求600次,用于解决推送,每分钟六百次的接口请求次数限制问题17 * @Auther: 屈艳锋18 * @Date: 2019/5/23 15:1219 */

20 @Component21 @RestController22 @Slf4j23 public classCurrentLimiter {24

25 /**

26 * 限流请求次数记录容器,用于记录前一分钟,当前分钟,后一分钟的请求次数27 */

28 static AtomicInteger[] limitRequestCountRecordArray = {new AtomicInteger(0), new AtomicInteger(0), new AtomicInteger(0)};29

30 /**

31 * 限流队列,用于存放超过请求次数限制的请求32 */

33 static LinkedBlockingQueue limitScheduleQueue = new LinkedBlockingQueue(1000);34

35

36 /**

37 * 定时任务,每逢五十秒时,将后一分钟的请求次数初始化为038 */

39 @Scheduled(cron = "0/50 * * * * ?")40 public voidinitNextMiniuteValue() {41

42 //限流容器长度

43 int limitArrayLength =limitRequestCountRecordArray.length;44

45 //获取当前分钟数据所在下标

46 int currentIndex = (int) (System.currentTimeMillis() / 60000) %limitArrayLength;47

48 //获取后一分钟数据所在下标

49 int nextIndex = 0;50 if (currentIndex < limitArrayLength - 1) {51 nextIndex = currentIndex + 1;52 }53

54 //将后一分钟的请求次数初始化为0

55 limitRequestCountRecordArray[nextIndex] = new AtomicInteger(0);56 log.info("执行是定时任务,当前分钟下标为{},请求次数为{}",currentIndex,limitRequestCountRecordArray[currentIndex].get());57 }58

59

60 /**

61 * 测试每分钟六百次限流62 *63 *@return

64 *@throwsInterruptedException65 */

66 @RequestMapping("/test")67 public String testLimiter() throwsInterruptedException {68

69 for (int i = 0; i < 1000; i++) {70

71 //获取当前分钟数数据所在限流容器的下标

72 int currentIndex = (int) (System.currentTimeMillis() / 60000) %limitRequestCountRecordArray.length;73

74 //如果超过阀值,则放入队列

75 if (limitRequestCountRecordArray[currentIndex].get() > 599) {76 limitScheduleQueue.put(i);77 } else{78 //当前分钟数数据加一

79 limitRequestCountRecordArray[currentIndex].incrementAndGet();80 log.info("{}分钟正常调用{}", getMinute(newDate()), i);81 }82

83 }84

85 if (limitScheduleQueue.size() > 0) {86 new Thread(this::limitHandler).start();87 }88 return "";89 }90

91

92 /**

93 * 限流处理94 *95 */

96 voidlimitHandler() {97

98 log.info("=========>当前时间:{}", getMinute(newDate()));99 for (int i = 0; i < limitScheduleQueue.size(); i++) {100

101 //获取当前分钟数数据所在限流容器的下标

102 int currentIndex = (int) (System.currentTimeMillis() / 60000) %limitRequestCountRecordArray.length;103

104 //如果超过阀值,则不处理

105 if (limitRequestCountRecordArray[currentIndex].get() > 599) {106 try{107 log.info("{}分钟已超过限制,休息一会,稍微继续~~~",getMinute(newDate()));108 Thread.sleep(60000);109 } catch(InterruptedException e) {110 }111 } else{112 //当前分钟数数据加一

113 limitRequestCountRecordArray[currentIndex].incrementAndGet();114 log.info("{}分钟正常调用中:{}", getMinute(newDate()), limitScheduleQueue.poll());115 }116

117 }118

119 if (limitScheduleQueue.size() > 0) {120 limitHandler();121 }122 }123

124 /**

125 * 返回当前分钟数126 *127 *@paramdate 日期128 *@return返回分钟129 */

130 public static intgetMinute(Date date) {131 Calendar calendar =Calendar.getInstance();132 calendar.setTime(date);133 returncalendar.get(Calendar.MINUTE);134 }135

136 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值