消息队列 : spring-boot 集成 rabbitmq

本文深入探讨了基于Erlang编写的开源消息队列RabbitMQ,详细介绍了其核心特性,包括数据的一致性、稳定性和可靠性。文章涵盖了如何在项目中引入RabbitMQ依赖,配置应用连接,并提供了创建工厂连接、模板配置及消费者实例的代码示例。此外,还讨论了RabbitMQ的优缺点,如适应性强但性能和吞吐量一般。

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

介绍:

RabbitMQ是基于Erlang语言编写的开源消息队列,通过Erlang的Actor模型实现了数据的稳定可靠传输。本身是实现AMQP的消息队列,因此官方推荐,如果仅仅是使用RabbitMQ的话,建议使用AMQP 0-9-1的协议。不过,因为其可扩展性,可以通过插件的形式使用STOMP、XMPP、AMQP 1.0,还可以通过插件使用HTTP这种非消息的传输协议。所以,RabbitMQ可以说是适应性非常强的一个消息队列中间件了。

当然,不仅是协议支持的多,还因为它实现了代理(Broker)架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,适宜于很多场景如路由、负载均衡或消息持久化等,用消息队列只需几行代码即可搞定。但是,这使得它的可扩展性差,速度较慢,因为中央节点增加了延迟,消息封装后也比较大,如需配置RabbitMQ则需要在目标机器上安装Erlang环境。

总的来说,RabbitMQ在数据一致性、稳定性和可靠性方面比较优秀,而且直接或间接的支持多种协议,对多种语言支持良好。但是其性能和吞吐量差强人意,由于Erlang语言本身的限制,二次开发成本较高

代码部分:

1、增加rabbitmq的依赖包



<!-- ampq 依赖包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
 </dependency>

2、application.xml文件中配置

#RabbitMQ配置信息
#spring.application.name=spirng-boot-rabbitmq
spring.rabbitmq.host=39.108.***.****
spring.rabbitmq.port=*****
spring.rabbitmq.username=****
spring.rabbitmq.password=******
spring.rabbitmq.virtual-host=/hotcomm_manager
spring.rabbitmq.queue=hotcomm.manager.qingdao

3、RabbitMq的工厂连接和模板创建

@Configuration
public class RabbitMQConfig {
	
	   /**
     * 注入配置文件属性
     */
	@Value("${spring.rabbitmq.host}")
	private String host;
	@Value("${spring.rabbitmq.port}")
	private Integer port;
	@Value("${spring.rabbitmq.username}")
	private String username;
	@Value("${spring.rabbitmq.password}")
	private String password;
	@Value("${spring.rabbitmq.virtual-host}")
	private String virtualhost;
	@Value("${spring.rabbitmq.queue}")
	private String queue;

	@Autowired
	SocketService socketService;
	@Autowired
	EventService eventService;
	@Autowired
	TMessageLogService MessageLogService;
	@Autowired
	AppPushService appPushService;
	@Autowired
	AppPushMsgMapper appPushMsgMapper;
	
	/**
     * 创建 ConnectionFactory
     *
     * @return
     * @throws Exception
     */
	
	@Bean
	public ConnectionFactory creatConnectionFactory() throws    Exception  {
		CachingConnectionFactory factory = new CachingConnectionFactory();
		factory.setHost(host);
		factory.setVirtualHost(virtualhost);
		factory.setPort(port);
		factory.setUsername(username);
		factory.setPassword(password);
		return factory;
		
	}
	
	
	  //rabbitmq的模板配置
	@Bean
	public RabbitTemplate receiveRabbitTemplate(ConnectionFactory connectionFactory) {
		RabbitTemplate firstRabbitTemplate = new RabbitTemplate(connectionFactory);
		return firstRabbitTemplate;
	}
	
      //消费者
	@Bean
	public SimpleMessageListenerContainer messageContainer(ConnectionFactory connectionFactory) {
		SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
		container.setQueues(new Queue[] { new Queue(queue) });   //设置监听的队列
		container.setExposeListenerChannel(true);
		container.setMaxConcurrentConsumers(5);
		container.setConcurrentConsumers(1);
		container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
		container.setMessageListener(new Receiver());
		return container;
	}

	class Receiver implements ChannelAwareMessageListener {

		@Override
		public void onMessage(Message message, Channel channel) throws Exception {
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
			byte[] body = message.getBody();
			String ss = new String(body);
			System.out.println(ss);
			publishMessage(ss);
		}
	}

	
	
