【RabbitMQ】| 狮子带你(超详细)原生Java操作兔子队列

news2024/9/21 14:52:10

目录

  • 一. 🦁 前言
  • 二. 🦁 原生Java操作RabbitMQ
    • Ⅰ. 简单模式
      • 1. 添加依赖
      • 2. 编写生产者
      • 3. 编写消费者
    • Ⅱ. 工作队列模式
      • 1. 编写生产者
      • 2. 编写消费者
      • 3. 实现
    • Ⅲ. 发布订阅模式
      • 1. 编写生产者
      • 2. 编写消费者
    • Ⅳ. 路由模式
      • 1. 编写生产者
      • 2. 编写消费者
    • Ⅴ. 通配符模式
      • 1. 编写生产者
      • 2. 编写消费者
  • 三. 🦁 总结

一. 🦁 前言

RabbitMQ 是一种快速、灵活、可靠的消息传递方式,可用于构建分布式应用程序、异步处理任务、实现消息队列等。下面是 Java 原生操作 RabbitMQ 的一些好处和用途:

  1. 简单易用:RabbitMQ 提供了丰富的 Java 客户端库,开发者可以轻松地使用 Java 代码进行消息发送和接收,无需学习复杂的消息传递协议和 API。

  2. 可扩展性强:RabbitMQ 支持集群和分布式部署,可以轻松地实现横向和纵向扩展,以适应不同规模和负载的应用需求。

  3. 可靠性高:RabbitMQ 提供了多种消息传递模式,包括持久化消息、确认机制、事务机制等,确保消息传递的可靠性和一致性。

  4. 异步处理能力:RabbitMQ 可以异步处理任务,提高应用程序的响应速度和吞吐量,实现任务削峰、应对高并发等需求。

  5. 可用于多种场景:RabbitMQ 可以用于构建分布式应用程序、实现消息队列、异步处理任务、实现实时数据同步等场景,具有广泛的应用场景和发展前景。

二. 🦁 原生Java操作RabbitMQ

Ⅰ. 简单模式

1. 添加依赖

    <!--rabbitmq依赖-->
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>5.14.0</version>
    </dependency>

2. 编写生产者

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

//生产者
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
//        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.建立信道
        Channel channel = connection.createChannel();
//        4.创建队列,若队列已存在则使用该队列
        /**
         * 参数1:队列名
         * 参数2:是否持久化,true表示MQ重启后队列还存在
         * 参数3:是否私有化,false表示所有消费者都可以访问,true表示只有第一次访问她的消费者才能访问
         * 参数4:是否自动删除,true表示不再使用队列时,自动删除
         * 参数5:其他额外参数
         */
        channel.queueDeclare("simple_queue",false,false,false,null);
//        5.发送消息
        String message = "hello rabbitmq";
        /**
         * 参数1:交换机名,""表示默认交换机
         * 参数2:路由键,简单模式就是队列名
         * 参数3:其他额外参数
         * 参数4:要传递的消息字节数组
         */
        channel.basicPublish("","simple_queue",null,message.getBytes());
//        6.关闭信道和连接
        channel.close();
        connection.close();
        System.out.println("=====发送成功====");
    }
}

image-20230411151940196

3. 编写消费者

因为消费者不知道生产者什么时候发送消息过来,所以消费者需要一直监听生产者

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消费者
 */
public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {
//        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("simple_queue",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("接收消息,消息为:"+message);
            }
        });
    }
}

image-20230411152552799

Ⅱ. 工作队列模式

image-20230411154500986

与简单模式相比,工作队列模式(Work Queue)多了一些消费者,该模式也使用direct交换机,应用于处理消息较多的情况。特点如下:

  1. 一个队列对应多个消费者。
  2. 一条消息只会被一个消费者消费。
  3. 消息队列默认采用轮询的方式将消息平均发送给消费者。

其实就是 简单模式plus版本。

1. 编写生产者

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

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
//        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.创建队列,持久化队列
        channel.queueDeclare("work_queue",true,false,false,null);
//        5.发送大量消息,参数3表示该消息为持久化消息,即除了保存到内存还保存到磁盘
        for (int i = 0; i < 100; i++) {
            channel.basicPublish("","work_queue", MessageProperties.PERSISTENT_TEXT_PLAIN,
                    ("您好,这是今天的第"+i+"条消息").getBytes(StandardCharsets.UTF_8));
        }
