RabbitMQ七种工作模式之简单模式, 工作队列模式, 发布订阅模式, 路由模式, 通配符模式

文章目录

  • 一. Simple(简单模式)
    • 公共代码:
    • 生产者:
    • 消费者:
  • 二. Work Queue(工作队列模式)
    • 公共代码:
    • 生产者:
    • 消费者1, 消费者2(代码相同):
  • 三. Publish/Subscribe(发布/订阅模式)
    • 公共代码:
    • 生产者:
    • 消费者:
  • 四. Routing(路由模式)
    • 公共代码:
    • 消费者:
  • 五. Topics(通配符模式)
    • 公共代码:
    • 生产者:
    • 消费者:

RabbitMQ 共提供了7种⼯作模式, 进⾏消息传递
在这里插入图片描述

一. Simple(简单模式)

在这里插入图片描述
P: ⽣产者, 也就是要发送消息的程序
C: 消费者,消息的接收者
Queue: 消息队列, 类似⼀个邮箱, 可以缓存消息; ⽣产者向其中投递消息, 消费者从其中取出消息.

特点: ⼀个⽣产者P,⼀个消费者C, 消息只能被消费⼀次. 也称为点对点(Point-to-Point)模式
适⽤场景: 消息只能被单个消费者处理

公共代码:

public class Common {public static final String HOST = "139.9.84.204";public static final Integer PORT = 5672;public static final String VIRTUALHOST = "study";public static final String USERNAME = "admin";public static final String PASSWORD = "admin";//简单模式public static final String simpleQueue = "simpleQueue";public static final String simpleMsg = "hello, simple.....";}

生产者:

public class ProducerDemo {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//声明队列//如果没有一个这样的队列, 会自动创建, 如果有, 则不创建channel.queueDeclare(Common.simpleQueue, true, false, false, null);for (int i = 0; i < 10; i++) {//发送消息String msg = Common.simpleMsg + i;channel.basicPublish("", Common.simpleQueue, null, msg.getBytes(StandardCharsets.UTF_8));}//释放资源channel.close();connection.close();}
}

消费者:

public class ConsumerDemo {public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();Channel channel = connection.createChannel();//声明队列channel.queueDeclare(Common.simpleQueue, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("获取到队列: " + new String(body));}};//消费消息channel.basicConsume(Common.simpleQueue, true, consumer);Thread.sleep(2000);//释放资源channel.close();connection.close();}
}

二. Work Queue(工作队列模式)

在这里插入图片描述
⼀个⽣产者P,多个消费者C1,C2. 在多个消息的情况下, Work Queue 会将消息分派给不同的消费者, 每个消费者都会接收到不同的消息.
特点: 消息不会重复, 分配给不同的消费者.
适⽤场景: 集群环境中做异步处理

公共代码:

  //工作队列模式public static final String workQueue = "workQueue";public static final String workQueueMsg = "hello, workQueue.....";

生产者:

public class Producer {public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost(Common.HOST);factory.setPort(Common.PORT);factory.setVirtualHost(Common.VIRTUALHOST);factory.setUsername(Common.USERNAME);factory.setPassword(Common.PASSWORD);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(Common.workQueue, true, false, false, null);for(int i = 0; i < 10; i++){String msg = Common.simpleMsg + i;channel.basicPublish("", Common.workQueue, null, msg.getBytes(StandardCharsets.UTF_8));}channel.close();connection.close();}
}

消费者1, 消费者2(代码相同):

public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost(Common.HOST);factory.setPort(Common.PORT);factory.setVirtualHost(Common.VIRTUALHOST);factory.setUsername(Common.USERNAME);factory.setPassword(Common.PASSWORD);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(Common.workQueue, true, false, false, null);DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.workQueue, true, consumer);
//        channel.close();
//        connection.close();}
}

先启动两个消费者, 再启动生产者:
在这里插入图片描述
在这里插入图片描述

三. Publish/Subscribe(发布/订阅模式)

在这里插入图片描述
图中X表⽰交换机, 在订阅模型中,多了⼀个Exchange角色, 过程略有变化
⼀个⽣产者P, 多个消费者C1, C2, X代表交换机消息复制多份,每个消费者接收相同的消息
⽣产者发送⼀条消息,经过交换机转发到多个不同的队列,多个不同的队列就有多个不同的消费者
适合场景: 消息需要被多个消费者同时接收的场景. 如: 实时通知或者⼴播消息

