当前位置: 首页 > news >正文

Spring Boot 中的虚拟线程

什么是虚拟线程?

虚拟线程(Virtual Threads)是 Java 19 引入的一项新特性,它属于 Project Loom 项目的一部分。与传统的线程(平台线程)不同,虚拟线程并不是由操作系统直接管理,而是由 Java 虚拟机(JVM)控制。虚拟线程在操作系统层面非常轻量,可以支持大量并发线程,而不会导致过高的内存占用和上下文切换开销。

在传统的 Java 应用中,每个线程都会由操作系统分配资源,这会导致线程数量的增长受到操作系统资源的限制。虚拟线程通过轻量级的调度机制使得创建数百万个线程变得可行,从而大大提高了并发处理的能力。


Spring Boot 中使用虚拟线程

Spring Boot 是构建 Java 应用程序的流行框架,它支持许多现代的 Java 特性,包括虚拟线程。借助虚拟线程,Spring Boot 应用能够更加高效地处理大量并发任务,特别是当任务是 I/O 密集型时。下面,我们将介绍如何在 Spring Boot 项目中启用虚拟线程,并展示一个简单的示例。

1. 准备工作

首先,你需要确保你的 Spring Boot 项目使用的是 Java 19 或更高版本,因为虚拟线程特性是从 Java 19 开始引入的。你可以通过更新 pom.xmlbuild.gradle 来配置 Java 版本。

Maven 配置:

<properties><java.version>19</java.version>
</properties>

Gradle 配置:

java {toolchain {languageVersion = JavaLanguageVersion.of(19)}
}
2. 创建虚拟线程池

虚拟线程是由 JVM 管理的轻量级线程,因此,我们需要配置 Spring Boot 使用虚拟线程池来执行异步任务。你可以通过自定义 Executor 来创建虚拟线程池。

