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

Kubernetes 高级调度

在 Kubernetes 集群管理中,调度策略的灵活性和智能性直接影响应用的稳定性和资源利用率。除了基础的 Pod 调度机制,Kubernetes 还提供了初始化容器、临时容器和自动扩缩容等高级特性,帮助开发者解决复杂场景下的部署、调试和资源管理问题。本文将深入解析这些高级调度特性,通过实战案例带你掌握其核心用法和最佳实践。

一、初始化容器(InitContainer):应用启动前的准备工作

在实际应用部署中,我们经常需要在应用容器启动前完成一些准备工作,比如等待依赖服务就绪、配置内核参数、初始化数据等。Kubernetes 的 InitContainer(初始化容器)正是为这类场景设计的特殊容器,它能够在应用容器启动前执行特定任务,确保应用运行环境满足预设条件。

1.1 InitContainer 的核心特性

InitContainer 是一种特殊的容器,与普通应用容器相比,具有以下独特特性:

  • 执行顺序:多个 Init 容器按定义顺序依次执行,前一个完成后才会启动下一个
  • 运行特性:始终运行到完成状态,不会像应用容器那样长期运行
  • 重启策略:如果 Init 容器失败,Kubernetes 会根据 Pod 的restartPolicy决定是否重启整个 Pod(Never策略下不会重启)
  • 资源处理:支持资源限制、数据卷挂载等特性,但不支持健康检查(livenessProbe、readinessProbe 等),因为它必须在 Pod 就绪前完成

1.2 InitContainer 的典型应用场景

Init 容器特别适合处理以下场景:

  • 等待其他服务就绪(如数据库、缓存服务)
  • 配置内核参数或系统设置
  • 初始化配置文件或数据库 schema
  • 安装应用容器中不存在的工具或依赖

1.3 InitContainer 实战案例

案例 1:延迟启动应用容器

有时我们需要让应用容器延迟启动(如等待基础设施初始化),可以通过 Init 容器的sleep命令实现:

apiVersion: v1
kind: Pod
metadata:name: init-delay-demolabels:app: init-demo
spec:containers:- name: app-containerimage: nginx:1.7.9ports:- containerPort: 80initContainers:- name: delay-initimage: busybox:1.28command: ["sh", "-c", "echo 'Waiting 15 seconds...'; sleep 15"]restartPolicy: Never

部署后观察 Pod 状态变化:

# 创建Pod
kubectl apply -f init-delay.yaml# 持续观察状态
watch kubectl get pods init-delay-demo

可以看到 Pod 会先处于Init:0/1状态 15 秒,等待 Init 容器完成后才会进入Running状态,这证明应用容器确实在 Init 容器完成后才启动。

案例 2:修改内核参数

某些应用需要特殊的内核参数配置(如调整虚拟内存策略),但普通容器默认没有足够权限。通过 Init 容器的特权模式可以安全地完成这类配置:

apiVersion: v1
kind: Pod
metadata:name: init-sysctl-demo
spec:containers:- name: app-containerimage: nginx:1.7.9initContainers:- name: sysctl-initimage: alpinecommand: ["sh", "-c", "/sbin/sysctl -w vm.swappiness=0"]securityContext:privileged: true  # 赋予特权模式restartPolicy: Never

部署后验证内核参数是否生效:

# 查看Pod运行节点
kubectl get pods init-sysctl-demo -o wide# 在对应节点上检查参数
ssh <node-name> "cat /proc/sys/vm/swappiness"  # 应输出0

注意:修改内核参数会影响整个节点,应谨慎操作。生产环境中建议通过sysctl.d配置文件或节点启动参数进行持久化设置。

案例 3:等待依赖服务就绪

微服务架构中,应用常常依赖其他服务(如数据库、缓存),我们可以使用 Init 容器等待这些依赖服务可用:

apiVersion: v1
kind: Pod
metadata:name: dependency-wait-demo
spec:containers:- name: app-containerimage: nginx:1.7.9ports:- containerPort: 80initContainers:- name: wait-redisimage: busybox:1.28command: ['sh', '-c', 'until nslookup redis-service; do echo waiting for redis; sleep 2; done;']- name: wait-mysqlimage: busybox:1.28command: ['sh', '-c', 'until nslookup mysql-service; do echo waiting for mysql; sleep 2; done;']

这个案例中,应用容器会等待redis-servicemysql-service两个服务可用后才启动。我们可以分步骤验证这个过程:

先部署应用 Pod(此时依赖服务不存在):

kubectl apply -f dependency-wait.yaml
kubectl get pods dependency-wait-demo  # 状态应为Init:0/2

部署 redis 服务:

# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- name: redisimage: redis:5.0
---
apiVersion: v1
kind: Service
metadata:name: redis-service
spec:selector:app: redisports:- port: 6379targetPort: 6379type: NodePort
kubectl apply -f redis-deployment.yaml
kubectl get pods dependency-wait-demo  # 状态变为Init:1/2

  1. 部署 mysql 服务:
# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: mysql
spec:replicas: 1selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalue: "password"volumeMounts:- mountPath: /var/lib/mysqlname: mysql-datavolumes:- name: mysql-datahostPath:path: /data/mysqltype: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:name: mysql-service
spec:selector:app: mysqlports:- port: 3306targetPort: 3306type: NodePort
kubectl apply -f mysql-deployment.yaml
kubectl get pods dependency-wait-demo  # 最终变为Running状态

通过这个案例可以看到,Init 容器能够有效地协调服务间的依赖关系,确保应用在所有依赖就绪后才启动。

1.4 InitContainer 的最佳实践

  • 最小化原则:Init 容器镜像应尽可能小,仅包含必要工具
  • 权限控制:仅在必要时使用特权模式,完成后立即退出
  • 日志记录:重要操作应输出日志,便于问题排查
  • 超时控制:对于可能阻塞的操作(如等待服务),应设置合理的超时机制
  • 资源配置:为 Init 容器配置适当的资源请求和限制,避免资源竞争

二、临时容器(Ephemeral Containers):在线调试的利器

在生产环境中,为了安全性和减小镜像体积,应用容器通常不会包含完整的调试工具(如curlnetstatvim等)。这给在线问题排查带来了困难 —— 当应用出现异常时,我们无法直接在容器内执行诊断命令。Kubernetes 1.16 版本引入的临时容器(Ephemeral Containers)正是为解决这类问题设计的,它允许我们临时向运行中的 Pod 添加调试容器,而不影响原有应用的运行。

2.1 临时容器的核心特性

临时容器是一种特殊的容器,专为调试目的设计,具有以下特点:

  • 临时性:不会被自动重启,添加后仅在当前 Pod 生命周期内存在
  • 调试导向:通常包含完整的调试工具(如busyboxdebian等镜像)
  • 无状态影响:不影响原有容器的运行状态和数据
  • 限制条件:不支持端口配置、健康检查、资源限制等字段
  • 添加方式:通过特殊的 API 端点添加,不能直接修改 Pod 的spec字段

2.2 临时容器的使用场景

临时容器主要用于以下调试场景:

  • 网络问题排查(如端口连通性、DNS 解析)
  • 进程状态检查(如查看进程列表、资源占用)
  • 文件系统检查(如查看配置文件、日志文件)
  • 环境变量验证(如检查应用配置是否正确)

2.3 临时容器实战案例

案例:调试运行中的 Tomcat 应用

假设我们有一个运行中的 Tomcat 应用,需要排查网络连接问题,但容器内没有curlnetstat工具,此时可以添加临时容器进行调试:

首先部署一个基础的 Tomcat 应用:

# tomcat-demo.yaml
apiVersion: v1
kind: Pod
metadata:name: tomcat-demo
spec:containers:- name: tomcatimage: kubeguide/tomcat-app:v1ports:- containerPort: 8080
kubectl apply -f tomcat-demo.yaml

