RabbitMQ详解(三):消息模式(fanout、direct、topic、work)

news2024/11/30 6:48:06

消费模式

参考官网:https://www.rabbitmq.com/getstarted.html

  • 简单模式 Simple, 参考RabbitMQ详解(二):消息模式 Simple(简单)模式

    简单模式是最简单的消息模式,它包含一个生产者、一个消费者和一个队列。生产者向队列里发送消息,消费者从队列中获取消息并消费。

  • 发布订阅模式 fanout

    同时向多个消费者发送消息的模式(类似广播的形式)

  • 路由模式 direct

    根据路由键选择性给多个消费者发送消息的模式

  • 主题模式 topic

    是direct模式上的一种叠加,增加了模糊路由RoutingKey的模式

  • 工作模式 work

    分发机制

消息模式-fanout(发布订阅)模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-baD08LMN-1683707937152)(RabbitMQ.assets/image-20230429025709492.png)]

  • 类型:fanout
  • 特点:Fanout—发布与订阅模式,是一种广播机制,它是没有路由key的模式。

创建交换机

在这里插入图片描述

注意 type 类型为fanout

在这里插入图片描述

在这里插入图片描述

绑定队列

  • 图像化管理页面新建queue02、queue03队列

    在这里插入图片描述

  • 点击交换器后,绑定创建的三个队列

    在这里插入图片描述

  • 绑定成功后会如图所示

    在这里插入图片描述

定义生产者

package com.cn.fanout;

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

/**
 * fanout(发布订阅) 生产者
 */
public class Producer {

