RabbitMQ安装以及入门学习

RabbitMQ学习,这里推荐几篇经典的文章,个人感觉受益匪浅

  1. rabbitmq安装:https://blog.csdn.net/cairuojin/article/details/81912033
  2. 偏理论:https://blog.csdn.net/whoamiyang/article/details/54954780
  3. 偏实战:https://blog.csdn.net/leixiaotao_java/article/details/78924863

RabbitMQ连接配置

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;

/**
 * @program: RabbitmqOne
 * @description:
 * @author: Hyz.gt
 * @create: /09/22  17:41
 **/
public class ConnectionUtils {

    public static Connection getConnection() throws IOException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.1.84");
        factory.setPort(5673);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("MyRabbitmq");
        return factory.newConnection();
    }
}

RabbitMQ的使用

import com.hyzgt.mq.listener.MyConfirmListener;
import com.hyzgt.mq.listener.MyReturnListener;
import com.hyzgt.mq.util.ConnectionUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @program: RabbitmqOne
 * @description:
 * @author: Hyz.gt
 * @create: /09/22  18:11
 *
 *
 * Exchange的四总类型:direct、fanout、topic、headers
 * direct:匹配RoutingKey完全相等的Queue
 * topic:匹配RoutingKey,支持使用通配符, '.#.'  代表匹配 没有字符或者多个字符,'.*.' 代表匹配一个字符
 **/
public class Main {

    private static final String  QUEUE_NAME = "test_queue_first";

    private static final String EXCHANGE_NAME = "test_exchange_topic";

    private static final String RoutingKey = "before.first";

    public static void main(String[] agrs) throws IOException, InterruptedException {

        Connection connection = ConnectionUtils.getConnection();
        //获取队列
        Channel channel = connection.createChannel();

        /**
         * confirm是RabbitMQ的一种事物解决方案,已经在transaction事物模式的channel是不能在设置成confirm模式,两者不能共存
         *
         * Channel.confirmSelect()方法将Channel信道设置成confirm模式。一旦信道被设置成confirm模式,该信道上的所有消息都会被指派一个唯一的ID(从1开始),
         * 一旦消息被对应的Exchange接收,Broker就会发送一个确认给生产者(其中deliveryTag就是此唯一的ID)
         *
         * 普通confirm模式是串行的,即每次发送了一次消息,生产者都要等待Broker的确认消息,然后根据确认标记权衡消息重发还是继续发下一条。由于是串行的,在效率上是比较低下的。
         *
         * 发送消息采用 channel.waitForConfirms() 等待Broker服务返回消息标记,如果发送失败会重新发送,串行发送
         * channel.waitForConfirmsOrDie(),批量发送消息,如果发送失败会重新发送,频繁失败性能不增反降
         *
         */
        channel.confirmSelect();

        /**
         * 实现ConfirmListener接口,用于监听Exchange,并不能保证消息进入Queue
         * ConfirmListener使用前提是在confirm模式下才能生效
         */
      // channel.addConfirmListener(new MyConfirmListener());


        /**
         * 监听消息是否发送到了队列,返回响应信息
         * ReturnListener使用前提是在channel.basicPublish()时,设置mandatory=true
         */
       // channel.addReturnListener(new MyReturnListener());


        /**
         *  创建队列Queue-----消息的载体,每个消息都会被投到一个或多个队列
         *
         *  param1            队列名称
         *  param2            持久性:true队列会再重启过后存在,但是其中的消息不会存在
         *  param3            是否只能由创建者使用,其他连接不能使用
         *  param4            是否自动删除(没有连接自动删除)
         *  param5            队列的其他属性(构造参数)
         */
        channel.queueDeclare(QUEUE_NAME,true,false,false,null);

        /**
         *  声明Exchange------消息交换机,它指定消息按什么规则,路由到哪个队列
         *
         *  param1            队列名称
         *  param2            Exchange的类型,可选择direct、fanout、topic、headers
         *  param3            持久性
         *  param4            是否只能由创建者使用,其他连接不能使用
         *  param5            是否自动删除(没有连接自动删除)
         *  param6            队列的其他属性(构造参数)
         */
        channel.exchangeDeclare(EXCHANGE_NAME, ExchangeType.Topic,true,false,false,null);


        /**
         *  将Queue和Exchange进行绑定(Binding)------ 它的作用就是把Exchange和Queue按照路由规则绑定起来.
         *
         *  param1            队列Queue名称
         *  param2            消息交换机Exchange名称
         *  param3            路由关键字,exchange根据这个关键字进行消息投递
         *  param4            队列的其他属性(构造参数)
         */
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,RoutingKey,null);

        /**
         *  推送消息.
         *
         *  param1            消息交换机Exchange名称
         *  param2            路由关键字
         *  param3            监听是否有符合的队列等同于mandatory=true/false,true(支持ReturnListener)
         *  param4            监听符合的队列上是有至少一个Consumer
         *  param5            设置消息持久化   MessageProperties.PERSISTENT_TEXT_PLAIN是持久化;MessageProperties.TEXT_PLAIN是非持久化
         *  param6            消息内容
         */
        for (int i = 0; i <10000 ;i++) {
            String messgae = "i="+i;
            channel.basicPublish(EXCHANGE_NAME,RoutingKey,true,false, MessageProperties.TEXT_PLAIN,messgae.getBytes());
           /* if(channel.waitForConfirms()){
                System.out.println(messgae+"-----【SUCCES】");
            }else{
                System.out.println(messgae+"------【ERROR】");
            }*/
        }
        channel.waitForConfirmsOrDie();

