springBoot对接多个mq并且实现延迟队列---未完待续

news2024/11/24 1:57:32

mq调用流程

创建消息转换器

package com.wd.config;

import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqMessageConvertConfig {

    /**
     * 公共的消息转换器
     *
     * @return MessageConverter
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

}

创建exchange交换机:普通交换机、延迟交换机、死信交换机

package com.wd.config;

import org.springframework.amqp.core.DirectExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqExchangeConfig {

    public static final int DELAY_TIME = 20 * 1000;

    /**
     * 普通交换机名称
     */
    public static final String EXCHANGE_NAME = "wd_exchange";

    /**
     * 延迟交换机名称
     */
    public static final String DELAY_EXCHANGE_NAME = "wd_delay_exchange";

    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE_NAME = "wd_dead_exchange";

    @Bean
    public DirectExchange exchange() {
        return new DirectExchange(EXCHANGE_NAME, true, false);
    }

    @Bean
    public DirectExchange delayExchange() {
        return new DirectExchange(DELAY_EXCHANGE_NAME, true, false);
    }

    @Bean
    public DirectExchange deadExchange() {
        return new DirectExchange(DEAD_EXCHANGE_NAME, true, false);
    }
}

创建master的connection

package com.wd.config.master;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqMasterConnectionConfig {

    @Value("${rabbitmq.master.vhost}")
    private String vhost;

    @Value("${rabbitmq.master.addresses}")
    private String addresses;

    @Value("${rabbitmq.master.username}")
    private String username;

    @Value("${rabbitmq.master.password}")
    private String password;

    @Bean
    public ConnectionFactory masterConnectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setAddresses(addresses);
        cachingConnectionFactory.setVirtualHost(vhost);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        return cachingConnectionFactory;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(@Qualifier("masterConnectionFactory") ConnectionFactory masterConnectionFactory,
                                         MessageConverter messageConverter)
    {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(masterConnectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
    }

}

创建slave的connection

package com.wd.config.slave;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqSlaveConnectionConfig {

    @Value("${rabbitmq.slave.vhost}")
    private String vhost;

    @Value("${rabbitmq.slave.addresses}")
    private String addresses;

    @Value("${rabbitmq.slave.username}")
    private String username;

    @Value("${rabbitmq.slave.password}")
    private String password;

    @Bean
    public ConnectionFactory slaveConnectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setAddresses(addresses);
        cachingConnectionFactory.setVirtualHost(vhost);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        return cachingConnectionFactory;
    }

    @Bean
    public RabbitTemplate slaveRabbitTemplate(@Qualifier("slaveConnectionFactory") ConnectionFactory slaveConnectionFactory,
                                         MessageConverter messageConverter)
    {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(slaveConnectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
    }

}

创建队列A:  分为普通队列、延迟队列、死信队列

package com.wd.config.queue;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static com.wd.config.RabbitmqExchangeConfig.DEAD_EXCHANGE_NAME;
import static com.wd.config.RabbitmqExchangeConfig.DELAY_TIME;

@Configuration
public class QueueAConfig {

    private static final String QUEUE_A_NAME = "wd_queue_a";

    private static final String DELAY_QUEUE_A_NAME = "wd_delay_queue_a";

    private static final String DEAD_QUEUE_A_NAME = "wd_dead_queue_a";

    private static final String QUEUE_A_ROUTING_KEY = "queue_A_routing_key";

    private static final String DELAY_QUEUE_A_ROUTING_KEY = "delay_queue_a_routing_key";

    private static final String DEAD_LETTER_QUEUE_A_ROUTING_KEY = "dead_letter_queue_A_routing_key";

    @Bean
    public Queue queueA() {
        return new Queue(QUEUE_A_NAME, true);
    }

    @Bean
    public Binding queueABinding(@Qualifier("queueA") Queue queueA,
                                 @Qualifier("exchange") DirectExchange exchange) {
        return BindingBuilder.bind(queueA).to(exchange).with(QUEUE_A_ROUTING_KEY);
    }

    @Bean
    public Queue delayQueueA() {
        Map<String, Object> args = new HashMap<>();
        //设置延迟队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        //设置延迟队列绑定的死信路由键
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_A_ROUTING_KEY);
        //设置延迟队列的 TTL 消息存活时间
        args.put("x-message-ttl", DELAY_TIME);
        return new Queue(DELAY_QUEUE_A_NAME, true, false, false, args);
    }

    @Bean
    public Binding delayQueueABinding(@Qualifier("delayQueueA") Queue delayQueueA,
                                      @Qualifier("delayExchange") DirectExchange delayExchange) {
        return BindingBuilder.bind(delayQueueA).to(delayExchange).with(DELAY_QUEUE_A_ROUTING_KEY);
    }

    @Bean
    public Queue deadQueueA() {
        return new Queue(DEAD_QUEUE_A_NAME, true);
    }

    @Bean
    public Binding deadQueueABinding(@Qualifier("deadQueueA") Queue deadQueueA,
                                     @Qualifier("deadExchange") DirectExchange deadExchange) {
        return BindingBuilder.bind(deadQueueA).to(deadExchange).with(DEAD_LETTER_QUEUE_A_ROUTING_KEY);
    }
}

