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

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);
}
}

浙公网安备 33010602011771号