记一次k8s下容器启动失败,容器无日志问题排查

news2025/3/10 15:14:22

问题

背景

本地开发时,某应用增加logback-spring.xml配置文件,加入必要的依赖:

<dependency>
	<groupId>net.logstash.logback</groupId>
	<artifactId>logstash-logback-encoder</artifactId>
	<version>8.0</version>
</dependency>

本地可以正常启动。

但是发布到测试环境后,容器启动失败
在这里插入图片描述
其状态CrashLoopBackOff,不管是通过执行kubectl logs <pod> -n <ns>命令查看日志,还是在KubeSphere查看容器日志,都没有任何日志输出。

排查

KubeSphere看到容器的状态为
在这里插入图片描述
容器的事件:
在这里插入图片描述
信息如下:

Warning  Unhealthy  75s (x10 over 5m15s)  kubelet            Startup probe failed: Get "http://172.20.0.95:8012/health": dial tcp 172.20.0.95:8012: connect: connection refused
Back-off restarting failed container fileview in pod 

使用k9s查看日志:
在这里插入图片描述
各种无头苍蝇乱排查:

  • 删除容器,自动重启,不行;
  • 修改探针时间,不行;
  • kubectl describe pod <pod_name> -n <ns>,没看出问题。

总之,看不到任何有效信息,无法定位问题。

workaround

通过KubeSphere,打开【应用负载】-【工作负载】,搜索【fileview】,【编辑YAML】,使用一个有效的之前的镜像版本,即回滚:
在这里插入图片描述
版本号,在Harbor镜像仓库里,根据代码提交和流水线构建日期,选择一个变更前的版本。然后删除容器组里的现有容器,会自动重启。

然后重启成功!!

说明还是由于代码提交导致测试环境里的容器启动失败。

Git Commit

代码提交记录如下:
在这里插入图片描述
新增的配置文件logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位毫秒。当scan为true时,此才能属性生效。默认时间间隔为30s。 -->
<configuration scan="true" scanPeriod="30 seconds">
    <!--  彩色日志依赖  -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>

    <!-- 线上日志文件路径-->
    <property name="JSON_FILE_PATH" value="/logs/service/fileview"/>

    <!--  控制台彩色日志格式  -->
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %green([traceId=%X{traceId} spanId=%X{spanId} sampled=%X{sampled}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!--  日志文件日志格式  -->
    <property name="FILE_LOG_PATTERN"
              value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} [%X{traceId}] ${PID:- } --- [%15t] %-40.40logger{39}:[%5.5line] - %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!--  json日志格式  -->
    <property name="JSON_LOG_PATTERN"
              value='{"localtime": "%date{yyyy-MM-dd HH:mm:ss.SSS}","level": "%level","pid": "${PID:-}","thread": "%thread","traceId": "%X{traceId}","class": "%logger","method": "%method","line": "%line","message": "%message","stack":"%wEx"}'/>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 以JSON格式写入log文件 -->
    <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${JSON_FILE_PATH}/log_%d{yyyyMMdd}_%i.log</FileNamePattern>
            <!--日志文件最大大小-->
            <maxFileSize>200MB</maxFileSize>
            <!--日志文件保留天数-->
            <maxHistory>5</maxHistory>
            <!-- 每个日志文件到200MB的时候开始切分,最多保留5天,但最大到5GB,哪怕没到5天也要删除多余的日志 -->
            <totalSizeCap>5GB</totalSizeCap>
            <!--启动项目触发删除检测  -->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <pattern>${JSON_LOG_PATTERN}</pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <!--本地调试打印控制台彩色日志-->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>

    <springProfile name="dev,uat,test,pre,gray,future,prd,prod">
        <root level="INFO">
            <appender-ref ref="JSON_FILE"/>
        </root>
    </springProfile>
</configuration>

在本地开发环境Debug模式启动应用时,可以正常启动。

另外,上面这个配置文件,引入一个LoggingEventCompositeJsonEncoder,因此需要引入logstash-logback-encoder依赖。

但没有注意到:Spring Boot并没有加载此文件logback-spring.xml,也没有重视这一点。

事实上,针对这次提交涉及的4个文件,到底是哪个改动引发问题,定位时,也耗费掉不少时间。

只是这里直接将问题定位为logback配置文件。

Docker

既然本地启动成功,测试环境启动失败。能不能在本地模拟测试环境?

于是花费一点时间,在Windows开发环境下安装Docker Desktop。

IDEA在某个版本后自带Docker开发插件:
在这里插入图片描述
稍微摸索一下,就知道如何使用Docker插件,填写镜像地址,点击Pull接口
在这里插入图片描述
镜像拉取成功后,点击右侧的Create Container:
在这里插入图片描述
容器启动失败,报错日志:

Logging system failed to initialize using configuration from 'null'
2024-12-29T08:31:31.991172257Z java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Could not create component [encoder] of type [net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder] java.lang.ClassNotFoundException: net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder
2024-12-29T08:31:31.991194340Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:24 - no applicable action for [providers], current ElementPath  is [[configuration][appender][encoder][providers]]
2024-12-29T08:31:31.991197106Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:26 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][encoder][providers][pattern]]
2024-12-29T08:31:31.991199506Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@38:30 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][encoder][providers][pattern][pattern]]
2024-12-29T08:31:31.991201798Z ERROR in ch.qos.logback.core.ConsoleAppender[JSON] - No encoder set for the appender named "JSON".