概念介绍
Exchange: 交换机 (X).
作⽤: ⽣产者将消息发送到Exchange, 由交换机将消息按⼀定规则路由到⼀个或多个队列中(上图中⽣产者将消息投递到队列中, 实际上这个在RabbitMQ中不会发⽣. )
RabbitMQ交换机有四种类型: fanout,direct, topic, headers, 不同类型有着不同的路由策略. AMQP协议⾥还有另外两种类型, System和⾃定义, 此处不再描述.

  1. Fanout:⼴播,将消息交给所有绑定到交换机的队列(Publish/Subscribe模式)
  2. Direct:定向,把消息交给符合指定routing key的队列(Routing模式)
  3. Topic:通配符,把消息交给符合routing pattern(路由模式)的队列(Topics模式)
  4. headers类型的交换器不依赖于路由键的匹配规则来路由消息, ⽽是根据发送的消息内容中的headers属性进⾏匹配. headers类型的交换器性能会很差,⽽且也不实⽤,基本上不会看到它的存在.

Exchange(交换机)只负责转发消息, 不具备存储消息的能⼒, 因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息就会丢失
RoutingKey: 路由键.⽣产者将消息发给交换器时, 指定的⼀个字符串, ⽤来告诉交换机应该如何处理这个消息.
Binding Key:绑定. RabbitMQ中通过Binding(绑定)将交换器与队列关联起来, 在绑定的时候⼀般会指定⼀个Binding Key, 这样RabbitMQ就知道如何正确地将消息路由到队列了.
在这里插入图片描述

公共代码:

   //发布订阅模式public static final String FANOUT_EXCHANGE = "fanoutExchange";public static final String FANOUT_QUEUE1 = "fanoutQueue1";public static final String FANOUT_QUEUE2 = "fanoutQueue2";

生产者:

创建交换机:

		//创建交换机channel.exchangeDeclare(Common.FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT, true, false, false, null);

参数解释:
在这里插入图片描述

  • exchange: 交换机名称
  • type: 交换机类型在这里插入图片描述
  • durable: 是否持久化
  • autoDelete: 自动删除, ⾃动删除的前提是⾄少有⼀个队列或者交换器与这个交换器绑定, 之后所有与这个交换器绑定的队列或者交换器都与此解绑
  • internal: 一般为false, 如果设置为true, 表⽰内部使⽤, 客⼾端程序⽆法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种⽅式
  • arguments: 参数
    创建队列:
	   //创建队列channel.queueDeclare(Common.FANOUT_QUEUE1, true, false, false, null);channel.queueDeclare(Common.FANOUT_QUEUE2, true, false, false, null);

绑定交换机和队列:

    //绑定交换机和队列channel.queueBind(Common.FANOUT_QUEUE1, Common.FANOUT_EXCHANGE, "");channel.queueBind(Common.FANOUT_QUEUE2, Common.FANOUT_EXCHANGE, "");

参数说明:
在这里插入图片描述

  • queue: 队列名
  • exchange: 交换机名
  • routingKey: 路由key, 路由规则, 如果交换机类型为fanout,routingkey设置为"",表⽰每个消费者都可以收到全部信息
    发送消息:
		 //发送消息String msg = "hello, fanout......";channel.basicPublish(Common.FANOUT_EXCHANGE, "", null, msg.getBytes(StandardCharsets.UTF_8));

完整代码:

public class Producer {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建交换机channel.exchangeDeclare(Common.FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT, true, false, false, null);//创建队列channel.queueDeclare(Common.FANOUT_QUEUE1, true, false, false, null);channel.queueDeclare(Common.FANOUT_QUEUE2, true, false, false, null);//绑定交换机和队列channel.queueBind(Common.FANOUT_QUEUE1, Common.FANOUT_EXCHANGE, "");channel.queueBind(Common.FANOUT_QUEUE2, Common.FANOUT_EXCHANGE, "");//发送消息String msg = "hello, fanout......";channel.basicPublish(Common.FANOUT_EXCHANGE, "", null, msg.getBytes(StandardCharsets.UTF_8));}
}

消费者:

