简介
RabbitMQ是一套开源(MPL)的消息队列服务软件,是由LShift提供的一个Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的Erlang写成。所有主要的编程语言均有与代理接口通讯的客户端库。RabbitMQ由Rabbit科技有限公司开发,并提供对其的支持。起初,Rabbit科技是LSHIFT和CohesiveFT在2007年成立的合资企业,2010年4月被VMware旗下的SpringSource收购。RabbitMQ在2013年5月成为GoPivotal的一部分。
AMQP:高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。 消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。RabbitMQ是一个开源的AMQP实现,服务端用erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS,支持AJAX等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现较好。
特性
1、可靠性(Reliability)
rabbitmq使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
2、灵活的路由(Flexible Routing)
在消息进入队列之前,是通过Exchange来路由信息的。对于典型的路由功能,rabbitmq已经提供了一些内置的Exchange来实现。针对更复杂的路由功能,可以将多个Exchange绑定在一起,也可以通过插件机制实现自己的Exchange。
3、消息集群(Clustering)
多个RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker(服务)。
4、高可用(Highly Available)
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用,也就是具有可伸缩性。
5、多种协议(Multi-protocol)
rabbitmq支持多种消息队列协议,如STOMP、MQIT等。
6、多语言客户端(Many Clients)
rabbitmq几乎支持所有的常用语言,如Java、.net、Ruby、Python等。
7、管理界面(Mangement UI)
rabbitmq提供了一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面。
8、跟踪机制(Tracing)
如果消息异常,rabbitmq提供了消息跟踪机制,使用者可以找出发生了什么。
9、插件机制(Plugin System)
rabbitmq提供了许多插件来从多方面进行扩展,使用者也可以编写自己的插件。
消息队列
Message queue 释义
createOrder(...){
//完成订单服务
doCreateOrder(...);
//调用其他服务接口
sendMsg(...);
updateUserInterestedGoods(...);
updateMemberCreditInfo(...);
}
存在问题:
优化方案:
案例分析:
带来的好处
1. 小红想给小明书的时候,不必问小明什么时候有空,亲手把书交给他了,小红只把书放到书架上就行了.这样小红小明的时间都更自由.
消息队列相关
AMQP
技术选型
RabbitMQ
RabbitMQ是一个实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务,用Erlang语言.
Docker安装部署RabbitMQ
拉取镜像
docker pull rabbitmq:management
docker run -itd \
--name my-rabbitmq \
-p 5672:5672 -p 15672:15672 \
--hostname my-rabbitmq-host \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
rabbitmq:management
firewall-cmd --zone=public --add-port=5672/tcp --add-port=15672/tcp --permanent
创建一个用户赋予权限
赋予访问虚拟机的权限
spring连接配置
准备工作
先搭建一个空项目作为我们的父项目,再创建两个子项目,分别为生产者和消费者,并且勾选我们所需要的依赖
修改yml配置文件
生产者:
server:
port: 8888
spring:
rabbitmq:
host: 192.168.169.131
password: 123456
port: 5672
username: spring
virtual-host: my_vhost
消费者;
server:
port: 9999
spring:
rabbitmq:
host: 192.168.169.131
password: 123456
port: 5672
username: spring
virtual-host: my_vhost
在生产者编写一个config类
package com.example.publisher;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@SuppressWarnings("all")
public class RabbitConfig{
@Bean
public Queue firstQueue(){
return new Queue("firstQueue");
}
@Bean
public Queue secondQueue(){
return new Queue("secondQueue");
}
}
再编写一个控制类
package com.example.publisher;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SuppressWarnings("all")
public class TestController {
@Autowired
private AmqpTemplate template;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping("/send1")
public String send1(){
template.convertAndSend("firstQueue","hello world");
return "😒";
}
@RequestMapping("/send2")
public String send2 () throws Exception{
User yhx=new User("yhx","520");
String json = objectMapper.writeValueAsString(yhx);
template.convertAndSend("secondQueue",yhx);
return "😒";
}
}
然后在消费者编写一个Receiver
package com.example.consumer;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues="firstQueue")
public class Receiver {
@Autowired
private ObjectMapper objectMapper;
@RabbitHandler
public void process(String json) throws Exception{
Object user = objectMapper.readValue(json, User.class);
log.warn("接收到:" + user);
}
}
再编写一个User完成自定义数据发送
package com.example.publisher;
import lombok.*;
import java.io.Serializable;
@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}
在网页上访问一下
我们可以发现RabbitMQ管理页面上也有