Docker下RabbitMQ延时队列实战两部曲之二:细说开发

简介: 在SpringBoot框架下进行RabbitMQ开发,并且在Docker环境部署和运行

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

本章涉及的脚本和源码下载

本章会开发一个yml脚本,三个基于SpringBoot的应用,功能如下:

  1. docker-compose.yml:启动所有容器的docker-compose脚本;
  2. delayrabbitmqconsumer:SpringBoot框架的应用,连接RabbitMQ的两个队列,消费消息;
  3. messagettlproducer:SpringBoot框架的应用,收到web请求后向RabbitMQ发送消息,消息中带有过期时间(TTL);
  4. queuettlproducer:SpringBoot框架的应用,收到web请求后向RabbitMQ发送消息,消息中不带过期时间(TTL),但是对应的消息队列已经设置了过期时间;

整体部署情况如下:
image.png

上述脚本和工程的源码都可以在github下载,地址和链接信息如下表所示:

名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议

这个git项目中有多个文件夹,三个SpringBoot工程分别在delayrabbitmqconsumer、messagettlproducer、queuettlproducer这三个文件夹下,如下图的三个红框所示:
image.png

docker-compose.yml文件在rabbitmq_docker_files文件夹下面的delaymq文件夹下,如下图:
image.png

环境信息

  • 操作系统:Ubuntu 16.04.3 LTS
  • Docker:1.12.6
  • RabbitMQ:3.7.5-rc.1
  • JDK:1.8.0_111
  • SpringBoot:1.4.1.RELEASE
  • Maven:3.5.0

开发步骤

  • 本次开发实战的步骤如下:
  1. 开发messagettlproducer应用,制作镜像;
  2. 开发queuettlproducer应用,制作镜像;
  3. 开发delayrabbitmqconsumer应用,制作镜像;
  4. 开发docker-compose.yml脚本;

messagettlproducer应用

  • messagettlproducer是个基于SpringBoot的web工程,有一个Controller可以响应web请求,收到请求后发送一条带有过期时间的消息到RabbitMQ的message.ttl.queue.source队列;
  • pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>com.bolingcavalry</groupId>
        <artifactId>messagettlproducer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>

        <name>messagettlproducer</name>
        <description>Demo project for Spring Boot</description>

        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>1.4.1.RELEASE</version>
                <relativePath/> <!-- lookup parent from repository -->
        </parent>

        <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
                <java.version>1.8</java.version>
        </properties>

        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-amqp</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-web</artifactId>
                </dependency>

                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
        </dependencies>

        <build>
                <plugins>
                        <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                        <plugin>
                                <groupId>com.spotify</groupId>
                                <artifactId>docker-maven-plugin</artifactId>
                                <version>0.4.12</version>
                                <!--docker镜像相关的配置信息-->
                                <configuration>
                                        <!--镜像名,这里用工程名-->
                                        <imageName>bolingcavalry/${project.artifactId}</imageName>
                                        <!--TAG,这里用工程版本号-->
                                        <imageTags>
                                                <imageTag>${project.version}</imageTag>
                                        </imageTags>
                                        <!--镜像的FROM,使用java官方镜像-->
                                        <baseImage>java:8u111-jdk</baseImage>
                                        <!--该镜像的容器启动后,直接运行spring boot工程-->
                                        <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
                                        <!--构建镜像的配置信息-->
                                        <resources>
                                                <resource>
                                                        <targetPath>/</targetPath>
                                                        <directory>${project.build.directory}</directory>
                                                        <include>${project.build.finalName}.jar</include>
                                                </resource>
                                        </resources>
                                </configuration>
                        </plugin>
                </plugins>
        </build>
</project>
  • 上面的内容中有以下两点需要注意:

a. 添加对spring-boot-starter-amqp的依赖,这里面是操作RabbitMQ所需的库;
b. 添加docker-maven-plugin插件,可以将当前工程直接制作成Docker镜像;

  • src/main/resources文件夹下面创建application.properties文件,内容如下,只配置了应用名称和RabbitMQ的virtualHost路径:
spring.application.name=messagettlproducer
mq.rabbit.virtualHost=/
  • RabbitTemplateConfig.java文件中是应用连接RabbitMQ的配置信息:
@Configuration
public class RabbitTemplateConfig {

    @Value("${mq.rabbit.address}")
    String address;

    @Value("${mq.rabbit.username}")
    String username;

    @Value("${mq.rabbit.password}")
    String password;

    @Value("${mq.rabbit.virtualHost}")
    String mqRabbitVirtualHost;

    //创建mq连接
    @Bean(name = "connectionFactory")
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();

        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(mqRabbitVirtualHost);
        connectionFactory.setPublisherConfirms(true);