public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.FANOUT_QUEUE1, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.FANOUT_QUEUE1, true, consumer);}
}
public class Consumer2 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.FANOUT_QUEUE2, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.FANOUT_QUEUE2, true, consumer);}
}

在这里插入图片描述

在这里插入图片描述

四. Routing(路由模式)

在这里插入图片描述
路由模式是发布订阅模式的变种, 在发布订阅基础上, 增加路由key
发布订阅模式是⽆条件的将所有消息分发给所有消费者, 路由模式是Exchange根据RoutingKey的规则, 将数据筛选后发给对应的消费者队列
适合场景: 需要根据特定规则分发消息的场景

公共代码:

 //路由模式public static final String DIRECT_EXCHANGE = "directExchange";public static final String DIRECT_QUEUE1 = "directQueue1";public static final String DIRECT_QUEUE2 = "directQueue2";

生产者:

public class Producer {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建交换机channel.exchangeDeclare(Common.DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT, true, false, false, null);//创建队列channel.queueDeclare(Common.DIRECT_QUEUE1, true, false, false, null);channel.queueDeclare(Common.DIRECT_QUEUE2, true, false, false, null);//绑定交换机和队列channel.queueBind(Common.DIRECT_QUEUE1, Common.DIRECT_EXCHANGE, "a");channel.queueBind(Common.DIRECT_QUEUE2, Common.DIRECT_EXCHANGE, "a");channel.queueBind(Common.DIRECT_QUEUE2, Common.DIRECT_EXCHANGE, "b");channel.queueBind(Common.DIRECT_QUEUE2, Common.DIRECT_EXCHANGE, "c");//发送消息String msg1 = "hello, direct a......";channel.basicPublish(Common.DIRECT_EXCHANGE, "a", null, msg1.getBytes(StandardCharsets.UTF_8));String msg2 = "hello, direct b......";channel.basicPublish(Common.DIRECT_EXCHANGE, "b", null, msg2.getBytes(StandardCharsets.UTF_8));String msg3 = "hello, direct c......";channel.basicPublish(Common.DIRECT_EXCHANGE, "c", null, msg3.getBytes(StandardCharsets.UTF_8));}
}

消费者:

public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.DIRECT_QUEUE1, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.DIRECT_QUEUE1, true, consumer);}
}
public class Consumer2 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.DIRECT_QUEUE2, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.DIRECT_QUEUE2, true, consumer);}
}

在这里插入图片描述
在这里插入图片描述

五. Topics(通配符模式)

在这里插入图片描述
路由模式的升级版, 在routingKey的基础上,增加了通配符的功能, 使之更加灵活.
Topics和Routing的基本原理相同,即:⽣产者将消息发给交换机,交换机根据RoutingKey将消息转发给与RoutingKey匹配的队列. 类似于正则表达式的⽅式来定义Routingkey的模式.
不同之处是:routingKey的匹配⽅式不同,Routing模式是相等匹配,topics模式是通配符匹配.
在这里插入图片描述

适合场景: 需要灵活匹配和过滤消息的场景

公共代码:

  //路由模式public static final String TOPIC_EXCHANGE = "topicExchange";public static final String TOPIC_QUEUE1 = "topicQueue1";public static final String TOPIC_QUEUE2 = "topicQueue2";

生产者:

public class Producer {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建交换机channel.exchangeDeclare(Common.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC, true, false, false, null);//创建队列channel.queueDeclare(Common.TOPIC_QUEUE1, true, false, false, null);channel.queueDeclare(Common.TOPIC_QUEUE2, true, false, false, null);//绑定交换机和队列channel.queueBind(Common.TOPIC_QUEUE1, Common.TOPIC_EXCHANGE, "*.a.*");channel.queueBind(Common.TOPIC_QUEUE2, Common.TOPIC_EXCHANGE, "*.*.b");channel.queueBind(Common.TOPIC_QUEUE2, Common.TOPIC_EXCHANGE, "c.#");//发送消息String msg1 = "hello, direct hello.a.b......";channel.basicPublish(Common.TOPIC_EXCHANGE, "hello.a.b", null, msg1.getBytes(StandardCharsets.UTF_8));//匹配队列1,2String msg2 = "hello, direct hello.world.b......";channel.basicPublish(Common.TOPIC_EXCHANGE, "hello.world.b", null, msg2.getBytes(StandardCharsets.UTF_8));//匹配队列2String msg3 = "hello, direct c.hello.b......";channel.basicPublish(Common.TOPIC_EXCHANGE, "c.hello.b", null, msg3.getBytes(StandardCharsets.UTF_8));//匹配队列2}
}