尝试直接在容器内执行调试命令(会失败,因为没有相关工具):

kubectl exec -it tomcat-demo -- curl localhost:8080
# 输出类似:OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "curl": executable file not found in $PATH: unknown

使用kubectl debug命令添加临时容器:

kubectl debug -it tomcat-demo --image=busybox:1.28 --target=tomcat

参数说明:

-it:交互式终端

--image:指定临时容器使用的镜像(包含调试工具)

--target:指定要调试的目标容器,临时容器会共享其进程命名空间

在临时容器中执行调试命令:

# 检查网络连通性
curl localhost:8080# 查看进程列表
ps aux# 检查网络连接
netstat -tuln# 查看文件系统
ls /usr/local/tomcat/conf

查看 Pod 中的临时容器:

kubectl describe pod tomcat-demo

在输出结果的Ephemeral Containers部分可以看到我们添加的临时容器信息,包括容器 ID、镜像和状态等。

退出临时容器后,临时容器会自动终止,但 Pod 的原有容器不受影响:

kubectl get pods tomcat-demo
# 状态仍为Running,原有容器正常运行

2.4 临时容器的高级用法

使用自定义调试镜像

对于复杂的调试场景,可以使用包含更多工具的自定义镜像,例如nicolaka/netshoot(一个专为网络调试设计的镜像):

kubectl debug -it tomcat-demo --image=nicolaka/netshoot --target=tomcat

这个镜像包含tcpdumpdigiftop等高级网络工具,适合深入排查网络问题。

调试已崩溃的容器

当应用容器崩溃且无法启动时,临时容器尤为有用。此时可以添加临时容器检查文件系统状态:

kubectl debug -it <crashing-pod> --image=busybox:1.28 --share-processes

通过--share-processes参数,临时容器可以访问 Pod 的进程命名空间,即使目标容器已经崩溃。

2.5 临时容器的注意事项

  • 权限控制:添加临时容器需要ephemeralcontainers权限,生产环境应严格控制该权限
  • 性能影响:虽然临时容器通常资源占用较小,但仍应在调试完成后及时清理
  • 安全风险:调试镜像可能包含敏感工具,应使用可信镜像源
  • 版本要求:需要 Kubernetes 1.16 + 版本,且 API 服务器需启用EphemeralContainers特性门控
  • 状态影响:临时容器不会出现在kubectl get podsREADY计数中,也不会影响 Pod 的状态

三、自动扩缩容(HPA):应对流量波动的智能调节

在实际生产环境中,应用的访问流量往往是动态变化的 —— 比如电商网站在促销活动期间流量会激增,而深夜流量则会大幅下降。如果手动调整 Pod 副本数,不仅反应迟缓,还可能造成资源浪费或服务不可用。Kubernetes 的 HPA(Horizontal Pod Autoscaler,水平 Pod 自动扩缩容)机制能够根据实时监控指标(如 CPU 使用率、内存使用率)自动调整 Pod 副本数量,在保证服务质量的同时最大化资源利用率。

3.1 HPA 的工作原理

HPA 通过以下流程实现自动扩缩容:

  1. 指标采集:Metrics Server 定期采集 Pod 的资源使用指标(CPU、内存等)
  2. 决策计算:HPA 控制器将当前指标与目标值比较,计算需要的副本数量
  3. 执行调整:HPA 控制器更新 Deployment/ReplicaSet 的副本数
  4. 反馈循环:定期重复上述过程,保持实际指标接近目标值

HPA 支持的指标类型包括:

  • 资源指标(CPU、内存使用率)
  • 自定义指标(如请求数、队列长度)
  • 外部指标(如云服务提供商的监控指标)

3.2 HPA 的核心参数

创建 HPA 时需要指定以下关键参数:

  • scaleTargetRef:目标资源(Deployment/ReplicaSet 等)
  • minReplicas:最小副本数
  • maxReplicas:最大副本数
  • targetCPUUtilizationPercentage:目标 CPU 利用率(百分比)
  • targetMemoryUtilizationPercentage:目标内存利用率(百分比)