创建队列B: 分为普通队列、延迟队列、死信队列

package com.wd.config.queue;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static com.wd.config.RabbitmqExchangeConfig.DEAD_EXCHANGE_NAME;
import static com.wd.config.RabbitmqExchangeConfig.DELAY_TIME;

@Configuration
public class QueueBConfig {
    private static final String QUEUE_B_NAME = "wd_queue_b";

    private static final String DELAY_QUEUE_B_NAME = "wd_delay_queue_b";

    private static final String DEAD_QUEUE_B_NAME = "wd_dead_queue_b";

    private static final String QUEUE_B_ROUTING_KEY = "queue_b_routing_key";

    private static final String DELAY_QUEUE_B_ROUTING_KEY = "delay_queue_b_routing_key";

    private static final String DEAD_LETTER_QUEUE_B_ROUTING_KEY = "dead_letter_queue_b_routing_key";

    @Bean
    public Queue queueB() {
        return new Queue(QUEUE_B_NAME, true);
    }

    @Bean
    public Binding queueBBinding(@Qualifier("queueB") Queue queueB,
                                 @Qualifier("exchange") DirectExchange exchange) {
        return BindingBuilder.bind(queueB).to(exchange).with(QUEUE_B_ROUTING_KEY);
    }

    @Bean
    public Queue delayQueueB() {
        Map<String, Object> args = new HashMap<>();
        //设置延迟队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        //设置延迟队列绑定的死信路由键
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_B_ROUTING_KEY);
        //设置延迟队列的 TTL 消息存活时间
        args.put("x-message-ttl", DELAY_TIME);
        return new Queue(DELAY_QUEUE_B_NAME, true, false, false, args);
    }

    @Bean
    public Binding delayQueueBBinding(@Qualifier("delayQueueB") Queue delayQueueB,
                                      @Qualifier("delayExchange") DirectExchange delayExchange) {
        return BindingBuilder.bind(delayQueueB).to(delayExchange).with(DELAY_QUEUE_B_ROUTING_KEY);
    }

    @Bean
    public Queue deadQueueB() {
        return new Queue(DEAD_QUEUE_B_NAME, true);
    }

    @Bean
    public Binding deadQueueABinding(@Qualifier("deadQueueB") Queue deadQueueB,
                                     @Qualifier("deadExchange") DirectExchange deadExchange) {
        return BindingBuilder.bind(deadQueueB).to(deadExchange).with(DEAD_LETTER_QUEUE_B_ROUTING_KEY);
    }

}

创建队列C: 分为普通队列、延迟队列、死信队列