消费者:

public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.TOPIC_QUEUE1, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.TOPIC_QUEUE1, true, consumer);}
}
public class Consumer2 {public static void main(String[] args) throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory factory = new ConnectionFactory();//2. 设置参数factory.setHost(Common.HOST);//ipfactory.setPort(Common.PORT);//端口号factory.setVirtualHost(Common.VIRTUALHOST);//虚拟机名称factory.setUsername(Common.USERNAME);//用户名factory.setPassword(Common.PASSWORD);//密码//3. 创建连接connectionConnection connection = factory.newConnection();//创建channelChannel channel = connection.createChannel();//创建队列channel.queueDeclare(Common.TOPIC_QUEUE2, true, false, false, null);//消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}};channel.basicConsume(Common.TOPIC_QUEUE2, true, consumer);}
}

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

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

相关文章

前端知识1html

VScode一些快捷键 Ctrl/——注释 !——生成html框架元素 *n——生成n个标签 直接书写html的名字回车生成对应的标签 常见标签 span&#xff1a; <span style"color: red;">hello</span> <span>demo</span> span实现&#xff1a; 标题…

Push an existing folder和Push an existing Git repository的区别

Push an existing folder 和 Push an existing Git repository 是在使用 Git 服务&#xff08;如 GitHub、GitLab、Bitbucket 等&#xff09;时两个常见的操作选项。它们的区别主要体现在项目的初始化和版本控制状态上&#xff1a; 1. Push an existing folder 适用场景&#…

Netty入门(快速了解以及使用netty)

二. Netty 入门 1. 概述 1.1 Netty 是什么&#xff1f; Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.Netty 是一个异步的、基于事件驱动的网络应用框架&…

Zemax 中 ZBF 文件激光传播的描述

激光传播是指激光束在空间或介质中传播的方式。激光的独特特性&#xff0c;例如相干性、单色性和准直性&#xff0c;使其行为与普通光源不同。了解激光传播的原理在光学、通信、医疗技术和科学研究等领域至关重要。 激光产生高斯光束&#xff0c;其中强度在光束横截面上服从高…

DataSophon集成CMAK KafkaManager

本次集成基于DDP1.2.1 集成CMAK-3.0.0.6 设计的json和tar包我放网盘了. 通过网盘分享的文件&#xff1a;DDP集成CMAK 链接: https://pan.baidu.com/s/1BR70Ajj9FxvjBlsOX4Ivhw?pwdcpmc 提取码: cpmc CMAK github上提供了zip压缩包.将压缩包解压之后 在根目录下加入启动脚本…

go基础总结

最近参加字节跳动后端青训营&#xff0c;技术栈是go。go跟Java还是有些区别的&#xff0c;所以自己做点笔记来总结总结go的基础语法 数据类型 go的数据类型有以下几类&#xff1a; 数值类型&#xff1a;整形分为(u)int8、(u)int16、(u)int32、byte、rune、uintptr…&#xf…

docker环境搭建

目录 环境配置指定docker镜像源 环境配置 使用ubuntu20版本 最好先修改一下镜像源&#xff0c;不然要下20分钟 sudo apt install docker.io还需要装以下这些 sudo apt-get install ca-certificates sudo apt-get install curl sudo apt-get install gnupg sudo apt-get ins…

策略模式实战 - 鸭展

该示例出自著名的《HeadFirst》系列的《HeadFirst设计模式》图书的第一个设计模式。用一个鸭子展览的小应用&#xff0c;一步步揭示了如何引入和使用策略模式将示例改造的完美一些。 文章目录 红头鸭与绿头鸭橡皮鸭和诱饵鸭用接口代替继承组合关系与策略模式 红头鸭与绿头鸭 当…

Java(三)IDE集成环境

Java开发使用的ICE集成环境就是大名鼎鼎的eclipse了。 Eclipse的功能很强大,不止可以用来开发java,还可以用来开发C++、Python、PHP等程序。 Eclipse是免费的,直接去官网下载就好了,官网地址: Eclipse Downloads | The Eclipse Foundation 双击安装,我们会看到如下界…

