消息
MQ(MessageQueue)消息队列/消息中间件,“先进先出”
企业级三种 异步消息传递技术规范:JMS、AMQP、MQTT
JMS(Java Message Service):等同jdbc,提供与消息服务相关的API接口,
JMS消息模型:
1.peer-2-peer:点对点模型,1个生产者对应1个消费者
2.publish-subscribe: 发布订阅模型,类似Redis,多个生产者对应多个消费者
JMS消息种类:Text,Map,Bytes,Stream,Stream,Object,Message(只有消息头和属性)
JMS实现产品:ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)
AMQP(advanced message queuing protocol):高级消息队列协议,规范了网络交换的数据格式,兼容JMS
优点:跨平台、服务器供应商,生产者,消费者无语言隔阂
AMQP消息模型:direct exchange、fanout exchange、topiic exchange、headers exchange、system exchange.
统一消息种类:byte[]
AMQP实现产品:RabbitMQ、StormMQ、RocketMQ
MQTT(Message Queueing Telemetry Transport):消息队列遥测传输,专为 小设备设计,应用于物联网
Kafka:,一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能。
ActiveMQ
下载地址:https://activemq.apache.org/components/classic/download/
启动:activemq.bat
访问服务器:http://127.0.0.1:8161
服务端口:61616,管理后台端口:8161
用户名&密码:admin
放入消息:(需要指定放入的位置)
方式1:convertAndSend(String destinationName, Object payload) //destinationName:规格命名:所属业务.队列名称.
方式2:
配置文件
server:
port: 80
spring:
activemq:
#代理地址
broker-url: tcp://localhost:61616
jms:
#打开发布订阅模型
pub-sub-domain: true
template:
default-destination: itheima
取出消息:
messagingTemplate.receiveAndConvert("queue.id",String.class);
自动监听取出消息
public class MessageListener {
@JmsListener(destination = "order.queue.id")
@SendTo("newqueue.id") //将返回结果发送到指定队列
public String receive(String id){
System.out.println("已完成短信发送业务,id:"+id);
return "new:"+id;
}
}
RabbitMQ:基于Erlang语言,需要安装Erlang
Erlang:
下载地址:https://www.erlang.org/downloads
安装后重启操作系统,依赖Windows组件
环境变量配置:
ERLANG_HOME
PATH
RabbitMQ:
下载地址:rabbitmq.com/install-windows.html
启动:管理员权限(命令 start),rabbitmq.service.bat(也可通过任务管理器开关服务)
所需插件:在rabbitmq-plugins
列出rabbitmq_management下插件:rabbitmq-plugins.bat list
可开启插件:rabbitmq-plugins.bat enable rabbitmq_management
浏览器访问管理:http://localhost:15672
用户名&密码:guest
——》direct exchange
server:
port: 80
spring:
rabbitmq:
host: localhost
port: 5672
//自定义类实现MessageService
@Autowired
private AmqpTemplate amqpTemplate;
3.配置类:设置direct exchange的交换机和队列
@Configuration
public class RabbitConfigDirect {
//消息队列
@Bean
public Queue directQueue(){
return new Queue("direct_queue"); //未列形参 durable:是否持久化、exclusive:是否连接专用(若连接关闭,队列删除)、autoDelete:false:生产者消费者不再使用此队列,自动删除
}
//交换机
@Bean
public DirectExchange directExchange(){
return new DirectExchange("directExchange");
}
//绑定队列与交换机
@Bean
public Binding bindingDirect(){
return BindingBuilder.bind(directQueue()).to(directExchange()).with("direct");
}
}
@RabbitListener(queues = "队列名称")
public void receive(String id){
System.out.println("*****,id:"+id);
}
——》topic exchange(与前者类似)
最大差别在Binding
RocketMQ:
下载链接:https://rocketmq.apache.org/
默认端口:9876
环境变量配置:
ROCKETMQ_HOME
PATH
NAMESRV_ADDR(建议): 127.0.0.1:9876 (NameServer,其他业务服务器注册代理(broker)到此服务器,生产者消费者寻找命名服务器)
先启动命名服务器mqnamesrv.cmd、后启动mqbroker.cmd(可双击)
可利用tools.sh和jar程序类测试是否
rocketmq:
name-server: localhost:9876
#初始化,需要设置默认生产者所属组
producer:
group: group_rocketmq
自定义类实现MessageService
@Autowired
private RocketMQTemplate rocketMQTemplate;
发送:
同步:.convertAndSend()
异步:
//async所需回调
SendCallback callback = new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("消息发送成功所作处理");
}
@Override
public void onException(Throwable e) {
System.out.println("消息发送失败时所作处理");
}
};
rocketMQTemplate.asyncSend(String destination, Object payload, SendCallback sendCallback);
自动监听:
@RocketMQMessageListener(topic = "order_id",consumerGroup = "group_rocketmq") //监听的队列名称、所属组(看配置)
public class MessageListener implements RocketMQListener<String> { //注消息类型
@Override
public void onMessage(String id) {
System.out.println("已完成短信发送业务(rocketmq),id:"+id);
}
}
springboot整合Kafka:https://kafka.apache.org/
启动命令:需要先启动类似命名空间的注册注心——zookeeper-server-start.bat …/…/config/zookeeper.properties 默认端口:2181(连)
kafka-server-start.bat 默认端口:9092
kafka-server.stop.bat. …/…/config/server.properties
spring:
kafka:
#访问服务器地址
bootstrap-servers: localhost:9092
#监听所需消费者id
consumer:
group-id: 组名
@Autowired
private KafkaTemplate<String,String> kafkaTemplate;
消息监听器:
@Component
public class MessageListener {
@KafkaListener(topics = "监听队列名")
public void onMessage(ConsumerRecord<String,String> record){
System.out.println("已完成短信发送业务(kafka),id:"+record.value());
}
}