package com.wd.config.queue;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static com.wd.config.RabbitmqExchangeConfig.DEAD_EXCHANGE_NAME;
import static com.wd.config.RabbitmqExchangeConfig.DELAY_TIME;

@Configuration
public class QueueCConfig {
    private static final String QUEUE_C_NAME = "wd_queue_c";

    private static final String DELAY_QUEUE_C_NAME = "wd_delay_queue_c";

    private static final String DEAD_QUEUE_C_NAME = "wd_dead_queue_c";

    private static final String QUEUE_C_ROUTING_KEY = "queue_c_routing_key";

    private static final String DELAY_QUEUE_C_ROUTING_KEY = "delay_queue_c_routing_key";

    private static final String DEAD_LETTER_QUEUE_C_ROUTING_KEY = "dead_letter_queue_c_routing_key";

    @Bean
    public Queue queueC() {
        return new Queue(QUEUE_C_NAME, true);
    }

    @Bean
    public Binding queueCBinding(@Qualifier("queueC") Queue queueC,
                                 @Qualifier("exchange") DirectExchange exchange) {
        return BindingBuilder.bind(queueC).to(exchange).with(QUEUE_C_ROUTING_KEY);
    }

    @Bean
    public Queue delayQueueC() {
        Map<String, Object> args = new HashMap<>();
        //设置延迟队列绑定的死信交换机
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        //设置延迟队列绑定的死信路由键
        args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_C_ROUTING_KEY);
        //设置延迟队列的 TTL 消息存活时间
        args.put("x-message-ttl", DELAY_TIME);
        return new Queue(DELAY_QUEUE_C_NAME, true, false, false, args);
    }

    @Bean
    public Binding delayQueueCBinding(@Qualifier("delayQueueC") Queue delayQueueC,
                                      @Qualifier("delayExchange") DirectExchange delayExchange) {
        return BindingBuilder.bind(delayQueueC).to(delayExchange).with(DELAY_QUEUE_C_ROUTING_KEY);
    }

    @Bean
    public Queue deadQueueC() {
        return new Queue(DEAD_QUEUE_C_NAME, true);
    }

    @Bean
    public Binding deadQueueCBinding(@Qualifier("deadQueueC") Queue deadQueueC,
                                     @Qualifier("deadExchange") DirectExchange deadExchange) {
        return BindingBuilder.bind(deadQueueC).to(deadExchange).with(DEAD_LETTER_QUEUE_C_ROUTING_KEY);
    }

}

创建master的消息监听RabbitListenerContainerFactory

后续使用注解 @RabbitListener 时指定ListenerContainerFactory

@RabbitListener(queues = DEAD_LETTER_QUEUE_B, containerFactory = "masterListenerContainerFactory")
package com.wd.config.master;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqMasterListenerConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory masterListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                                         @Qualifier(value = "masterConnectionFactory") ConnectionFactory masterConnectionFactory,
                                                                         MessageConverter messageConverter) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        // 设置消息转换器
        factory.setMessageConverter(messageConverter);
        // 关闭自动ACK
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        configurer.configure(factory, masterConnectionFactory);
        return factory;
    }
}

创建slave的消息监听RabbitListenerContainerFactory

后续使用注解 @RabbitListener 时指定ListenerContainerFactory

@RabbitListener(queues = DEAD_LETTER_QUEUE_B, containerFactory = "slaveListenerContainerFactory")
package com.wd.config.slave;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitmqSlaveListenerConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory slaveListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                                         @Qualifier(value = "slaveConnectionFactory") ConnectionFactory slaveConnectionFactory,
                                                                         MessageConverter messageConverter) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        // 设置消息转换器
        factory.setMessageConverter(messageConverter);
        // 关闭自动ACK
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        configurer.configure(factory, slaveConnectionFactory);
        return factory;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度解析React 18应用性能提升