这说明什么??

说明在以容器方式启动应用时,应用加载logback配置文件失败。

此时,才开始重视前文提到的:应用启动时,Spring Boot并没有加载logback-spring.xml文件。

logback

现在来解决,为啥本地开发环境Debug模式启动应用,Spring Boot为啥没有加载logback-spring.xml文件。

应用的目录结构如下:
在这里插入图片描述
因为application.properties文件在config目录下,于是不带思考地,把logback-spring.xml文件也放在config目录下。

logback-spring.xml文件移到resources目录下,Spring Boot还是不能加载logback-spring.xml文件。

把文件重命名为为logback.xml,终于可以加载。

JDK版本

本地启动,应用不再报错,发布到测试环境,容器启动还是失败。

不过,终于可以看到容器日志!!!具体的报错信息(经过换行处理,方便阅读):

Exception in thread "main" java.lang.UnsupportedClassVersionError: 
net/logstash/logback/encoder/LoggingEventCompositeJsonEncoder has been compiled by a more recent version of the Java Runtime (class file version 55.0), 
this version of the Java Runtime only recognizes class file versions up to 52.0

很熟悉的报错,是不是:

  • 52.0对应于JDK 8版本
  • 55.0对应于JDK 11版本

此应用的Dockerfile如下:

FROM harbor.aaaa.com/library/fileview:4.4.0-beta

ADD target/kkFileView-*.tar.gz /opt/
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.4.0-beta/bin
ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-Dspring.config.location=/opt/kkFileView-4.4.0-beta/config/application.properties", "-jar", "/opt/kkFileView-4.4.0-beta/bin/kkFileView-4.4.0-beta.jar"]

基础镜像是fileview:4.4.0-beta,看不出Java版本,默认应该就是JDK 8。

登录到Harbor镜像仓库,查看镜像信息,果然是JDK8:

{
    "ArgsEscaped": true,
    "Cmd": [
        "/bin/bash"
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk1.8.0_251/bin",
        "JAVA_HOME=/usr/local/jdk1.8.0_251",
        "CLASSPATH=/usr/local/jdk1.8.0_251/lib/dt.jar:/usr/local/jdk1.8.0_251/lib/tools.jar",
        "LANG=zh_CN.UTF-8",
        "LC_ALL=zh_CN.UTF-8"
    ],
    "Labels": {
        "org.opencontainers.image.ref.name": "ubuntu",
        "org.opencontainers.image.version": "20.04"
    }
}

其构建历史(无关信息)为:

ARG RELEASE
ARG LAUNCHPAD_BUILD_ARCH
LABEL org.opencontainers.image.ref.name=ubuntu
LABEL org.opencontainers.image.version=20.04
ADD file:e7cff353f027ecf0a2cb1cdd51714de3b083a11a0d965f104489f9a7e6925056 in /
CMD ["/bin/bash"]
COPY fonts/* /usr/share/fonts/chinese/ # buildkit
COPY server-jre-8u251-linux-x64.tar.gz /tmp/server-jre-8u251-linux-x64.tar.gz # buildkit
COPY LibreOffice_7.5.3.2_Linux_x86-64_deb.tar.gz /tmp/libreoffice_deb.tar.gz # buildkit
RUN RUN apt-get clean && apt-get update && sed -i 's/http:\/\/archive.ubuntu.com/https:\/\/mirrors.aliyun.com/g' /etc/apt/sources.list && sed -i 's/# deb/deb/g' /etc/apt/sources.list && apt-get install -y --reinstall ca-certificates && apt-get clean && apt-get update && apt-get install -y locales language-pack-zh-hans && localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 && export DEBIAN_FRONTEND=noninteractive && apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && apt-get install -y fontconfig ttf-mscorefonts-installer ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy && apt-get install -y wget && cd /tmp && tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ && apt-get install -y libxrender1 libxinerama1 libxt6 libxext-dev libfreetype6-dev libcairo2 libcups2 libx11-xcb1 libnss3 && tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.5.3.2_Linux_x86-64_deb/DEBS && dpkg -i *.deb && rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* && cd /usr/share/fonts/chinese && mkfontscale && mkfontdir && fc-cache -fv # buildkit
ENV JAVA_HOME=/usr/local/jdk1.8.0_251
ENV CLASSPATH=/usr/local/jdk1.8.0_251/lib/dt.jar:/usr/local/jdk1.8.0_251/lib/tools.jar
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk1.8.0_251/bin
ENV LANG=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
CMD ["/bin/bash"]

本地开发环境切换到JDK 8,debug模式启动应用,果然启动报错:
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.StaticLoggerBinder

但是,为啥和测试环境的报错信息不一样呢??

org.slf4j.impl.StaticLoggerBinder这个类是在logback-classic-1.2.3.jar里引入的:
在这里插入图片描述
不管了,开发任务太重了。没有时间去仔细探究。

降低logstash-logback-encoder版本8.0到6.6:

<dependency>
	<groupId>net.logstash.logback</groupId>
	<artifactId>logstash-logback-encoder</artifactId>
	<version>6.6</version>
</dependency>

不再报错:Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.StaticLoggerBinder

提交代码,触发流水线构建,发布到测试环境,启动成功。

logback.xml还是logback-spring.xml

问题虽然解决。

但是还留有不少疑问,此应用分明是一个Spring-Boot应用啊,为啥不能加载logback-spring.xml
在这里插入图片描述
可以加载logback.xml
在这里插入图片描述
另外,虽然可以加载文件,但是应用启动时会打印出一些ERROR日志:
在这里插入图片描述
报错日志如下:

13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@72:65 - no applicable action for [springProfile], current ElementPath  is [[configuration][springProfile]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@73:28 - no applicable action for [root], current ElementPath  is [[configuration][springProfile][root]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@74:39 - no applicable action for [appender-ref], current ElementPath  is [[configuration][springProfile][root][appender-ref]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@75:44 - no applicable action for [appender-ref], current ElementPath  is [[configuration][springProfile][root][appender-ref]]

请教DeepSeek,给出的一个比较靠谱的解释是这样的:
在这里插入图片描述

反思

  1. Q:为啥本地可以启动成功,测试环境不行?
    A:使用的JDK版本不一样。只有这一个服务最特殊,使用JDK 8版本,其他应用都是使用OpenJDK 11版本。
  2. Q:为啥测试环境的报错信息是UnsupportedClassVersionError,也就是使用的JDK版本引入一个更高JDK版本编译的依赖;而本地开发环境的报错是:NoClassDefFoundError?
    A:不知道。
  3. Q:为啥不能加载logback-spring.xml文件?可以加载logback.xml文件,但是有报错信息:no applicable action for [springProfile]
    A:唯一(有可能的)合理的解释,这依旧是一个Spring应用,虽然放在根目录下面的启动类,有@SpringBootApplication注解。

    Spring应用默认加载logback.xml文件,Spring Boot应用默认加载logback-spring.xml文件?让Spring去加载logback-spring.xml文件(经过重命名处理后可以加载logback.xml,但是文件里依旧有一些springProfile配置项),于是会报错no applicable action for [springProfile]。好像可以自圆其说。
  4. Q:Spring应用和Spring Boot应用的区别是什么?分界线是什么?@SpringBootApplication注解吗?
    A:不知道,此问题并不是没有意义的。
    在这里插入图片描述

参考

  • ChatGPT
  • DeepSeek

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

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

相关文章

KAFKA入门:原理架构解析

文章目录 一、认识kafka二、架构介绍2.1 工作流程2.2 Kafka可靠性保证2.3 Kafka存储 一、认识kafka Kafka到底是个啥&#xff1f;用来干嘛的&#xff1f; 官方定义如下&#xff1a; Kafka is used for building real-time data pipelines and streaming apps. It is horizont…

Redis - 6 ( 9000 字 Redis 入门级教程 )

一&#xff1a;Redis Java 集成到 Spring Boot 1.1 使用 Spring Boot 连接 Redis 单机 在创建项目时&#xff0c;勾选 NoSQL 分类下的 Spring Data Redis&#xff0c;同时勾选 Web 分类下的 Spring Web。这样既能方便集成 Redis&#xff0c;又能通过 Web 接口进行后续测试&am…

笔记本如何录屏幕视频和声音?快速入门的两种方法

“你好&#xff01;我想要制作线上教学课程&#xff0c;包括录制课程内容和我的声音&#xff0c;然后分享给我的学生&#xff0c;以便他们课后复习&#xff0c;但我不知道笔记本如何录屏幕视频和声音&#xff1f;有没有好的工具推荐&#xff1f;” 随着远程办公、在线学习和直播…

Flutter中的网络请求图片存储为缓存,与定制删除本地缓存

Flutter中的网络请求图片存储为缓存&#xff0c;与定制删除本地缓存 1&#xff1a;封装请求图片函数 2&#xff1a;访问的图片都会转为本地缓存&#xff0c;当相同的请求url&#xff0c;会在本地调用图片 3&#xff1a;本地缓存管理【windows与andriod已经测试】【有页面】【有…

Android设备使用AOA协议进行主机与配件模式通信

1.使用TYPC-C数据线连接两台华为手机&#xff1a; TYPE-C线&#xff0c;先连接下图右边的ACCESSORY 再连接左边的HOST 此时左边的HOST(白色) 会给右边的ACCESSORY(黑色) 充电 接着打开左连接的HostChart会自动调起授权&#xff0c;然后会启动右边的AccessoryChart USB HOS…

机器学习基础-支持向量机SVM

目录 基本概念和定义 1. 超平面&#xff08;Hyperplane&#xff09; 2. 支持向量&#xff08;Support Vectors&#xff09; 3. 线性可分 4. 边界 SVM算法基本思想和分类 基本思想 间隔最大化 间隔&#xff08;Margin&#xff09; 软边距 SVM 核函数的概念 基本概念…

ubuntu开机启动服务

需求背景&#xff1a; 需要监控日志&#xff0c;每次都是手动启动 nohup ./prometheus >/dev/null & nohub ./node_exporter >/dev/null & 需求目标&#xff1a; 重启后系统自动启动服务

图漾相机基础操作

1.客户端概述 1.1 简介 PercipioViewer是图漾基于Percipio Camport SDK开发的一款看图软件&#xff0c;可实时预览相机输出的深度图、彩色图、IR红外图和点云图,并保存对应数据&#xff0c;还支持查看设备基础信息&#xff0c;在线修改gain、曝光等各种调节相机成像的参数功能…

【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现

实验二 交换机基本配置和VLAN 间路由实现 一、实验目的 1&#xff0e;了解交换机的管理方式。 2&#xff0e;掌握通过Console接口对交换机进行配置的方法。 3&#xff0e;掌握交换机命令行各种模式的区别&#xff0c;能够使用各种帮助信息以及命令进行基本的配置。 4&…

【论文笔记】QLoRA: Efficient Finetuning of Quantized LLMs

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: QLoRA: Efficient Finetun…

Apache Paimon-实时数据湖

一、Apache Paimon是什么? Flink社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合&#xff0c;推出新一代的 Streaming Lakehouse 技术&#xff0c;促进数据在数据湖上真正实时流动起来&#xff0c;并为用户提供实时离线一体化的开发体验。 …

为什么相关性不是因果关系?人工智能中的因果推理探秘

目录 一、背景 &#xff08;一&#xff09;聚焦当下人工智能 &#xff08;二&#xff09;基于关联框架的人工智能 &#xff08;三&#xff09;基于因果框架的人工智能 二、因果推理的基本理论 &#xff08;一&#xff09;因果推理基本范式&#xff1a;因果模型&#xff0…

AI Development Notes 1 - introduction with the OpenAI API Development

Official document&#xff1a;https://platform.openai.com/docs/api-reference/chat/create 1. Use APIfox to call APIs 2.Use PyCharm to call APIs 2.1-1 WIN OS.Configure the Enviorment variable #HK代理环境&#xff0c;不需要科学上网(价格便宜、有安全风险&#…

路由组件与一般组件的区别

路由组件与一般组件的区别 1. 基本概念 1.1 路由组件 路由组件是指通过路由规则映射的组件&#xff0c;通常放在 pages 或 views 文件夹中。 1.2 一般组件 一般组件是指通过 import 导入后直接使用的组件&#xff0c;通常放在 components 文件夹中。 2. 主要区别 2.1 存…

K8s高可用集群之Kubernetes集群管理平台、命令补全工具、资源监控工具部署及常用命令

K8s高可用集群之Kubernetes管理平台、补全命令工具、资源监控工具部署及常用命令 1.Kuboard可视化管理平台2.kubectl命令tab补全工具3.MetricsServer资源监控工具4.Kubernetes常用命令 1.Kuboard可视化管理平台 可以选择安装k8s官网的管理平台&#xff1b;我这里是安装的其他开…

【C++】18.继承

文章目录 1.继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 1.3 继承类模板 2.基类和派生类对象赋值转换3.继承中的作用域3.1 隐藏规则&#xff1a;3.2 考察继承作用域相关选择题 4.派生类的默认成员函数4…

51单片机——8*8LED点阵

LED 点阵的行则为发光二极管的阳极&#xff0c;LED 点阵的列则为发光二极管的阴极 根据 LED 发光二极管导通原理&#xff0c;当阳极为高电平&#xff0c;阴极为低电平则点亮&#xff0c;否则熄灭。 因此通过单片机P0口可控制点阵列&#xff0c;74HC595可控制点阵行 11 脚 SR…

FastDeploy部署paddlecls分类模型(windows)

目录 写在前面 总体步骤 C SDK编译库 方式1&#xff1a;编译安装 方式2&#xff1a;下载预编译库 准备模型、文件、代码和数据 模型文件类型 samples代码 待预测图像 使用 FastDeploy C SDK 将cpp源码编译为exe 编写cpp代码 cpp代码编译exe 运行可执行程序exe 将…

电脑如何无线控制手机?

想在电脑上无线控制手机&#xff0c;需要用到Total Control控制软件&#xff0c;具体步骤如下&#xff1a; 1、首先我们在电脑上安装上控制软件Total Control并打开。 2、开启手机USB调试和ADB仅充电模式。 3、手机电脑均连接上相同局域网。 4、连接(首次使用需要用手机U…

C++ Qt练习项目 QChar功能测试

个人学习笔记 代码仓库 GitCode - 全球开发者的开源社区,开源代码托管平台 新建项目 设计UI 1、拖入group box去掉名字 2、拖入2个LineEdit 3、拖入两个Label 4、拖入两个PushButton 5、点栅格布局 1、拖入GroupBox 2、拖入4个PushButton 3、点栅格布局 1、拖入GroupBo…