    public static void main(String[] args) {

        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("生产者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
              //5.申请队列存储信息,此步骤不需要了,我们手动在图形管理页面创建好交换机及绑定好队列queue01、queue02、queue03
            //6.准备发送消息的内容
            String message = "hello,rabbitmq!";
            //7.1.准备交换机
            String exchangeName = "fanout-exchange";
            //7.2.定义路由key,fanout模式没有routingKey参数
            String routingKey = "";
            // 7.3: 发送消息给中间件rabbitmq-server
            /*
             * @params1: 交换机exchange
             * @params2: 队列名称/routingkey
             * @params3: 属性配置
             * @params4: 发送消息的内容
             */
            channel.basicPublish(exchangeName, routingKey, null, message.getBytes());
            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }  finally {
            // 8: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
  • 启动生产者, 会看到每个队列都投递了一条消息

    在这里插入图片描述

定义消费者

package com.cn.fanout;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * fanout(发布订阅) 消费者
 */
public class Consumer {

    public static Runnable runnable =  new Runnable(){
        @Override
        public void run() {
            //1.创建连接工厂
            ConnectionFactory factory = new ConnectionFactory();
            //2.设置工厂属性
            factory.setHost("请填写自己的ip地址");
            factory.setPort(5672);
            factory.setUsername("admin");
            factory.setPassword("admin");
            factory.setVirtualHost("/");

            final String queueName = Thread.currentThread().getName();
            Connection connection = null;
            Channel channel = null;
            try {
                //3.从连接工厂中获取连接
                connection = factory.newConnection("生产者1");
                //4.从连接中获取通道
                channel = connection.createChannel();
                //5.接收消息
                channel.basicConsume(queueName, true, new DeliverCallback() {
                    public void handle(String s, Delivery delivery) throws IOException {
                        System.out.println(queueName + "收到消息是:" + new String(delivery.getBody(), Charset.defaultCharset()));
                    }
                }, new CancelCallback() {
                    public void handle(String s) throws IOException {
                        System.out.println("接收消息失败了...");
                    }
                });
                System.out.println(queueName + "开始接收消息 ");
                System.in.read();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 6: 释放连接关闭通道
                if (channel != null && channel.isOpen()) {
                    try {
                        channel.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    };


    public static void main(String[] args) {
        // 启动三个线程去执行
        new Thread(runnable, "queue01").start();
        new Thread(runnable, "queue02").start();
        new Thread(runnable, "queue03").start();
    }

}
  • 启动消费者,会看到队列中消息已经被消费

    在这里插入图片描述

  • 查看控制台打印日志
    在这里插入图片描述

消费模式-Direct(路由)模式

在这里插入图片描述

  • 类型:direct
  • 特点:Direct模式是fanout模式上的一种叠加,增加了路由RoutingKey的模式。

创建交换机

在这里插入图片描述

绑定队列

在这里插入图片描述

定义生产者

package com.cn.direct;

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

/**
 * direct(路由) 生产者
 */
public class Producer {

    public static void main(String[] args) {

        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("生产者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.申请队列存储信息,此步骤不需要了,我们手动在图形管理页面创建好交换机及绑定好队列queue01、queue02、queue03
            //6.准备发送消息的内容
            String message = "hello,rabbitmq,direct!";
            //7.1.准备交换机
            String exchangeName = "direct-exchange";
            //7.2.定义路由key, direct需要增加routingKey1参数
            String routingKey1 = "email";
//            String routingKey2 = "sms";
            // 7.3: 发送消息给中间件rabbitmq-server
            /*
             * @params1: 交换机exchange
             * @params2: 队列名称/routingkey
             * @params3: 属性配置
             * @params4: 发送消息的内容
             */
            channel.basicPublish(exchangeName, routingKey1, null, message.getBytes());
//            channel.basicPublish(exchangeName, routingKey2, null, message.getBytes());
            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }  finally {
            // 8: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
  • 启动生产者, 会看到只有quque01队列投递了一条消息

    在这里插入图片描述

  • 因为我们的routingKey指定为email,绑定的队列信息如下,所有只有queue01接收到了消息

    在这里插入图片描述

定义消费者

//同fanout模式消费者代码相同 
  • 启动消费者,会看到队列中消息已经被消费

    在这里插入图片描述

  • 查看控制台打印日志

    在这里插入图片描述

消费模式-Topic(主题)模式

在这里插入图片描述

  • 类型:topic
  • 特点:Topic模式是direct模式上的一种叠加,增加了模糊路由RoutingKey的模式。
  • “#” : 匹配一个或者多个
    “**”:匹配一个*

创建交换机

在这里插入图片描述

绑定队列

在这里插入图片描述

定义生产者

package com.cn.topic;

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

/**
 * topic(主题) 生产者
 */
public class Producer {

    public static void main(String[] args) {

        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("生产者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.申请队列存储信息,此步骤不需要了,我们手动在图形管理页面创建好交换机及绑定好队列queue01、queue02、queue03
            //6.准备发送消息的内容
            String message = "hello,rabbitmq,topic!";
            //7.1.准备交换机
            String exchangeName = "topic-exchange";
            //7.2.定义路由key, 模糊匹配
            String routingKey1 = "com.order.xxx";
            // 7.3: 发送消息给中间件rabbitmq-server
            /*
             * @params1: 交换机exchange
             * @params2: 队列名称/routingkey
             * @params3: 属性配置
             * @params4: 发送消息的内容
             */
            channel.basicPublish(exchangeName, routingKey1, null, message.getBytes());
            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }  finally {
            // 8: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
  • 启动生产者, 会看到quque01、queue02队列分别投递了一条消息

    在这里插入图片描述

    • 因为我们的routingKey指定为com.order.xxx,绑定的队列信息如下,所有queue01、queue02接收到了消息

      在这里插入图片描述

定义消费者

//同fanout模式消费者代码相同
  • 启动消费者,会看到队列中消息已经被消费

    在这里插入图片描述

  • 查看控制台打印日志

    在这里插入图片描述

完整的声明创建方式

上面操作的案例 我们都是在管理页面端进行交换机的创建以及绑定,现在我们使用纯代码的方式进行操作

定义生产者

package com.cn.all;

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 factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("生产者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.准备发送消息的内容
            String message = "hello,rabbitmq,all!";
            //6.1.准备交换机
            String exchangeName = "direct-message-exchange";
            //6.2.交换机类型
            String exchangeType = "direct";
            //6.3.声明交换机(是否持久化,true代表交换机不会随着服务器重启丢失)
            channel.exchangeDeclare(exchangeName,exchangeType,true);
            //7.声明队列
            channel.queueDeclare("queue04", true, false ,false, null);
            channel.queueDeclare("queue05", true, false ,false, null);
            channel.queueDeclare("queue06", true, false ,false, null);
            //8.定义路由key
            String routingKey1 = "order";
            String routingKey2 = "course";
            //9.队列和交换机进行绑定
            channel.queueBind("queue04", exchangeName, routingKey1);
            channel.queueBind("queue05", exchangeName, routingKey1);
            channel.queueBind("queue06", exchangeName, routingKey2);
            //10: 发送消息给中间件rabbitmq-server
            /*
             * @params1: 交换机exchange
             * @params2: 队列名称/routingkey
             * @params3: 属性配置
             * @params4: 发送消息的内容
             */
            channel.basicPublish(exchangeName, routingKey1, null, message.getBytes());
            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }  finally {
            // 8: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
  • 启动生产者, 会看到交换机和队列都已创建好,并且已经互相绑定好

    在这里插入图片描述

    在这里插入图片描述

定义消费者

同fanout模式消费者代码相同
  • 启动消费者,会看到队列中消息已经被消费

    在这里插入图片描述

  • 查看控制台打印日志

    在这里插入图片描述

消费模式-Work(工作)模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Xal6iTH-1683712829119)(RabbitMQ.assets/image-20230504154716085.png)]

当有多个消费者时,我们的消费会被哪个消费者消费呢?我们该如何均衡消费者消费信息的多少呢?

  • 轮询模式:一个消费者一条,按均分发
  • 公平分发: 根据消费者消费能力进行公平分发,处理快的处理的快,处理慢的处理的少,按劳分配

轮询模式

  • 类型:无
  • 特点:该模式接收消息是当有多个消费者接入时,消息的分配模式是一个消费者分配一条,直至消息消费完成;

定义生产者

package com.cn.work.roundrobin;

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 factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("生产者7");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.申请队列存储信息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             */
            channel.queueDeclare("queue07", true ,false,false, null);
            //6.准备发送消息的内容
            for (int i = 0; i < 20; i++) {
                String message = "hello,rabbitmq,work!" + i;
                // 7: 发送消息给中间件rabbitmq-server
                /*
                 * @params1: 交换机exchange
                 * @params2: 队列名称/routing
                 * @params3: 属性配置
                 * @params4: 发送消息的内容
                 */
                channel.basicPublish("", "queue07", null, message.getBytes());
            }
            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }  finally {
            // 8: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

定义消费者1

package com.cn.work.roundrobin;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.Charset;

public class Consumer1 {

    public static void main(String[] args) {

        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("消费者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.接收消息(应答机制参数为true  自动应答)
            channel.basicConsume("queue07", true, new DeliverCallback() {
                public void handle(String s, Delivery delivery) throws IOException {
                    System.out.println("Consumer1收到消息是:" + new String(delivery.getBody(), Charset.defaultCharset()));
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                public void handle(String s) throws IOException {
                    System.out.println("Consumer1接收消息失败了...");
                }
            });
            System.out.println("Consumer1开始接收消息");
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

定义消费者2

同上,名称稍修改即可
				    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

先在管理页面创建好队列queue,然后启动消费者1和2,最后启动生产者看页面日志

消费者1和消费者2

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

work1和work2的消息处理能力不同,但是最后处理的消息条数相同,是“按均分配”。

公平分发

  • 类型:无
  • 特点:由于消息接收者处理消息的能力不同,存在处理快慢的问题,我们就需要能者多劳,处理快的多处理,处理慢的少处理;

定义生产者

//同上轮询模式的生产者代码相同

定义消费者1

注意:

  • //设置消费消息指标

    finalChannel.basicQos(1);

  • finalChannel.basicConsume(“queue1”, false, new DeliverCallback() { … })

  • //修改为手动应答
    finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);

package com.cn.work.fairdispatch;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.Charset;

public class Consumer1 {

    public static void main(String[] args) {

        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置工厂属性
        factory.setHost("请填写自己的ip地址");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //3.从连接工厂中获取连接
            connection = factory.newConnection("消费者1");
            //4.从连接中获取通道
            channel = connection.createChannel();
            //5.接收消息(应答机制参数为false  手动应答)
            final Channel finalChannel = channel;
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue07", false, new DeliverCallback() {
                public void handle(String s, Delivery delivery) throws IOException {
                    System.out.println("Consumer1收到消息是:" + new String(delivery.getBody(), Charset.defaultCharset()));
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //修改为手动应答
                    finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
                }
            }, new CancelCallback() {
                public void handle(String s) throws IOException {
                    System.out.println("Consumer1接收消息失败了...");
                }
            });
            System.out.println("Consumer1开始接收消息");
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

定义消费者2

同上,名称稍修改即可

先在管理页面创建好队列queue,然后启动消费者1和2,最后启动生产者看页面日志

消费者1和消费者2

在这里插入图片描述

在这里插入图片描述

小结

  • 消费者一次接收一条消息,代码channel.BasicQos(0, 1, false);
  • 公平分发需要消费者开启手动应答,关闭自动应答
  • 关闭自动应答代码channel.BasicConsume(“queue_test”, false, consumer);
  • 消费者开启手动应答代码:channel.BasicAck(ea.DeliveryTag, false);

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

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

相关文章

量化散户交易数据:追涨爆亏99%,杀跌少赚28倍?| 追涨杀跌一时爽,散户钱包火葬场?【邢不行】

你第一次炒股的经历是不是这样的&#xff1a; 你有一个朋友&#xff0c;他说在XX股票上大赚了一笔&#xff0c;你听后是既羡慕又不服。 于是你下载了炒股软件&#xff0c;看了眼这只股票&#xff0c;有点心动。但由于没有交易经验&#xff0c;股价又确实涨了不少&#xff0c;…

Python基础入门编程代码练习(四)

一、遍历列表 通过 input输入3个人信息&#xff0c;每个人有姓名和年龄&#xff0c;将信息存入字典中&#xff0c;并将将字典存入列表。 遍历列表&#xff0c;打印每个人的信息&#xff0c;打印格式如下&#xff1a; 张三 20李四 22王五 23 1. 输入三个人的信息 (输入 inpu…

qiankun 微前端 demo(Vue2)

前言 这是我最近刚开始学微前端&#xff08;qiankun框架&#xff09;做的一个小demo&#xff0c;做的时候还是遇到很多问题的&#xff0c;在网上也是看了很多别人的Blog&#xff0c;最后也是磨出来了&#x1f602;&#x1f602;&#x1f602;&#xff1b;这篇文章总统分为分为…

国产麒麟操作系统 myCat1.6读写分离

我的环境是麒麟操作系统&#xff0c;我只配置读写分离 一、使用说明&#xff0c;java环境&#xff0c;解压就能用 下载地址https://raw.githubusercontent.com/MyCATApache/Mycat-download/master/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz mycat 是j…

OJ刷题之旅

题目 现在给你两种颜色的箩筐&#xff0c;需要的时候&#xff0c;就把一个个大小差一圈的筐叠上去&#xff0c;使得从上往下看时&#xff0c;边筐花色交错。这个工作现在要让计算机来完成&#xff0c;得看你的了。 输入 输入是一个个的三元组&#xff0c;分别是&#xff0c;外…

SpringCloud使用SkyWalking实现分布式链路追踪1

文章目录 一、MicrometerTracingBrave(Sleuth)链路追踪1、MicrometerTracingBrave和Zipkin的概论2、Docker搭建Zipkin服务3、MicrometerTracingBrave和Zipkin实现链路追踪 二、SkyWaking服务的安装与使用1、SkyWalking的概论2、Java探针的环境搭建3、Java探针实现日志监控4、Sk…

Netty——介绍和maxContentLength配置

官网 介绍 Netty框架的设计思路是基于NIO的事件驱动编程模型&#xff0c;核心组件包括&#xff1a; Channel&#xff1a;通道&#xff0c;负责网络数据的读写操作&#xff1b; EventLoop&#xff1a;事件循环&#xff0c;处理I/O事件和用户自定义事件&#xff1b; ChannelFut…

【子集树】输出一个序列的子序列

【子集树】输出一个序列的子序列 给一个序列 1 2 3 输出序列的子集 1 2 3 12 13 23 123 如何实现&#xff1f; 由上可以看出 类似于全排列 如何用全排列 实现子集输出&#xff1f; 也就是子集树&#xff1f; #include<iostream>using namespace std;const int N 1e5…

【C++技能树】令常规运算符用在类上 --类的六个成员函数II

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0.运算符重载1.赋值运算符 重载2.比较运算符 重载3.比较运算符 ! 重载4.比较运算符 < 重载5.比较运算符 < 重载6. 比较…

图片处理软件:分享6款非常实用的图片处理工具

目录 一、移动端 1、snapseed 2、一键抠图 3、pixlr 二、电脑端 1、图片编辑助手 2.GIMP 3、photopea 今天给大家分享6款非常实用的图片处理工具&#xff0c;其中包含移动端和电脑端&#xff0c;每一款都非常实用&#xff0c;希望对大家能有所帮助&#xff01; 一、移…

《编程思维与实践》1059.计算a的n次方的大整数

《编程思维与实践》1059.计算a的n次方的大整数 题目 思路 高精度的问题统一的解决思路是用一个数组去存大整数的每一位数,运算转化为对数组的操作. 可以从个位开始存(逆序),也可以从最高位开始存(顺序),以处理方便为主要考虑因素. 同时可以将大整数定义为一个结构体,包含位数,…

软件架构:理解分析三层结构观点

三层结构的简单描述及优点   三层体系结构&#xff0c;即用户层、应用层和数据库服务器。用户层主要指用户界面&#xff0c;它要求尽可能的简单&#xff0c;使最终用户不需要进行任何培训就能方便地访问信息&#xff1b;第二层就是应用服务器&#xff0c;也就是常说的中间件&…

webpack: 4 loader汇总(style-loader等)

所有的loader必须匹配规则&#xff0c;否则不生效 配置文件中&#xff0c;module中rules的use执行顺序是从后往前执行 url-loader 用于将文件转换为base64 URI的webpack加载程序。 options limit limit指定文件大小&#xff0c;小于limit的图片不会生成图片以base64格式被引入…

客观地说,应该看一看 Web3.0 了

武术圈有名言&#xff1a;“八极加劈挂&#xff0c;神鬼都害怕”。要是 Web3.0AGI 的话&#xff0c;世界将会变成什么样子&#xff1f; 数科星球原创作者丨苑晶编辑丨大兔 Web3.0 的价值开始受到重视&#xff0c;在最近&#xff0c;来自香港的好消息再次带火了这个领域的热度。…

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化 重要更新&#xff1a;修复 136 个 bug。 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-nsx-t-3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org VMwa…

ChatGPT 接入飞书教程,创建自己的聊天机器人

ChatGPT 接入飞书教程,创建自己的聊天机器人 一、飞书进入开发者平台。点击创建应用。二、打开Aircode,点击创建应用,上面输入名字,下面选择Node.js v16三、配置环境,点击Environments,创建四个变量,全部要大写本教程收集于: AIGC从入门到精通教程 首先,准备三个账号…

FPGA实现MPEG2视频压缩PCIe传输 提供软硬件工程源码和技术支持

目录 1、前言2、MPEG2视频压缩实现3、我已有的FPGA图像视频编解码方案4、我已有的PCIE方案5、MPEG2视频压缩PCIE传输设计方案FPGA硬件设计软件设计 6、Vivado工程详解7、Linux下的XDMA驱动安装8、上板调试验证9、福利&#xff1a;工程代码的获取 1、前言 MJPEG、MPEG2、MPEG4、…

IOS开发指南之storyboard中控件与变量关联及控件事件与方法关联

1.创建IOS工程 2.选择 interface为storyboard,语言选择Objective-C 打开工程后可看到工程默认添加了两个storyboard文件 Main.storyboard为应用主场景,LaunchScreen为启动屏幕场景 3.双击Main.storyboard打开设计窗口,并拖放控件布局如下 4.为控件添加关联变量与(IBOutlet与I…

身高测量仪红外传感测距模块应用方案 WTU201F2 B004 低功耗

​身高测量仪被广泛用于医疗、教育等领域&#xff0c;而红外测距模块在身高测量仪中的应用则成为了一种新的技术手段。红外测距模块是基于红外线技术的一种测距器件&#xff0c;在身高测量仪中&#xff0c;红外测距模块能够精准地测量出人体的高度。与传统的测量方法相比&#…

品牌如何从零开始运营抖音,带你全面了解

随着短视频逐渐深入我们的生活&#xff0c;巨大的流量吸引了众多人群。很多人因此也想开始做抖音&#xff0c;很多品牌却因为内容制作流程复杂&#xff0c;不知从何入门。今天&#xff0c;和大家分享下品牌如何从零开始运营抖音。 其实在开始一件事情之前&#xff0c;最主要的是…