众所周知,React 18 引入的一个重要特性就是并发功能,从根本上改变了 React 应用程序的渲染方式。本文将带大家一同探讨这些最新功能的具体作用,特别是如何提高应用程序性能。 一、主线程与长任务 当我们在浏览器中运行 JavaScript 时,JS 引擎会在单线程环境下执行代码内容…

Kubernetes基础(二)-Headless Service

1 简介 Headless Service是一种特殊的服务类型&#xff0c;它不会分配虚拟 IP&#xff0c;而是直接暴露所有 Pod 的 IP 和 DNS 记录。这客户端可以直接访问 Pod IP 地址&#xff0c;并使用这些 IP 地址进行负载均衡。 Headless Services是一种特殊的service&#xff0c;其spec…

封装了一个中间放大效果的iOS轮播视图

效果图 计算逻辑 设定在中间展示的size&#xff0c;即正常size&#xff0c;然后设置水平和竖直方向上的margin, 在view的origin和scrollView的contentoffset相等的时候&#xff0c;即 视图处在正中间的时候&#xff0c;最大&#xff0c;然后通过计算其他视图的origin和scrollV…

计算机基础 堆和栈

首先我们需要知道的是栈和堆是两种数据结构 1.栈和堆的定义 栈&#xff1a;是一种先进后出的数据结构&#xff0c;是一种线性结构 堆是一种树形结构&#xff0c;是一颗完全二叉树&#xff0c; 其存储的元素可以通过指针或引用访问 最大堆【大根堆】 &#xff1a;堆中的每一个…

js-cookie使用 js深度克隆(判断引用类型是数组还是对象的方法)

cookie和深度拷贝的使用 1、js-cookie使用2、js深度克隆 1、js-cookie使用 前端的本地存储分为 localstorage、sesstionstorage、cookie 但是咱们有时候需要做7天免登录的需求时&#xff0c;选择 cookie 作为前端的本地存储是在合适不过的了 直接操作 cookie 可以&#xff0c; …

ModbusTCP 转 Profinet 主站网关在博图配置案例

兴达易控ModbusTCP转Profinet网关&#xff0c;在 Profinet 侧做为 Profinet 主站控制器&#xff0c;接 Profinet 设备&#xff0c;如伺服驱动器&#xff1b;兴达易控ModbusTCP 和 Profinet网关在 ModbusTCP 侧做为 ModbusTCP 从站&#xff0c;接 PLC、上位机、wincc 屏等。 拓扑…

Spring事务1+入门案例(简约银行转账)

0、事务基础概念 1.事务角色&#xff1a; 2.事务相关配置 一、配置文件的书写 1.JDBC配置文件 public class JdbcConfig {Value("${jdbc.driver}")private String driver;Value("${jdbc.url}")private String url;Value("${jdbc.username}")p…

win11安装h3c lab无法启动putty终端的解决方法

文章目录 问题记录作者自己的解决方法第一步&#xff1a;安装MobaXterm第二步&#xff1a;修改h3c lab的终端工具 问题记录 win11可以同时安装vm、virtualBox、typer-v安装&#xff0c;因为在最新的系统中已经兼容但是可能出现win11安装h3c lab无法启动putty终端的问题&#x…

数据结构_顺序表_尾插、尾删、头插、头删(附带详解)

文章目录 前言一. 线性表二. 顺序表 - - - 数组2.1 什么是顺序表2.2 顺序表一般可以分为2.2.1 静态顺序表&#xff08;使用定长数组存储元素&#xff09;2.2.2 动态顺序表&#xff1a;使用动态开辟的数组存储2.2.3 顺序表的接口实现 三. SeqList.c 中各个接口的实现。3.1 初始化…

Java实现Modbus Tcp协议读写模拟工具数据

标题 前言一、读写模拟工具中数据(1) 定义Controller层(2) 定义Service层实现 二、调试(1) 读数据(2) 向寄存器写单个数据(3) 向寄存器写多个数据 前言 参考文章&#xff1a;https://www.cnblogs.com/ioufev/p/10831289.html 该文中谈及常见的几种读取设备数据实现&#xff0…