//        6.关闭资源
        channel.close();
        connection.close();
    }
}

image-20230411155449300

2. 编写消费者

这里使用创建了三个消费者,来接收生产者的消息

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        监听队列,处理消息
        channel.basicConsume("work_queue",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("消费者1消费消息,消息为:"+message);
            }
        });
    }
}

3. 实现

先把三个消费者运行起来,再运行生产者,得到的消息就会轮询均分

image-20230411160256568

Ⅲ. 发布订阅模式

在开发过程中,有一些消息需要不同消费者进行不同的处理,如电商网站的同一条促销信息需要短信发送、邮件发送、站内信发送等。此时可以使用发布订阅模式(Publish/Subscribe)

特点:

  1. 生产者将消息发送给交换机,交换机将消息转发到绑定此交换机的每个队列中。
  2. 工作队列模式的交换机只能将消息发送给一个队列,发布订阅模式的交换机能将消息发送给多个队列。发布订阅模式使用fanout交换机。

1. 编写生产者

这里创建了三条队列,一条是发送短信,一条是站内信,一条是邮件队列、

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

import javax.swing.plaf.TreeUI;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

/**
 * 发布订阅者模式跟简单和工作模式不一样,不是使用默认的交换机,而是自己创建fanout交换机,生产者把消息发到交换机,由交换机转发到与之绑定的队列
 */
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.建立信道
        Channel channel = connection.createChannel();
//        4.创建交换机
        /**
         * 参数1:交换机名
         * 参数2:交换机类型
         * 参数3:交换机是否持久化
         */
        channel.exchangeDeclare("exchange_fanout", BuiltinExchangeType.FANOUT,true);
//        5.创建队列
        channel.queueDeclare("SEND_MAIL",true,false,false,null);
        channel.queueDeclare("SEND_MESSAGE",true,false,false,null);
        channel.queueDeclare("SEND_STATION",true,false,false,null);
//        6.交换机绑定队列
        /**
         * 参数1:队列名
         * 参数2:交换机名
         * 参数3:路由关键字,发布订阅模式只需要写""即可
         */
        channel.queueBind("SEND_MAIL","exchange_fanout","");
        channel.queueBind("SEND_MESSAGE","exchange_fanout","");
        channel.queueBind("SEND_STATION","exchange_fanout","");
//        7.发送消息
        for (int i = 0; i < 10; i++) {
            channel.basicPublish("exchange_fanout","",null,
                    ("您好,尊敬的用户,秒杀商品活动开始啦:"+i).getBytes(StandardCharsets.UTF_8));
        }
//        8.关闭资源
        channel.close();
        connection.close();
    }
}

2. 编写消费者

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

//短信消费者
public class ConsumerMessage {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_MESSAGE",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送短信,消息为:"+message);
            }
        });
    }
}

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

//邮件消费者
public class ConsumerMail {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_MAIL",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送邮件,消息为:"+message);
            }
        });
    }
}
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

//站内信消费者
public class ConsumerStation {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_STATION",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送站内信,消息为:"+message);
            }
        });
    }
}

发布订阅模式也允许多个消费者监听同一个队列(工作模式),例如 两个发送短信消费者监听同一个短信生产者,这样短信生产者的消息将会被轮询平分。

Ⅳ. 路由模式

image-20230411173014108

使用发布订阅模式时,所有消息都会发送到绑定的队列中,但很多时候,不是所有消息都无差别的发布到所有队列中。比如电商网站

的促销活动,双十一大促可能会发布到所有队列;而一些小的促销活动为了节约成本,只发布到站内信队列。此时需要使用路由模式

(Routing)完成这一需求。意思就是只发给与绑定相同路由关键字的队列

特点:

  1. 每个队列绑定路由关键字RoutingKey。

  2. 生产者将带有RoutingKey的消息发送给交换机,交换机根据RoutingKey转发到指定队列。路由模式使用direct交换机。

1. 编写生产者

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

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

/**
 * 发布订阅者模式跟简单和工作模式不一样,不是使用默认的交换机,而是自己创建fanout交换机,生产者把消息发到交换机,由交换机转发到与之绑定的队列
 */