自定义虚拟线程池配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;@Configuration
public class VirtualThreadConfig {@Beanpublic Executor virtualThreadExecutor() {// 使用 Java 19 新的虚拟线程池return Executors.newVirtualThreadPerTaskExecutor();}
}
3. 异步执行任务

在 Spring Boot 中,你可以使用 @Async 注解来让方法异步执行。通过将异步任务执行在虚拟线程上,可以充分利用虚拟线程的并发能力。

首先,我们创建一个异步服务类,该类中的方法将使用虚拟线程池来执行:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
public class MyAsyncService {@Asyncpublic void processTask() {System.out.println("Task running on thread: " + Thread.currentThread().getName());// 模拟耗时任务try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

然后,在你的应用程序中调用该异步服务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class MyRunner implements CommandLineRunner {@Autowiredprivate MyAsyncService myAsyncService;@Overridepublic void run(String... args) throws Exception {// 调用异步方法myAsyncService.processTask();myAsyncService.processTask();myAsyncService.processTask();}
}
4. 启用异步处理

为了让 Spring Boot 支持异步处理,你需要在配置类中添加 @EnableAsync 注解:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {
}

通过这种方式,Spring Boot 会自动使用虚拟线程池来执行标记为 @Async 的异步方法。


虚拟线程的优势

虚拟线程带来了许多好处,特别是在需要处理大量并发任务的场景中:

  1. 低内存开销: 虚拟线程比传统的操作系统线程更轻量,因为它们不需要独立的栈空间,减少了内存消耗。
  2. 快速线程切换: 由于虚拟线程的调度是由 JVM 控制的,线程切换的开销大大降低。即使创建和切换数百万个线程也不会对性能造成严重影响。
  3. 高并发处理能力: 虚拟线程使得应用程序能够轻松处理成千上万的并发任务,而不会遇到传统线程池的性能瓶颈。
  4. 简化的并发编程: 虚拟线程使得并发编程变得更加直观,开发者可以像处理普通线程一样处理虚拟线程,而不必担心操作系统的线程管理细节。

虚拟线程的适用场景

虚拟线程特别适用于以下场景:

  • Web 服务: 当 Spring Boot 应用需要处理大量并发 HTTP 请求时,虚拟线程能够提高并发处理的效率,减少系统资源的消耗。
  • 微服务架构: 在微服务架构中,每个微服务都可能需要处理大量的请求,虚拟线程能够有效地支持这种高并发负载。
  • I/O 密集型任务: 虚拟线程最适合用于 I/O 密集型的应用场景,比如数据库访问、文件读取/写入、网络通信等。

虚拟线程的挑战与考虑

尽管虚拟线程带来了巨大的并发性能提升,但在某些场景下仍需谨慎使用:

  • CPU 密集型任务: 虚拟线程更适用于 I/O 密集型任务。对于 CPU 密集型任务,过多的虚拟线程可能会导致 CPU 饱和,反而影响性能。
  • 线程安全: 与传统的线程一样,虚拟线程之间也需要处理线程安全的问题。在高并发环境下,需要特别注意同步问题。

总结

虚拟线程为 Java 提供了一个轻量级的并发解决方案,尤其适用于高并发和 I/O 密集型应用。在 Spring Boot 中启用虚拟线程,可以大大提升应用的并发能力,尤其是在微服务和 Web 服务架构中。通过简单的配置,开发者可以充分利用虚拟线程池来提升任务的执行效率,减少资源的消耗。

随着虚拟线程的广泛应用,Spring Boot 和 Java 开发者能够更加高效地构建高并发、高性能的应用程序。尽管虚拟线程是一个强大的工具,但在设计并发系统时仍需要结合实际需求,权衡其优缺点,以获得最佳的性能提升。

相关文章:

Spring Boot 中的虚拟线程

什么是虚拟线程&#xff1f; 虚拟线程&#xff08;Virtual Threads&#xff09;是 Java 19 引入的一项新特性&#xff0c;它属于 Project Loom 项目的一部分。与传统的线程&#xff08;平台线程&#xff09;不同&#xff0c;虚拟线程并不是由操作系统直接管理&#xff0c;而是…...

el-table 实现纵向多级表头

为了实现上图效果&#xff0c;最开始打算用el-row、el-col去实现&#xff0c;但发现把表头和数据分成两大列时&#xff0c;数据太多时会导致所在格高度变高。但由于每一格数据肯定不一样&#xff0c;为保持高度样式一致&#xff0c;就需要我们手动去获取最高格的高度之后再设置…...

探秘Kafka源码:关键内容解析

文章目录 一、以kafka-3.0.0为例1.1安装 gradle 二、生产者源码2.1源码主流程图2.2 初始化2.3生产者sender线程初始化2.4 程序入口2.5生产者 main 线程初始化2.6 跳转到 KafkaProducer构造方法 一、以kafka-3.0.0为例 打开 IDEA&#xff0c;点击 File->Open…->源码包解…...

Promise编码小挑战

题目 我们将实现一个 createImage 函数&#xff0c;该函数返回一个 Promise&#xff0c;用于处理图片加载的异步操作。此外&#xff0c;还会实现暂停执行的 wait 函数。 Part 1: createImage 函数 该函数会&#xff1a; 创建一个新的图片元素。将图片的 src 设置为提供的路径…...

PyQt实战——将pcm文本数据转换成.pcm的二进制文件

系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序入口QMainWindow&#xff08;三&…...

数据结构之线性表

1.什么是线性表 线性表的概念 定义&#xff1a;线性表是由n个数据元素组成的有限序列。每个数据元素&#xff08;除了第一个和最后一个&#xff09;都有且仅有一个前驱和一个后继。逻辑结构&#xff1a;线性表的逻辑结构可以用一个序列来表示&#xff0c;例如 L(a1,a2,…,an)。…...

量子行走的干涉性和叠加性

需要注意公式的一些特殊情况&#xff0c;举例&#xff0c;当dj2和dj3 dj2 dj3...

Fabric环境部署-安装Go

安装go语言环境 国内镜像&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 1.选择版本下载后解压&#xff1a;注意go1.11.linux-amd64.tar.gz换成你下的 sudo tar zxvf go1.21.linux-amd64.tar.gz -C /usr/local 2.. 创建Go目录 mkdir $HOME/go 3. 用vi打开~./bashrc&…...

网站设计总结后期维护与更新的重要性

当我们谈论网站设计时&#xff0c;往往会聚焦在初始阶段的创意和实现上。然而&#xff0c;一旦网站建成并上线&#xff0c;后期维护与更新的重要性就显得尤为突出。一个网站的成功不仅取决于其初始设计&#xff0c;更在于持续的维护与更新。 首先&#xff0c;后期维护能够确保网…...

『SQLite』详解运算符

内容摘要&#xff1a;本节讲解运算符&#xff0c;包括&#xff1a;算术运算符、比较运算符、逻辑运算符和位运算符。 什么是运算符&#xff1f; 运算符是一个保留字或字符&#xff0c;主要用于 SQLite 语句的 WHERE 子句中执行操作。它用于指定 SQLite 语句中的条件&#xff0…...

计算机网络--根据IP地址和路由表计算下一跳

一、必备知识 1.无分类地址IPV4地址网络前缀主机号 2.每个IPV4地址由32位二进制数组成 3. /15这个地址表示网络前缀有15位&#xff0c;那么主机号32-1517位。 4.地址掩码&#xff08;子网掩码&#xff09;&#xff1a;所对应的网络前缀为1&#xff0c;主机号为0。 5.计算下…...

如何使用 Ansys OptiSlang 同时运行多个参数化设计研究

了解如何通过使用 OptiSLang 同时运行多个参数化设计研究来提高工作效率。 了解参数化设计研究的重要性 参数化设计研究在工程和设计过程中起着至关重要的作用。通过改变输入参数&#xff0c;工程师可以探索不同设计选择的效果&#xff0c;并优化其设计以满足性能、成本或其他…...

《 拼数 》

题目描述 设有 nn 个正整数 a1…ana1​…an​&#xff0c;将它们联接成一排&#xff0c;相邻数字首尾相接&#xff0c;组成一个最大的整数。 输入格式 第一行有一个整数&#xff0c;表示数字个数 nn。 第二行有 nn 个整数&#xff0c;表示给出的 nn 个整数 aiai​。 输出格…...

Memcached CAS 命令

Memcached CAS&#xff08;Check-And-Set 或 Compare-And-Swap&#xff09; 命令用于执行一个"检查并设置"的操作 它仅在当前客户端最后一次取值后&#xff0c;该key 对应的值没有被其他客户端修改的情况下&#xff0c; 才能够将值写入。 检查是通过cas_token参数进…...

ElasticSearch基础-文章目录

ElasticSearch学习总结1&#xff08;环境安装&#xff09; ElasticSearch学习总结2&#xff08;基础查询&#xff09; ElasticSearch学习总结3&#xff08;.NetCore操作ES&#xff09; ElasticSearch学习总结4&#xff08;sql操作ES&#xff09; ElasticSearch学习总结5&am…...

后台管理系统动态面包屑Breadcrumb组件的实现

在后管理系统开发中&#xff0c;面包屑导航是一个非常常见的功能&#xff0c;通常是根据当前的 url 自动生成面包屑导航菜单&#xff0c;当跳转路由发生变化时&#xff0c;面包屑导航都会随之发生变化&#xff0c;即动态面包屑。 要完成动态面包屑我们需要制作一个动态数组&am…...

java项目之校园管理系统的设计与实现(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的校园管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; springboot校园…...

浅谈棋牌游戏开发流程八:运维与数据分析

一、前言&#xff1a;为什么“云端运维”和“数据分析”如此重要&#xff1f; 在前面几篇文章中&#xff0c;我们已经从客户端、后端架构、用户系统、房间匹配与对局流程、数据库设计与优化、支付与充值、安全与反外挂等角度&#xff0c;系统性地搭建了一个棋牌游戏的基本框架…...

uniapp:微信小程序文本长按无法出现复制菜单

一、问题描述 在集成腾讯TUI后&#xff0c;为了能让聊天文本可以复制&#xff0c;对消息组件的样式进行修改&#xff0c;主要是移除下面的user-select属性限制&#xff1a; user-select: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms…...

跨物种筛选同源基因

工具&#xff1a;R&#xff1a;biomaRt 原始文件&#xff1a;human、mouse、macaque、marmoset四个物种的gene list&#xff0c;有些是用ensembl ID&#xff0c;有的是用gene name来表示。 目的&#xff1a;找到四个物种的gene list之间的1v1同源基因 1. 找到物种间的1v1同源…...

大模型数据采集和预处理:把所有数据格式,word、excel、ppt、jpg、pdf、表格等转为数据

大模型数据采集和预处理&#xff1a;把所有数据格式&#xff0c;word、excel、ppt、jpg、pdf、表格等转为数据 文本/图片/表格&#xff0c;分别提取处理工具选择不同格式文件&#xff0c;使用不同工具处理1. 确认目标2. 分析过程(目标-手段分析法)3. 实现步骤4. 代码封装效果展…...

k8s修改存储目录-介绍

k8s修改存储目录-介绍 文章目录 k8s修改存储目录-介绍总结&#xff1a;介绍指定 Docker 或 containerd 镜像和容器存储目录Docker 存储目录containerd 存储目录 指定 Kubelet 的存储目录指定 Pod 和容器存储目录 docker 运行时&#xff0c;迁移目录实操&#xff1a;https://blo…...

【电源专题】为什么测试电源的SW波形上冲振荡之前的0V电位要先来个小的下降

在同步电源的开关节点SW波形测试中,你可能会发现周期性的SW波形在上升前的一小段时间时间内会有一个小小的下跌,这个下跌会低于0V。那么这个下跌是怎么来的呢? 如下所示为某降压转换器的SW开关节点波形: 其展开后可以看到在上升之前有20ns左右的时间,SW电压是下跌…...

常见的反规范化技术

在数据库设计中&#xff0c;数据规范化和反规范化是两种重要的策略&#xff0c;它们在一定程度上存在权衡。规范化通过组织表结构&#xff0c;减少数据冗余&#xff0c;提高数据一致性和降低更新异常&#xff0c;使数据存储更加高效、可靠。然而&#xff0c;过度的规范化会导致…...

Linux中隐藏操作身法

从历史记录中删除指定的命令 假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办&#xff1f;很简单。通过下面的命令来删除&#xff1a; history | grep "keyword"例如:history | grep set o history 批量第二条和第四条删除&#xff1a; sed…...

Transformer知识梳理

Transformer知识梳理 文章目录 Transformer知识梳理什么是Transformer&#xff1f;语言模型迁移学习 Transformer结构注意力层原始结构 总结 什么是Transformer&#xff1f; 语言模型 Transformer模型本质上都是预训练语言模型&#xff0c;大部分采用自监督学习&#xff08;S…...

Nexus Message Transaction Services(MTS)

Nexus 系列交换机遇到以下情形时&#xff0c;可以尝试查看是否是 MTS 消息卡在缓冲区过多&#xff0c;因为 MTS 负责处理模块内以及跨模块&#xff08;包括跨管理引擎&#xff09;的各服务之间的消息路由和排队。 • CPU 高 • 命令行无响应、响应慢 • 控制平面中断 • 流量问…...

网络编程基础:连接Java的秘密网络

1 网络编程的重要性 网络编程允许Java应用程序与其他计算机或设备进行通信。这包括从简单的数据传输到复杂的分布式系统和Web服务。 2 Java网络编程的核心类 Java提供了多个类来支持网络编程&#xff1a; InetAddress&#xff1a;表示网络上的IP地址。 URL&#xff1a;表示统…...

uniapp中判断设备类型

全局变量&#xff1a; 在 UniApp 中&#xff0c;你可以通过 uni.getDeviceInfo 获取设备信息&#xff0c;并将设备类型全局存放。通常&#xff0c;这些信息可以存放在 app.vue 的全局变量中&#xff0c;以便在整个应用中访问。 以下是如何在 app.vue 中实现这一功能的完整代码…...

数据可视化分析详解

数据可视化分析是一种通过图形、表格、图标和其他视觉元素来呈现数据的方式&#xff0c;使得数据更易于理解和分析。以下是关于数据可视化分析的一些关键点&#xff1a; 一、定义与目的 数据可视化分析是指利用图形化手段&#xff0c;清晰地有效地传达与沟通信息。它将数据以…...

_使用CLion的Vcpkg安装SDL2,添加至CMakelists时报错,编译报错

语言&#xff1a;C20 编译器&#xff1a;gcc 14.2 摘要&#xff1a;初次使用Vcpkg添加SDL2&#xff0c;出现CMakelists找不到错误、编译缺失main错误、运行失败错误。 CMakelists缺失错误&#xff1a; 使用CLion的Vcpkg安装SDL2时&#xff0c;按照指示把对应代码添加至CMakel…...

QT中Qstring和QByteArray有什么区别?

数据存储内容方面 QString&#xff1a; 主要用于存储和处理Unicode编码的文本字符串。它能够很好地处理包含各种语言字符的文本信息&#xff0c;如中文、日文、韩文等多种语言文字。例如&#xff0c;QString str "你好&#xff0c;世界&#xff01;";可以方便地存储…...

Viggle AI:支持小孩或者卡通人物吗? [Viggle AI实战教程] – 第2篇

历史文章 Suno AI API接入 - 将AI音乐接入到自己的产品中&#xff0c;支持120并发任务 万物皆能舞&#xff0c;AI让你秒变“舞”林高手 – Viggle AI“舞”所不能 Viggle AI&#xff1a;打造爆款 AI 视频&#xff0c;让照片 “踢” 起足球 Viggle AI&#xff1a;开启3D动画…...

庐山派K230学习日记4 PWM控制

1 本节介绍​ &#x1f4dd;本节您将学习如何通过将K230开发板的GPIO引脚复用为PWM功能并输出PWM信号&#xff1b;实现输出PWM信号及控制板载无源蜂鸣器发出声音。 &#x1f3c6;学习目标 1️⃣如何将GPIO引脚配置为PWM模式&#xff0c;通过40Pin排针中的部分引脚来输出PWM信号…...

Android配件应用默认启动与USB权限申请区别

使用效果&#xff1a; USB配件授权演示 选择USB配件默认打开应用 申请USB配件使用权限...

【车载开发系列】GPIO模式分类

【车载开发系列】GPIO模式分类 这里写目录标题 【车载开发系列】GPIO模式分类一. GPIO概念二. GPIO的模式区分三. GPIO的八大模式1&#xff09;推挽输出&#xff08;Output push-pull&#xff09;2&#xff09;开漏输出&#xff08;Output open-drain&#xff09;3&#xff09;…...

uniapp--HBuilder开发

提示&#xff1a;本文为学习内容&#xff0c;若有错误&#xff0c;请联系作者&#xff0c;谦虚受教。 文章目录 前言一、下载HBuilder二、添加modbus相关库1.下载nodejs2.下载modbus库3.项目添加modbus库 三、HBuilder相关功能语句1.文件夹说明2.消息信息框3.开关按钮4.选中按钮…...

学习笔记|arduino uno r3|点亮|hello world|Atmega328P|开发板学习:概述

目录 arduino uno r3开发板学习开发板概述重要引脚介绍配置开发环境安装 Arduino IDE 编程环境介绍Arduino 介绍 实操连接选择程序程序代码编译和执行 总结课后练习 arduino uno r3开发板学习 开发板概述 Arduino UNO 是一款基于Atmega328P 的微控制器开发板。它有 14 个数字…...

Go语言的 的注解(Annotations)核心知识

Go语言的注解&#xff08;Annotations&#xff09;核心知识 Go语言是一种简洁且高效的编程语言&#xff0c;广泛应用于后端开发、云计算和微服务架构。在探索Go语言的特性时&#xff0c;我们不可忽视一个重要的概念&#xff1a;注解&#xff08;Annotations&#xff09;。虽然…...

WinRAR中“自动加密”如何使用?

WinRAR加密大家都不陌生&#xff0c;那么自动加密功能大家熟悉嘛&#xff1f;如何使用自动加密功能&#xff1f;今天介绍详细教程给大家。 打开WinRAR软件之后选择工具栏中的【选项】&#xff0c;点击设置 然后切换到【压缩】选项卡&#xff0c;点击【创建默认配置】&#xff…...

`http_port_t

http_port_t 是 SELinux&#xff08;Security-Enhanced Linux&#xff09;中的一种端口类型标签&#xff0c;用于标识哪些端口可以被 HTTP 和 HTTPS 服务使用。SELinux 是一种强制访问控制&#xff08;MAC&#xff09;安全模块&#xff0c;它通过定义安全策略来限制进程对系统资…...

C++编程等级认证学习计划

C编程等级认证学习计划 计划目标 在30天内系统学习并掌握C编程等级认证&#xff08;一至八级&#xff09;的知识点&#xff0c;为参加认证考试做好充分准备。 前期准备 学习资料收集 准备涵盖C编程一至八级知识点的专业教材&#xff0c;如《C Primer》等。收集相关的在线教…...

c和c++中为什么要防止头文件被重复包含!

在编程中&#xff0c;头文件就像一本工具书&#xff0c;它包含了函数、类、宏、全局变量等的定义和声明&#xff0c;供其他代码文件引用。想象一下&#xff0c;如果你在写一篇文章时&#xff0c;反复引用同一本工具书的内容&#xff0c;会发生什么情况呢&#xff1f; 1. 避免重…...

安的厦小程序开发日志

目录 背景名字由来架构文件目录app.jsonapp.wxsspackage.jsonproject.config.jsindex.wxmlindex.wxssindex.jsindex.jsondetail.wxmldetail.wxssdetail.jsdetail.json参考资料背景 我们正在经历一场价值观的变迁,过去的丈母娘和女朋友总是要求男方要买房,那是因为房子是当下…...

深度评测uni-app x:开启跨平台开发新篇章

文章目录 一、引言1.1 跨平台开发的崛起1.2 uni-app x 初印象 二、uni-app x 核心特性评测2.1 uts 语言&#xff1a;跨平台编程新利器2.2 uvue 渲染引擎&#xff1a;原生渲染新体验2.3 强大的组件和 API 支持2.4 插件生态&#xff1a;拓展无限可能 三、与 uni-app 对比&#xf…...

第06章 重定向与管道

一、概述 在企业生产环境中&#xff0c;如何记录一个程序运行的过程记录或者定时任务执行的结果呢&#xff1f;假设定时任务凌晨执行&#xff0c;我们在白天上班时需要查看执行是否成功要怎么办&#xff1f;就可以使用本章介绍的重定向和管道符号。 二、重定向 2.1 文件描述…...

python中的字典类型数据及其操作

1、字典的定义 映射是一种键&#xff08;索引&#xff09;和值&#xff08;数据&#xff09;的对应键值对&#xff1a;键是数据索引的扩展字典是键值对的集合&#xff0c;键值对之间无序字典采用大括号{}和dict()创建&#xff0c;键值对用冒号&#xff1a;表示&#xff0c;key…...

『SQLite』表达式操作

摘要&#xff1a;表达式是一个或多个值、运算符和计算值的 SQL 函数的组合。SQL 表达式与公式类似&#xff0c;都写在查询语言中。 基本语法 SELECT column1, column2, columnN FROM table_name WHERE [CONTION | EXPRESSION];布尔表达式 SQLite 的布尔表达式在匹配单个值的…...

PHP7和PHP8的最佳实践

php 7 和 php 8 的最佳实践包括&#xff1a;使用类型提示以避免运行时错误&#xff1b;利用命名空间组织代码并避免命名冲突&#xff1b;采用命名参数、联合类型等新特性增强可读性&#xff1b;用错误处理优雅地处理异常&#xff1b;关注性能优化&#xff0c;如避免全局变量和选…...

Python实现一个简单的 HTTP echo 服务器

一个用来做测试的简单的 HTTP echo 服务器。 from http.server import HTTPServer, BaseHTTPRequestHandler import jsonclass EchoHandler(BaseHTTPRequestHandler):def do_GET(self):# 构造响应数据response_data {path: self.path,method: GET,headers: dict(self.headers…...