在阿里云/Linux环境搭建Gitblit服务

在阿里云/Linux环境搭建Gitblit服务 1. 整体描述2. 前期准备3. 安装步骤3.1 下载gitblit3.2 上传gitblit3.3 解压文件3.4 修改文件配置3.5 启动gitblit3.6 安全组配置 4. 总结 1. 整体描述 前段时间买了一个阿里云服务器&#xff0c;2核2G&#xff0c;3M固定带宽的配置&#x…

MySQL的获取、安装、配置及使用教程

一、获取MySQL 官网地址:https://www.mysql.com MySQL产品:企业版(Enterprise)和社区版(Community)社区版是通过GPL协议授权的开源软件&#xff0c;可以免费使用。企业版是需要收费的商业软件 MySQL版本历史:5.0、5.5、5.6、5.7和8.0(最新版本)两种打包版本:MSI(安装版)和ZI…

故障处理--kuboard无法访问,etcd磁盘空间不足

问题现象&#xff1a; kuboard页面报错 排查过程&#xff1a; 1、查看kuboard是否正常。 2、查看kuboard容器的日志&#xff1a; docker logs -f --tail10 kuboard 大概内容如下&#xff1a; levelerror msg"failed to rotate keys: etcdserver: mvcc: database sp…

前端技术(23) : 聊天页面

来源: GPT生成之后微调 效果图 HTML代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>聊天</t…

海外的bug-hunters,不一样的403bypass

一种绕过403的新技术&#xff0c;跟大家分享一下。研究HTTP协议已经有一段时间了。发现HTTP协议的1.0版本可以绕过403。于是开始对lyncdiscover.microsoft.com域做FUZZ并且发现了几个403Forbidden的文件。 &#xff08;访问fsip.svc为403&#xff09; 在经过尝试后&#xff0…

如何使用Java编写Jmeter函数

Jmeter 自带有各种功能丰富的函数&#xff0c;可以帮助我们进行测试&#xff0c;但有时候提供的这些函数并不能满足我们的要求&#xff0c;这时候就需要我们自己来编写一个自定义的函数了。例如我们在测试时&#xff0c;有时候需要填入当前的时间&#xff0c;虽然我们可以使用p…

无人设备遥控器之动态调频功能篇

一、动态调频功能概述 动态调频功能是指无人机遥控器能够根据当前环境或用户需求&#xff0c;自动调整无线电信号的频率&#xff0c;以优化通信质量和控制性能。这一功能对于确保无人机在复杂环境中的稳定飞行和精确控制至关重要。 二、动态调频的工作原理 频率选择与调整&am…

Android -- [SelfView] 自定义多行歌词滚动显示器

Android – [SelfView] 自定义多行歌词滚动显示器 流畅、丝滑的滚动歌词控件* 1. 背景透明&#xff1b;* 2. 外部可控制进度变化&#xff1b;* 3. 支持屏幕拖动调节进度&#xff08;回调给外部&#xff09;&#xff1b;效果 歌词文件&#xff08;.lrc&#xff09; 一. 使用…

【知识点】图与图论入门

何为图论 见名知意&#xff0c;图论 (Graph Theory) 就是研究 图 (Graph) 的数学理论和方法。图是一种抽象的数据结构&#xff0c;由 节点 (Node) 和 连接这些节点的 边 (Edge) 组成。图论在计算机科学、网络分析、物流、社会网络分析等领域有广泛的应用。 如下&#xff0c;这…

前海紫荆花广场附近路面的临时停车点

前海紫荆花广场附近路面的临时停车点大概20个的样子 具体在紫荆花广场的侧边&#xff0c;每天都有车停。建议临时应急停。因为虽然没有交警贴罚单&#xff0c;但是还是会被贴违停。 不少车贴如下禁停标志。其实附近桂湾公园就可以免费停车&#xff0c;可能是公园停满了&#xf…

【5G】5G Physical Layer物理层(一)

5G多址接入和物理层与长期演进&#xff08;LTE&#xff09;存在一些差异。在下行方向&#xff0c;5G与LTE相似&#xff0c;依旧采用正交频分多址&#xff08;OFDMA&#xff09;。而在上行方向&#xff0c;5G采用了OFDMA和单载波频分多址&#xff08;SC-FDMA&#xff09;&#x…