RabbitMQ入门案例之Work模式

news2024/9/24 13:26:22

前言

本文章将介绍RabbitMQ的Work模式,其中这个模式又细分为轮询分发和公平分发,本文将会用Java代码结合RabbitMQ的web管理界面进行实操演示。

官网文档地址:https://rabbitmq.com/getstarted.html

什么是Work模式

RabbitMQ的Work模式是一种简单的消息队列模式,也叫做“竞争消费者模式”或“任务分发模式”。在这种模式下,多个消费者同时监听同一个队列,当队列中有消息时,多个消费者之间会进行竞争,只有一个消费者能够获得这个消息并进行处理。其他消费者则需要等待下一个消息的到来。

工作原理是这样的:生产者向队列中发送任务消息,多个消费者同时监听队列,当队列中有消息时,RabbitMQ会将消息分发给其中的一个消费者。每个消费者都会独立处理自己分配到的任务,消费者之间的工作是平等的,不会区分谁优先谁没有优先,直到队列中的任务被消费完或者没有消费者在处理为止。

在工作模式中,RabbitMQ允许多个消费者同时监听同一个队列,并且每个消费者只能接收一条消息,这使得消息在执行过程中可以分布到多个消费者中,并且每个消费者可以执行自己的任务。这种模式广泛应用于分布式系统中的任务调度或者并行处理等场景中。

Work模式中的轮询分发

在消息队列中,轮询是指多个消费者从消息队列中获取消息的方式。消费者将以轮询的方式获取消息,也就是每个消费者按照顺序逐个接收消息。当一个消费者接收到一条消息时,它会对这个消息进行处理,然后确认已经处理完成,随后再尝试获取下一条消息,如果当前消费者在处理消息时,消息队列对其它消费者进行了轮询派发,则消息队列会将该消息重新分配给其他消费者。

比如说,消息队列中有消息 A、B、C、D、E 五条消息,同时有三个消费者(消费者 1、消费者 2 和消费者 3)在等待消息,那么轮询的过程大致如下:

  1. 消费者 1 获取消息 A,并进行处理,确认已经处理完毕,然后尝试获取下一条消息;
  2. 消费者 2 获取消息 B,并进行处理,确认已经处理完毕,然后尝试获取下一条消息;
  3. 消费者 3 获取消息 C,并进行处理,确认已经处理完毕,然后尝试获取下一条消息;
  4. 消费者 1 尝试获取下一条消息,但此时没有消息可供获取;
  5. 消费者 2 尝试获取下一条消息,但此时没有消息可供获取;
  6. 消费者 3 尝试获取下一条消息,此时消息队列轮询派发了消息 D 给消费者 3,因此消费者 3 获取消息 D 并进行处理;
  7. 消费者 1 尝试获取下一条消息,此时消息队列轮询派发了消息 E 给消费者 1,因此消费者 1 获取消息 E 并进行处理;
  8. 消费者 2 尝试获取下一条消息,但此时没有消息可供获取。

这样一直轮询下去,直到所有的消息都被处理完毕。

代码实现

创建一个maven项目,导入依赖

	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--RabbitMQ依赖-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.10.0</version>
        </dependency>
    </dependencies>

创建生产者,代码如下:

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