        /**
         *  basicQos:指该消费者在接收的队列里的消息,但没有应答结果之前,队列不会在发送消息给消费者
         *
         *  param1            ${param2}容纳最大的数量,
         *  param2            true代表通道chanel,false代表消费者consumer
         *
         *  下面代表的意思是:允许消费者在同一时刻下支撑10个消息
         */
        channel.basicQos(10,false);
        channel.basicQos(15,true);

        /**
         * DefaultConsumer:默认消费者,处理所有ID
         *
         *  接收消息 channel.basicConsume(param1,param2,param3);函数,重写Consumer接收消息
         *
         *  param1            队列Queue名称
         *  param2            true:自动应答   false:手动应答
         *  param3            消费者
         *
         *  手动应答channel.basicAck(param1,param2),应答成功后RabbitMQ会从队列的内存中删除该条消息,一般表示成功
         * param1             唯一ID
         * param2             true:表示小于ID的一起应答  false:只应答当前ID
         *
         *  手动应答channel.basicNack(param1,param2,param3),一般表示应答失败
         * param1             唯一ID
         * param2             true:当前ID以及小于ID   false:当前ID
         * param3             true:Queue保留ID对应的消息  false:Queue丢弃ID对应的消息    基于 param2 的条件决定丢弃还是保留哪些ID
         *
         * 手动应答channel.basicReject(param1,param2),没有批量操作之外,类似basicNack 一般表示应答失败
         * param1             唯一ID
         * param3             true:Queue保留ID对应的消息  false:Queue丢弃ID对应的消息
         *
         */
        Thread thread1 = new Thread(()->{
            Consumer consumer = new DefaultConsumer(channel){
                /**
                 *  收到消息的回调函数
                 * @param consumerTag
                 * @param envelope
                 * @param properties
                 * @param body
                 * @throws IOException
                 */
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    String mes = new String(body, "utf-8");
                    System.out.println(mes);
                //    channel.basicAck(envelope.getDeliveryTag(),false);
                //    channel.basicNack(envelope.getDeliveryTag(),false,false);
                    channel.basicReject(envelope.getDeliveryTag(),false);
                }


                /**
                 * 消费者注册成功的回调函数
                 * @param consumerTag
                 */
                @Override
                public void handleConsumeOk(String consumerTag) {
                    System.out.println("消费者注册成功的回调函数"+consumerTag);
                }

                /**
                 * 手动取消消费者注册成功的回调函数
                 * @param consumerTag
                 */
                @Override
                public void handleCancelOk(String consumerTag) {
                    System.out.println("手动取消消费者注册成功的回调函数"+consumerTag);
                }

                /**
                 * 当消费者因为其他原因被动取消注册时调用,比如queue被删除了。
                 * @param consumerTag
                 * @throws IOException
                 */
                @Override
                public void handleCancel(String consumerTag) throws IOException {
                    System.out.println("当消费者因为其他原因被动取消注册时调用,比如queue被删除了"+consumerTag);
                }

                /**
                 * 当通道或者基础连接被关闭时调用
                 * @param consumerTag
                 * @param sig
                 */
                @Override
                public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {
                    System.out.println("当通道或者基础连接被关闭时调用"+consumerTag);
                }

                /**
                 * 收回OK
                 * @param consumerTag
                 */
                @Override
                public void handleRecoverOk(String consumerTag) {
                    System.out.println("收回OK"+consumerTag);
                }
            };
            try {
                channel.basicConsume(QUEUE_NAME,false,consumer);
                Thread.sleep(20000);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"Thread-Customs");
        thread1.start();
        thread1.join();

        channel.close();
        connection.close();
    }
}

ExchangeType:内容是Exhcange的类型

/**
 * @program: RabbitmqOne
 * @description:
 * @author: Hyz.gt
 * @create: /09/23  14:53
 **/
public interface ExchangeType {

    String Topic = "topic";

    String Direct = "direct";

    String Fanout = "fanout";

    String Headers = "headers";
}

RabbitMQ的Listener

  1. ConfirmListener:用于监听消息是否进入交换机(Exchange)
import com.rabbitmq.client.ConfirmListener;

import java.io.IOException;

/**
 * 实现ConfirmListener接口,用于监听Exchange,并不能保证消息进入Queue
 * ConfirmListener使用前提是在confirm模式下才能生效
 */
public class MyConfirmListener implements ConfirmListener {

    @Override
    public void handleAck(long l, boolean b) throws IOException {
        System.out.println("handleAck{l:"+l+",b:"+b+"}");
    }

    @Override
    public void handleNack(long l, boolean b) throws IOException {
        System.out.println("handleNack{l:"+l+",b:"+b+"}");
    }
}
  1. ReturnListener:用于监听消息是否发送到了队列,返回响应信息
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.ReturnListener;

import java.io.IOException;

/**
 * @program: RabbitmqOne
 * @description:
 * @author: Hyz.gt
 * @create: /09/24  09:38
 **/
public class MyReturnListener implements ReturnListener {


    @Override
    public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties basicProperties, byte[] body) throws IOException {
        System.out.println("消息发送到队列失败:回复编码:"+replyCode+",回复失败文本:"+replyText+",接收Exchange:"+exchange+",使用RoutingKey:"+routingKey+",发送内容:"+new String(body));
    }
}

如有文章存在问题,请指正,我也在学习的路上,其次各位在学习中碰到不懂的可以在文章推荐的三篇文章中查阅

GitHub地址:https://github.com/HeYongZhang/LearningMaterials.git

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值