KAFKA入门教程

目录

1.安装kafka

2.安装kafkamanager可视化工具

3.springboot整合kafka

1.pom导包

2.启动类和yml配置

3.代码演示 

编写生产者:

消费者:


1.安装kafka

进入kafka官网下载对应版本kafka

kafka官网地址:Apache Kafka

kafka是使用Scala开发,所以版本号是由 Scala的版本号和Kafka版本号组成的,如:kafka_2.12-3.2.0 , 2.12是scala版本, 3.2.0是kafka版本,下载完成解压得到kafka,目录结构如下:

结构介绍:
 

bin :kafka的执行脚本 ,其中包括启动kafka的脚本:kafka-server-start.bat 和 zookeeper-server-start.bat 启动zookeeper的脚本(kafka内置有zookeeper) ,bin/windows 目录中的脚本是针对windows平台。
config : 配置文件目录 ,包括server.properties :kafka的配置 ; zookeeper.properties :zookeeper的配置, producer.properties:生产者的配置 ; consumer.properties 消费者的配置等等。
libs : 依赖的三方jar包

可以进入config文件夹,修改kafka和zookeeper配置文件:

zookeeper.properties是作为zookeeper的配置文件,dataDir为数据目录,clientPort为启动端口,比如你想修改zookeeper的默认端口通过配置文件修 clientPort=2181项即可 ,如下:

server.properties作为kafka的配置文件,我们关注下面几个配置,你也可以根据情况进行修改

broker.id =0 : 如果是做个多个kafka主机集群,那么brocker.id不能重复,0 ;1 ;2 增长
zookeeper.connect : zookeeper的地址 ,如果有多个zk就用逗号隔开配置多个地址
num.partions = 1 : 默认partions 数量默认为1
log.dirs : 日志目录,不建议放到tmp临时目录,一定要修改,如:log.dirs=d:/kafka-logs

在安装目录下运行cmd,使用命令:

.\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties

启动zookeeper

使用命令:

.\bin\windows\kafka-server-start.bat .\config\server.properties

启动kafka

2.安装kafkamanager可视化工具

进入git官网下载:kafka-manager 项目地址:https://github.com/yahoo/kafka-manager

可以直接下载release版本

下载好后需要解压然后对原始文件进行编译,编译完成后会的得到一个kafka-manager-1.3.3.23.zip文件,解压这个文件之后才能启动manager

这里建议大家直接下载编译好的mangaer,地址:

链接:https://pan.baidu.com/s/1oEC2XlPtlSZmOotPYGjpOQ?pwd=jne1 
提取码:jne1

解压好后得到如下结构:

使用bin\kafka-manager命令启动kafka-manager:

启动完成之后访问:http://localhost:9000/ 可以看到kafkaManager主页:

第一次进入需要新建 Cluster

输入集群的名字(如Kafka-Cluster-1)和 Zookeeper 服务器地址(如localhost:2181),选择最接近的Kafka版本(如0.8.1.1)

注意:如果没有在 Kafka 中配置过 JMX_PORT,千万不要选择第一个复选框。
Enable JMX Polling
如果选择了该复选框,Kafka-manager 可能会无法启动。

 

以下全使用默认设置:

点击进入刚刚创建的集群即可看到如下结构:

点击topics可以看到所有创建的topic主题;brokers则代表所有集群内的kafka服务,有几个服务就会显示几个broker;点击topics可以进入查看topic

进入test_topic:

相关参数和使用教程文档可以参考这个大佬的文章:Kafka可视化管理工具kafka-manager部署安装和使用_kafka manager-CSDN博客

3.springboot整合kafka

1.pom导包

创建一个maven结构的springboot项目,首先在pom中导入如下依赖:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>

2.启动类和yml配置

导入依赖之后需要为SpringBoot创建启动类,在启动类中我们通过注解的方式创建一个Topic,如下:

@SpringBootApplication
public class KafKaApplication {

    private static final String TOPIC_NAME = "kafka_test_topic";

    public static void main(String[] args) {
        SpringApplication.run(KafKaApplication.class);
    }

    //通过定义Bean的方式创建Topic
    @Bean
    public NewTopic topicHello(){
        //创建Topic : topic名字, partition数量 , replicas副本数量
        return TopicBuilder.name(TOPIC_NAME).build();
    }
}

在yml中对kafka做一些常规配置,如下:

server:
  port: 12012
spring:
  application:
    name: application-kafka
  kafka:
    bootstrap-servers: localhost:9092 #这个是kafka的地址,对应你server.properties中配置的
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer #键序列化
      value-serializer: org.apache.kafka.common.serialization.StringSerializer #值序列化
      retries: 1 # 消息发送重试次数
      # acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
      # acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
      # acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
      acks: 1 #应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
      batch-size: 16384 #批量大小
      properties:
        linger:
          ms: 0 #提交延迟
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer #键序列化
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer #值序列化
      group-id: test-consumer-group #消费者的ID,这个对应 config/consumer.properties中的group.id

更详细的全局配置以及说明:

spring :
kafka :
bootstrap-servers : 192.168.10.70 : 9092
producer :
# 发生错误后,消息重发的次数。
retries : 0
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批
次可以使用的内存大小,按照字节数计算。
batch-size : 16384
# 设置生产者内存缓冲区的大小。
buffer-memory : 33554432
# 键的序列化方式
key-serializer : org.apache.kafka.common.serialization.StringSerializer
# 值的序列化方式
value-serializer : org.apache.kafka.common.serialization.StringSerializer
# acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
# acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
# acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功
响应。
acks : 1
consumer :
# 自动提交的时间间隔 在 spring boot 2.X 版本中这里采用的是值的类型为 Duration 需要符合
特定的格式,如 1S,1M,2H,5D
auto-commit-interval : 1S
# 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
# latest (默认值)在偏移量无效的情况下,消费者将从最新的记录开始读取数据(在消费者启动之
后生成的记录)
# earliest :在偏移量无效的情况下,消费者将从起始位置读取分区的记录
auto-offset-reset : earliest
# 是否自动提交偏移量,默认值是 true, 为了避免出现重复数据和数据丢失,可以把它设置为 false,
然后手动提交偏移量
enable-auto-commit : false
# 键的反序列化方式
key-deserializer : org.apache.kafka.common.serialization.StringDeserializer
# 值的反序列化方式
value-deserializer :
org.apache.kafka.common.serialization.StringDeserializer
# 配置使用默认的消费组 ID
group-id : defaultConsumerGroup
listener :
# 在侦听器容器中运行的线程数。
concurrency : 5
#listner 负责 ack ,每调用一次,就立即 commit
ack-mode : manual_immediate
missing-topics-fatal : false

3.代码演示 

编写生产者:

编写生产者案例 ,Kafka提供了 KafkaTemplate 用来向Kafka发送消息,直接在查询中注入即可使用。KafkaTemplate提供了很多个重载的send方法,方法返回ListenableFuture对象,即发送的结果对象。

同步阻塞

需要特别注意的是: future.get()方法会阻塞,他会一直尝试获取发送结果,如果Kafka迟迟没有返回发送结果那么程序会阻塞到这里。所以这种发送方式是同步的。

当然如果你的消息不重要允许丢失你也可以直接执行 : kafkaTemplate.send ,不调用get()方法获取发送结果,程序就不会阻塞,当然你也就不知道消息到底有没有发送成功。

异步非阻塞

幸好Kafka为 ListenableFuture 提供了Callback异步回调,我们可以通过异步回调来接收发送结果

@RestController("/producer")
@Api(tags = "生产者示例接口", description = "生产者示例接口 | 消息发送测试接口", hidden = false)
public class ProducerContrller {

    private static final String TOPIC_NAME = "kafka_test_topic";
    @Autowired
    private KafkaTemplate<Object,Object> kafkaTemplate;