public class Producer {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("ip地址");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("生产者");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 6: 准备发送消息的内容
            //===============================end topic模式==================================
            for (int i = 1; i <= 20; i++) {
                //消息的内容
                String msg = "学习:" + i + "号";
                // 7: 发送消息给中间件rabbitmq-server
                // @params1: 交换机exchange
                // @params2: 队列名称/routingkey
                // @params3: 属性配置
                // @params4: 发送消息的内容
                channel.basicPublish("", "queue1", null, msg.getBytes());
            }
            System.out.println("消息发送成功!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

对于消费者,我们需要创建两个来进行演示轮询分发,并且这两个消费者还是指向同一个消息队列:

//work1
import com.rabbitmq.client.*;
import java.io.IOException;

public class Work1 {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("ip地址");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者-Work1");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 5: 申明队列queue存储消息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
            // 这里如果queue已经被创建过一次了,可以不需要定义
//            channel.queueDeclare("queue1", false, false, false, null);
            // 同一时刻,服务器只会推送一条消息给消费者
            // 6: 定义接受消息的回调
            Channel finalChannel = channel;
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", true, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work1-收到消息是:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(2000);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work1-开始接受消息");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
import com.rabbitmq.client.*;
import java.io.IOException;

public class Work2 {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("ip地址");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者-Work2");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 5: 申明队列queue存储消息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
            // 这里如果queue已经被创建过一次了,可以不需要定义
            //channel.queueDeclare("queue1", false, true, false, null);
            // 同一时刻,服务器只会推送一条消息给消费者
            //channel.basicQos(1);
            // 6: 定义接受消息的回调
            Channel finalChannel = channel;

            finalChannel.basicQos(1);

            finalChannel.basicConsume("queue1", true, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work2-收到消息是:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(200);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work2-开始接受消息");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

注意:执行上面三段代码的开始执行顺序,work1和work2先开启,后面在开始producer分发任务。可以想想为什么要这样(doge)

我们需要注意到的是,work1和work2的处理速度是不一样的,work1每次处理消息后,会使线程睡眠2秒,而work2的处理速度是0.2秒,当我们执行开始后,你会发现,work2已经结束了消息的接收,但是work1还在工作,work2不会继续到消息队列中获取消息,它是忙完就下班了!但是最终结果一定是均分的,结果如下:
在这里插入图片描述在这里插入图片描述
在这些work1 和 work2 的两端代码中,有一个代码是值得我们了解一下的

Channel finalChannel = channel;
finalChannel.basicQos(1);

这段代码是用来设置RabbitMQ消费者的最大并发处理量(max prefetch count),即同时从队列中预取的消息的个数。通过这个属性的设置,我们可以让RabbitMQ在可控的范围内平衡系统的负载,避免所有消息都在一瞬间被一台消费端处理完而造成其他消费端处于闲置状态的情况。

一般来讲,如果没有显式的设置 prefetch count,RabbitMQ会默认设置一个 prefetch count 值为 0,这时候它将会帮助你处理尽可能多的消息。如果你需要其他值,可以使用channel.basicQos 方法进行设置。在多个消费者队列的情况下,不同队列可能分配不同的 max prefetch count 值。

在上面的代码中,可以看到我们设置了 prefetch count 值为 1。这意味着在当前消费者从队列中预取的消息达到了 1 条之后,它需要等待确认(acknowledge)之前的消息处理完后才能预取下一条消息。这样可以避免当前消费者占用过多的 RabbitMQ 资源,也可以保证程序的稳定性。

Work模式中的公平分发

与轮询分发不同的是,公平分发是一种类似于能力越大责任越大的机制,这个分发模式下,如果某个消费者的带宽大处理速度快,处理的消息数量就多,反之亦然。简而言之,按劳分配

代码

生产者代码与轮询模式的一样,就不在放出来

消费者代码如下:

import com.rabbitmq.client.*;
import java.io.IOException;

public class Work1 {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("43.139.42.244");
        connectionFactory.setPort(5678);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者-Work1");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 5: 申明队列queue存储消息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
            // 这里如果queue已经被创建过一次了,可以不需要定义
//            channel.queueDeclare("queue1", false, false, false, null);
            // 同一时刻,服务器只会推送一条消息给消费者
            // 6: 定义接受消息的回调
            Channel finalChannel = channel;
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", false, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work1-收到消息是:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(2000);
                        finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work1-开始接受消息");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
import com.rabbitmq.client.*;
import java.io.IOException;

public class Work2 {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("43.139.42.244");
        connectionFactory.setPort(5678);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者-Work2");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 5: 申明队列queue存储消息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
            // 这里如果queue已经被创建过一次了,可以不需要定义
            //channel.queueDeclare("queue1", false, true, false, null);
            // 同一时刻,服务器只会推送一条消息给消费者
            //channel.basicQos(1);
            // 6: 定义接受消息的回调
            Channel finalChannel = channel;
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", false, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work2-收到消息是:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(200);
                        finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work2-开始接受消息");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

公平分发的代码与轮询代码不同的地方如下两张图对比

※公平分发
在这里插入图片描述
※轮询分发
在这里插入图片描述
这个不同地方的参数为:**autoAck,它表示的意义为是否开启自动确认模式。**如果为true,表示一旦消费端成功收到消息,就立即确认消息,RabbitMQ就会将其从队列中删除。如果为false,则需要手动确认消息。

这个参数的设置意义就是实现消息的手动确认,处理不同线程处理任务不同的耗时而导致一个线程忙死一个线程闲死的资源没有充分利用问题。使用这个手动确认,我们就可以做到“按劳分配”的机制

按照work1+work2->producer的先后,执行代码,结果如下:
在这里插入图片描述
在这里插入图片描述
因为work1的线程睡眠为2秒,work2为0.2秒,所以work2 能力大,处理的消息就越多。

总结

(1)当队列里消息较多时,我们通常会开启多个消费者处理消息;公平分发和轮询分发都是我们经常使用的模式。

(2)轮询分发的主要思想是“按均分配”,不考虑消费者的处理能力,所有消费者均分;这种情况下,处理能力弱的服务器,一直都在处理消息,而处理能力强的服务器,在处理完消息后,处于空闲状态;

(3)公平分发的主要思想是”能者多劳”,按需分配,能力强的干的多。

到这里文章就结束了,感谢阅读
如有错误,欢迎指出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/672665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ActiveX控件打包成Cab置于网页中自动下载安装

[背景] 做过ActiveX控件的朋友都知道&#xff0c;要想把自己做的ActiveX控件功能放在自己的网页上使用&#xff0c;那么用户在客户端就必须进行本地的注册&#xff0c;也就是说用户得首先要把该ActiveX控件(test.ocx)放在本机的%system%/system32下&#xff0c;然后运行DOS工具…

Linux:第四章课后习题及答案

第四章 目录和文件管理 Q1&#xff1a;Linux系统中有哪些文件类型 Linux文件类型常见的有&#xff1a;普通文件、目录 文件、设备文件&#xff08;字符设备文件和块设备 文件&#xff09;、管道文件和符号链接文件等。普通文件 用“ls -lh”命令查看某个文件的属性&#xff0…

Docker 部署 分布式搜索引擎 Elastic Search

文章目录 ⛄引言一、使用Elastic Search 的好处二、部署ES⛅部署kibana⚡部署分词器 三、词典扩展与停用⛅扩展词典⚡停用词典 ⛵小结 ⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮…

【C++篇】模板

友情链接&#xff1a;C/C系列系统学习目录 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的…

使用 InstructPix2Pix 对 Stable Diffusion 进行指令微调

本文主要探讨如何使用指令微调的方法教会 Stable Diffusion 按照指令 PS 图像。这样&#xff0c;我们 Stable Diffusion 就能听得懂人话&#xff0c;并根据要求对输入图像进行相应操作&#xff0c;如: 将输入的自然图像卡通化 。 图 1&#xff1a;我们探索了 Stable Diffusion …

深入探索Android应用启动原理:从入口到界面展示

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。&#x1f60a; 座右铭&#xff1a;不想…

day12_面向对象的三大特征之一(封装)

封装概述​​​​​​​ 为什么需要封装&#xff1f; 现实生活中&#xff0c;每一个个体与个体之间是有边界的&#xff0c;每一个团体与团体之间是有边界的&#xff0c;而同一个个体、团体内部的信息是互通的&#xff0c;只是对外有所隐瞒。例如&#xff1a;我们使用的电脑&a…

【从删库到跑路】MySQL数据库的查询(单表查询,多表查询,内外连接,联合查询,子查询)

&#x1f38a;专栏【MySQL】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;多表查询⭐多表关系&#x1f388;一对多&#x…

自动化运维工具-Ansible详解

目录 一、Ansible介绍 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;特性 &#xff08;三&#xff09;优势 &#xff08;四&#xff09;基本架构 &#xff08;五&#xff09;任务执行模式 &#xff08;六&#xff09;ansible与其余配置管理软件的对比 二、…

【C++篇】STL标准模板库

友情链接&#xff1a;C/C系列系统学习目录 知识点内容正确性以C Primer&#xff08;中文版第五版&#xff09;、C Primer Plus&#xff08;中文版第六版&#xff09;为标准&#xff0c;同时参考其它各类书籍、优质文章等&#xff0c;总结归纳出个人认为较有逻辑的整体框架&…

SpringCloud Alibaba入门1之创建多模块工程

一、创建父项目 创建一个父Maven项目&#xff0c;项目命名为myshop,用于管理子模块。 创建项目后&#xff0c;删除src和增加pom设置 二、创建子module 右键父项目&#xff0c;新建module 此我们的子module就创建完成了。接下来如法炮制&#xff0c;创建另外几个子module&…

【Python 基础篇】Python 元组及元组常用函数

文章目录 导言一、什么是元组二、创建元组2.1 使用括号创建元组2.2 使用函数创建元组 三、访问元组元素四、元组常用函数4.1 len()4.2 count()4.3 index() 总结 导言 当我们需要存储一组不可变的数据时&#xff0c;Python中的元组&#xff08;Tuple&#xff09;就派上了用场。…

chatgpt赋能python:Python文件与目录

Python文件与目录 Python拥有强大的文件和目录操作功能&#xff0c;这使得它成为一个非常强大的编程语言之一。Python的文件和目录操作功能可以帮助你创建、读取和写入文件&#xff0c;访问和处理目录结构&#xff0c;以及对文件和目录进行各种操作。 在这篇文章中&#xff0…

jmeter连接数据mysql数据库

1. 数据库驱动下载 下载地址&#xff1a;https://dev.mysql.com/downloads/connector/j/5.1.html 将下载后的 mysql-connector-java-8.0.27.jar 包放到jmeter的lib目录下 2. 创建jdbc connnection configuration jdbc:mysql://43.224.3.131:3360/student?allowMultiQueriest…

【C++篇】C++与C小知识点区别

友情链接&#xff1a;C/C系列系统学习目录 知识点内容正确性以C Primer&#xff08;中文版第五版&#xff09;、C Primer Plus&#xff08;中文版第六版&#xff09;为标准&#xff0c;同时参考其它各类书籍、优质文章等&#xff0c;总结归纳出个人认为较有逻辑的整体框架&…

2023-01-06 LightDB单机安装.md

LightDB单机安装 LightDB官网&#xff1a;https://www.hs.net/lightdb 下载安装包&#xff1a;lightdb-x-13.8-22.3-7953-el7.x86_64.zip 前置准备 防火墙配置(选择一种操作) firewall防火墙 firewall-cmd --permanent --add-port5432/tcp firewall-cmd --permanent --add-port…

【Unity Shader】从入门到感慨(2)用C#画一个立方体

文章目录 一、构成一个立方需要多少个顶点?二、定义三角面的索引数组:三、定义UV坐标数组:四、最后构建Mesh:五、完整代码:一、构成一个立方需要多少个顶点? 这个问题是面试经常被问到的题。如上图,我们知道在几何中立方体有6个面,8个顶点。但在图形学中,顶点指的是模…

神经网络:卷积操作

当谈到计算机视觉中的网络模型结构时&#xff0c;卷积操作是其中一个关键的组成部分。卷积操作是一种基于局部区域的操作&#xff0c;它在计算机视觉中用于图像处理和特征提取。 卷积操作的原理如下&#xff1a; 给定一个输入图像和一个称为卷积核&#xff08;或滤波器&#x…

HCIP网络笔记分享——IA回顾及OSPF协议

第一部分 HCIA回顾1、网络基础2、动态路由协议3、路由认证4、路由控制&#xff08;AD metric &#xff09; 一、知识巩固二、场景模拟1、获取IP地址1.1 DHCP --- 动态主机配置协议1.1.1 DHCP客户端1.1.2 DHCP服务器1.1.3 DHCP客户端1.1.4 DHCP服务器 2、打开浏览器3、路由器进行…

QT 多语言 中英文切换

本文详细的介绍了利用Qt语言大师工具&#xff0c;实现Qt程序的多国家语言切换。例如新建界面、pro参数、更新翻译、QT预言家翻译语言、翻译中文、翻译英文、发布翻译、核心代码、h源代码、cpp源代码、演示效果等操作。 本文作者原创&#xff0c;转载请附上文章出处与本文链接…