rabbitmq搭建与使用

rabbitmq搭建与项目中使用

1.Linux rabbitmq离线安装

rabbitmq依赖

Rabbitmq安装主要依赖两个rpm包, erlang和socat

1.下载erlang

https://packagecloud.io/rabbitmq/erlang,下载对应的erlang包

注意:centos7需要19.3以上版本

erlang-22.1.8-1.el7.x86_64.rpm

2.下载socat

http://www.rpmfind.net/linux/rpm2html/search.php?query=socat(x86-64),下载对应的socat安装包

socat-1.7.3.2-2.el7.x86_64.rpm

3.下载rabbitmq离线包

http://www.rabbitmq.com/install-rpm.html,下载centos7版本的安装包

rabbitmq-server-3.8.2-1.el7.noarch.rpm

rpm安装

使用rpm安装

sudo rpm -ivh erlang-22.1.8-1.el7.x86_64.rpm
sudo rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm
sudo rpm -ivh rabbitmq-server-3.8.2-1.el7.noarch.rpm

启动rabbitmq服务

1.执行sudo service rabbitmq-server start
显示如下表示成功

Redirecting to /bin/systemctl start rabbitmq-server.service

2.配置rabbitmq管理账户

rabbitmqctl add_user admin admin  # 设置账户密码为admin admin

3.设置admin为管理员权限

rabbitmqctl set_user_tags admin administrator

4.打开rabbitmq web管理界面

rabbitmq-plugins enable rabbitmq_management

5.理链接为:http://localhost:15672,登陆账户密码为设置的admin admin

常见错误

1.启动错误

Job for rabbitmq-server.service failed because the control process exited with error code. See "systemctl status rabbitmq-server.service" and "journalctl -xe" for details.

查看journalctl -xe查看错误日志。

可能是版本问题,erlang的版本,安装rabbitmq版本是3.8.2,需要的erlang版本大于20.3,应为安装的erlang版本是19.3.

更换erlang版本,重新安装即可

2.阿里云服务器部署rabbitmq服务后,无法访问http://ip:15672

阿里云服务器有自己的安全策略配置,部署任何服务后,无法直接访问,需要去阿里云的安全策略组织里面开放服务对应的端口,才能继续访问。

开放之后,就可以正常访问页面了。

3.无法访问rabbitmq的web页面

如果要访问rabbitmq的web页面,需要开启web页面的插件

rabbitmq-plugins enable rabbitmq_management

img

2.项目中使用

1.1 rabbitmq 配置类

    private String host = "127.0.0.1";
    private int port = 5672;
	private String addresses = "";
    private String username = "xxx";
    private String password = "xxxx";
    private String virtualHost = "/xxx";
    private boolean publisherConfirms = true;
    private int connectionCacheSize = 5;
    private int connectionLimit = 100;
    private int connectionTimeout = 180000;
    private int concurrentConsumers = 3;
    private int maxConcurrentConsumers = 10;
    private int prefetchCount = 100;
    private boolean durable = true;
    private boolean autoDelete = false;
    private boolean exclusive = false;
    private Retry retry = new Retry();
1.封装生产者
1.1生产者工厂类
    @SuppressWarnings("deprecation")
    @Bean
    @ConditionalOnMissingBean(name = "connectionFactory")
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        if(StringUtil.isNotBlank(rabbitConfigure.getAddresses())) {
        	connectionFactory.setAddresses(rabbitConfigure.getAddresses());
        }
        else {
        	connectionFactory.setHost(rabbitConfigure.getHost());
        	connectionFactory.setPort(rabbitConfigure.getPort());
        }
		connectionFactory.setUsername(rabbitConfigure.getUsername());
        connectionFactory.setPassword(rabbitConfigure.getPassword());
        connectionFactory.setVirtualHost(rabbitConfigure.getVirtualHost());
        /** 如果要进行消息回调,则这里必须要设置为true */
        connectionFactory.setPublisherConfirms(rabbitConfigure.isPublisherConfirms());
        //connectionFactory.setConnectionCacheSize(rabbitProducerConfigure.getConnectionCacheSize());
        //connectionFactory.setConnectionLimit(rabbitProducerConfigure.getConnectionLimit());
        connectionFactory.setConnectionTimeout(rabbitConfigure.getConnectionTimeout());
        
        return connectionFactory;
    }

    @Bean
    @Scope("prototype")
    @ConditionalOnMissingBean(name = "rabbitTemplate")
    public RabbitTemplate rabbitTemplate() {
    	RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
    	//MessageConverter messageConverter = new Jackson2JsonMessageConverter(JacksonUtil.mapper());
    	MessageConverter messageConverter = new SimpleMessageConverter();
    	rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
    }
    
	@Bean(name = "messageChannel")
	public Channel messageChannel() {
		Channel channel = null;
		try {
			if(logger.isDebugEnabled()){
				logger.debug("Message channel initial.");
			}
			channel = connectionFactory().createConnection().createChannel(false);
			channel.exchangeDeclare(
					QueueConstants.Message.EXCHANGE_MESSAGE, 
					BuiltinExchangeType.DIRECT, 
					rabbitConfigure.isDurable(), 
					rabbitConfigure.isAutoDelete(), 
					null);
		} catch (Exception e) {
			logger.error("RabbitMQ initial failed:", e);
		}
		
		return channel;
	}