	/**
	 * 解析message信息,确定设备类型,查询指定表,确定责任人,发送信息(测试)
	 * 
	 * @param message
	 */
	public void publishMessage(String message) throws MyException {
		TMessageLog tMessageLog = new TMessageLog();
		Gson gson = new Gson();
		T_dev_alarm dev_alarm = gson.fromJson(message, T_dev_alarm.class);
		// 查询当前设备的责任人(安装位置等)
		AlarmDev dev = eventService.selectDevForUser(dev_alarm.getDeviceid(), dev_alarm.getModuleid());
		dev.setAlarmtime(ConverUtil.dateForString(new Date()));
		String json = JSONUtil.toJson(dev);
		tMessageLog.setMessage(json);
		tMessageLog.setReceiverid(dev.getOwnid());
		tMessageLog.setSendtime(ConverUtil.dateForString(new Date()));
		tMessageLog.setUserid(0);
		// String s="{\"systate\":,\"message\":"+tMessageLog+"}";
		// 推送指定用户
		// socketService.sendMessageToOne(tMessageLog);
		// 广播
		socketService.sendMessageToAll(tMessageLog);
		if (dev.getOwnid() != null && !dev.getOwnid().equals(null) && !dev.getOwnid().equals("")) {
			String[] uid = dev.getOwnid().split(",");
			List<String> list = new ArrayList<>();
			for (String u : uid) {
				if (!list.contains(u)) {
					list.add(u);
				}
			}
			for (int i = 0; i < list.size(); i++) {
				// 查出用户regid
				T_hk_apppush t_hk_apppush = appPushService.selectRegid(Integer.valueOf(list.get(i)));
				int code = 0;
				if (t_hk_apppush != null) {
					// 向单个用户推送报警消息
					dev.setId(dev_alarm.getId());
					code = PushUtil.sendAllsetNotification("报警消息", "设备:" + dev.getDevnum() + "发生报警,请及时查看处理",
							JSONUtil.toJson(ApiResult.resultInfo("0", "报警", dev)), t_hk_apppush.getRegid(), 86400);
				}
				if (code == 0 || code == 201) {// 201推送失败
					// 推送失败的时候,把推送信息存进数据库,等下次登录的时候从数据库取出推送
					T_hk_apppush_msg t_hk_apppush_msg = new T_hk_apppush_msg();// 推送消息储存表
					t_hk_apppush_msg.setTitle("报警消息");
					t_hk_apppush_msg.setContent("设备:" + dev.getDevnum() + "发生报警,请及时查看处理");
					t_hk_apppush_msg.setMessage(JSONUtil.toJson(ApiResult.resultInfo("0", "报警", dev)));
					t_hk_apppush_msg.setRegids("0");
					t_hk_apppush_msg.setTimeToLive(String.valueOf(86400));
					t_hk_apppush_msg.setUserid(Integer.valueOf(list.get(i)));
					// 插入推送消息数据库
					appPushMsgMapper.insertSelective(t_hk_apppush_msg);
				}
			}
		}
	}
}

 

### Spring Boot 整合 RabbitMQ 实现消息队列 #### 添加依赖项 为了使Spring Boot项目能够与RabbitMQ交互,需在`pom.xml`文件中加入特定的依赖项。这可以通过引入`spring-boot-starter-amqp`来完成[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` #### 配置RabbitMQ连接属性 接着要配置RabbitMQ的相关参数以便于建立连接。这些设置通常位于应用的配置文件内,比如`application.properties`或`application.yml`。以下是基于YAML格式的一个例子: ```yaml spring: rabbitmq: host: localhost port: 5672 username: guest password: guest ``` #### 创建配置类 定义一个Java配置类用来声明必要的组件如队列、交换器以及绑定关系等。下面展示了一个简单的案例,其中包含了创建名为`orderQueue`的队列并与主题型交换器相联接的过程[^4]。 ```java import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class RabbitMqConfiguration { private static final String ORDER_QUEUE_NAME = "order.queue"; private static final String TOPIC_EXCHANGE_NAME = "topic.exchange"; @Bean public Queue orderQueue() { return new Queue(ORDER_QUEUE_NAME, true); } @Bean public TopicExchange topicExchange() { return new TopicExchange(TOPIC_EXCHANGE_NAME); } @Bean public Binding orderBinding(Queue orderQueue, TopicExchange topicExchange) { return BindingBuilder.bind(orderQueue).to(topicExchange).with("order.routing.key"); } } ``` #### 编写生产者逻辑 接下来编写负责向指定路由键发送消息的服务端代码。这里给出了一段基本的例子,展示了怎样通过模板对象将一条字符串形式的消息推送到之前设定好的队列里去。 ```java import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MessageProducerService { private final RabbitTemplate rabbitTemplate; @Autowired public MessageProducerService(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; } public void sendMessage(String messageContent){ System.out.println("[x] Sending message : '" + messageContent + "'"); rabbitTemplate.convertAndSend("topic.exchange", "order.routing.key", messageContent); } } ``` #### 构建消费者部分 最后一步就是设立接收并处理来自目标队列的数据的方法。此过程涉及监听某个具体的队列,并对接收到的内容作出响应动作。 ```java import com.rabbitmq.client.Channel; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener; import org.springframework.stereotype.Component; @Component public class OrderConsumer implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { byte[] body = message.getBody(); try{ System.out.println(new String(body)); // 手动确认消费成功 channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); }catch (Exception e){ // 处理失败情况下的回滚操作或其他措施 channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值