RabbitMQ的学习总结(1)

1.消息队列的作用,以及准备工作

1.1. 为什么要用 MQ 1.流量消峰 举个例子,如果订单系统最多能处理一万次订单,这个处理能力应付正常时段的下单时绰绰有余,正 常时段我们下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作系统是处理不了的,只能限 制订单超过一万后不允许用户下单。使用消息队列做缓冲,我们可以取消这个限制,把一秒内下的订单分 散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比不能下单的体 验要好。 2.应用解耦 以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合 调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。当转变成基于 消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在 这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成。当物流 系统恢复后,继续处理订单信息即可,中单用户感受不到物流系统的故障,提升系统的可用性。 3.异步处理 有些服务间调用是异步的,例如 A 调用 B,B 需要花费很长时间执行,但是 A 需要知道 B 什么时候可 以执行完,以前一般有两种方式,A 过一段时间去调用 B 的查询 api 查询。或者 A 提供一个 callback api, B 执行完之后调用 api 通知 A 服务。这两种方式都不是很优雅,使用消息总线,可以很方便解决这个问题, A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ,MQ 会将此 消息转发给 A 服务。这样 A 服务既不用循环调用 B 的查询 api,也不用提供 callback api。同样 B 服务也不 用做这些操作。A 服务还能及时的得到异步处理成功的消息。

1.2.rabbitMQ在linux下的常用命令

1.添加开机启动 RabbitMQ 服务 chkconfig rabbitmq-server on 2.启动服务 /sbin/service rabbitmq-server start 3.查看服务状态 /sbin/service rabbitmq-server status 4.停止服务(选择执行) /sbin/service rabbitmq-server stop 5.开启 web 管理插件 rabbitmq-plugins enable rabbitmq_management 用默认账号密码(guest)访问地址 http://192.168.121.111:15672/出现权限问题 6.添加一个新的用户 创建账号 rabbitmqctl add_user admin 123

admin 123代表账号和密码(自己设置) 7.设置用户角色 rabbitmqctl set_user_tags admin administrator 8.设置用户权限 rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"

用户 user_admin 具有/vhost1 这个 virtual host 中所有资源的配置、写、读权限

9.当前用户和角色

rabbitmqctl list_users

2.简单的代码整合

2.1用Java代码进行操作

P代表一个生产者,C代表一个消费者 ,生产者负责将消费者传递给消费者

下面引入非SpringBoot整合的依赖包(后边会有整合SpringBoot的包)

<!--指定 jdk 编译版本-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <!--rabbitmq 依赖客户端-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!--操作文件流的一个依赖-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

生产者代码

/**
 * 生产者:发消息
 */
public class Producer {
    //队列
    public static final String QUEUE_NAME="hello";

    //
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建一个连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //设置连接工场ip,连接rabbitMQ的队列
        factory.setHost("192.168.121.111");
        //用户名
        factory.setUsername("admin");
        //密码
        factory.setPassword("123");
        //创建连接
        Connection connection = factory.newConnection();
        //获取信道
        Channel channel = connection.createChannel();
        /**
         * 生成一个队列
         * 1.队列名称
         * 2.队列里面的消息是否持久化 默认情况 消息存储在内存中
         * 3.该队列是否只供一个消费者进行消息共享,true:可以多个,false:一个
         * 4.是否自动删除,最后一个消费者开连接后该队列是否自动删除,true:自动,false:则相反
         */
        Map<String,Object> arguments=new HashMap<>();
        arguments.put("x-max-priority",10);//官方允许是在0-255,允许优先级的范围0-10
        channel.queueDeclare(QUEUE_NAME,false,false,false,arguments);
        //发消息
        String message="hello world";
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
        /**
         * 发送一个消息
         * 1.发送到哪个交换机
         * 2.路由的key值是哪个,本次是队列的名称
         * 3.其他参数信息
         * 4.发送的消息的消息体
         */
        System.out.println("消息发送完毕");

    }

}

消费者代码

/**
 * 消费者 接受消息的
 */

public class Consumer {
    //队列名称
    public static final String QUEUE_NAME="hello";

    //接收消息
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //设置连接工场ip,连接rabbitMQ的队列
        factory.setHost("192.168.121.111");
        //用户名
        factory.setUsername("admin");
        //密码
        factory.setPassword("123");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        //声明
        DeliverCallback deliverCallback=(String var1, Delivery var2)->{
            System.out.println(new String(var2.getBody()));
        };
        //取消消息时的回调
        CancelCallback cancelCallback=consumerTag->{
            System.out.println("消息消费被中断");
        };
        /**
         * 消费者消费消息
         * 1.消费哪个队列
         * 2.消费成功后是否自动应答 true 代表的是自动应答,false代表的是手动应答
         * 3.消费者未成功消费的回调
         * 4.消费者取消消费的回调
         */
        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
    }

}

这样就实现了一个简单的工作队列

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值