环境准备
安装jdk
因为rocketmq是使用java代码编写的,所以需要先安装jdk。
⽹上下载⼀个rpm包,⽐如jdk-8u191-linux-x64.rpm.
建议以管理员的身份安装。su 命令
先给rpm安装包添加执⾏权限:chmod +x jdk-8u191-linux-x64.rpm
使⽤rpm命令安装jdk:rpm -ivh jdk-8u191-linux-x64.rpm
执⾏完后即完成了jdk的安装,检查安装的jdk:java -version
默认的安装⽬录是/usr/java/ls /usr/java/
配置环境变量 --> 配置jdk到PATH⽬录vim ~/.bash_profile
末尾增加配置内容:
export JAVA_HOME=/usr/java/latest
export PATH=$PATH:$JAVA_HOME/bin
重新加载配置⽂件:source ~/.bash_profile
然后就可以使用javac、jps这些命令来检查是否安装好。
安装rocketMQ
主要是看你项目使用的版本是那个,对应就下载哪个。所以这⾥也选择安装对应的服务端版本。我的4.7.1
wget https://archive.apache.org/dist/rocketmq/4.7.1/rocketmq-all-4.7.1-bin-release.zip
解压缩
unzip rocketmq-all-4.7.1-bin-release.zip -- 解压
cd rocketmq-all-4.7.1-bin-release -- 进入rocketmq目录
启动Name Server
启动之前先检查⼀下Name Server的jvm配置,避免服务器内存不⾜,导致出现各种问题。vim ./bin/runserver.sh
堆内存默认给了4G,⽐较占⽤内存了,如果只是开发测试环境,建议调⼩jvm的配置。我都是修改成256M。
守护进程⽅式启动Name Server:nohup sh ./bin/mqnamesrv &
查看启动⽇志:
tail -f ~/logs/rocketmqlogs/namesrv.log
启动Broker
启动之前先检查⼀下Broker的jvm配置,避免服务器内存不⾜,导致出现各种问题。vim bin/runbroker.sh
nohup sh bin/mqbroker -n 172.40.125.86:9876 &
-- 172.40.125.86:9876是Name Server服务的地址与端⼝
查看启动⽇志:tail -f ~/logs/rocketmqlogs/broker.log
还可以弄一个rocketmq的控制台。
- 先下载 rocketmq-console-ng-1.0.1.jar
- 守护进程⽅式启动rocketmq-console
nohup java -jar -server -Xms2g -Xmx2g -Drocketmq.config.namesrvAddr=172.40.125.86:9876 -Dserver.port=8080 rocketmq-console-ng-1.0.1.jar &
-- rocketmq-console-ng-1.0.1.jar是本地上传到服务器的
-- 172.40.125.86:9876是Name Server的地址
浏览器访问console控制台:
http://ip:8080/
就可以了。
如果没有Linux的环境,也可以在win10环境启动rocketmq
http://t.zoukankan.com/yyee-p-14569864.html
代码
1. 在pom里加入依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
2. 在application.yml 文件里
rocketmq:
name-server: 192.168.16.43:9876 # 你的rocketmq的IP地址
3. MQ的配置文件
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(RocketMQProperties.class)
public class RocketMQConfig {
}
RocketMQProperties rocketmq的配置信息
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* rocketmq的配置信息
*/
@ConfigurationProperties(prefix = "rocketmq")
public class RocketMQProperties {
private String nameServer;
public String getNameServer() {
return nameServer;
}
public void setNameServer(String nameServer) {
this.nameServer = nameServer;
}
}
生产者:
package com.example.demoall.mq.producer;
import com.example.demoall.mq.config.RocketMQProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Slf4j
@Component
public class DefaultProducer {
private final TransactionMQProducer producer;
@Autowired
public DefaultProducer(RocketMQProperties rocketMQProperties) {
producer = new TransactionMQProducer("order_default_producer_group");
producer.setNamesrvAddr(rocketMQProperties.getNameServer());
start();
}
/**
* 对象在使用之前必须要调用一次,只能初始化一次
*/
public void start() {
try {
this.producer.start();
} catch (MQClientException e) {
log.error("producer start error", e);
}
}
/**
* 一般在应用上下文,使用上下文监听器,进行关闭
*/
public void shutdown() {
this.producer.shutdown();
}
/**
* 发送消息
*
* @param topic topic
* @param message 消息
*/
public void sendMessage(String topic, String message, String type) {
sendMessage(topic, message, -1, type);
}
/**
* 发送消息
*
* @param topic topic
* @param message 消息
*/
public void sendMessage(String topic, String message, Integer delayTimeLevel, String type) {
Message msg = new Message(topic, message.getBytes(StandardCharsets.UTF_8));
try {
if (delayTimeLevel > 0) {
msg.setDelayTimeLevel(delayTimeLevel);
}
SendResult send = producer.send(msg);
if (SendStatus.SEND_OK == send.getSendStatus()) {
log.info("发送MQ消息成功, type:{}, message:{}", type, message);
} else {
// throw new OrderBizException(send.getSendStatus().toString());
}
} catch (Exception e) {
log.error("发送MQ消息失败:", e);
// throw new OrderBizException(OrderErrorCodeEnum.SEND_MQ_FAILED);
}
}
public TransactionMQProducer getProducer() {
return producer;
}
}
消费者:
消费者的配置
ConsumerConfig.java
package com.example.demoall.mq.consumer;
import com.example.demoall.mq.config.RocketMQProperties;
import com.example.demoall.mq.consumer.listener.PaidOrderSuccessListener;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConsumerConfig {
@Autowired
private RocketMQProperties rocketMQProperties;
/**
* 订单完成支付消息消费者
*
* @param paidOrderSuccessListener
* @return
* @throws MQClientException
*/
@Bean("paidOrderSuccessConsumer")
public DefaultMQPushConsumer paidOrderSuccessConsumer(PaidOrderSuccessListener paidOrderSuccessListener)
throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("paid_order_success_consumer_group");
consumer.setNamesrvAddr(rocketMQProperties.getNameServer());
consumer.subscribe("paid_order_success_topic", "*");
consumer.registerMessageListener(paidOrderSuccessListener);
consumer.start();
return consumer;
}
}
监听消费者
package com.example.demoall.mq.consumer.listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 监听订单支付成功后的消息
*/
@Slf4j
@Component
public class PaidOrderSuccessListener implements MessageListenerConcurrently {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
try {
for(MessageExt messageExt : list) {
String message = new String(messageExt.getBody());
System.out.println("消费的消息是:" + message);
}
System.out.println("消费成功!!!");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} catch (Exception e) {
log.error("consumer error", e);
//本地业务逻辑执行失败,触发消息重新消费
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
}
发送消息
@RestController
@RequestMapping("/mq/test")
public class MQcontroller {
@Autowired(required = false)
private DefaultProducer defaultProducer;
@GetMapping("/mqtest")
public String triggerOrderPaidEvent(@RequestParam("orderId") String orderId) {
System.out.println(orderId);
String msgJson = JSON.toJSONString(orderId);
System.out.println("发生消息" + orderId);
defaultProducer.sendMessage("paid_order_success_topic", msgJson, "订单已完成支付");
return orderId;
}
}
目前这个案例是往paid_order_success_topic发送消息。
这个mq的使用模式相对来说比较简洁。
项目的代码:https://gitee.com/adonggege/demoall/tree/master
加油!
可以私信我交流哈