        //该方法配置多个host,在当前连接host down掉的时候会自动去重连后面的host
        connectionFactory.setAddresses(address);

        return connectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    //必须是prototype类型
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }
}
  • 上面的代码有以下几点要注意:

a. address、username、password这些变量的值,是从操作系统的环境变量中获取的,我们在启动Docker容器的时候将这些值配置到容器的环境变量中,程序运行的时候就能取到了;
b. connectionFactory()方法根据上述配置参数和RabbitMQ建立连接;
c. rabbitTemplate()创建RabbitTemplate对象,我们可以在其他Bean中通过Autowire使用;

  • MessageTtlRabbitConfig.java类中是和消息队列相关的配置:
    /**
     * 成为死信后,重新发送到的交换机的名称
     */
    @Value("${message.ttl.exchange}")
    private String MESSAGE_TTL_EXCHANGE_NAME;

    /**
     * 不会被消费的队列,投递到此队列的消息会成为死信
     */
    @Value("${message.ttl.queue.source}")
    private String MESSAGE_TTL_QUEUE_SOURCE;

    /**
     * 该队列被绑定到接收死信的交换机
     */
    @Value("${message.ttl.queue.process}")
    private String MESSAGE_TTL_QUEUE_PROCESS;

    /**
     * 配置一个队列,该队列的消息如果没有被消费,就会投递到死信交换机中,并且带上指定的routekey
     * @return
     */
    @Bean
    Queue messageTtlQueueSource() {
        return QueueBuilder.durable(MESSAGE_TTL_QUEUE_SOURCE)
                .withArgument("x-dead-letter-exchange", MESSAGE_TTL_EXCHANGE_NAME)
                .withArgument("x-dead-letter-routing-key", MESSAGE_TTL_QUEUE_PROCESS)
                .build();
    }

    @Bean("messageTtlQueueProcess")
    Queue messageTtlQueueProcess() {
        return QueueBuilder.durable(MESSAGE_TTL_QUEUE_PROCESS) .build();
    }

    @Bean("messageTtlExchange")
    DirectExchange messageTtlExchange() {
        return new DirectExchange(MESSAGE_TTL_EXCHANGE_NAME);
    }

    /**
     * 绑定指定的队列到死信交换机上
     * @param messageTtlQueueProcess
     * @param messageTtlExchange
     * @return
     */
    @Bean
    Binding bindingExchangeMessage(@Qualifier("messageTtlQueueProcess") Queue messageTtlQueueProcess, @Qualifier("messageTtlExchange") DirectExchange messageTtlExchange) {
        System.out.println("11111111111111111111111111111111111111111111111111");
        System.out.println("11111111111111111111111111111111111111111111111111");
        System.out.println("11111111111111111111111111111111111111111111111111");
        System.out.println("11111111111111111111111111111111111111111111111111");
        return BindingBuilder.bind(messageTtlQueueProcess)
                .to(messageTtlExchange)
                .with(MESSAGE_TTL_QUEUE_PROCESS);
    }
  • 上面的代码有以下几点要注意:

a. MESSAGE_TTL_EXCHANGE_NAME、MESSAGE_TTL_QUEUE_SOURCE、MESSAGE_TTL_QUEUE_PROCESS这些变量的值,是从操作系统的环境变量中获取的,我们在启动Docker容器的时候将这些值配置到容器的环境变量中,程序运行的时候就能取到了;
b. connectionFactory()方法根据上述配置参数和RabbitMQ建立连接;
c. rabbitTemplate()创建RabbitTemplate对象,我们可以在其他Bean中通过Autowire使用;
d. messageTtlQueueSource()方法创建了一个队列用于投递消息,通过x-dead-letter-exchangex-dead-letter-routing-key这两个参数,设置了队列消息过期后转发的交换机名称,以及携带的routing key;

  • 为了设置消息过期,我们还要定制一个ExpirationMessagePostProcessor类,作用是将给消息类设置过期时间,后面发送消息时会用到这个类:
package com.bolingcavalry.messagettlproducer;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;

/**
 * @Description :
 * @Author : zq2599@gmail.com
 * @Date : 2018-06-02 23:33
 */
public class ExpirationMessagePostProcessor implements MessagePostProcessor {
    private final Long ttl; // 毫秒

    public ExpirationMessagePostProcessor(Long ttl) {
        this.ttl = ttl;
    }

    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
        message.getMessageProperties() .setExpiration(ttl.toString()); // 设置per-message的失效时间
        return message;
    }
}
  • 用于处理web请求的SendMessageController 类,源码如下:
/**
 * @Description : 用于生产消息的web接口类
 * @Author : zq2599@gmail.com
 * @Date : 2018-06-02 23:00
 */
@RestController
public class SendMessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${message.ttl.queue.source}")
    private String MESSAGE_TTL_QUEUE_SOURCE;

    /**
     * 生产一条消息,消息中带有过期时间
     * @param name
     * @param message
     * @param delaytime
     * @return
     */
    @RequestMapping(value = "/messagettl/{name}/{message}/{delaytime}", method = RequestMethod.GET)
    public @ResponseBody
    String messagettl(@PathVariable("name") final String name, @PathVariable("message") final String message, @PathVariable("delaytime") final int delaytime) {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timeStr = simpleDateFormat.format(new Date());
        String queueName = MESSAGE_TTL_QUEUE_SOURCE;
        String  sendMessage = String.format("hello, %s , %s, from queue [%s], delay %d's, %s", name, message, MESSAGE_TTL_QUEUE_SOURCE, delaytime, timeStr);
        rabbitTemplate.convertAndSend(MESSAGE_TTL_QUEUE_SOURCE,
                                        (Object)sendMessage,
                                        new ExpirationMessagePostProcessor(delaytime*1000L));

        return "send message to [" +  name + "] success , queue is : " + queueName + " (" + timeStr + ")";
    }
}
  • 如上所示,发送消息的代码很简单,调用rabbitTemplate的convertAndSend就能发送消息到message.ttl.queue.source队列(指定路由键的Direct方式),再传入ExpirationMessagePostProcessor作为处理消息的工具;
  • 以上就是messagettlproducer应用的主要代码介绍,编码完毕后,在pom.xml文件所在目录执行mvn clean package -U -DskipTests docker:build,即可编译、构建、制作Docker镜像;

queuettlproducer应用

  • queuettlproducer和messagettlproducer极为相似,都是接受web请求后向RabbitMQ发送消息,不同之处有以下两点:
  1. queuettlproducer在绑定队列的时候,会设置队列上所有消息的过期时间,messagettlproducer没做这个设置;
  2. queuettlproducer在发送消息的时候,没有设置该消息的过期时间,messagettlproducer会对每条消息都设置过期时间;
  • 因此,queuettlproducer和messagettlproducer这两个应用的代码大部分是相同的,这里只要关注不同的部分即可;
  • 队列和交换机的配置类,QueueTtlRabbitConfig:
@Configuration
public class QueueTtlRabbitConfig {

    /**
     * 成为死信后,重新发送到的交换机的名称
     */
    @Value("${queue.ttl.exchange}")
    private String QUEUE_TTL_EXCHANGE_NAME;

    /**
     * 不会被消费的队列,投递到此队列的消息会成为死信
     */
    @Value("${queue.ttl.queue.source}")
    private String QUEUE_TTL_QUEUE_SOURCE;

    /**
     * 该队列被绑定到接收死信的交换机
     */
    @Value("${queue.ttl.queue.process}")
    private String QUEUE_TTL_QUEUE_PROCESS;

    @Value("${queue.ttl.value}")
    private long QUEUE_TTL_VALUE;

    /**
     * 配置一个队列,该队列有消息过期时间,消息如果没有被消费,就会投递到死信交换机中,并且带上指定的routekey
     * @return
     */
    @Bean
    Queue queueTtlQueueSource() {
        return QueueBuilder.durable(QUEUE_TTL_QUEUE_SOURCE)
                .withArgument("x-dead-letter-exchange", QUEUE_TTL_EXCHANGE_NAME)
                .withArgument("x-dead-letter-routing-key", QUEUE_TTL_QUEUE_PROCESS)
                .withArgument("x-message-ttl", QUEUE_TTL_VALUE)
                .build();
    }

    @Bean("queueTtlQueueProcess")
    Queue queueTtlQueueProcess() {
        return QueueBuilder.durable(QUEUE_TTL_QUEUE_PROCESS) .build();
    }

    @Bean("queueTtlExchange")
    DirectExchange queueTtlExchange() {
        return new DirectExchange(QUEUE_TTL_EXCHANGE_NAME);
    }

    /**
     * 绑定
     * @param queueTtlQueueProcess
     * @param queueTtlExchange
     * @return
     */
    @Bean
    Binding bindingExchangeMessage(@Qualifier("queueTtlQueueProcess") Queue queueTtlQueueProcess, @Qualifier("queueTtlExchange") DirectExchange queueTtlExchange) {
        System.out.println("22222222222222222222222222222222222222222222222222");
        System.out.println("22222222222222222222222222222222222222222222222222");
        System.out.println("22222222222222222222222222222222222222222222222222");
        System.out.println("22222222222222222222222222222222222222222222222222");
        return BindingBuilder.bind(queueTtlQueueProcess)
                .to(queueTtlExchange)
                .with(QUEUE_TTL_QUEUE_PROCESS);
    }
}
  • 上述代码请注意以下两点:

a. queueTtlQueueSource()方法用来设置队列,除了x-dead-letter-exchangex-dead-letter-routing-key这两个参数,还多了x-message-ttl,此参数对应的值就是进入该队列的每一条消息的过期时间;
b. bindingExchangeMessage()方法将队列queue.ttl.queue.source绑定到Direct模式的交换机;

  • 处理web请求的SendMessageController类:
@RestController
public class SendMessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${queue.ttl.queue.source}")
    private String QUEUE_TTL_QUEUE_SOURCE;

    /**
     * 生产一条消息,消息中不带过期时间,但是对应的队列中已经配置了过期时间
     * @param name
     * @param message
     * @return
     */
    @RequestMapping(value = "/queuettl/{name}/{message}", method = RequestMethod.GET)
    public @ResponseBody
    String queuettl(@PathVariable("name") final String name, @PathVariable("message") final String message) {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timeStr = simpleDateFormat.format(new Date());
        String queueName = QUEUE_TTL_QUEUE_SOURCE;
        String  sendMessage = String.format("hello, %s , %s, from queue [%s], %s", name, message, queueName, timeStr);
        rabbitTemplate.convertAndSend(queueName, sendMessage);

        return "send message to [" +  name + "] success , queue is : " + queueName + " (" + timeStr + ")";
    }
}
  • 如上所示,发送消息时只有routing key和消息对象这两个参数;
  • 以上就是发送消息到队列的应用源码,编码完毕后,在pom.xml文件所在目录执行mvn clean package -U -DskipTests docker:build,即可编译、构建、制作Docker镜像;
  • 接下来我们看看消息消费者工程delayrabbitmqconsumer的源码;

delayrabbitmqconsumer应用

  • delayrabbitmqconsumer应用连接到消息队列,消费收到的每条消息;
  • RabbitTemplateConfig.java是连接到RabbitMQ的配置信息,和前面两个应用一样,不再赘述;
  • 消费message.ttl.queue.process这个队列发出的消息,对应实现类是MessageTtlReceiver:
/**
 * @Description : 消息接受类,接收第一类延时消息(在每条消息中指定过期时间)的转发结果
 * @Author : zq2599@gmail.com
 * @Date : 2018-06-03 9:52
 */
@Component
@RabbitListener(queues = "${message.ttl.queue.process}")
public class MessageTtlReceiver {
    private static final Logger logger = LoggerFactory.getLogger(MessageTtlReceiver.class);

    @RabbitHandler
    public void process(String message) {
        logger.info("receive message : " + message);
    }
}
  • 如上所示,只要用注解RabbitListener配置好队列的名称即可,编码完毕后,在pom.xml文件所在目录执行mvn clean package -U -DskipTests docker:build,即可编译、构建、制作Docker镜像;

docker-compose.yml配置

  • 最后我们看一下所有容器的配置文件docker-compose.yml:
version: '2'
services:
  rabbit1:
    image: bolingcavalry/rabbitmq-server:0.0.3
    hostname: rabbit1
    ports:
      - "15672:15672"
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=888888
  rabbit2:
    image: bolingcavalry/rabbitmq-server:0.0.3
    hostname: rabbit2
    depends_on:
      - rabbit1
    links:
      - rabbit1
    environment:
     - CLUSTERED=true
     - CLUSTER_WITH=rabbit1
     - RAM_NODE=true
     - HA_ENABLE=true
    ports:
      - "15673:15672"
  rabbit3:
    image: bolingcavalry/rabbitmq-server:0.0.3
    hostname: rabbit3
    depends_on:
      - rabbit2
    links:
      - rabbit1
      - rabbit2
    environment:
      - CLUSTERED=true
      - CLUSTER_WITH=rabbit1
    ports:
      - "15675:15672"
  messagettlproducer:
    image: bolingcavalry/messagettlproducer:0.0.1-SNAPSHOT
    hostname: messagettlproducer
    depends_on:
      - rabbit3
    links:
      - rabbit1:rabbitmqhost1
      - rabbit2:rabbitmqhost2
      - rabbit3:rabbitmqhost3
    ports:
      - "18080:8080"
    environment:
      - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672
      - mq.rabbit.username=admin
      - mq.rabbit.password=888888
      - message.ttl.exchange=message.ttl.exchange
      - message.ttl.queue.source=message.ttl.queue.source
      - message.ttl.queue.process=message.ttl.queue.process
  queuettlproducer:
    image: bolingcavalry/queuettlproducer:0.0.1-SNAPSHOT
    hostname: queuettlproducer
    depends_on:
      - messagettlproducer
    links:
      - rabbit1:rabbitmqhost1
      - rabbit2:rabbitmqhost2
      - rabbit3:rabbitmqhost3
    ports:
      - "18081:8080"
    environment:
      - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672
      - mq.rabbit.username=admin
      - mq.rabbit.password=888888
      - queue.ttl.exchange=queue.ttl.exchange
      - queue.ttl.queue.source=queue.ttl.queue.source
      - queue.ttl.queue.process=queue.ttl.queue.process
      - queue.ttl.value=5000
  delayrabbitmqconsumer:
    image: bolingcavalry/delayrabbitmqconsumer:0.0.1-SNAPSHOT
    hostname: delayrabbitmqconsumer
    depends_on:
      - queuettlproducer
    links:
      - rabbit1:rabbitmqhost1
      - rabbit2:rabbitmqhost2
      - rabbit3:rabbitmqhost3
    environment:
     - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672
     - mq.rabbit.username=admin
     - mq.rabbit.password=888888
     - message.ttl.queue.process=message.ttl.queue.process
     - queue.ttl.queue.process=queue.ttl.queue.process
  • 上述配置文件有以下几点需要注意:
  • rabbit1、rabbit2、rabbit3是RabbitMQ高可用集群,如果您对RabbitMQ高可用集群感兴趣,推荐您请看《Docker下RabbitMQ四部曲》系列文章;
  • 三个SpringBoot应用都配置了mq.rabbit.address参数,值是三个RabbitMQ server的IP加端口,这样如果RabbitMQ集群中有一台机器故障了也不会影响正常的消息收发;
  • 使用了link参数后,容器内就能通过link的参数取代对应的IP;
  • 至此,Docker下的RabbitMQ延时队列实战就完成了,实战中Docker发挥的作用并不大,只是用来快速搭建环境,关键还是三个工程中对队列的各种操作,希望本系列能帮助您快速构建延时队列相关服务;

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
7天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。
|
1月前
|
消息中间件 存储 监控
RabbitMQ 队列之战:Classic 和 Quorum 的性能洞察
RabbitMQ 是一个功能强大的消息代理,用于分布式应用程序间的通信。它通过队列临时存储消息,支持异步通信和解耦。经典队列适合高吞吐量和低延迟场景,而仲裁队列则提供高可用性和容错能力,适用于关键任务系统。选择哪种队列取决于性能、持久性和容错性的需求。
128 6
|
1月前
|
存储 持续交付 开发者
掌握Docker容器化:提升开发效率与应用部署
【10月更文挑战第4天】在现代软件开发中,Docker容器化技术因其轻量级、可移植和快速部署的特点,成为提升开发效率和简化部署流程的关键工具。本文介绍了Docker的基本概念、核心组件及其优势,并探讨了如何在开发环境中搭建、微服务架构及CI/CD流程中有效利用Docker,助力软件开发更加高效便捷。
|
1月前
|
消息中间件 数据采集 中间件
RabbitMQ的使用—实战
RabbitMQ的使用—实战
|
2月前
|
持续交付 开发者 Docker
掌握 Docker:容器化技术在现代开发中的应用
Docker 是一个开源容器化平台,使开发者能够将应用程序及其依赖项封装在轻量级容器中,确保跨平台的一致性。本文介绍了 Docker 的基本概念、核心组件及优势,并展示了其在快速部署、一致性、可移植性和微服务架构中的应用。通过示例说明了 Docker 在本地开发环境搭建、服务依赖管理和 CI/CD 流程中的作用,以及多阶段构建、资源限制和网络模式等高级特性。掌握 Docker 可大幅提升开发效率和应用管理能力。
|
2月前
|
消息中间件 JSON Java
|
2月前
|
消息中间件
rabbitmq,&队列
rabbitmq,&队列
|
2月前
|
消息中间件 缓存 Java
RocketMQ的JAVA落地实战
RocketMQ作为一款高性能、高可靠、高实时、分布式特点的消息中间件,其核心作用主要体现在异步处理、削峰填谷以及系统解耦三个方面。
170 0
|
3月前
|
机器学习/深度学习 Kubernetes Docker
机器学习开发的灵药:Docker容器
机器学习开发的灵药:Docker容器
|
2月前
|
消息中间件 JSON Java
玩转RabbitMQ声明队列交换机、消息转换器
玩转RabbitMQ声明队列交换机、消息转换器
87 0