rabbitmq.channel方法介绍

本文详细介绍了RabbitMQ中Channel的相关操作,包括exchangeDeclare用于创建交换机,涉及exchange类型、是否持久化等参数;basicQos设置消息预取量,控制服务器发送给消费者的并发消息数量;basicPublish发布消息,包含路由键、消息持久化选项等;basicAck手动确认消息处理完成;queueDeclare声明队列以及queueBind绑定队列与交换机。这些操作是RabbitMQ中消息传递的核心部分。

rabbitmq.channel参数详解

channel.exchangeDeclare():使用fanout类型创建的交换机

1、type:有direct、fanout、topic三种
2、durable:truefalse true:服务器重启会保留下来Exchange。警告:仅设置此选项,不代表消息持久化。即不保证重启后消息还在
3、autoDelete:truefalse.true:当已经没有消费者时,服务器是否可以删除该Exchange

Exchange.DeclareOk exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete,
                                       Map<String, Object> arguments) throws IOException;

chanel.basicQos(): 同一时刻服务器发多少条消息给消费者

1、prefetchSize:0 
2、prefetchCount:会告诉RabbitMQ不要同时给一个消费者推送多于N个消息,即一旦有N个消息还没有ack,则该consumer将block掉,直到有消息ack
3、global:true\false 是否将上面设置应用于channel,简单点说,就是上面限制是channel级别的还是consumer级别

void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;

channel.basicPublish(): 向server发布一条消息

1、routingKey:路由键,#匹配0个或多个单词,*匹配一个单词,在topic exchange做消息转发用
2、mandatory:true:如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者。false:出现上述情形broker会直接将消息扔掉
3、mmediate:true:如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。
4BasicProperties :需要注意的是BasicProperties.deliveryMode,0:不持久化 1:持久化 这里指的是消息的持久化,配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留
简单来说:mandatory标志告诉服务器至少将该消息route到一个队列中,否则将消息返还给生产者;immediate标志告诉服务器如果该消息关联的queue上有消费者,则马上将消息投递给它,如果所有queue都没有消费者,直接把消息返还给生产者,不用将消息入队列等待消费者了。

void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
            throws IOException;

channel.basicAck(): 消息处理完成,手动确认提交

1、deliveryTag:该消息的index
2、multiple:是否批量.true:将一次性ack所有小于deliveryTag的消息。

void basicAck(long deliveryTag, boolean multiple) throws IOException;

channel.basicConsume(): 消息消费完成确认

1、autoAck:是否自动ack,如果不自动ack,需要使用channel.ack、channel.nack、2、channel.basicReject 进行消息应答

String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;

channel.queueDeclare(): 声明一个队列

1、durable:truefalse true:在服务器重启时,能够存活
2、exclusive :是否为当前连接的专用队列,在连接断开后,会自动删除该队列,生产环境中应该很少用到吧。
3、autodelete:当没有任何消费者使用时,自动删除该队列。

Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                                 Map<String, Object> arguments) throws IOException;

channel.queueBind(): 将队列跟交换器进行绑定

1、queue:队列名称
2、exchange:交换机名称
3、routingKey:队列跟交换机绑定的键值
channel.queueBind(queueName, EXCHANGE_NAME, "black");
你遇到的错误: ``` Method [public void com.sunzhu.spring.springboot319rabbitmq.rabbitmq.RabbitC.queueA(java.util.List<com.sunzhu.spring.springboot319rabbitmq.rabbitmq.Order>, com.rabbitmq.client.Channel, long[])] was found but could not be invoked with the incoming message ``` 说明: - Spring 找到了你的方法,**但无法正确地将消息参数绑定到方法上**。 - 这通常是因为 **Spring 无法识别消息的结构** 或者 **参数顺序/类型不匹配**。 --- ## 🧠 问题根本原因 ### 1. **Spring AMQP 无法自动识别 List<Order> 类型** - Spring AMQP 默认使用 `SimpleMessageConverter`,它无法处理 `List<Order>` 这种泛型结构。 - 即使你配置了 `Jackson2JsonMessageConverter`,如果你没有正确使用 `@Payload` 注解,Spring 也不会触发反序列化。 ### 2. **参数顺序或类型不匹配** - Spring AMQP 有固定的参数绑定顺序,例如: - `@Payload` 参数(消息体) - `Channel` - `@Header` 注解的参数 - 如果顺序不对,或者类型不匹配,Spring 就无法调用方法--- ## ✅ 正确的解决方式 ### ✅ 步骤一:确保已配置 `Jackson2JsonMessageConverter` ```java @Configuration public class RabbitConfig { @Bean public MessageConverter jackson2JsonMessageConverter() { return new Jackson2JsonMessageConverter(); } @Bean public RabbitListenerContainerFactory<SimpleMessageListenerContainer> batchContainerFactory( ConnectionFactory connectionFactory, MessageConverter jackson2JsonMessageConverter) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(jackson2JsonMessageConverter); factory.setBatchListener(true); factory.setPrefetchCount(10); return factory; } } ``` ### ✅ 步骤二:确保 `Order` 类有无参构造函数并实现 `Serializable` ```java public class Order implements Serializable { private String orderId; private BigDecimal amount; public Order() {} // 必须有无参构造函数 // getters and setters } ``` ### ✅ 步骤三:监听方法中使用 `@Payload` 明确指定反序列化目标 ```java @RabbitListener(queues = "queueA", containerFactory = "batchContainerFactory") public void queueA(@Payload List<Order> orders, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long[] deliveryTags) throws IOException { try { for (Order order : orders) { System.out.println("Received order: " + order); } // 确认整个批次的消息 channel.basicAck(deliveryTags[deliveryTags.length - 1], true); } catch (Exception e) { // 拒绝整个批次的消息,并重新入队 channel.basicNack(deliveryTags[deliveryTags.length - 1], true, true); } } ``` ### ✅ 步骤四:发送消息时确保是 JSON 格式 如果你是手动发消息测试,确保消息是 JSON 格式,例如: ```json [ { "orderId": "1001", "amount": 100.00 }, { "orderId": "1002", "amount": 200.00 } ] ``` 你可以使用 RabbitMQ 的管理界面或代码发送: ```java @Autowired private RabbitTemplate rabbitTemplate; public void sendBatch() { List<Order> orders = Arrays.asList( new Order("1001", new BigDecimal("100.00")), new Order("1002", new BigDecimal("200.00")) ); rabbitTemplate.convertAndSend("queueA", orders); } ``` --- ## ✅ 额外建议 - 如果你使用的是 **Spring Boot 2.4+ 或 3.x**,请确保你依赖了 `spring-boot-starter-amqp` 和 `jackson-databind`。 - 使用 `@RabbitListener` 时,方法参数顺序非常重要,推荐按以下顺序书写: 1. `@Payload T payload` 2. `Channel channel` 3. `@Header Map<String, Object> headers` 4. `Message message` --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值