    /**
     * 同步,阻塞消息队列
     * @param msg
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @PostMapping("/sendSyncMsg/{msg}")
    @ApiOperation(value = "生产者生成数据", notes = "同步,阻塞消息队列")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "msg", value = "需要发送的数据", required = true, dataType = "String"),
    })
    public String sendSyncMsg(@PathVariable("msg")String msg) throws ExecutionException, InterruptedException {
        ListenableFuture<SendResult<Object, Object>> future = kafkaTemplate.send(TOPIC_NAME, msg);
        System.out.println("发送结果:"+future.get().toString());
        return "发送成功";
    }

    /**
     * 异步,非阻塞消息队列
     * @param msg
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @PostMapping("/sendAsyncMsg/{msg}")
    @ApiOperation(value = "生产者生成数据", notes = "异步,非阻塞消息队列")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "msg", value = "需要发送的数据", required = true, dataType = "String"),
    })
    public String sendAsyncMsg(@PathVariable("msg")String msg) throws ExecutionException, InterruptedException {
        ListenableFuture<SendResult<Object, Object>> future = kafkaTemplate.send(TOPIC_NAME, msg);
        future.addCallback(new ListenableFutureCallback<SendResult<Object, Object>>() {
            @Override
            public void onFailure(Throwable ex) {
                ex.getStackTrace();
            }

            @Override
            public void onSuccess(SendResult<Object, Object> result) {
                System.out.println("发送结果:"+result);
            }
        });
        return "发送成功";
    }

}

也有原生的使用KafkaProducer的方式创建生产者发送消息,这样的好处是可以灵活配置,不需要每次对kafka配置修改后就要重启服务

以下是代码示例:

/**
     * 原生构建KafkaProducer的生产者方法接口
     *
     * @param msg
     * @return
     */
    @PostMapping("/sendMsgByProducer/{msg}")
    @ApiOperation(value = "生产者生成数据", notes = "原生构建KafkaProducer的生产者方法接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "msg", value = "需要发送的数据", required = true, dataType = "String"),
    })
    public String sendMsgByProducer(@PathVariable("msg") String msg){
        // 创建一个 Map或Properties 对象,用于构建 Kafka 生产者的配置信息
//        Properties map = new Properties();
        Map map = new HashMap();
        // 这个是kafka的地址,对应你server.properties中配置的
        map.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        map.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);// 键序列化
        map.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);// 值序列化
        map.put(ProducerConfig.RETRIES_CONFIG, 1); // 设置重试次数
        map.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, 1000); // 设置重试间隔
        if (false) {
            // 添加ssl认证
            String userName = "";
            String passWord = "";
            map.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT");
            map.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
            map.put(SaslConfigs.SASL_JAAS_CONFIG,
                    "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"" + userName + "\" password=\"" + passWord + "\";");
        }
        // 创建 KafkaProducer 对象 kafkaProducer,并传入配置信息 map
        KafkaProducer kafkaProducer = new KafkaProducer<>(map);
        // 创建要发送的消息 ProducerRecord,同时订阅主题和需要发送的内容
        ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC_NAME, msg);
        // 1.不需要回调的消息发送方式
        kafkaProducer.send(record);

        // 创建一个 CompletableFuture 对象 future 用于异步处理发送消息的结果
        CompletableFuture<Object> future = new CompletableFuture<>();
        try {
            // 2.需要回调的消息发送方式
            kafkaProducer.send(record, (data, exception) -> {
                if (exception == null) {
                    System.out.println(String.format("Message sent successfully! Topic: {} Partition: {} Offset: {}", data.topic(), data.partition(), data.offset()));
                    future.complete("消息投递成功,无异常"); // 成功时完成future
                } else {
                    System.out.println(String.format("Error sending message: " + exception.getMessage(), exception));
                    future.completeExceptionally(exception); // 错误时传递异常
                }
            });
        }catch (Exception e){
            e.printStackTrace();

        } finally {
            // 关闭生产者通道,释放资源
            kafkaProducer.flush();
            kafkaProducer.close();
        }

        return "发送成功";
    }

消费者:

使用@KafkaListener注释来接收消息,用法比较简单,实例如下:

@Component
public class HelloConsumer {

    @KafkaListener(topics = "kafka_test_topic")
    public void handle(ConsumerRecord consumerRecord) {
        System.out.println("消费者消费消息:" + consumerRecord);
        System.out.println(String.format("消费者收到消息,topic:%s,partition:%s", consumerRecord.topic(), consumerRecord.partition()));
        System.out.println("消费内容:" + consumerRecord.value());
    }

    //消费消息的时候,给方法添加 Acknowledgment 参数用来签收消息
    @KafkaListener(topics = "kafka_test_topic", containerFactory = "kafkaManualAckListenerContainerFactory")
    public void handler(String message, Acknowledgment ack){
        System.out.println("收到消息:"+message);
        //确认收到消息
        ack.acknowledge();
    }
}

也有原生的使用KafkaProducer的方式创建生产者发送消息的示例:

使用while循环来保证达到与注解的方式相同的实时接收消息的相同的功能,这样的好处是可以灵活配置,可以每次订阅多个不同的topic,不使用的topic可以直接释放掉

