rabbitmq springboot整合

本文采用directExchange,为保证针对同个用户的消息要有消费顺序,采用多队列,每条队列单线程消费进行配置

消息发送端配置

  配置参数接收类

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
* 配置类
*/
@Configuration
@ConfigurationProperties(prefix = "spring.rabbitmq")
public class RabbitMqProperties {
    private String addresses;//地址
    private String username;//用户名
    private String password;//密码
    private Boolean publisherConfirms;//是否发送校验
    private String virtualHost;//虚拟地址
    private Boolean defaultDurable;// 是否持久化
    private Boolean autoDelete;//当所有消费客户端连接断开后,是否自动删除队列

    public String getAddresses() {
        return addresses;
    }

    public void setAddresses(String addresses) {
        this.addresses = addresses;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Boolean getPublisherConfirms() {
        return publisherConfirms;
    }

    public void setPublisherConfirms(Boolean publisherConfirms) {
        this.publisherConfirms = publisherConfirms;
    }

    public String getVirtualHost() {
        return virtualHost;
    }

    public void setVirtualHost(String virtualHost) {
        this.virtualHost = virtualHost;
    }

	public Boolean getDefaultDurable() {
        return defaultDurable;
    }

    public void setDefaultDurable(Boolean defaultDurable) {
        this.defaultDurable = defaultDurable;
    }

    public Boolean getAutoDelete() {
        return autoDelete;
    }

    public void setAutoDelete(Boolean autoDelete) {
        this.autoDelete = autoDelete;
    }
}

  配置参数

#rabbitmq配置信息
spring.rabbitmq.addresses=127.0.0.1:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisherConfirms=true
spring.rabbitmq.virtualHost=/rabbit
spring.rabbitmq.defaultDurable=true
spring.rabbitmq.autoDelete=false
rabbitmq.routingKey.count=3
rabbitmq.exchange=local.exchange
rabbitmq.routingKey=local.queue_

  配置类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.amqp.rabbit.support.CorrelationData;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;


@Configuration
public class AmqpConfig {

    private static Logger log = LoggerFactory.getLogger(AmqpConfig.class);

    @Autowired
    private RabbitMqProperties rabbitMqProperties;

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory connectionFactory=new CachingConnectionFactory();
        connectionFactory.setAddresses(rabbitMqProperties.getAddresses());
        connectionFactory.setUsername(rabbitMqProperties.getUsername());
        connectionFactory.setPassword(rabbitMqProperties.getPassword());
        connectionFactory.setVirtualHost(rabbitMqProperties.getVirtualHost());
       connectionFactory.setPublisherConfirms(rabbitMqProperties.getPublisherConfirms());
        return connectionFactory;
    }

    // 这里作用域设置为原型模式  每次获取都会得到一个新的实例
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate(){
        RabbitTemplate rabbitTemplate=new RabbitTemplate(connectionFactory());
        //数据转换为json存入消息队列
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        //发布确认
        rabbitTemplate.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) -> {
            if (!ack){
                log.error("发送到消息失败");
                throw new RuntimeException("send error " + cause);
            }
        });
        return rabbitTemplate;
    }

    /**
     * rabbitAdmin代理类
     * @return
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        return new RabbitAdmin(connectionFactory);
    }
}

  发送消息util类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

/**
* 消息发送util
*/
@Component
public class SendMsgUtils {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private AmqpTemplate rabbitTemplate;

  
    public void sendMsg(String exchange, String routingKey,String content){
        MessageProperties messageProperties = new MessageProperties();
        // 设置消息持久化
        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        try {
            Message message = new Message(content.getBytes("utf-8"),messageProperties);
            rabbitTemplate.send(exchange, routingKey, message);
        } catch (UnsupportedEncodingException e) {
            logger.info("发送消息失败 exchange{},routingKey:{},content",exchange,routingKey,content);
            e.printStackTrace();
        }
    }
}

  测试controller类

@RestController
@RequestMapping(path = "/test")
public class TestController {
    
        @Value("${rabbitmq.exchange}")
	private String AUDIENCE_EXCHANGE;// 交换器名

	@Value("${rabbitmq.routingKey}")
	private String ROUTING_KEY;// 路由键

	@Value("${rabbitmq.routingKey.count}")
	private Integer ROUTING_KEY_COUNT;// 路由键个数

        @Autowired
	private SendMsgComponent sendMsgComponent;

	@PostMapping(path = "/sendMessage")
        public void testSend(String userId,String message){
            // 计算路由键  
	    int routeKey = HashUtils.getHash(userId) % ROUTING_KEY_COUNT;
            // 发送消息
	    sendMsgComponent.sendMsg(AUDIENCE_EXCHANGE,ROUTING_KEY+routeKey,message);
    }
  
}


	org.springframework.boot
	spring-boot-starter-amqp

消息接收端配置

  配置参数

#rabbitmq配置信息
spring.rabbitmq.addresses=127.0.0.1:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisherConfirms=true
spring.rabbitmq.virtualHost=/rabbitpre
spring.rabbitmq.defaultDurable=true
spring.rabbitmq.autoDelete=false
# exchange
rabbitmq.exchange=local.exchange
# 3个队列消费
rabbitmq.queue_0=local.queue_0
rabbitmq.queue_1=local.queue_1
rabbitmq.queue_2=local.queue_2
#消费队列数
rabbitmq.queue.audience.count=3

  xml配置




      
    
       
    

    
    
    
    

    
    
        
            
            
            
        
    
    
    

    
    
    
    
    
    

    

  消息监听器

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.zbmy.rabbit.workbench.data.server.utils.HashUtils;
import org.elasticsearch.client.transport.TransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

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

@Component
public class MqListener implements ChannelAwareMessageListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(UpdateAudienceListener.class);

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        try {
            byte[] body = message.getBody();
            String messageStr = new String(body, "UTF-8");
            doSomething(parseMessage(messageStr));
            // 确认     false不批量确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            LOGGER.error("处理消息失败:{}", e);
            // 拒绝消息     false不重新放入队列
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

    private Map parseMessage(String messageStr){
        Map resultMap = new HashMap<>();
        Map map = JSON.parseObject(messageStr);
        for (Map.Entry entry : map.entrySet()) {
            resultMap.put(entry.getKey(),entry.getValue());
        }
        return resultMap;
    }
}

基础知识推荐这篇文章  https://www.jianshu.com/p/79ca08116d57

mq官方各版本文档地址  https://docs.spring.io/spring-amqp/docs/

 

你可能感兴趣的:(rabbitmq,消息中间件)