3.3 HPA 实战案例

案例:基于 CPU 使用率的 Nginx 自动扩缩容

下面通过一个完整案例演示如何配置 HPA,实现基于 CPU 使用率的自动扩缩容:

步骤 1:部署 Metrics Server

HPA 依赖 Metrics Server 采集资源指标,首先需要部署该组件(如果尚未部署):

# 下载Metrics Server部署文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml# 修改配置(解决自签名证书问题,仅用于测试环境)
sed -i 's/--kubelet-insecure-tls//g' components.yaml
echo '        - --kubelet-insecure-tls' >> components.yaml  # 添加到metrics-server容器的args中# 部署
kubectl apply -f components.yaml# 验证部署
kubectl get pods -n kube-system | grep metrics-server
步骤 2:部署 Nginx 应用并配置资源请求

HPA 需要基于资源请求(requests)计算使用率,因此必须为容器配置资源请求:

# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-hpa-demo
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80resources:requests:cpu: 10m  # 最小CPU需求,用于计算使用率
kubectl apply -f nginx-deployment.yaml# 创建Service以便外部访问
kubectl expose deployment nginx-hpa-demo --port=80
步骤 3:创建 HPA 配置

使用kubectl autoscale命令创建 HPA:

# 创建HPA,目标CPU使用率10%,副本数在1-10之间
kubectl autoscale deployment nginx-hpa-demo --cpu-percent=10 --min=1 --max=10

也可以通过 YAML 文件创建更复杂的 HPA 配置:

# nginx-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: nginx-hpa-demo
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: nginx-hpa-demominReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 10

