Rabbit MQ ——API的使用(三)

本文详细介绍了RabbitMQ的多种使用方式,包括原生Java API、Spring集成及注解式监听,涵盖了生产者、消费者的具体实现,适用于不同场景的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RabbitMq有很多使用方式,里面我将常用的几种方式列出,以便日后回故:

 

 

一,原生java  API方式 :

 

maven依赖:

		<dependency>
			<groupId>com.rabbitmq</groupId>
			<artifactId>amqp-client</artifactId>
		</dependency>

 

 

生产者:

package com.lyy.rabbitmq.base;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ReturnListener;

public class Producer {

	public static void main(String[] args) throws Exception, TimeoutException {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		connectionFactory.setPort(5672);
		connectionFactory.setVirtualHost("/");
		
		Connection connection = connectionFactory.newConnection();
		Channel channel = connection.createChannel();
		
		//开启消息发送确认模式
		channel.confirmSelect();
		//增加消息发送确认监听
		channel.addConfirmListener(new ConfirmListener() {

			@Override
			public void handleAck(long deliveryTag, boolean multiple) throws IOException {
				System.out.println("成功");
				
			}

			@Override
			public void handleNack(long deliveryTag, boolean multiple) throws IOException {
				System.err.println("失败");
				
			}
			
		});
		
		//增加return监听(当前的Exchange不存在或者指定的路由Key无匹配)
		channel.addReturnListener(new ReturnListener() {
			
			@Override
			public void handleReturn(int replyCode, String replyText, String exchange,
					String routingKey, AMQP.BasicProperties properties, byte[] body)
					throws IOException {
				System.err.println("---------handle  return----------");
				System.err.println("replyCode: " + replyCode);
				System.err.println("replyText: " + replyText);
				System.err.println("exchange: " + exchange);
				System.err.println("routingKey: " + routingKey);
				System.err.println("properties: " + properties);
				System.err.println("body: " + new String(body));
				
			}
		});
		
		
		String exchange = "test_topic_exchange_01";
		String routingKey = "lyy.test";
		
		Map<String, Object> map = new HashMap<>();
		map.put("custom", "hehe");
		BasicProperties properties = new AMQP.BasicProperties.Builder()
		//持久化
		.deliveryMode(2)
		.contentEncoding("UTF-8")
		//消息过期时间
		.expiration("10000")
		//自定义参数
		.headers(map)
		.build();
		
		
		String body = "test ";
		
		//Mandatory:如果为true,则监听器会接收到路由不可达的消息,如果为False,那么Broker端自动删除改消息。
		channel.basicPublish(exchange, routingKey,true, properties, body.getBytes());
		
		
//		channel.close();
//		connection.close();
	}
}

 

 

消费者:

package com.lyy.rabbitmq.base;

import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Consumer {

	
	public static void main(String[] args) throws Exception, TimeoutException {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		connectionFactory.setPort(5672);
		connectionFactory.setVirtualHost("/");
		connectionFactory.setAutomaticRecoveryEnabled(true);
		connectionFactory.setNetworkRecoveryInterval(3000);
		
		Connection connection = connectionFactory.newConnection();
		
		Channel channel = connection.createChannel();
		
		String exchange = "test_topic_exchange_01";
		String exchangeType = "topic";
		String queue = "test_queue";
		String routingKey = "lyy.#";
		
		
		channel.exchangeDeclare(exchange, exchangeType);
		
		channel.queueDeclare(queue, true, false, false, null);
		
		channel.queueBind(queue, exchange, routingKey);
		
		//1 限流方式  第一件事就是 autoAck设置为 false
		channel.basicQos(0, 1, false);
		
		// 手工签收 必须要关闭 autoAck = false
		channel.basicConsume(queue, false, new MyConsumer(channel));
	}
}

 

 

消费处理类:

package com.lyy.rabbitmq.base;

import java.io.IOException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

public class MyConsumer extends DefaultConsumer {
	private Channel channel;
	public MyConsumer(Channel channel) {
		super(channel);
		this.channel = channel;
	}
	@Override
	public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
			throws IOException {
		System.out.println(new String(body));
		
		Object object = properties.getHeaders().get("custom");
		System.out.println(object.toString());
		
		long deliveryTag = envelope.getDeliveryTag();
		System.out.println(deliveryTag);
		
		channel.basicAck(deliveryTag, false);
//		channel.basicNack(deliveryTag, false, true);
	}
	
	
	

}

 

 

 

二,spring 使用方式 1:

 

maven 依赖:

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

 

配置类:

package com.lyy.rabbitmq.spring;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

	@Bean
	public ConnectionFactory connectionFactory(){
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
		connectionFactory.setAddresses("127.0.0.1:5672");
		connectionFactory.setUsername("guest");
		connectionFactory.setPassword("guest");
		connectionFactory.setVirtualHost("/");
		return connectionFactory;
	}
	
	@Bean
	public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
		RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
		rabbitAdmin.setAutoStartup(true);
		return rabbitAdmin;
	}
	
	
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
    	RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    	return rabbitTemplate;
    }
}

 

生产者:

package com.lyy.rabbitmq.spring;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.fasterxml.jackson.databind.ObjectMapper;



@RunWith(SpringRunner.class)
@SpringBootTest
public class Producer {

	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	
	@Test
	public void send() throws Exception {
		MessageProperties messageProperties = new MessageProperties();
		//下面两句必须加上,消息费才可以传成对应的对象
		messageProperties.setContentType("application/json");
		messageProperties.getHeaders().put("__TypeId__", "com.lyy.rabbitmq.spring.Order");
		Order order = new Order();
		order.setId("1");
		order.setDes("order test");
		ObjectMapper mapper = new ObjectMapper();
		String json = mapper.writeValueAsString(order);
		Message message = new Message(json.getBytes(), messageProperties);
		rabbitTemplate.convertAndSend("spring-test001", "spring.queue002", message);
	}
}

 

 

消费者:

 

package com.lyy.rabbitmq.spring;

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

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.ConsumerTagStrategy;
import org.springframework.amqp.support.converter.ContentTypeDelegatingMessageConverter;
import org.springframework.amqp.support.converter.DefaultJackson2JavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Consumer {

	@Bean
	public TopicExchange exchange001() {
		return new TopicExchange("spring-test001", true, false);
	}
	
	@Bean
	public Queue queue001() {
		return new Queue("spring-test001",true);
	}
	
	@Bean
	public Queue queue002() {
		return new Queue("spring-test002",true);
	}
	
	@Bean
	public Binding binding001() {
		return BindingBuilder.bind(queue001()).to(exchange001()).with("spring.queue001");
	}
	
	@Bean
	public Binding binding002() {
		return BindingBuilder.bind(queue002()).to(exchange001()).with("spring.queue002");
	}
	
	
	@Bean
	public SimpleMessageListenerContainer messageListener(ConnectionFactory connectionFactory) {
		SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
		//消息签收模式
		container.setAcknowledgeMode(AcknowledgeMode.AUTO);
		//监听的队列
		container.setQueues(queue001(),queue002());
		//监听方法的并发数设置
		container.setConcurrentConsumers(1);
		container.setMaxConcurrentConsumers(3);
		//失败是否重回队列
		container.setDefaultRequeueRejected(false);
		//消费者标识
		container.setConsumerTagStrategy(new ConsumerTagStrategy() {
			
			@Override
			public String createConsumerTag(String queue) {
				return queue + UUID.randomUUID().toString();
			}
		});
		
		
		//使用适配器方式处理消息
		MessageListenerAdapter adapter = new MessageListenerAdapter(new MyDelegate());
		
		Map<String, String> queueOrTagToMethodName = new HashMap<String, String>();
		queueOrTagToMethodName.put("spring-test001", "processQueueMessage");
		queueOrTagToMethodName.put("spring-test002", "processQueueMessage");
		//队列和处理方法的对应关系
		adapter.setQueueOrTagToMethodName(queueOrTagToMethodName);
		
        //全局的转换器,可以同步配置多个类型的转换器
		ContentTypeDelegatingMessageConverter convert = new ContentTypeDelegatingMessageConverter();
		
		//json格式的转换器
//		Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
//		convert.addDelegate("json", jackson2JsonMessageConverter);
//		convert.addDelegate("application/json", jackson2JsonMessageConverter);
		
		//json转对象
		Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
        //这个一定要设置,信息所有包路径
        javaTypeMapper.setTrustedPackages("*");
        
        //指定映射类的关系
        Map<String, Class<?>> idClassMapping = new HashMap<String, Class<?>>();
		idClassMapping.put("order", com.lyy.rabbitmq.spring.Order.class);
		javaTypeMapper.setIdClassMapping(idClassMapping);
		jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
		convert.addDelegate("application/json", jackson2JsonMessageConverter);
		
        
        adapter.setMessageConverter(convert);
        container.setMessageListener(adapter);
		
		
		return container;
	}
}

 

消费者代理处理类:

 

package com.lyy.rabbitmq.spring;

public class MyDelegate {

	
	/**
	 * 根据发送消息的类型自动调用参数类型匹配的方法
	 * @param message
	 */
	public void processQueueMessage(String message) {
		System.out.println(message);
	}
	
	
	public void processQueueMessage(Order order) {
		System.out.println(order.getDes());
	}
}

 

 

 

三,spring 使用方式 ——注解式声明监听:

 

生产者:

package com.lyy.rabbitmq.springboot;

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

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import com.lyy.rabbitmq.spring.Order;


