消息中间件RocketMq之Api使用
简单使用
- Producer
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("myProducer01");
// 设置nameserver 地址
producer.setNamesrvAddr("127.0.0.1:9876");
producer.start();
// topic 消息发送的地址
// body 消息具体内容
new Thread(() -> {
for (int i = 0; i < 1000000; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg0 = new Message("myTopic001", ("我是消息" + i+ LocalDateTime.now()).getBytes());
// 单个发送
SendResult sendResult1 = null;
try {
sendResult1 = producer.send(msg0);
} catch (MQClientException e) {
e.printStackTrace();
} catch (RemotingException e) {
e.printStackTrace();
} catch (MQBrokerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("单个发送" + sendResult1);
}
producer.shutdown();
System.out.println("关闭");
}).start();
/*
Message msg1 = new Message("myTopic001", "我是消息1".getBytes());
Message msg2 = new Message("myTopic001", "我是消息2".getBytes());
Message msg3 = new Message("myTopic001", "我是消息3".getBytes());
ArrayList<Message> list = new ArrayList<Message>();
list.add(msg1);
list.add(msg2);
list.add(msg3);
// 批量发送
SendResult sendResult3 = producer.send(list);
System.out.println("批量发送"+sendResult3);*/
}
- consumer 消费端
public static void main(String[] args)throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("myConsumer01");
consumer.setNamesrvAddr("127.0.0.1:9876");
// 每个consumer只能关注一个topic
// topic 关注的消息主题
// 过滤器 * 表示不过滤
consumer.subscribe("myTopic001", "*");
// 注册消息监听
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.println(new String(msg.getBody())+ "=》消费时间:" + LocalDateTime.now());;
}
// 默认情况下这条消息只会被一个consumer消费 点对点的
// message 状态修改
// ack 确认消费
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 设置消费模式
// CLUSTERING 集群模式,只消费一次
// BROADCASTING 广播模式 可多次消费
consumer.setMessageModel(MessageModel.CLUSTERING);
consumer.start();
System.out.println("Consumer 02 start...");
}
异步消息发送
public static void main(String[] args)throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("producer02");
producer.setNamesrvAddr("47.111.130.108:9876");
producer.start();
// 异步可靠消息发送
// 不会阻塞,等待broker的确认
// 采用事件监听方式接受返回
new Thread(() -> {
for (int i = 0; i < 1000000; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg0 = new Message("myTopic001", ("我是消息" + i + "=>" + LocalDateTime.now()).getBytes());
// producer.setRetryTimesWhenSendAsyncFailed(retryTimesWhenSendAsyncFailed);
try {
producer.send(msg0, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功 sendResult =》 " + sendResult);
}
@Override
public void onException(Throwable e) {
// 如果发生异常
e.printStackTrace();
System.out.println("如果发生异常");
}
});
} catch (MQClientException e) {
e.printStackTrace();
} catch (RemotingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
producer.shutdown();
System.out.println("已经停机");
}).start();
}
消息的发送
- 同步消息
消息发送中进入同步等待状态,可以保证消息投递一定到达
- 异步消息
想要快速发送消息,又不想丢失的时候可以使用异步消息
producer.send(message,new SendCallback() {
public void onSuccess(SendResult sendResult) {
// TODO Auto-generated method stub
System.out.println("ok");
}
public void onException(Throwable e) {
// TODO Auto-generated method stub
e.printStackTrace();
System.out.println("err");
}
});
- 单向消息
只发送消息,不等待服务器响应,只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。
producer.sendOneway(message);
- 批量消息发送
可以多条消息打包一起发送,减少网络传输次数提高效率。
producer.send(Collection c)
方法可以接受一个集合 实现批量发送
public SendResult send(
Collection<Message> msgs) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
return this.defaultMQProducerImpl.send(batch(msgs));
}
- 批量消息要求必要具有同一topic、相同消息配置
- 不支持延时消息
- 建议一个批量消息最好不要超过1MB大小
- 如果不确定是否超过限制,可以手动计算大小分批发送
消费模式
// CLUSTERING 集群模式,只消费一次
// BROADCASTING 广播模式 可多次消费
consumer.setMessageModel(MessageModel.CLUSTERING);
- 集群模式
集群消息是指集群化部署消费者
当使用集群消费模式时,MQ 认为任意一条消息只需要被集群内的任意一个消费者处理即可。
特点
- 每条消息只需要被处理一次,broker只会把消息发送给消费集群中的一个消费者
- 在消息重投时,不能保证路由到同一台机器上
- 消费状态由broker维护
- 广播模式
当使用广播消费模式时,MQ 会将每条消息推送给集群内所有注册过的客户端,保证消息至少被每台机器消费一次。
特点
-
消费进度由consumer维护
-
保证每个消费者消费一次消息
-
消费失败的消息不会重投
TAG过滤
可以使用tag来过滤消费
- 使用
在Producer中使用Tag:
Message msg = new Message("TopicTest","TagA" ,("Hello RocketMQ " ).getBytes(RemotingHelper.DEFAULT_CHARSET));
在Consumer中订阅Tag:
consumer.subscribe("TopicTest", "TagA||TagB");// * 代表订阅TopicTest下的TagA或TagB的消息
SQL表达式过滤
消费者将收到包含TAGA或TAGB或TAGB的消息. 但限制是一条消息只能有一个标签,而这对于复杂的情况可能无效。 在这种情况下,您可以使用SQL表达式筛选出消息.
- 配置
在broker.conf
中添加配置
enablePropertyFilter=true
启动broker 加载指定配置文件
../bin/mqbroker -n 192.168.150.113:9876 -c broker.conf
- 使用
发送消息时
message.putUserProperty("age","18");
消费消息时
MessageSelector messageSelector = MessageSelector.bySql("age >= 18 and age <= 28");
consumer.subscribe("myTopic003",messageSelector );
- Sql语法
RocketMQ只定义了一些基本的语法来支持这个功能。 你也可以很容易地扩展它.
- 数字比较, 像
>
,>=
,<
,<=
,BETWEEN
,=
;- 字符比较, 像
=
,<>
,IN
;IS NULL
或者IS NOT NULL
;- 逻辑运算
AND
,OR
,NOT
;
常量类型是:
- 数字, 像123, 3.1415;
- 字符串, 像‘abc’,必须使用单引号;
NULL
, 特殊常数;- 布尔常量,
TRUE
或FALSE
;
延迟消息
RocketMQ使用messageDelayLevel可以设置延迟投递
- 默认配置为
messageDelayLevel 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
- 配置
在broker.conf
中添加配置
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
这个配置项配置了从1级开始,各级延时的时间,可以修改这个指定级别的延时时间;
时间单位支持:s、m、h、d,分别表示秒、分、时、天;
3。 使用
发送消息时设置
message.setDelayTimeLevel(1);