JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器

JMS

JMS是Java Message Service的简称,是Java定义的一套消息服务标准,类似于JDBC。只要是符合JMS规范标准的,都是通用的Java消息服务

MOM

MOM是Message Oriented Middleware的简称

RabbitMQ

RabbitMQ是实现了AMQP(Advanced Message Queuing Protocol - 高级消息队列协议)的开源消息代理软件
RabbitMQ服务器是用Erlang语言编写的

1.RabbitMQ的安装

将RabbitMQ部署到CentOS中

  1. 预装环境

    yum install ncurses ncurses-base ncurses-devel ncurses-libs ncurses-static ncurses-term ocaml-curses ocaml-curses-devel -y
    
    yum install openssl-devel zlib-devel -y
    
    yum -y install make ncurses-devel gcc gcc-c++ unixODBC unixODBC-devel openssl openssl-devel
    
  2. Erlang的安装

    # 创建安装目录
    mkdir /usr/local/erlang
    
    # 进入目录
    cd /usr/local/erlang
    
    # 下载安装包
    wget http://erlang.org/download/otp_src_20.0.tar.gz
    
    # 解压
    tar -xf otp_src_20.0.tar.gz
    
    # 设置安装环境
    ./configure --prefix=/opt/erlang --with-ssl -enable-threads -enable-smmp-support -enable-kernel-poll --enable-hipe --without-javac
    
    # 编译并安装
    make&&make install
    
    # 设置软连接
    ln -s /opt/erlang/bin/erl /usr/local/bin/erl
    
    # 进入erlang应用环境
    /usr/local/bin/erl
    
    # 测试
    EvenN = lists:filter (fun (N) -> N rem 2 == 0 end, lists:seq (1,100)).
    # 退出erlang应用环境
    halt().
    

    JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第1张图片

    # 设置环境变量
    vim /etc/profile
    # 添加内容
    # ERLANG_HOME=/opt/erlang
    # PATH=$ERLANG_HOME/bin:$PATH
    # export ERLANG_HOME
    # export PATH
    
    # 保存后重载
    source /etc/profile
    
    # 检查是否加载成功
    echo $ERLANG_HOME
    echo $PATH
    

    JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第2张图片
    JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第3张图片

  3. 安装RabbitMQ

    # 进入安装目录
    cd /usr/local/erlang
    
    # 下载安装包
    http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-generic-unix-3.6.10.tar.xz
    
    # 安装xz解压插件
    yum -y install xz
    
    # 解压xz文件
    xz -d rabbitmq-server-generic-unix-3.6.10.tar.xz
    
    # 解压tar文件
    tar -xvf rabbitmq-server-generic-unix-3.6.10.tar
    
    # 解压后移动到/opt/rabbitmq目录
    mv rabbitmq_server-3.6.10 /opt/rabbitmq/
    
    # 进入rabbitmq的可执行目录
    cd /opt/rabbitmq/sbin
    
    # 启动rabbitmq
    # 直接启动使用
    ./rabbitmq-server
    # 后台启动使用
    ./rabbit-server -detached
    
    # 开启插件管理页面
    ./rabbitmq-plugins enable rabbitmq_management
    
    # 创建用户密码
    ./rabbitmqctl add user admin 123
    
    # 设置用户角色
    ./rabbitmqctl set_user_tags admin administrator
    
    # 用户授权
    ./rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
    
    # 访问
    # 在浏览器输入ip+端口号
    http://192.168.54.121:15672
    
    # 关闭服务
    ./rabbitmqctl stop
    

    JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第4张图片

2.MQ的作用

MQ主要的功能是通过将同步转变为异步,实现流量削峰的作用
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第5张图片
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第6张图片
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第7张图片
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第8张图片
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第9张图片

3.RabbitMQ的原理

JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第10张图片

  1. Publisher:出版者,即消息的生产者,也是一个向交换器发布消息的客户端应用程序
  2. Exchange:交换器,用来接收生产者发送的消息,并将这些消息路由给服务器中的队列。常见类型(direct、topic、fanout)
  3. Binding:绑定,用于消息队列和交换器之间的关联,一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表
  4. Queue:消息队列,是消息的容器,也是消息的终点,用来保存消息,直到发送给消费者。一个消息可以投入一个或多个队列;消息一直在队列中,等待消费者链接到队列将其取出
  5. Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个虚拟主机本质上就是一个迷你版的RabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制等。虚拟主机是AMQP概念的基础,必须在链接时指定,RabbitMQ默认的虚拟主机是/
  6. Broker:表示消息队列服务器实体,也就是RabbitMQ整体应用
  7. Connection:链接,指RabbitMQ服务器和服务建立的TCP链接
  8. Channel:信道,是TCP里面的虚拟链接,发布消息、接收消息、订阅队列等动作都是通过信道完成的(使用信道可以降低资源的浪费,提高TCP链接性能)
  9. Consumer:消费者,即消息的消费者,表示一个从消息队列中取出消息的客户端应用程序
  10. Routing-key:路由键,队列通过路由键绑定到交换器。消息发送到MQ服务器时,会拥有一个路由键,RabbitMQ会将其和绑定使用的路由键进行匹配,相匹配则投递到该队列;不匹配,则投入黑洞