@RunWith(SpringRunner.class)
@SpringBootTest
public class Producer {

	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	@Test
	public void sendMessage() {
		Map<String, Object> headers = new HashMap<String, Object>();
		headers.put("abcd", "zs");
		MessageHeaders messageHeaders = new MessageHeaders(headers);
		Message<String> message = MessageBuilder.createMessage("spring boot rabittMq ", messageHeaders);
		
		rabbitTemplate.setConfirmCallback(new MyConfirmCallback());
		rabbitTemplate.setReturnCallback(new MyReturnCallback());
		
		
		rabbitTemplate.convertAndSend("springboot-exchanges", "springboot.string", 
				message, new CorrelationData(UUID.randomUUID().toString()));
		
	}
	@Test
	public void sendOrder() {
		Map<String, Object> headers = new HashMap<String, Object>();
		headers.put("abcd", "zs");
		MessageHeaders messageHeaders = new MessageHeaders(headers);
		
		Order order = new Order();
		order.setId("123456");
		
		Message<Order> message = MessageBuilder.createMessage(order,messageHeaders);
		
		rabbitTemplate.setConfirmCallback(new MyConfirmCallback());
		rabbitTemplate.setReturnCallback(new MyReturnCallback());
		

		
		rabbitTemplate.convertAndSend("springboot-exchanges", "springboot.order", 
				message, new CorrelationData(UUID.randomUUID().toString()));
		
	}
}

 

ConfirmCallback:

package com.lyy.rabbitmq.springboot;

import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.support.CorrelationData;

public class MyConfirmCallback implements ConfirmCallback {

	@Override
	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
		//消息唯一标识
		System.out.println(correlationData);
		System.out.println(cause);
		if(!ack) {
			System.out.println("发送异常,日志记录");
		}

	}

}

 

ReturnCallback:

package com.lyy.rabbitmq.springboot;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;

public class MyReturnCallback implements ReturnCallback {

	@Override
	public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
		System.out.println(message);
		System.out.println(replyCode);
		System.out.println(replyText);
		System.out.println(exchange);
		System.out.println(routingKey);
	}

}

 

消费者:

 

package com.lyy.rabbitmq.springboot;

import java.io.IOException;
import java.util.Map;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.lyy.rabbitmq.spring.Order;
import com.rabbitmq.client.Channel;

@Service(value="springbootConsumer")
public class Consumer {

	@RabbitListener(bindings = @QueueBinding(value = @Queue(value="springboot-test",durable = "true"), 
			exchange = @Exchange(name="springboot-exchanges",durable="true",type="topic"),
			key="springboot.string"))
	@RabbitHandler
	public void onMessage(Message<Object> message, Channel channel) throws Exception {
		Object object = message.getPayload();
		System.out.println(object);
		MessageHeaders headers = message.getHeaders();
		Object object2 = headers.get("abcd");
		System.out.println(object2);
		
		//配置文件中设置的手工签收
		channel.basicAck(Long.parseLong(headers.get(AmqpHeaders.DELIVERY_TAG).toString()), false);
		
	}
	
	
	@RabbitListener(bindings = @QueueBinding(
			value = @Queue(value = "${spring.rabbitmq.listener.order.queue.name}", 
			durable="${spring.rabbitmq.listener.order.queue.durable}"),
			exchange = @Exchange(value = "${spring.rabbitmq.listener.order.exchange.name}", 
			durable="${spring.rabbitmq.listener.order.exchange.durable}", 
			type= "${spring.rabbitmq.listener.order.exchange.type}", 
			ignoreDeclarationExceptions = "${spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions}"),
			key = "${spring.rabbitmq.listener.order.key}"
			)
	)
	@RabbitHandler
	public void onOrderMessage(@Payload Order order, 
			Channel channel, 
			@Headers Map<String, Object> headers) throws Exception {
		System.out.println("--------------------------------------");
		System.out.println("消费端order: " + order.getId());
		Long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
		//手工ACK
		channel.basicAck(deliveryTag, false);
	}
}

 

application.properties

 

spring.rabbitmq.addresses=127.0.0.1:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=15000

#producer
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.template.mandatory=true

#consumer
spring.rabbitmq.listener.simple.acknowledge-mode=manual
spring.rabbitmq.listener.simple.concurrency=5
spring.rabbitmq.listener.simple.max-concurrency=10

#custom
spring.rabbitmq.listener.order.queue.name=springboot-test2
spring.rabbitmq.listener.order.queue.durable=true
spring.rabbitmq.listener.order.exchange.name=springboot-exchanges
spring.rabbitmq.listener.order.exchange.durable=true
spring.rabbitmq.listener.order.exchange.type=topic
spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions=true
spring.rabbitmq.listener.order.key=springboot.order

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值