无硬盘的版本 1099,14寸笔记本,而且无硬盘的,特别有有意思,可以自己购买个硬盘,安装linux系统或者windows。

1&#xff0c;千元笔记本&#xff0c;金属外壳 有人进行评测了&#xff1a; https://www.bilibili.com/video/BV1Td4y1K7Cp 1499元的全新笔记本&#xff0c;有什么猫腻&#xff1f; 看了下价格&#xff0c;现在还优惠400&#xff0c;变成了1099。 https://item.jd.com/100851…

Django — 请求和响应

目录 一、请求1、概念2、请求参数方式分类3、案例3.1、URL 路径参数3.2、查询字符串参数3.3、form 表单传参3.4、Json 格式参数3.5、上传文件 二、响应1、HttpResponse2、JsonResponse 三、GET 和 POST 区别1、相同点2、不同点 一、请求 1、概念 请求&#xff08;Request&…

DDR4 眼图测试方法

DDR的全拼是Double Data Rate SDRAM双倍数据速率同步动态随机存取内存。主要就是用在电脑的内存。他的特点就是走线数量多&#xff0c;速度快&#xff0c;操作复杂&#xff0c;给测试和分析带来了很大的挑战。目前DDR技术已经发展到了DDR5&#xff0c;性能更高&#xff0c;功耗…

【算法练习Day4】 两两交换链表节点删除链表倒数第 N 个结点环形链表 II

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 两两交换链表中的节点一…

毫米波雷达 TI IWR1443 在 ROS 中进行 octomap 建图

个人实验记录 /mmwave_ti_ros/ros_driver/src/ti_mmwave_rospkg/launch/1443_multi_3d_0.launch <launch><!-- Input arguments --><arg name"device" value"1443" doc"TI mmWave sensor device type [1443, 1642]"/><arg…

一例“msvc编译器O2优化导致的崩溃”的分析

1. 初步分析 某进程崩溃必现。 打开崩溃dmp&#xff0c;结合c源代码&#xff0c;崩溃大致发生在某dll代码里的这句&#xff1a;SAFE_DELETE(pContentData); En_HP_HandleResult CTcpOperation::OnClintReceive(HP_Client pSender, HP_CONNID dwConnID, const BYTE * pdata, i…

组队竞赛(int溢出问题)

目录 一、题目 二、代码 &#xff08;一&#xff09;没有注意int溢出 &#xff08;二&#xff09;正确代码 1. long long sum0 2. #define int long long 3. 使用现成的sort函数 一、题目 二、代码 &#xff08;一&#xff09;没有注意int溢出 #include <iostream&g…

机器学习的主要内容

分类任务 回归任务 有一些算法只能解决回归问题有一些算法只能解决分类问题有一些算法的思路既能解决回归问题&#xff0c;又能解决分类问题 一些情况下&#xff0c; 回归任务可以转化为分类任务&#xff0c; 比如我们预测学生的成绩&#xff0c;然后根据学生的成绩划分为A类、…

js制作柱状图的x轴时间, 分别展示 月/周/日 的数据

背景 有个需求是要做一个柱状图, x 轴是时间, y 轴是数量. 其中 x 轴的时间有三种查看方式: 月份/周/日, 也就是分别查看从当前日期开始倒推的最近每月/每周/每日的数量. 本篇文章主要是用来制作三种不同的 x 轴 从当前月开始倒推月份 注意 getMonth() 函数可以获取当前月份…

【【萌新的FPGA学习之实战流水灯】】

萌新的FPGA学习之实战流水灯 实验任务 本节的实验任务是使用领航者底板上的两个 PL LED 灯顺序点亮并熄灭&#xff0c;循环往复产生流水灯的效 果&#xff0c;流水间隔时间为 0.5s。 1MHz&#xff1d;1000000Hz 10的6次方 1ns&#xff1d;10的-9次方秒 开发板晶振50Mhz 计算得…