消息生产者端使用 ScheduledExecutorService 来定期重置计数器,以实现限流

使用 ScheduledExecutorService 可以很容易地实现定时任务,比如每秒重置计数器来实现限流。下面是一个改进的示例,展示了如何在消息生产者端使用 ScheduledExecutorService 来定期重置计数器,以实现限流:

java
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

public class LimitedRateProducer {
private static final String TOPIC = “test-topic”;
private static final String TAG = “*”;
private static final long MAX_RATE = 100L; // 每秒最大发送速率
private static final long RESET_INTERVAL = 1000; // 重置计数器的时间间隔,单位毫秒
private final DefaultMQProducer producer;
private final AtomicLong counter = new AtomicLong(0);
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

public LimitedRateProducer() throws Exception {  
    producer = new DefaultMQProducer("limited-rate-producer-group");  
    producer.setNamesrvAddr("localhost:9876");  
    producer.start();  

    // 安排一个任务来每秒重置计数器  
    scheduler.scheduleAtFixedRate(() -> counter.set(0), RESET_INTERVAL, RESET_INTERVAL, TimeUnit.MILLISECONDS);  
}  

public void sendMessage(String content) throws Exception {  
    long currentRate = counter.incrementAndGet();  
    if (currentRate > MAX_RATE) {  
        // 超出限流速率,丢弃消息或执行其他策略  
        counter.decrementAndGet(); // 减少计数器,因为这条消息没有被发送  
        System.out.println("Message discarded due to rate limit.");  
        return;  
    }  

    Message msg = new Message(TOPIC, TAG, content.getBytes());  
    producer.send(msg);  
}  

public void shutdown() throws Exception {  
    producer.shutdown();  
    scheduler.shutdown(); // 关闭调度器,停止所有计划任务  
}  

public static void main(String[] args) throws Exception {  
    LimitedRateProducer producer = new LimitedRateProducer();  
    // 模拟发送消息  
    for (int i = 0; i < 1000; i++) {  
        producer.sendMessage("Hello RocketMQ " + i);  
        // 休眠一段时间来模拟发送间隔  
        Thread.sleep(10);  
    }  
    producer.shutdown(); // 关闭生产者和调度器  
}  

}
在这个示例中,我们创建了一个 ScheduledExecutorService 来定期重置 counter。scheduleAtFixedRate 方法用于安排一个固定频率执行的任务,这里我们设置每 RESET_INTERVAL 毫秒(即每秒)执行一次任务,任务的内容是简单地将 counter 设置为0。

代码注意事项:

  1. 异常处理

    • sendMessage 方法中,当调用 producer.send(msg) 时,应该捕获并处理可能抛出的异常。
    • shutdown 方法中,也需要处理 producer.shutdown()scheduler.shutdown() 可能抛出的异常。
  2. 资源关闭

    • shutdown 方法中,不仅要关闭 scheduler,还要确保 producer 也被正确关闭,并等待关闭操作完成。
    • 考虑使用 try-finally 块或 try-with-resources 语句来确保资源被释放。
  3. 并发安全

    • 虽然 AtomicLong 提供了线程安全的计数器操作,但如果限流逻辑变得更复杂,可能需要进一步考虑并发控制。
  4. 限流精度

    • 使用 ScheduledExecutorService 的定时任务进行限流可能不够精确,特别是在高并发场景下。如果精度要求较高,可能需要考虑使用其他限流算法或工具。
  5. 日志记录

    • 在限流逻辑中加入日志记录,有助于监控和调试。当消息被丢弃或限流逻辑被触发时,应该记录相关信息。

设计注意事项:

  1. 可扩展性

    • 如果未来需要调整限流策略或增加其他功能,设计应该考虑易于扩展和维护。
  2. 灵活性

    • 提供配置化支持,允许用户动态调整限流速率、重置间隔等参数。
  3. 健壮性

    • 考虑系统在各种异常情况下的表现,如网络故障、消息队列不可用等,确保系统能够优雅地处理这些情况。
  4. 性能考虑

    • 在高并发场景下,限流逻辑可能成为性能瓶颈。需要通过性能测试和调优来确保系统的性能。

