一、RabbitMQ 初建 生产消费

RabbitMQ 初建 生产消费

RabbitMQ:http://www.rabbitmq.com/

  • 是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、C、用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不错
  • 缺点:使用Erlang开发,阅读和修改源码难度大

什么是AMQP?

  • AMQP(advanced message queuing protocol)在2003年时被提出,最早用于解决金融领不同平台之间的消息传递交互问题,就是是一种协议,兼容JMS
  • 更准确说的链接协议 binary- wire-level-protocol 直接定义网络交换的数据格式,类似http
  • 具体的产品实现比较多,RabbitMQ就是其中一种

特性:

  • 独立于平台的底层消息传递协议
  • 消费者驱动消息传递
  • 跨语言和平台的互用性、属于底层协议
  • 有5种交换类型direct,fanout,topic,headers,system
  • 面向缓存的、可实现高性能、支持经典的消息队列,循环,存储和转发
  • 支持长周期消息传递、支持事务(跨消息队列)

AMQP和JMS的主要区别:

1.AMQP可跨平台语言生产消费,java生产的消息可以Python进行消费,可以用HTTP进行类比,不关心实现接口的语言,JMS则必须是java写的生产端和消费端。

2.AMQP的消息类型是Byt[],而JMS的消息类型是TextMessage/ObjectMessage/StreamMessage等。

1.环境准备(使用docker容器)

1)docker安装

搞个虚拟机装centos系统然后安装docker

#更新yum
yum update
yum install epel-release -y
yum clean all
yum list
#安装运行docker
yum install docker-io -y
systemctl start docker
#检测安装结果
docker info
systemctl start docker     #运行Docker守护进程
systemctl stop docker      #停止Docker守护进程
systemctl restart docker   #重启Docker守护进程
#列举全部 容器 : 
docker ps -a

#列举当前运行的容器:
docker ps

#检查容器内部信息:
docker inspect 容器名称

#删除镜像:
docker rmi IMAGE_NAME
#强制移除镜像不管是否有容器使用该镜像 增加 -f 参数
#删除前到停掉

#停止某个容器:
docker stop 容器名称

#启动某个容器:
docker start 容器名称

#移除某个容器: 
docker rm 容器名称 (容器必须是停止状态)

2)拉取RabbitMQ镜像并启动

#拉取镜像
docker pull rabbitmq:management

docker run -d --hostname rabbit_host1 --name xd_rabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=123456 -p 15672:15672 -p 5672:5672 rabbitmq:management

#说明
-d 以守护进程方式在后台运行
-p 15672:15672 management 界面管理访问端口
-p 5672:5672 amqp 访问端口
--name:指定容器名
--hostname:设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts,作为容器主机IP的别名,并且将显示在容器的bash中

-e 参数
  RABBITMQ_DEFAULT_USER 用户名
  RABBITMQ_DEFAULT_PASS 密码

4369 erlang 发现口

5672 client 端通信口

15672 管理界面 ui 端口

25672 server 间内部通信口

ip:15672访问管理界面

后续如果关闭虚拟机后再启动服务就用

#1.查容器名
docker ps -a
#2.根据容器名启动
docker start 容器名称或容器id

如下图:

在这里插入图片描述

2.java工程创建编写

创建一个空的maven工程(我用的jdk1.8的)然后在pom里导入引用包

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <skipTests>true</skipTests>
</properties>
<dependencies>
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>5.10.0</version>
    </dependency>
</dependencies>

导入所需包之后便可以写一个组简单的生产消费,根据官方样例代码
在这里插入图片描述

在这里插入图片描述

根据官方样例改造成自己的

send.java

public class Send {

    // 队列名称
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        // 连接信息
        factory.setHost("20.18.24.143");
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setVirtualHost("devTest");
        factory.setPort(5672);

        // 继承
        try (Connection connection = factory.newConnection();
             // 创建信道
             Channel channel = connection.createChannel()) {
            /**
             * 队列名称
             * 持久化配置:mq重启后还在
             * 是否独占:只能有一个消费者监听队列;当connection关闭是否删除队列,一般是false,发布订阅是独占
             * 自动删除: 当没有消费者的时候,自动删除掉,一般是false
             * 其他参数
             *
             * 队列不存在则会自动创建,如果存在则不会覆盖,所以此时的时候需要注意属性
             */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            String message = "Hello World!";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
            System.out.println(" [x] Sent '" + message + "'");
        }
    }

}

Recv.java代码

public class Recv {
    private final static String QUEUE_NAME = "hello";
    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        // 连接信息
        factory.setHost("20.18.24.143");
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setVirtualHost("devTest");
        factory.setPort(5672);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
        // 消费
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                super.handleDelivery(consumerTag, envelope, properties, body);
                // 一般固定,一般称为会话名称
                System.out.println("consumerTag: "+consumerTag);
                // 可以获取交换机、路由键等信息
                System.out.println("envelope: "+envelope);
                //
                System.out.println("properties: "+properties);
                //
                System.out.println("body: "+new String(body,"utf-8"));
            }
        };
        channel.basicConsume(QUEUE_NAME,true,consumer);
    }
}

先启动Recv消费者代码再启动生产者代码Send
控制台打印如下:

 [*] Waiting for messages. To exit press CTRL+C
consumerTag: amq.ctag-fwM_uUThzXI3cZBV6U6fvg
envelope: Envelope(deliveryTag=1, redeliver=false, exchange=, routingKey=hello)
properties: #contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
body: Hello World!

期初控制台只打印到CTRL+C那里,后面没有,只当生产者发送到channel中后消费者才有的消费,才有后面的日志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值