springboot消息服务
JMS(java message service)消息服务:java原生的,不能跨平台;ActiveMQ
AMQP(advanved message queue protocol)高级消息队列()跨平台,只能发送字节序列;RabbitMQ
--------
RabbitMQ
核心概念:
Message:消息,消息是不具名的,它由消息头和消息体组成的。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)
、priority(相对于其他的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
publisher:消息生产者,也是一个向交换器发布消息的客户端应用程序
Exchange:交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。Exchange有4中类型:direct(默认,点对点)、fanout,topic和headers,
不同类型的Exchange转发消息的策略有所区别
queue:消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连
接到这个队列将其取走。
binding:绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则。
Connection:网络连接,比如一个TCP连接
Channel:信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息
、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP连
接。
Consumer:消息消费者
virtual host:虚拟主机,表示一批交换器、消息队列和相关对象。
broker:消息队列服务器实体

--------------
RabbitMQ运行机制
AMQP中消息的路由过程和java开发者熟悉的JMS存在一些差别,AMQP中增强了Exchange和Binding的角色。生产者把消息发布到Exchange上,消息最终到达队列
被消费者接收,而Binding决定交换器的消息应该发送到那个队列。
producer->Exchanger->Binding->Queues-consumer;中间三个是在消息服务器中。
-----------

安装RabbitMQ:(windows版本)
需要先安装erlang,可以进入rabbitmq,里面会提示安装erlang,点击进去,可以找到需要按照的版本。需要配置erlang环境变量;
1、新建一个系统变量:变量名为ERLANG_HOME,变量值为安装Erlang的路径
2、将新建的系统变量添加在Path中:格式为%ERLANG_HOME%\bin
3、然后我们打开cmd输入erl查看是Erlan是否安装好、下图就表示已经安装好了
二、安装RabbitMQ
1、首先使用cmd进入sbin目录(我的sbin目录是:C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.7\sbin)
2、然后输入: rabbitmq-plugins.bat enable rabbitmq_management 开启插件
3、还是在sbin目下:输入 rabbitmq-server 启动RabbitMQ服务
4、浏览器登录:localhost:15672访问RabbitMQ的后台管理页面(初始化用户名和密码都是guest)
--------------------
需要在Rabbit中设置Exchange,queue,routingkey;将queue绑定在Exchange
这样才能在程序中发送到指定的Exchange管理的queue中。不然发送的信息无法在RabbitMQ中寻找的到
-------------------
springboot整合rabbitMQ
1、在pom文件中加入rabbitMQ依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2、springboot会自动配置
自动配置类是rabbitautoConfiguration
有自动配置了连接工程ConnectionFactory
RabbitProperties封装了RabbitMQ配置
使用RabbitTemplate操作rabbitmq(发送和接收消息)
AmqpAdmin:RabbitMA系统管理功能组件
amqp:可以创建queue,exchange,binding

----------------------

给对象指定序列化格式为json

@Configuration
public class MyRabbitMQConfig {

    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    
}
public class RabbitTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    /**
     * 点对点
     */
    @Test
    public void directTest(){
        //Message需要自己构造一个,定义消息头和消息体
        //rabbitTemplate.send(exchange, routingKey, message);
        //只需要传入对象,自动序列化发送给rabbit
        //rabbitTemplate.Send(exchange, routingKey, object);
        //Object指定的序列化是java的,
        //可以自己指定序列化json格式,配置MyRabbitMQConfig
        //rabbitTemplate.convertAndSend("lazy.direct","lazy.test","first");
        Map<String, Object> map = new HashMap<>();
        map.put("h1", "one");
        map.put("h2", "tow");
        rabbitTemplate.convertAndSend("lazy.direct","lazy.test",map);
    }
    /**
     * 接收消息
     */
    @Test
    public void receiveTest(){
        Object object = rabbitTemplate.receiveAndConvert("lazy.test");
        System.out.println(object.getClass());
        System.out.println(object);
    }
    /**
     * 广播,不需要routingkey
     */
    @Test
    public void sendMsg(){
        Map<String, Object> map = new HashMap<>();
        map.put("h1", "one");
        map.put("h2", "tow");
        rabbitTemplate.convertAndSend("lazy.fanout","",map);
    }
    
}
------------
消息队列使用场景:生产者发送消息,消费者获取指定消息;消费者需要监听指定的消息队列:
1、开启@EnableRabbit注解
@EnableRabbit //开启rabbit注解
@SpringBootApplication
public class RabbitApplication{
    public static void main(String[] args) {
        SpringApplication.run(RabbitApplication.class, args);
    }
}
2、在消费者上标注注解,并指定队列名称:@RabbitListener(queue="lazy.fanout"),方法参数是接收指定的消息体的,方法参数一定是跟消息体一致的,否则

不能取出消息;
@Service
public class RabbitService {
    @RabbitListener(queues="lazy.fanout")
    public void receive(Map map){
        System.out.println("接收消息:"+map);
    }    
}
注:public void receive(Map map,String str)是不行的,因为消息中只存储map;可以专门写监听类,将消息接收到,然后调用这个方法获取消息。
--------------
//使用AmqpAdmin创建、删除Exchange/queue/binding
@Test
public void amqpAdminTest(){
    //创建exchange,这里的Exchange可以有TopicExchange,FanoutExchange等
    //amqpAdmin.declareExchange(new DirectExchange("amqpAdmin.direct"));
    //创建队列new Queue("amqpAdmin.queue",true),第二个参数表示是否持久化
    //amqpAdmin.declareQueue(new Queue("amqpAdmin.queue",true));
    //在exchange绑定queue
    amqpAdmin.declareBinding(new Binding("amqpAdmin.queue", Binding.DestinationType.QUEUE, "amqpAdmin.direct", 

"amqpAdmin.lazy",null));        
}

posted on 2019-05-04 20:36  lazyli  阅读(203)  评论(0编辑  收藏  举报