安全性注意事项:

  1. 防止拒绝服务攻击(DoS)

    • 如果限流逻辑不当,恶意用户可能会利用它发起DoS攻击。因此,需要确保限流策略能够有效防止此类攻击。
  2. 敏感信息保护

    • 在日志记录和错误处理中,避免泄露敏感信息,如用户凭证、内部系统细节等。

测试注意事项:

  1. 单元测试

    • LimitedRateProducer 类进行单元测试,验证限流逻辑的正确性。
  2. 集成测试

    • 在实际环境中进行集成测试,确保限流逻辑与整个系统的其他部分协同工作。
  3. 性能测试

    • 在不同负载下进行性能测试,确保系统在高并发场景下能够保持稳定和高效的限流能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/559147.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入探究图像增强(C语言实现)

我们将从基础出发使用C语言进行图像处理与分析&#xff0c;重点讨论图像增强和平滑技术。图像增强技术旨在通过增加对比度、亮度和整体清晰度来改善图像的视觉质量。另一方面&#xff0c;图像平滑方法则用于减少噪声并减少图像中的突变&#xff0c;使图像更加均匀和视觉上吸引人…

利用二维码定位技术实现桌面机器人简易定位方案(上篇)

目录 1、前言2、二维码的定位标签识别原理3、生成定位标签3、基于定位标签的物体识别与定位 1、前言 机械手臂尤其是工业场景下大部分的应用是在一个平面&#xff08;桌面&#xff09;内完成一些抓取工作。一般可以用示教方式完成重复步骤。但是示教方式&#xff0c;对于一些活…

过氧化氢滴定方法可用的PFA器皿有哪些?

滴定液:KMnO4标准溶液 试液:H2O2商品液(3%)&#xff0c;H2SO4 (3.0mol/L ) 指示剂:酚酞指示剂 仪器:分析天平&#xff0c;PFA酸式滴定管50mL&#xff0c;PFA 移液管10mL/25mL、PFA 容量瓶250mL、PFA锥形瓶250mL 1、KMnO4标准溶液浓度的标定(见实验:高锰酸钾标准溶液的配制与…

记一次普通的单表查询sql优化,去掉文件排序

一现象&#xff1a; 有空观察了线上某个sql语句执行计划&#xff0c;发现在500多毫秒左右&#xff0c;打算进行下优化。 二步骤&#xff1a; 对查询列assessment_periodic_id、assessment_user_id、create_time添加了组合索引并指定了倒叙。加入create_time 使查询结果不需要在…

阿里云OSS 存储对象的注册与使用

目录 一、什么是阿里云OSS 二、 点击免费试用 2.1 选择第一个&#xff0c;点击免费试用 ​编辑 2.2 登录管理控制台 2.3 进入Bucket 2.4、在阿里云网站上的个人中心配置Accesskey,查询accessKeyId和accessKeySecret。 2.5、进入AccssKey管理页面应该会出现下图提示&…

通用大模型研究重点之五:llama family

LLAMA Family decoder-only类型 LLaMA&#xff08;Large Language Model AI&#xff09;在4月18日公布旗下最大模型LLAMA3&#xff0c;参数高达4000亿。目前meta已经开源了80亿和700亿版本模型&#xff0c;主要升级是多模态、长文本方面工作。 模型特点&#xff1a;采用标准的…

Java面试八股之Java异常处理完成后,Exception对象会发生什么变化

Java异常处理完成后&#xff0c;Exception对象会发生什么变化 这个题的难度在于&#xff0c;看到题之后可能不知道面试官想问什么。在面试中&#xff0c;如果实在没明白&#xff0c;可以让面试官再深入阐述一下。 Java异常处理完成后&#xff0c;Exception对象失去了程序中的…

自定义Blazor单文件Web程序端口

#接 上篇 Mysql快速迁移版的制作过程# 上一篇《Mysql8快速迁移版的制作过程》完成了快速迁移的数据库的准备&#xff0c;今天接着讲基于Blazor的Web程序快速迁移版的制作。 单文件发布的难点不在发布而是因为程序系统默认给了个5001的端口&#xff0c;而是如何能够让用户自定…

Leetcode 11.盛最多水的容器(暴力->双指针)

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 示例 …