@RestController
@Api(tags = "消费者示例接口", description = "消费者示例接口 | 消费消息测试接口", hidden = false)
public class ConsumerContrller {

    @PostMapping("/useMsg")
    @ApiOperation(value = "消费者消费数据", notes = "消费者消费消息数据")
    public String useMsg(){
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Collections.singletonList("kafka_test_topic"));

        try {
            while (true) {
                ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
                for (ConsumerRecord<String, String> record : records) {
                    System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
                }
            }
        } catch (WakeupException e) {
            // Ignore exception for shutdown
        } finally {
            consumer.close();
        }

        return "消费成功";
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin 数据解析(Gson)

一、添加依赖 build.gradle.kts(:app) // gson数据解析implementation("com.google.code.gson:gson:2.8.6") 对象类&#xff1a; // 对象类 class Account {var uid:String "00001"var userName:String "Freeman"var password:String &quo…

Midjourney能让角色保持一致了

Midjourney发布新功能&#xff0c;网友直呼“不可思议”&#xff01; 现在你可以让生成的图像几乎保持角色一致&#xff0c;belike&#xff1a; 所有超级英雄长一个模样盯着你。 甚至动漫风、写实风等跨风格生成也同样适用&#xff1a; 保持同一风格&#xff0c;感jio配上文字…

【python】自动化工具Selenium与playwright去除webdriver检测

对这个世界如果你有太多的抱怨 跌倒了就不敢继续往前走 为什么人要这么的脆弱 堕落 请你打开电视看看 多少人为生命在努力勇敢的走下去 我们是不是该知足 珍惜一切 就算没有拥有 &#x1f3b5; 周杰伦《稻香》 # -*- coding:utf-8 -*- import timefrom s…

【C语言】如何规避野指针

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 目录 一、概念&#xff1a; 二、野指针成因&#xff1a; 2.1. 指针未初始化 2.2 指针越界访问 3. 指针指向的空间释放 三、如何规避野指针 3.…

Manacher 算法——Leetcode 5.最长回文子串

在了解之前&#xff0c;我们先要了解什么是回文串&#xff0c;什么是回文子串。 回文串和回文子串&#xff1a; 回文串是指一个字符串正序遍历和反向遍历结果相同的字符串。如 ABBA&#xff0c;正着读反着读结果是一样的。 有了回文串的概念&#xff0c;回文子串的概念也就显…

STM32的DMA搬运串口数据

简介&#xff1a; 最近在学习stm32的外设初始化过程中&#xff0c;学到DMA这个外设的时候&#xff0c;还是花费了不少时间&#xff0c;特此记录一下。 实验&#xff1a;配置DMA搬运UART1的数据 &#xff0c;串口调试工具给单片机发送数据&#xff0c;然后单片机回发给串口调试…

Python实现企业微信自动打卡程序二:跳过节假日,随机打卡时间,定时任务,失败通知

实现打卡时间随机范围 既然我们程序写完后需要定时执行&#xff0c;那定时执行打卡就会导致每次上班或下班打卡时都是同一时间&#xff0c;这并不好&#xff0c;为了避免被发现&#xff0c;每次打卡时间都是同一时间&#xff0c;这里我们优化程序&#xff0c;增加随机等待时间来…

CSS元素显示模式

CSS元素显示模式 定义&#xff1a;元素显示模式是指元素&#xff08;即标签&#xff09;以什么方式进行显示。 HTML元素分为块元素和行内元素 块元素 常见块元素 &#xff08;下列仅举出部分&#xff09; <h1>~<h6>、<p>、<div>、<ul>、<…

进程间通信——IPC(Linux)

进程间通信 前言一、管道1. 管道原理2. 匿名管道①理解匿名管道②创建匿名管道——pipe③模拟实现进程池——管道 3. 命名管道①理解命名管道②使用命名管道——mkfifo拓展 —— 日志俩无关进程通信 3. 小结①管道总结②拓展命令和接口 二、System V1. 共享内存①原理②使用共享…

9、设计模式之组合模式(Composite)

一、什么是组合模式 组合模式也成为整体部分模式&#xff0c;是一种结构型设计模式。它将对象组合成树形的层次结构&#xff0c;用来表示“整体-部分”的关系。通过组合模式&#xff0c;我们可以使用相同的方式处理单个对象和多个对象组合。 二、角色组成 组件&#xff08;Com…

Unity URP 如何写基础的几何着色器

这是使用几何着色器在点中心生成一个点并根据这个点把原本的面片分成三个三角形的操作。 对于几何着色器构造相对简单&#xff0c;网上的信息也相对较多&#xff0c;需要注意的点就是需要提供一个新的数据结构供几何着色器输出&#xff0c;因为几何着色器在顶点之后&#xff0…

properties文件和yml文件的区别以及文件优先级

properties文件和yml文件的区别 yml是按照缩进关系&#xff0c;而properties用"."来表示关系springboot默认生成的是properties文件当properties文件和yml文件都存在时&#xff0c;properties文件的优先级更高。 properties文件的样式 yml文件的样式 文件优先级 r…

使用 Jenkins 和 Spinnaker 构建 Kubernetes CI/CD

无论您是新手还是持续集成和持续交付以及容器化领域的经验丰富&#xff0c;本文都将为您提供设置 Spinnaker 以满足您的软件应用程序交付需求的基本知识。 了解 Jenkins、Spinnaker 和 Kubernetes Kubernetes 和 Jenkins 是两个强大的工具&#xff0c;它们相互配合&#xff0…

新加坡大带宽服务器托管优势

在数字化快速发展的今天&#xff0c;服务器托管成为企业拓展业务、提高服务质量的关键环节。而新加坡作为一个国际性的金融、贸易和科技创新中心&#xff0c;其大带宽服务器托管服务在全球范围内享有盛誉。本文将为您科普新加坡大带宽服务器托管的诸多优势。 首先&#xff0c;新…

第十五届蓝桥杯(Web 应用开发)模拟赛 3 期-大学组(被题目描述坑惨了)

目录 1.创意广告牌 2.原子化css 3.神秘咒语 4.朋友圈 5.美食蛋白揭秘 6.营业状态变更 7.小说阅读器 8.冰岛人 9.这是一个”浏览器“ 10.趣味加密解密 总结 1.创意广告牌 这个题目不多说了&#xff0c;只要知道这些css应该都能写出来&#xff0c;不会的平时多查查文…

Docker部署ChatGLM3、One API、FastGPT

创建并运行chatglm3容器 docker run --name chatglm3 -p 8000:8000 registry.cn-hangzhou.aliyuncs.com/ryyan/chatglm.cpp:chatglm3-q5_1 创建并运行one-api容器 (其中挂载路径 D:\one-api 可以选择你自己喜欢的目录) docker run --name oneapi -d -p 3000:3000 -e TZAsia…

k8s基本使用(namespace,pod增删查)-持续更新中

目录 1. 查看Namespace 2. 创建Namespace 2.1 使用纯命令行创建 2.2 编写yaml文件创建 3. 删除Namespace 3.1 使用纯命令行删除 3.2 使用yaml文件删除 二、Pod 1. 查看pod 1.1 查看默认空间的pod 1.2 查看指定空间的pod 1.3 查看全部pod 1.4 查看pod更多信息 1…

HUAWEI 华为交换机 配置 MAC 地址漂移检测示例

组网需求 如 图 2-17 所示&#xff0c;网络中两台 LSW 间网线误接形成了网络环路&#xff0c;引起 MAC 地址发生漂 移、MAC 地址表震荡。 为了能够及时检测网络中出现的环路&#xff0c;可以在 Switch 上配置 MAC 地址漂移检测功能&#xff0c; 通过检测是否发生MAC 地址漂移…

Python in Visual Studio Code 2024年3月发布

排版&#xff1a;Alan Wang 我们很高兴地宣布 2024 年 3 月发布适用于 Visual Studio Code 的 Python 和 Jupyter 扩展&#xff01; 此版本包括以下公告&#xff1a; 新的“Add Imports”代码操作设置调试 Django 或 Flask 应用时自动启动浏览器Python REPL 的 Shell 集成对本…

Python学习:基本数据类型

Python3 命令行参数 Python 提供了 getopt 模块来获取命令行参数。 %> python test.py arg1 arg2 arg3Python 中也可以所用 sys 的 sys.argv 来获取命令行参数&#xff1a; sys.argv 是命令行参数列表。 len(sys.argv) 计算命令行参数个数。 sys.argv[0] 表示脚本名。tes…