1.2 封装消费者
@EnableRabbit
@Configuration
@ConditionalOnProperty(prefix = "com.xx.xx", name = "enabled", havingValue = "true", matchIfMissing = true)
public class RabbitConsumerConfig {
	
	@Autowired
	private RabbitConfigure rabbitConfigure;

	@Bean
	@ConditionalOnMissingBean(name = "connectionFactory")
	public ConnectionFactory connectionFactory() {
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
		if(StringUtil.isNotBlank(rabbitConfigure.getAddresses())) {
        	connectionFactory.setAddresses(rabbitConfigure.getAddresses());
        }
        else {
        	connectionFactory.setHost(rabbitConfigure.getHost());
        	connectionFactory.setPort(rabbitConfigure.getPort());
        }
		connectionFactory.setUsername(rabbitConfigure.getUsername());
		connectionFactory.setPassword(rabbitConfigure.getPassword());
		connectionFactory.setVirtualHost(rabbitConfigure.getVirtualHost());
		/** 如果要进行消息回调,则这里必须要设置为true */
		connectionFactory.setPublisherConfirms(rabbitConfigure.isPublisherConfirms());
		//connectionFactory.setConnectionCacheSize(rabbitConsumerConfigure.getConnectionCacheSize());
		//connectionFactory.setConnectionLimit(rabbitConsumerConfigure.getConnectionLimit());
		connectionFactory.setConnectionTimeout(rabbitConfigure.getConnectionTimeout());
		
		return connectionFactory;
	}

	@Bean
	/** 因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置 */
	@Scope("prototype")
	@ConditionalOnMissingBean(name = "rabbitTemplate")
	public RabbitTemplate rabbitTemplate() {
		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
		//MessageConverter messageConverter = new Jackson2JsonMessageConverter(JacksonUtil.mapper());
		MessageConverter messageConverter = new SimpleMessageConverter();
    	rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
	}
	
	/**
	 * 使用@RabbitListener必须配置该选项
	 *
	 * @return 
	 */
	@Bean
	public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
		factory.setConnectionFactory(connectionFactory());
		factory.setConcurrentConsumers(rabbitConfigure.getConcurrentConsumers());
		factory.setMaxConcurrentConsumers(rabbitConfigure.getMaxConcurrentConsumers());
		factory.setPrefetchCount(rabbitConfigure.getPrefetchCount());
		//MessageConverter messageConverter = new Jackson2JsonMessageConverter(JacksonUtil.mapper());
		MessageConverter messageConverter = new SimpleMessageConverter();
		factory.setMessageConverter(messageConverter);
		
		if(rabbitConfigure.getRetry().isEnabled()) {
			factory.setAdviceChain(
					RetryInterceptorBuilder
					.stateless()
					.recoverer(new RejectAndDontRequeueRecoverer())
					.retryOperations(createSimpleRetryTemplate())
					.build()
					);
		}
		
		return factory;
	}
	
	private RetryTemplate createSimpleRetryTemplate() {
		RetryTemplate retryTemplate = new RetryTemplate();
		
		retryTemplate.setRetryPolicy(new SimpleRetryPolicy(rabbitConfigure.getRetry().getMaxAttempts()));
		
		ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
		backOffPolicy.setInitialInterval(rabbitConfigure.getRetry().getInitialInterval());
		backOffPolicy.setMultiplier(rabbitConfigure.getRetry().getMultiplier());
		backOffPolicy.setMaxInterval(rabbitConfigure.getRetry().getMaxInterval());
		retryTemplate.setBackOffPolicy(backOffPolicy);
		
		return retryTemplate;
	}

	@Bean
	@ConditionalOnProperty(prefix = "com.lc.mq.message.consumer", name = "enabled", havingValue = "true", matchIfMissing = true)
	public IQueueConsumer<DefaultMessage<?>> rabbitMessageQueueConsumer() {
		return new RabbitMessageQueueConsumer<DefaultMessage<?>>();
	}