查看HPA状态:
```bash
kubectl get hpa

初始状态应显示当前 CPU 使用率为 0%,副本数为 2(与 Deployment 初始配置一致)。

步骤 4:模拟流量压力测试

为了触发 HPA 的扩容机制,我们需要增加 Nginx 的 CPU 负载。可以通过循环发送 HTTP 请求实现:

# 打开新终端,执行压力测试
while true; do wget -q -O- http://<nginx-service-ip> > /dev/null; done

其中<nginx-service-ip>可以通过kubectl get svc nginx-hpa-demo命令获取。

步骤 5:观察 HPA 扩容过程

等待约 1 分钟(HPA 默认每 15 秒检查一次指标),再次查看 HPA 状态:

kubectl get hpa -w  # -w参数实时监控变化

随着 CPU 使用率超过目标值(10%),可以看到 HPA 会逐渐增加副本数,直到 CPU 使用率回落至目标值附近或达到最大副本数(10 个)。

同时查看 Pod 数量变化:

kubectl get pods -l app=nginx -w

可以看到新的 Pod 被不断创建,以分担负载压力。

步骤 6:停止压力测试,观察缩容过程

按下Ctrl+C终止压力测试,再次观察 HPA 和 Pod 变化:

kubectl get hpa -w
kubectl get pods -l app=nginx -w

随着 CPU 使用率下降,HPA 会逐渐减少副本数,直到恢复到最小副本数(1 个)或满足目标使用率的合理水平。

3.4 HPA 高级配置:基于内存和自定义指标

除了 CPU 使用率,HPA 还支持基于内存使用率和自定义指标进行扩缩容。

基于内存使用率的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: nginx-memory-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: nginx-hpa-demominReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 80  # 内存使用率目标值80%
同时基于 CPU 和内存的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: nginx-mixed-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: nginx-hpa-demominReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 10- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 80

当同时配置多个指标时,HPA 会根据每个指标计算所需副本数,取最大值进行调整。

3.5 HPA 的最佳实践

  • 合理设置副本范围minReplicas应保证服务基本可用性,maxReplicas应考虑集群总资源限制
  • 避免频繁扩缩容:可以通过--horizontal-pod-autoscaler-downscale-delay参数设置缩容延迟(默认 5 分钟),防止短时间内的频繁波动
  • 资源请求配置:必须为容器设置合理的resources.requests,否则 HPA 无法计算使用率
  • 目标值选择:CPU 目标使用率一般设置在 50%-80% 之间,内存目标使用率可适当提高
  • 结合监控:通过 Prometheus 等工具监控 HPA 行为,优化扩缩容参数
  • 测试验证:在生产环境部署前,务必通过压力测试验证 HPA 的有效性

四、Pause 容器:Pod 网络的基石

在深入理解 Kubernetes 的容器调度时,我们经常会遇到一个特殊的容器 ——Pause 容器。它是每个 Pod 中第一个启动的容器,虽然不执行任何业务逻辑,却在 Pod 的网络架构中扮演着至关重要的角色。

4.1 Pause 容器的核心作用

Pause 容器是一个极其精简的容器(镜像大小仅几百 KB),主要作用是为 Pod 内的所有容器提供共享的网络命名空间:

  • 网络命名空间共享:Pod 内的所有容器(包括 Init 容器、应用容器、临时容器)都共享 Pause 容器的网络命名空间,因此拥有相同的 IP 地址和端口空间
  • 网络稳定性保障:即使 Pod 内的所有应用容器都停止,Pause 容器仍会保持运行,确保 Pod 的网络配置不会丢失
  • 基础设施支撑:负责初始化 Pod 的网络接口,为整个 Pod 提供网络连接能力

4.2 Pause 容器的实现原理

Kubernetes 的 Pod 网络模型要求 Pod 内的所有容器能够通过localhost直接通信,并且对外表现为一个单一的网络实体。这一模型的实现依赖于 Linux 的命名空间(Namespace)机制:

  1. 当创建 Pod 时,Kubernetes 首先启动 Pause 容器,为其分配独立的网络命名空间
  2. Pause 容器执行/pause命令(一个无限循环的小程序),保持容器运行状态
  3. 后续创建的所有容器通过Join Namespace机制加入 Pause 容器的网络命名空间
  4. 所有容器共享相同的 IP 地址、端口范围和网络配置

4.3 验证 Pause 容器的存在

可以通过以下命令查看运行中的 Pause 容器:

# 查看某个Pod所在的节点
kubectl get pods <pod-name> -o wide# 在对应节点上执行docker命令(或containerd命令)
ssh <node-name> "docker ps | grep <pod-name> | grep pause"

输出结果类似:

9ee9ad88890b   registry.aliyuncs.com/google_containers/pause:3.6   "/pause"   54 seconds ago   Up 53 seconds   k8s_POD_nginx_default_8a0b9ac3-3cab-4ae6-94e2-624046f5aa87_0

可以看到每个 Pod 都有一个以pause镜像运行的容器,名称以k8s_POD_为前缀。

五、高级调度特性的综合应用场景

在实际生产环境中,这些高级调度特性往往需要结合使用,以解决复杂的部署和运维问题。以下是几个典型的综合应用场景:

5.1 微服务应用的完整部署流程

  1. Init 容器

    • 等待数据库和缓存服务就绪
    • 初始化数据库 schema
    • 下载并解密配置文件
  2. 应用容器

    • 启动微服务应用
    • 连接数据库和缓存服务
  3. HPA

    • 基于 CPU 和内存使用率自动扩缩容
    • 应对流量波动
  4. 临时容器

    • 当应用出现异常时,添加临时容器排查问题
    • 检查网络连接、配置文件和进程状态

5.2 数据库应用的部署与维护

  1. Init 容器

    • 检查存储卷是否就绪
    • 配置内核参数(如共享内存、文件描述符限制)
    • 初始化数据库(首次启动时)
  2. 应用容器

    • 启动数据库服务
    • 挂载持久化存储卷
  3. 临时容器

    • 在线备份数据库
    • 执行数据校验和修复操作
    • 分析慢查询日志

六、常见问题与解决方案

6.1 Init 容器相关问题

问题 1:Init 容器陷入无限重启循环

可能原因

Init 容器执行的命令返回非零退出码

依赖的服务始终无法就绪

资源不足导致 Init 容器无法完成

解决方案

# 查看Init容器日志
kubectl logs <pod-name> -c <init-container-name># 描述Pod状态,查找错误信息
kubectl describe pod <pod-name>

根据日志信息修复命令逻辑或依赖服务,必要时调整restartPolicyNever,避免无限重启。

问题 2:Init 容器占用过多资源

解决方案
为 Init 容器配置合理的资源限制:

initContainers:
- name: resource-heavy-initimage: some-imageresources:limits:cpu: "1"memory: "1Gi"requests:cpu: "500m"memory: "512Mi"

6.2 临时容器相关问题

问题 1:无法添加临时容器,提示权限不足

解决方案
确保当前用户具有ephemeralcontainers权限,必要时创建 RBAC 规则:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: ephemeral-debugger
rules:
- apiGroups: [""]resources: ["pods/ephemeralcontainers"]verbs: ["create"]
问题 2:临时容器无法连接到目标容器的进程

解决方案
添加临时容器时指定--target参数,共享目标容器的进程命名空间:

kubectl debug -it <pod-name> --image=busybox:1.28 --target=<target-container-name>

6.3 HPA 相关问题

问题 1:HPA 不触发扩缩容

可能原因

  • Metrics Server 未部署或运行异常
  • 未为容器配置resources.requests
  • 指标数据未达到扩缩容阈值
  • HPA 配置错误

解决方案

# 检查Metrics Server状态
kubectl get pods -n kube-system | grep metrics-server# 查看HPA事件
kubectl describe hpa <hpa-name># 检查Pod指标是否正常采集
kubectl top pods
问题 2:HPA 频繁扩缩容("抖动" 现象)

解决方案

增大扩缩容阈值的差距(如 CPU 使用率上下限差 20% 以上)

调整 HPA 的检查间隔(--horizontal-pod-autoscaler-sync-period

设置缩容延迟(--horizontal-pod-autoscaler-downscale-delay

七、总结与展望

Kubernetes 的高级调度特性 —— 初始化容器、临时容器和 HPA 自动扩缩容 —— 为复杂应用场景提供了强大的支持

http://www.dtcms.com/a/274747.html

相关文章:

  • SSM与SpringBoot面试题
  • Gin 中常见参数解析方法
  • 解锁48V USB-C供电潜力,慧能泰重磅推出PD3.2 DRP芯片HUSB253
  • 使用 SSH 连接 GitHub
  • UC浏览器PC版自2016年后未再更新不支持vue3
  • Grok-4 发布会图文总结
  • 【常见分布及其特征(1)】引言
  • 异步复习(线程)
  • CS144 lab2 tcp_receiver
  • Linux入门篇学习——Linux 编写第一个自己的命令,make 工具和 makefile 文件
  • C语言实现Linux命令行工具:VI和CAT
  • 飞算JavaAI进阶:重塑Java开发范式的AI革命
  • LGA核心板贴装指南:关键细节决定产品成败
  • MD2Doc转换器(基于Python)
  • Java 中的锁分类
  • 网页嵌入与接入功能说明
  • LeetCode经典题解:128、最长连续序列
  • Vue3 postcss-px-to-viewport-8-plugin
  • 力扣-21.合并两个有序链表
  • 【三维重建工具】NeRFStudio、3D GaussianSplatting、Colmap安装与使用指南
  • (7)机器学习小白入门 YOLOv:机器学习模型训练详解
  • 「GRPO训练参数详解:理解Batch构成与生成数量的关系」
  • 如何使用数字化动态水印对教育视频进行加密?
  • 学习日记-spring-day46-7.11
  • 【Linux-云原生-笔记】系统引导修复(grub、bios、内核、系统初始化等)
  • USB数据丢包真相:为什么log打印会导致高频USB数据丢包?
  • 数据库系统的基础知识(三)
  • Logback.xml配置详解与实战指南
  • 目标检测中的NMS算法详解
  • Java基础-String常用的方法