// 生产者
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
        // 2.创建连接
        Connection connection = connectionFactory.newConnection();
        // 3.建立信道
        Channel channel = connection.createChannel();
        // 4.创建交换机
        channel.exchangeDeclare("exchange_routing", BuiltinExchangeType.DIRECT,true);
        // 5.创建队列
        channel.queueDeclare("SEND_MAIL2",true,false,false,null);
        channel.queueDeclare("SEND_MESSAGE2",true,false,false,null);
        channel.queueDeclare("SEND_STATION2",true,false,false,null);
        // 6.交换机绑定队列
        channel.queueBind("SEND_MAIL2","exchange_routing","import");
        channel.queueBind("SEND_MESSAGE2","exchange_routing","import");
        channel.queueBind("SEND_STATION2","exchange_routing","import");
        channel.queueBind("SEND_STATION2","exchange_routing","normal");
        // 7.发送消息
        channel.basicPublish("exchange_routing","import",null,
                "双十一大促活动".getBytes());
        channel.basicPublish("exchange_routing","normal",null,
                "小心促销活动".getBytes());
        // 8.关闭资源
        channel.close();
        connection.close();
    }
}

2. 编写消费者

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

//发送邮件消费者
public class ConsumerMail {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_MAIL2",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送邮件,消息为:"+message);
            }
        });
    }
}

//发送信息消费者
public class ConsumerMessage {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_MESSAGE2",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送短信,消息为:"+message);
            }
        });
    }
}

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

//站内信消费者
public class ConsumerStation {
    public static void main(String[] args) throws IOException, TimeoutException {
        //        1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
//        2.创建连接
        Connection connection = connectionFactory.newConnection();
//        3.创建信道
        Channel channel = connection.createChannel();
//        4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果为false,则需要手动确认消息已收到,否则MQ会一直发送消息。
         * 参数3:Consumer的实现类,重写该类方法表示接收到这个消息之后该如何消费消息
         */
        channel.basicConsume("SEND_STATION2",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发送站内信,消息为:"+message);
            }
        });
    }
}

Ⅴ. 通配符模式

image-20230411204903551

通配符模式(Topic)是在路由模式的基础上,给队列绑定带通配符的路由关键字,只要消息的RoutingKey能实现通配符匹配,就会将消

息转发到该队列。通配符模式比路由模式更灵活,使用topic交换机。

通配符规则:

1 消息设置RoutingKey时,RoutingKey由多个单词构成,中间以 . 分割。

2 队列设置RoutingKey时, # 可以匹配任意多个单词, * 可以匹配任意一个单词。

1. 编写生产者

image-20230411211252594

package com.itbz.mq.topic;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 发布订阅者模式跟简单和工作模式不一样,不是使用默认的交换机,而是自己创建fanout交换机,生产者把消息发到交换机,由交换机转发到与之绑定的队列
 */
// 生产者
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.79.50.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lion");
        connectionFactory.setPassword("lion");
        connectionFactory.setVirtualHost("/");
        // 2.创建连接
        Connection connection = connectionFactory.newConnection();
        // 3.建立信道
        Channel channel = connection.createChannel();
        // 4.创建交换机
        channel.exchangeDeclare("exchange_topic", BuiltinExchangeType.TOPIC,true);
        // 5.创建队列
        channel.queueDeclare("SEND_MAIL3",true,false,false,null);
        channel.queueDeclare("SEND_MESSAGE3",true,false,false,null);
        channel.queueDeclare("SEND_STATION3",true,false,false,null);
        // 6.交换机绑定队列
        channel.queueBind("SEND_MAIL3","exchange_topic","#.mail.#");
        channel.queueBind("SEND_MESSAGE3","exchange_topic","#.message.#");
        channel.queueBind("SEND_STATION3","exchange_topic","#.station.#");
        // 7.发送消息
            // 三个队列都匹配上了
        channel.basicPublish("exchange_topic","mail.message.station",null,
                "双十一大促活动".getBytes());
            // 只发给station
        channel.basicPublish("exchange_topic","station",null,
                "小心促销活动".getBytes());
        // 8.关闭资源
        channel.close();
        connection.close();
    }
}