Postman调用OpenApi接口

首先你需要科学上网。。。。。 请求方式&#xff1a;post 请求地址&#xff1a;https://api.openai.com/v1/chat/completions 请求头&#xff1a; Authorization : Bearer key Content-Type : application/json Body : { "messages": [{ "role": &quo…

【精简改造版】大型多人在线游戏BrowserQuest服务器Golang框架解析(1)——功能清单

1.匿名登录 2.服务连接 3.新手引导 4.随机出生点 5.界面布局 6.玩法帮助 7.NPC会话 8.成就系统 9.成就达成 10.用户聊天 11.战斗&信息展示 12.药水使用 13.副本传送 14.玩家死亡 15.超时断开

OpenHarmony 视图缩放组件—subsampling-scale-image-view

简介 深度缩放视图&#xff0c;图像显示&#xff0c;手势平移缩放双击等 效果图&#xff08;旋转、缩放、平移&#xff09; 下载安装 ohpm install ohos/subsampling-scale-image-view OpenHarmony ohpm 环境配置等更多内容&#xff0c;请参考如何安装 OpenHarmony ohpm 包 使…

Servlet第四篇【request对象常用方法、应用】

什么是HttpServletRequest HttpServletRequest对象代表客户端的请求&#xff0c;当客户端通过HTTP协议访问服务器时&#xff0c;HTTP请求头中的所有信息都封装在这个对象中&#xff0c;开发人员通过这个对象的方法&#xff0c;可以获得客户这些信息。 简单来说&#xff0c;要得…

mysql四种引擎区别

MySQL 提供了多种不同的数据库引擎&#xff0c;其中最常见的有 MyISAM、InnoDB、MEMORY 和 BLACKHOLE。这四个引擎分别有以下特点&#xff1a; 1. MyISAM MyISAM 是 MySQL 的默认引擎。它对于只有较少的修改、大量读取的应用场景具有良好的性能。它不支持事务处理&#xff0c;也…

理解字符串常量池(JVM)

大纲 思考 如何查看字符串常量池&#xff08;StringTable&#xff09;&#xff1f; 使用 jclasslib 插件打开字节码&#xff0c;选择 常量池 -> 显示所选 -> CONSTANT_String_info&#xff0c;左侧过滤后的内容即为字符串常量池 字符串常量池、方法区、永久代和元空间的…

Dynamic Wallpaper for Mac:动态壁纸让桌面更生动

Dynamic Wallpaper for Mac是一款为苹果电脑用户精心设计的动态壁纸软件&#xff0c;它以其丰富的功能和精美的壁纸库&#xff0c;为用户带来了更加生动和个性化的桌面体验。 Dynamic Wallpaper for Mac v17.8中文版下载 这款软件支持多种动态壁纸&#xff0c;用户可以根据自己…

unity学习(86)——细节优化

东西已经做出来了&#xff0c;现在需要的是优化&#xff0c;说得简单&#xff0c;做起来难。 1.122包的优化&#xff0c;避免重复创建&#xff01; 2.为何会出现一边动&#xff0c;一边不动的情况。重复登录后依旧是unity可以看到移动&#xff0c;但是exe那边看不到移动&#…

数据结构PT1——线性表/链表

1&#xff1a;顺序存储实现(数组实现) Data&#xff1a; a1 a2 .....ai ai1 .... an .... typedef struct LNode *List; //指向LNode的指针&#xff0c;这是typedef的&#xff0c;你可以随时声明&#xff0c;而不加typedef只是创建一个 struct LNode{ //结构体成员ElementT…

Vue.js------Vue组件基础

能够理解Vue组件概念和作用能够掌握封装创建组件能力能够使用组件之间通信能够完成todo案例 一.Vue组件创建和使用 1.折叠面板-实现多个 创建一个文件夹demo 具体步骤请参考vue.js---vue基础 ⚫ 解决方案: 采用vue提供的单.vue文件-组件方式来封装一套然后复用 在component…

Jackson 2.x 系列【24】Spring Web 集成

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. Spring Web3. Jackson2ObjectMapperBuilder4. Jackson2ObjectMapperFa…
最新文章