4.RabbitMQ的使用

  1. 创建父工程并引入相关依赖
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
        <packaging>pompackaging>
        <modules>
            <module>messagesmodule>
            <module>consumermodule>
            <module>publishermodule>
        modules>
    
        <parent>
            <artifactId>spring-boot-parentartifactId>
            <groupId>org.springframework.bootgroupId>
            <version>2.1.10.RELEASEversion>
        parent>
    
        <groupId>cn.khuegroupId>
        <artifactId>rabbitmq-test-01artifactId>
        <version>1.0-SNAPSHOTversion>
    
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-amqpartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
            dependency>
        dependencies>
    project>
    
  2. 创建commons子工程
    1. 创建一个自定义消息类
      package cn.khue.message;
      
      import java.io.Serializable;
      import java.util.Objects;
      
      public class MyMessage implements Serializable {
               
          private Integer id;
          private String remark;
          private Object data;
      
          public MyMessage(Integer id, String remark, Object data) {
               
              this.id = id;
              this.remark = remark;
              this.data = data;
          }
      
          public MyMessage() {
               
          }
      
          @Override
          public String toString() {
               
              return "MyMessage{" +
                      "id=" + id +
                      ", remark='" + remark + '\'' +
                      ", data=" + data +
                      '}';
          }
      
          public Integer getId() {
               
              return id;
          }
      
          public void setId(Integer id) {
               
              this.id = id;
          }
      
          public String getRemark() {
               
              return remark;
          }
      
          public void setRemark(String remark) {
               
              this.remark = remark;
          }
      
          public Object getData() {
               
              return data;
          }
      
          public void setData(Object data) {
               
              this.data = data;
          }
      
          @Override
          public boolean equals(Object o) {
               
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              MyMessage myMessage = (MyMessage) o;
              return Objects.equals(id, myMessage.id) &&
                      Objects.equals(remark, myMessage.remark) &&
                      Objects.equals(data, myMessage.data);
          }
      
          @Override
          public int hashCode() {
               
              return Objects.hash(id, remark, data);
          }
      }	
      
  3. 创建consummer子工程
    1. 引入依赖
      	
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>rabbitmq-test-01artifactId>
              <groupId>cn.khuegroupId>
              <version>1.0-SNAPSHOTversion>
          parent>
          <modelVersion>4.0.0modelVersion>
      
          <artifactId>consumerartifactId>
      
          <dependencies>
              
              <dependency>
                  <groupId>cn.khuegroupId>
                  <artifactId>messagesartifactId>
                  <version>1.0-SNAPSHOTversion>
              dependency>
          dependencies>
      project>
      
    2. 创建启动类
      @SpringBootApplication
      //导入spring-boot-starter-amqp,该注解自动生效(可以不写),但不会扫描@RabbitListener和@RabbitHandler等注解,薛涛提供@Component注解
      //@EnableRabbit
      public class ConsumerApp{
               
      	public static void main(String[] args){
               
      		SpringApplication.run(ConsumerApp.class,args);
      	}
      }
      
    3. 创建配置文件
      # 自定义队列、交换器、路由键参数
      mq.exchange.name=my-exchange
      mq.queue.name=my-queue
      mq.queue.routing-key=my-routing-key
      
      # 配置RabbitMQ路径
      spring.rabbitmq.host=192.168.54.121
      spring.rabbitmq.port=5672
      spring.rabbitmq.virtual-host=/
      spring.rabbitmq.username=admin
      spring.rabbitmq.password=123
      
    4. 创建消费者类
      package cn.khue.consumer;
      
      import cn.khue.message.MyMessage;
      import org.springframework.amqp.rabbit.annotation.*;
      import org.springframework.stereotype.Component;
      
      @RabbitListener(bindings = {
               
              @QueueBinding(
              	name = @Queue(
              		name = "${mq.queue.name}",
              		autoDelete = "false"),
              	exchange = @Exchange(
              		name = "${mq.exchange.name}",
              		type = "direct",
              		autoDelete = "false"),
              	key = "${mq.queue.routing-key}")
      })
      @Component
      public class MyConsumer {
               
          //处理消息
          @RabbitHandler
          public void message(MyMessage message){
               
              System.out.println("\033[36m"+message+"\033[m");
          }
      }
      
    5. 启动测试
      查看RabbitMQ界面管理器【192.168.54.121:15672】
      JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第11张图片
      JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第12张图片
  4. 创建publisher子模块
    1. 引入依赖
      
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>rabbitmq-test-01artifactId>
              <groupId>cn.khuegroupId>
              <version>1.0-SNAPSHOTversion>
          parent>
          <modelVersion>4.0.0modelVersion>
      
          <artifactId>publisherartifactId>
      
          <dependencies>
              
              <dependency>
                  <groupId>cn.khuegroupId>
                  <artifactId>messagesartifactId>
                  <version>1.0-SNAPSHOTversion>
              dependency>
          dependencies>
      project>
      
    2. 创建启动类
      package cn.khue;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      
      @SpringBootApplication
      public class PublisherApp {
               
          public static void main(String[] args) {
               
              SpringApplication.run(PublisherApp.class,args);
          }
      }
      
    3. 创建配置文件
      # 配置交换器、路由键参数
      mq.exchange.name=my-exchange
      mq.queue.routing-key=my-routing-key
      
      # 配置RabbitMQ路径
      spring.rabbitmq.host=192.168.54.121
      spring.rabbitmq.port=5672
      spring.rabbitmq.virtual-host=/
      spring.rabbitmq.username=admin
      spring.rabbitmq.password=123
      
    4. 创建自定义消息发送者类
      package cn.khue.publisher;
      
      import cn.khue.message.MyMessage;
      import org.springframework.amqp.core.AmqpTemplate;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Component;
      
      @Component
      public class MyPublisher {
               
          @Autowired
          private AmqpTemplate template;
      
          @Value("${mq.exchange.name}")
          //发送到哪一个交换器
          private String exchangeName;
          
          @Value("${mq.queue.routing-key}")
          //路由键是什么
          private String routingKey;
      
          public void sendMessage(Integer id,String remark,Object data){
               
              //创建消息主体
              MyMessage message=new MyMessage(id,remark,data);
              //发送消息
              this.template.convertAndSend(exchangeName,routingKey,message);
          }
      }
      
    5. 创建测试类
      package cn.khue.test;
      
      import cn.khue.PublisherApp;
      import cn.khue.publisher.MyPublisher;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.test.context.junit4.SpringRunner;
      
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = {
               PublisherApp.class})
      public class PublisherAppTest {
               
          @Autowired
          private MyPublisher publisher;
      
          @Test
          public void sendTest(){
               
              //输出10个消息
              for (int i = 0; i <10 ; i++) {
               
                  this.publisher.sendMessage(i,"消息"+i,"内容是"+i);
              }
          }
      }
      
      JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第13张图片

RabbitMQ交换器

RabbitMQ常用交换器有:direct交换器、topic交换器及fanout交换器

1.direct交换器

direct交换器是一种点对点、实现发布/订阅标准的交换器,根据路由键信息决定消息存储在哪个队列
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第14张图片

2.topic交换器

topic交换器也叫主题交换器,或规则匹配交换器,它是通过自定义的模糊匹配规则来决定消息存储在哪些队列
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第15张图片

3.fanout交换器

fanout交换器也叫广播交换器,它会将接收的消息发送给绑定的所有队列,不会尝试匹配路由键,所以无需提供路由键信息
JMS概念、MOM概念、RabbitMQ简介、安装与使用、RabbitMQ的交换器_第16张图片

你可能感兴趣的:(RabbitMQ)