2. 编写消费者

跟前面差不多。。。

三. 🦁 总结

这篇万字长文总结了原生Java操作RabbitMQ的各种过程,希望对您有帮助哦!!!咱们下期见!😄

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

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

相关文章

SpringCloud源码之Spring Cloud Common核心接口说明

spring cloud commons spring cloud提供的通用抽象包&#xff0c;组件的实现基本上都依赖于当前包的接口定义实现功能&#xff0c;下面就是梳理一下当前包中都提供了哪些比较重要的接口 1. 服务注册 1.1 DiscoveryClient DiscoveryClient 是一个顶级的接口类&#xff0c;用…

node项目的建立

文章目录 1.node项目的建立1.1项目初始化1.2 安装express1.3 初始化服务器 2.配置跨域2.1安装cors2.2cors的引入&#xff08;app.js中&#xff09; 3.初始化路由3.1新建文件3.2初始路由模块3.3app.js注册3.4 在postman测试 4.抽离路由处理模块3.1 在router_handler新建user.js3…

为什么LC谐振频率附近信号会被放大

这个是LC低通滤波电路&#xff0c; 它的增益曲线是这样的 很多同学不理解为什么谐振频率附近信号会被放大&#xff0c;今天就来聊一聊为什么谐振频率附近信号会被放大。 看到这个LC低通滤波电路&#xff0c;假设输入信号源内阻为Rs&#xff0c;L和C为理想电感和电容&#xff0…

Jmeter(五)_CSV Data参数化,Beanshell

一.CSV Data Set Config 准备好一个txt文件&#xff0c;写入如下内容&#xff0c;第一行可以不写&#xff0c;写了的话也会作为一组数据被运行&#xff1a; 然后把后缀名改为CSV&#xff0c;这样一个参数化文件就准备好了 然后打开jmeter&#xff0c;在需要使用这个参数化…

数据库系统-数据库查询实现算法

文章目录 一、一趟扫描算法1.1 算法概述1.2 算法逻辑&物理实现1.2.1 逻辑层面1.2.2 物理层面1.2.2.1 P11.2.2.2 P21.2.2.3 P31.2.2.4 P4 1.3 迭代器构造查询实现算法1.4 关系操作的一趟扫描算法1.4 基于索引的查询实现算法 二、两趟扫描算法2.1 两趟算法基本思想2.2 多路归…

Clickhouse分布式表引擎(Distributed)写入核心原理解析

Clickhouse分布式表引擎&#xff08;Distributed&#xff09;写入核心原理解析 Clickhouse分布式表引擎&#xff08;Distributed&#xff09;写入核心原理解析Clickhouse分布式表引擎&#xff08;Distributed&#xff09;查询核心原理解析 Distributed表引擎是分布式表的代名…

vue打包并部署到nginx上

一、打包vue项目 打包的命令依据项目的配置可能会有所不同&#xff0c;打包的命令可以在package.json中查看 项目中vue.config.js中的配置如下&#xff1a; proxy关系到我们项目部署到nginx上需要配置对应的反向代理 publicPath关系到我们部署时是否需要配置子路径 默认情况…

基于公共信箱的全量消息实现

作者 | 百度消息中台团队 导读 消息中台为百度App以及厂内百度系产品提供即时通讯的能力&#xff0c;提供包括私聊、群聊、聊天室、直播弹幕等用户沟通场景&#xff0c;并帮助业务通过消息推送触达用户。百度App存在需要以『低用户打扰』的形式触达全量用户的场景&#xff0c;而…

AcWing第 96 场周赛

竞赛 - AcWing 一、完美数 4876. 完美数 - AcWing题库 1、题目 如果一个正整数能够被 2520 整除&#xff0c;则称该数为完美数。 给定一个正整数 n&#xff0c;请你计算 [1,n]范围内有多少个完美数。 输入格式 一个整数 n。 输出格式 一个整数&#xff0c;表示 [1,n] 范…

C++:Article : 链接器(三):库与可执行文件的生成

