Rabbitmq(二)

1.Rabbitmq的消息确认机制(事务+confirm)

在rabbitmq中我们可以通过持久化数据,解决rabbitmq服务器异常的数据丢失问题

问题 :生产者将消息发送出去之后,到底有没有到达rabbitmq服务器 默认情况 不知道

两种方式:

AMQP实现了事务机制

confirm模式

事务机制

txSelect txCommit txRollback

txSelect :用户当前channel设置成transation模式

txCommit:用于提交事务

txRollback:回滚事务

生产者

package cn.zhm.util.tx;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;

/**
 * @description: 事务生生产者
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 00:45
 **/
public class TxSend {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 0:45
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_tx_name";
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
    try {
        //获取一个连接
        connection =  GetRabbitConnectUtil.getMQConnection();
        //从连接中获取一个通道
        channel =  connection.createChannel();

        //创建队列声明
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        String msg ="hello tx.....";

        //添加事务
        channel.txSelect();

        channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
        int  i = 10/0;
        //提交事务
        System.out.println(msg);
        channel.txCommit();

    }catch (Exception e){
        e.printStackTrace();
        //回滚事务
        channel.txRollback();
        System.out.println("提交信息发生异常 Rollback。。。");

    }
    }
}

 

运行结果:

提交信息发生异常 Rollback。。。

消费者

package cn.zhm.util.tx;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @description: tx 消费者
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 00:59
 **/
public class Txreception {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 1:00
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_tx_name";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
        try {
            //获取一个连接
            connection =  GetRabbitConnectUtil.getMQConnection();
            //从连接中获取一个通道
            channel =  connection.createChannel();

            //创建队列声明
            boolean durable = false;
            channel.queueDeclare(QUEUE_NAME,durable,false,false,null);

            //获取消息

            DefaultConsumer 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);
                    String smg = new String(body,"utf-8");
                    System.out.println("消费者接收消息:"+smg);
                }
            };

            //监听队列
            channel.basicConsume(QUEUE_NAME,true,consumer);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // channel.close();
            // connection.close();
        }

    }
}

消费者没有收到 信息。

confirm模式

生产者端confirm模式的实现

confirm模式最大的好处在于是异步处理

开启confirm模式

 channel.confirmSelect();

编程模式

1.普通 发一条 waitForConfirms()

package cn.zhm.util.confirm;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * @description: confirm普通模式
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 02:08
 **/
public class send1 {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 2:09
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_confirm_name";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
        try {
            //获取一个连接
            connection =  GetRabbitConnectUtil.getMQConnection();
            //从连接中获取一个通道
            channel =  connection.createChannel();

            //创建队列声明
            channel.queueDeclare(QUEUE_NAME,false,false,false,null);

            String msg ="hello confirm.....";

            //生产调用confirmSelect将channel设置confirm模式
            channel.confirmSelect();

            channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
            if(!channel.waitForConfirms()){
                System.out.println("message sends failed");
            }else {
                System.out.println("message sends success");
            }
            //提交事务
            System.out.println(msg);

        }catch (Exception e){
            e.printStackTrace();

        }

    }
}

2.批量的 发一批 channel.waitForConfirms(); 但是如果有一条信息发送失败则整个批量信息都不能发送成功。

package cn.zhm.util.confirm;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * @description: confirm普通模式
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 02:08
 **/
public class send1 {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 2:09
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_confirm_name";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
        try {
            //获取一个连接
            connection =  GetRabbitConnectUtil.getMQConnection();
            //从连接中获取一个通道
            channel =  connection.createChannel();

            //创建队列声明
            channel.queueDeclare(QUEUE_NAME,false,false,false,null);

            //生产调用confirmSelect将channel设置confirm模式
            channel.confirmSelect();

            for ( int i =1 ; i <= 10 ; i++){
                String msg ="hello confirm....."+i;
                channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
                System.out.println(msg);
            }

            if(!channel.waitForConfirms()){
                System.out.println("message sends failed");
            }else {
                System.out.println("message sends success");
            }

        }catch (Exception e){
            e.printStackTrace();

        }

    }
}

3.异步confirm模式 提供 一个回调方法。

异步模式

生产者:

package cn.zhm.util.confirm;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;

import java.io.IOException;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * @description: confirm异步模式
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 02:08
 **/
public class sendAcy {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 2:09
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_confirmAcy_name";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
        try {
            //获取一个连接
            connection =  GetRabbitConnectUtil.getMQConnection();
            //从连接中获取一个通道
            channel =  connection.createChannel();

            //创建队列声明
            channel.queueDeclare(QUEUE_NAME,false,false,false,null);

            //生产调用confirmSelect将channel设置confirm模式
            channel.confirmSelect();

            //未确认的消息标识
            final SortedSet <Long> comfimSorted = Collections.synchronizedSortedSet(new TreeSet<Long>());

            //通道添加监听
            channel.addConfirmListener(new ConfirmListener() {
                //没有问题的handleAck 成功
                public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                    if (multiple){
                        System.out.println("=====handleAck=== multiple = ture");
                        comfimSorted.headSet(deliveryTag+1).clear();//+1
                    }else{
                        System.out.println("=====handleAck===  multiple=flase");
                        comfimSorted.remove(deliveryTag);
                    }

                }
                //有问题的时候处理逻辑 失败
                public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                    if (multiple){
                        System.out.println("=====handleAck=== multiple = ture");
                        comfimSorted.headSet(deliveryTag+1).clear();
                    }else{
                        System.out.println("=====handleAck===  multiple=flase");
                        comfimSorted.remove(deliveryTag);
                    }

                }
            });

            String msg = "hello acy....";
            //发送信息
            while (true){
                long seqNo = channel.getNextPublishSeqNo();
                channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
                //存放没有回值的信息id
                comfimSorted.add(seqNo);
            }


        }catch (Exception e){
            e.printStackTrace();

        }

    }
}

消费者:

package cn.zhm.util.confirm;

import cn.zhm.util.GetRabbitConnectUtil;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @description: 异步模式消费者
 * @author: zhaohaiming
 * @Version V1.0.0
 * @create: 2019-08-18 14:25
 **/
public class ReceptionAcy {
    /**
     * @Description:    java类作用描述
     * @Author:         zhaohaiming
     * @CreateDate:     2019/8/18 14:26
     * @Version:        1.0

     */
    private static final String QUEUE_NAME = "test_confirmAcy_name";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection connection = null;
        Channel channel = null;
        try {
            //获取一个连接
            connection =  GetRabbitConnectUtil.getMQConnection();
            //从连接中获取一个通道
            channel =  connection.createChannel();

            //创建队列声明
            boolean durable = false;
            channel.queueDeclare(QUEUE_NAME,durable,false,false,null);

            channel.basicConsume(QUEUE_NAME,true,new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    String smg = new String(body,"utf-8");
                    System.out.println("消费者接收消息:"+smg);
                }
            });


        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

  • 0
    点赞
  • 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、付费专栏及课程。

余额充值