1.3 生产者推送接口
String exchange = QueueConstants.Message.EXCHANGE_MESSAGE;
		String routing = QueueConstants.Message.ROUTING_KEY_MESSAGE;
		if(StrUtil.isNotBlank(message.getExchange())) {
			exchange = message.getExchange();
		}
		if(StrUtil.isNotBlank(message.getRouting())) {
			routing = message.getRouting();
		}
		if(logger.isDebugEnabled()){
			logger.debug("send to exchange {}, routing {} of message {}.", exchange, routing, message);
		}
		rabbitTemplate.convertAndSend(exchange, routing, message);

 private void sendEmail(List<String> receivers, String content) {
        DefaultMessage<?> message = null;
        /* start mail */
        message = new DefaultMessage<>();
        message.setMessageType(MessageType.MAIL.name());

        if (BeanUtils.isEmpty(receivers)) {
            receivers = new ArrayList<String>();
            receivers.add("xuq@bpmhome.cn");
        }
        message.setReceivers(receivers);

        DefaultMessageTemplate template = new DefaultMessageTemplate();
        template.setContentType(ContentType.PLAIN);
        template.setKey("test");
        template.setName("测试");
        template.setSubject("邮件测试");

        if (StringUtil.isBlank(content)) {
            content = "测试内容";
        }
        template.setContent(content);

        message.setTemplate(template);

        messageQueueProducer.push(message);
        /* end email */
    }
1.4 消费者处理消息工具类
	public static void handle(Message<?> message) {
		handle(message, getMessageQueueHandlers());
	}
	
	public static void handle(Message<?> message, Map<String, IMessageQueueHandler<Message<?>>> messageQueueHandlers) {
		if(null == message || null == message.getMessageType()) {
			logger.warn("message or handler type is null.");
			return;
		}
		
		String handlerKey = StringUtil.build(message.getMessageType().toLowerCase(), "MessageQueueHandler");
		IMessageQueueHandler<Message<?>> messageQueueHandler = messageQueueHandlers.get(handlerKey);
		if(null != messageQueueHandler)
		{
			if(logger.isDebugEnabled()){
				logger.debug("Message handler of {} for {}.", messageQueueHandler.getMessageType(), message);
			}
			messageQueueHandler.send(message);
		}
		else
		{
			logger.warn("the handler type of {} is null.", message.getMessageType());
		}
	}
1.5 消费者监听类
public class RabbitChannelMessageListener implements ChannelAwareMessageListener {

	private static final Logger logger = LoggerFactory.getLogger(RabbitChannelMessageListener.class);

	@Override
	public void onMessage(Message message, Channel channel) throws Exception {
		logger.info("queue {} on message.", message.getMessageProperties().getConsumerQueue());
		/*
		 * byte[] body = message.getBody(); logger.info("接收到消息:" + new
		 * String(body)); JSONObject jsonObject = null; try { jsonObject =
		 * JSONObject.parseObject(new String(body)); if (消费成功) {
		 * logger.info("消息消费成功");
		 * 
		 * channel.basicAck(message.getMessagePropertites().getDeliveryTag(),
		 * false);//确认消息消费成功
		 * 
		 * }else if(可重试的失败处理){
		 * 
		 * channel.basicNack(message.getMessageProperties().getDeliveryTag(),
		 * false, true);
		 * 
		 * } else { //消费失败
		 * 
		 * channel.basicNack(message.getMessageProperties().getDeliveryTag(),
		 * false, false); } catch (JSONException e) {
		 * channel.basicNack(message.getMessageProperties().getDeliveryTag(),
		 * false, false);//消息丢弃 logger.error("This message:" + jsonObject +
		 * " conversion JSON error "); }
		 */
	}
1.6 绑定队列到交换机
@RabbitListener(bindings = {
				@QueueBinding(
						exchange = @Exchange(value = QueueConstants.Message.EXCHANGE_MESSAGE),
						key = QueueConstants.Message.ROUTING_KEY_MESSAGE,
						value = @Queue(value = QueueConstants.Message.QUEUE_NAME)
					)
				})
public class RabbitMessageQueueConsumer<M extends Message<?>> implements IQueueConsumer<M> {
	
	@RabbitHandler
	@Override
	public void popup(M message) {
		MessageHandlerUtil.handle(message);
	}

}
posted @ 2024-02-21 20:57  我想去海边  阅读(65)  评论(0)    收藏  举报