链接器&#xff1a;库与可执行文件 1. 静态库1.1 静态链接下&#xff0c;可执行文件如何生成 2. 动态库2.1 动态库特点以及与静态库使用方式差异2.2 动态库和静态库使用时间 3. load-time dynamic linking&#xff08;加载时动态链接&#xff09;3.1&#xff1a;阶段一&#xf…

【工具】FFmpeg|超大视频本地有损压缩,500MB变25MB(支持 Windows、Linux、macOS)

参考&#xff1a; 如何将一分钟长的1080p视频压缩至5MB以内&#xff1f;-知乎-滔滔清风近期HEVC扩展备用安装方法-B站-悲剧天下 总共三个步骤&#xff0c;安装FFmpeg、运行指令、打开视频。 亲测 500MB 变 25MB。 1 安装FFmpeg 对于不需要看教程可以自行完成安装的同学们&am…

MySQL基础案例——数据表的基本操作:创建表和修改表

目录 案例目的&#xff1a; 创建表&#xff1a; 创建offices&#xff1a; 创建employees表&#xff1a; 修改表&#xff1a; 将 employees 的 mobile 字段移动到 officeCode 字段后&#xff1a; 将 birth 字段名称改为 employee_birth: 修改 sex 字段&#xff0c;数据类…

TryHackMe-Looking Glass(boot2root)

Looking Glass 穿过镜子。仙境挑战室的续集。 端口扫描 循例nmap 又是一堆ssh&#xff0c;跟之前的玩法一样 找到正确的ssh端口之后后给了一段密文&#xff0c;要求输入secret才能进入ssh 这看起来非常像凯撒密码 唯一可识别的信息是Jabberwocky&#xff0c;我们找到了它 它…

IDA简单使用

今天来简单介绍一下逆向中常用到的另一个静态分析工具IDA&#xff0c;还是昨天那个打印demo&#xff08;64位&#xff09;&#xff1a; #include #include char a[] "https://www.vultop.com/"; int main(int argc, char* argv[]) { printf("%s", a)…

什么是微服务

目录 一、微服务介绍 1. 什么是微服务 2. 微服务由来 3. 为什么需要微服务&#xff1f; 3.1 最期的单体架构带来的问题 3.2 微服务与单体架构区别 3.3 微服务与SOA区别 4. 微服务本质 5. 什么样的项目适合微服务 6. 微服务折分与设计 6.1 微服务设计原则 7. 微服务…

linux gcc + openocd + stlink + cubeMX + cortex Debug

文章目录 运行环境&#xff1a;1.1 gcc1)下载并解压gcc2)环境配置 2.1 openocd1)下载并解压openocd2)环境配置&#xff08;没有权限就加sudo&#xff09; 3.1 stlink1)下载并双击安装stlink 4.1 cubeMX1)下载并解压cubeMX2)生成makefile工程 5.1 cortex Debug1)setting设置2)la…

冷链物流运转 3D 可视化监控,助力大数据实时监控

智慧物流是以信息化为依托并广泛应用物联网、人工智能、大数据、云计算等技术工具&#xff0c;在物流价值链上的 6 项基本环节&#xff08;运输、仓储、包装、装卸搬运、流通加工、配送&#xff09;实现系统感知和数据采集的现代综合智能型物流系统。随着冷链信息化、数字化发展…

史上最全! 瑞芯微RK3568核心板评估板资源分享!

▎瑞芯微RK3568芯片 高性能处理器&#xff1a;采用四核A55架构CPU&#xff0c;G52 GPU&#xff1b;内置NPU&#xff0c;可提供1T算力 高可靠性设计&#xff1a;支持DDR及CPU Cache全链路ECC 内置自研ISP图像处理器&#xff1a;8M30fps处理能力&#xff0c;强大的HDR功能&#…

Springboot Netty 实现自定义协议

Netty是由JBOSS提供的一个java开源框架&#xff0c;现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说&#xff0c;Netty 是一个基于NIO的客户、服务器端的编程框架&…

《编程思维与实践》1039.字符组合

《编程思维与实践》1039.字符组合 题目 思路 先将字符串去重排序(保证每个组合中的字符按字典序),然后枚举出所有组合的情形,最后再进行字典序排序即可. 其中字符串的去重排序可以利用ASCII码值进行桶排序,关键在于如何枚举所有组合的情形. 每个位置有两种可能(选或不选),但至…