记一次springboot应用偶发502错误的排查过程

【minio】linux集群部署minio,springboot整合教程,解决Response code: 502, Content-Type: null, body:问题 linux部署minio,java sdk调用操作minio教程 阅读详情
AI摘要

本文探讨了一种特定场景下出现502 Bad Gateway错误的原因及解决方案,涉及到Tomcat内部处理流程、finalize方法的调用及其对后续请求的影响。

我们有一个系统,自上线以来,总隔三差五有用户反馈偶尔会有请求502 bad gateway的情况产生,但发生频率不高,也没发现有什么规律。经反复测试我们发现如果系统开启了图片水印功能,这个现象就比较容易重现(刷新带有图片的页面的时候)。所以我们初步怀疑这个情况和图片处理肯定是有点关系的。502的error code是nginx返回的,而且返回速度很快,看起来上游要么是直接拒绝连接了,要么是连接上了之后很快返回了。通过直接访问springboot应用尝试,发现是后一种情况,chrome里面提示net::ERR_EMPTY_RESPONE。也死马当活马医,尝试了修改tomcat的线程和连接数配置,但并没有起什么作用(实际使用连接数也远没到default值)。如果增加最小堆内存的大小,这个现象出现的会少一些,但堆内存的使用离最大值也差非常多,内存很充足。所以对这个问题没有什么头绪,只能猜测是不是和图片处理频繁gc有关,但按常理gc也不应该直接返回空,只会导致响应慢一些而已。

为了定位这个问题,我们先把tomcat和catalina的日志级别设到了TRACE级别,试图从中寻找一些规律。经过艰难的调试和重现后发现,每次出现failed的request的时候,都会伴随有这样的日志

2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.coyote.http11.Http11NioProtocol:? - Processing socket [org.apache.tomcat.util.net.NioChannel@418ea230:java.nio.channels.SocketChannel[connected local=/192.168.95.113:8080 remote=/192.168.105.93:60196]] with status [OPEN_READ]
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.coyote.http11.Http11NioProtocol:? - Found processor [null] for socket [org.apache.tomcat.util.net.NioChannel@418ea230:java.nio.channels.SocketChannel[connected local=/192.168.95.113:8080 remote=/192.168.105.93:60196]]
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.coyote.http11.Http11NioProtocol:? - Popped processor [org.apache.coyote.http11.Http11Processor@7aea45c9] from cache
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.coyote.http11.Http11Processor:? - Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1678d428:org.apache.tomcat.util.net.NioChannel@418ea230:java.nio.channels.SocketChannel[connected local=/192.168.95.113:8080 remote=/192.168.105.93:60196]], Status in: [OPEN_READ], State out: [CLOSED]
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.coyote.http11.Http11NioProtocol:? - Pushed Processor [org.apache.coyote.http11.Http11Processor@7aea45c9]
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.tomcat.util.net.NioEndpoint:? - Calling [org.apache.tomcat.util.net.NioEndpoint@6eb17ec8].closeSocket([org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1678d428:org.apache.tomcat.util.net.NioChannel@418ea230:java.nio.channels.SocketChannel[connected local=/192.168.95.113:8080 remote=/192.168.105.93:60196]])
java.lang.Exception: null
        at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doClose(NioEndpoint.java:1165)
        at org.apache.tomcat.util.net.SocketWrapperBase.close(SocketWrapperBase.java:394)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.cancelledKey(NioEndpoint.java:667)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:829)
2021-11-18 11:42:33,199 DEBUG [http-nio-8080-exec-3] org.apache.tomcat.util.threads.LimitLatch:? - Counting down[http-nio-8080-exec-3] latch=7

经过查看tomcat源代码并和正常请求比对后发现,在tomcat的Http11Processor中,Status in: OPEN_READ的状态应该是正常的,但State Out: CLOSED是有问题的,正常情况下State Out应该是OPEN。从源代码我们可以看到,State Out是CLOSED意味着Http11Processor的service方法中出现了什么异常情况,所以调用了setErrorState。但service方法中代码比较长,有很多地方调用了setErrorState,一时半会儿也不知道是哪个分支导致的。所以我们采用了arthas的trace命令去跟踪service方法,想看下当返回State是ERROR的时候,调用路径是怎么样的

trace org.apache.coyote.http11.Http11Processor service 'returnObj.toString == "CLOSED"'

2021-11-18 19:22:00 [http-nio-8080-exec-8] INFO  result -`---ts=2021-11-18 19:22:00;thread_name=http-nio-8080-exec-8;id=4f;is_daemon=true;priority=5;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@1a1d6a08
    `---[0.028744ms] org.apache.coyote.http11.Http11Processor:service()
        +---[0.001952ms] org.apache.coyote.Request:getRequestProcessor() #274
        +---[0.001255ms] org.apache.coyote.RequestInfo:setStage() #275
        +---[0.003611ms] org.apache.coyote.http11.Http11Processor:setSocketWrapper() #278
        +---[7.81E-4ms] org.apache.coyote.http11.Http11Processor:getErrorState() #287
        +---[8.45E-4ms] org.apache.coyote.ErrorState:isError() #287
        +---[7.97E-4ms] org.apache.coyote.RequestInfo:setStage() #480
        +---[7.17E-4ms] org.apache.coyote.http11.Http11Processor:getErrorState() #482
        `---[6.07E-4ms] org.apache.coyote.ErrorState:isError() #482

从这个结果我们可以发现,在service方法最开始的(287行)第一个while循环处的isError()就已经是true了。也就是说这个processor刚进来时errorState状态就是不对的。为了确认这一点,我们使用watch查看他进来时候的errorState值

watch org.apache.coyote.http11.Http11Processor service '{params[0], target.errorState}' -b -f

证实了在进service方法的时候errorState就已经是CLOSE_CONNECTION_NOW的状态了。

这肯定不是一个合理的状态,此时我怀疑会不会是前一个请求把状态设置为失败影响了下一个请求。所以就通过日志里面processor对象的地址找前一次请求,分析他的返回参数,结果发现前一次请求返回的时候errorState是正常的。事实上通过tomcat代码也可以发现,每个processor在用完之后放回cache的时候会调用recycle方法,把errorState重置为None,正常肯定是不会影响下一个请求的。

到这个时候就有点迷茫了,为什么会在两次请求中间,在缓存中没有被别人使用的processor的errorState就发生了变化呢。一度怀疑会不会是tomcat的bug,但搜了issue list并没有什么结果。最后还是通过源代码我们发现,errorState变量改变的入口只有setErrorState方法,所以我们应该可以监控一下setErrorState的调用堆栈,看看将state设成CLOSE_CONNECTION_NOW的时候的调用栈会是怎么样的,就能知道processor的errorState是什么时候和被谁设成了CLOSE_CONNECTION_NOW

stack org.apache.coyote.AbstractProcessor setErrorState  'params[0].toString == "CLOSE_CONNECTION_NOW"'


ts=2021-11-18 19:53:53;thread_name=Finalizer;id=3;is_daemon=true;priority=8;TCCL=null
    @org.apache.coyote.AbstractProcessor.setErrorState()
        at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:371)
        at org.apache.coyote.Response.action(Response.java:211)
        at org.apache.coyote.Response.sendHeaders(Response.java:437)
        at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:291)
        at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:272)
        at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:118)
        at javax.imageio.stream.MemoryCacheImageOutputStream.flushBefore(MemoryCacheImageOutputStream.java:194)
        at javax.imageio.stream.MemoryCacheImageOutputStream.close(MemoryCacheImageOutputStream.java:180)
        at javax.imageio.stream.ImageInputStreamImpl.finalize(ImageInputStreamImpl.java:884)
        at java.lang.System$2.invokeFinalize(System.java:2125)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:87)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:171)

一看这返回结果就恍然大悟了。这是ImageInputStreamImpl的finalize方法被调用的时候,会去调用response的相关方法,而此时response早已经结束了,就会导致IOException的产生,最后会导致processor的state被设置成CLOSE_CONNECTION_NOW。finalize的方法的调用时机是不确定的,这也造成了这个问题出现的随机性。

至此还有一个疑问是,为什么ImageInputStreamImpl的finalize会调用MemoryCacheImageOutputStream的close呢?查看代码发现MemoryCacheImageOutputStream实际上是继承自他的,继承链为:MemoryCacheImageOutputStream=>ImageOutputStreamImpl=>ImageInputStreamImpl。 所以此处回收的其实是MemoryCacheImageOutputStream类的实例。

所以这个问题最终的解决方案有两个

  1. 不使用这些Image相关的输入输出类(实际上这些类是在javax.desktop模块里面的,从名字也可以看出来,可能并不适合在server环境使用),可以考虑使用opencv之类的工具。
  2. 在服务端处理的时候不能把response的OutputStream直接传给MemoryCacheImageOutputStream,需要先写到某个临时文件,然后再通过普通的IO copy到response中。

通过这次得到两个经验

  • arthas真的还是挺好用的,是debug的一个利器
  • finalize方法还是不要用的好,这里出现问题实在是太难debug了
nacos+spring cloud gateway 出现503 Service Unavailable 描述 spring-boot :2.4.2 Springcloud :2020.0.1 Springcloud Alibaba :2021.1 不是此版本,可能,并不是适合。 问题经过 开始的时候,Gateway模块引入以下依赖: <!--nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactI 阅读详情

相关推荐

SpringBoot阿里云部署全指南:JDK11+MySQL5.7+Nginx+Systemd

SpringBoot生产部署是Java Web应用上线的关键环节,涉及JDK环境配置、数据库服务搭建、反向代理设置及进程守护等核心原理。理解JDK版本兼容性(如OpenJDK 11替代Oracle JDK)、MySQL密码策略与远程访问机制、Nginx反向代理路径匹配规则,是保障服务稳定的基础技术价值。典型应用场景包括阿里云ECS CentOS服务器上的企业级Web系统发布、校招新人实战训练及中小团队快速交付。本文聚焦SpringBoot项目在真实云环境中的可追溯部署实践,深度融合JDK11安装验证与Sys

weixin_34238633的博客 328

Nginx与Spring Boot的错误模拟实践:探索502和504错误的原因

刚工作那会,最常见的报错是,曾经也碰到过前端反馈或者,那时候傻傻的搞不懂,以为这种都是外部服务或者网络运维部那边的问题。当时那个服务里正好有个调用日志,平时会记录各种200,4xx状态码的信息。于是我跑到服务日志里去搜索了一下502这个数字,毫无发现。于是跟反映错误的前端说,“服务日志里并没有502的记录,你是不是搞错啦?现在想想,果然那时候还是个小白。。。在Nginx中,access.log和error.log是两个重要的日志文件,用于记录服务器的访问和错误信息。

Apple_Boy的博客 6242

SpringBoot+Modbus4j实现工业PLC数据采集与存储方案

Modbus协议作为工业自动化领域广泛应用的通信标准,通过TCP/IP协议实现设备间数据交换。其采用主从架构和功能码机制,支持寄存器读写等基础操作。在工业物联网场景中,高效采集PLC设备数据对实现设备监控和预测性维护具有关键价值。本文介绍的轻量化方案结合SpringBoot框架与modbus4j库,通过Redis实现实时数据缓存,解决了传统SCADA系统部署复杂的问题。该架构特别适合智能制造、能源监控等需要快速实施的中小型工业现场,可显著降低数据采集延迟至毫秒级。

weixin_33985679的博客 383

IOException: Connection reset by peer

用posrtman调用Resultful接口出现的异常如下: 021-11-09 16:28:20.307 DEBUG 445852 --- [nio-8000-exec-1] org.apache.tomcat.util.net.NioEndpoint : Registered write interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1809b8b6:org.apache.tomcat.util.net

zhanwuguo8346的博客 2959

SpringBoot整合Modbus TCP:工业数据采集全流程实战与避坑指南

工业物联网与农业物联网场景中,设备数据采集是连接物理世界与业务系统的关键环节。Modbus TCP作为工业现场最普及的通讯协议之一,以简洁的报文结构和良好的设备兼容性,成为传感器、PLC、网关等设备接入的首选方式。理解Modbus TCP的寄存器映射机制、功能码定义以及大端字节序规则,是正确解析设备数据的基础。在工程实践中,通过SpringBoot定时轮询Modbus从站寄存器,能够高效实现环境监测数据的采集、解析与入库,为智能大棚、智慧工厂等场景提供实时数据支撑。本文以农业大棚环境采集项目为例,完整梳理了

weixin_33842304的博客 356

API适配层实战:低成本无缝迁移OpenAI Codex应用到DeepSeek

在AI应用开发中,API接口标准化与协议适配是解决服务依赖和成本控制的关键技术。其核心原理是通过中间件拦截请求,实现不同服务提供商API格式之间的映射与转换,从而在不修改客户端代码的前提下,实现后端服务的无缝切换。这一技术价值在于保护现有开发投资,降低迁移成本,并提升系统架构的灵活性与抗风险能力。典型的应用场景包括:当上游AI服务API发生变更、成本上升或需要引入更具性价比的替代方案时,开发者可通过构建API适配层,快速、平滑地完成切换。本文以热门的OpenAI Codex API向国产大模型DeepSee

weixin_34005042的博客 407

Spring下WebSocket报HttpMediaTypeNotAcceptableException问题分析

一、问题描述 在我们使用WebSocket的过程中,突然间发现线上的环境抛出了HttpMediaTypeNotAcceptableException异常, 请求的uri:/im/conn/074/q4rvc1nc/xhr_streaming,异常堆栈如下: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation at org.springfram

duzm200542901104的专栏 4208

ASP.NET Core中间件管道深度解析与实战避坑指南

ASP.NET Core中间件管道是理解请求生命周期的核心机制,其本质是由委托链构成的‘洋葱模型’执行流。掌握其原理需厘清Func<HttpContext, Func<Task>, Task>签名逻辑、next调用时机及短路行为,技术价值在于实现可预测、可诊断、可干预的HTTP处理流程。典型应用场景包括自定义认证授权、日志追踪、异常熔断与响应压缩等,而真实生产问题如JWT状态丢失、CORS预检失败、HTTPS重定向失效,往往根源于中间件注册顺序或上下文污染。本文聚焦C#泛型约束与协变逆变边界推导在中间件设计

diaojin6880的博客 396

负载均衡500/502/504错误排查

对于配置负载均衡之后,访问网站出现500 Internal Server Error, 502 Bad Gateway, 504 Gateway Timeout等错误,有可能由多种原因导致,例如运营商拦截,客户端异常行为导致防火墙封杀,负载均衡配置错误或者健康检查失败,后端Web应用访问问题等。 可能原因以及解决方案一、源站域名没有备案或者域名没有在高防或者安全网络配置七层转发 解决方案:请将域

******* ▄︻┻┳═一 ******* 8225

2026工业串口服务器选型白皮书:12项产线实测硬指标

串口服务器已从基础数据透传设备演变为工业实时控制链路的关键神经节点。其核心价值在于保障RS-485物理层稳定、Modbus/TCP协议栈高并发与MQTT TLS 1.3安全上报三重能力的协同可靠。技术原理上,它需在电磁干扰、温度漂移、网络抖动及固件异常等复杂工况下维持μs级时间同步、VOD电压余量和分级缓存策略。工程实践中,92%的现场故障源于对驱动能力、协议状态机内存分配、EFT群脉冲防护等隐性指标的误判。本文聚焦NCOM622等新一代设备,系统解构12项官网不标但产线必验的硬指标,覆盖汽车焊装、光伏逆变

weixin_34026276的博客 250

大厂Python自动化测试面试题合集

题目:函数的作用是什么?调用函数的语法?答案:将独立功能代码封装成模块,复用代码;函数名(实参)。题目:函数 return 作用是什么?无 return 时函数返回什么?多返回值底层是什么类型?答案:返回函数执行结果;无 return 默认返回 None;return x,y,z 底层自动封装为元组。题目:函数四大参数类型分别是什么?定义顺序要求?答案:必选参数、默认参数、可变位置 * args、命名关键字、可变关键字 **kwargs;顺序:必选→默认→*args→命名关键字→**kwargs。

悦分享 104

踩坑 - 压测三轮后 502:一个默认 10 的连接池如何拖垮整个服务

除了 Tomcat 那个"请求线程池",业务代码常自己开线程池做并行查询、异步任务。这些池子同样有core/max/queueCapacity/拒绝策略,配不好一样堆积。两个高频坑:① @Async不指定线程池时,早期默认走——它不复用线程、来一个建一个,高并发下疯狂创建线程直到 OOM;不传线程池时走,这是全 JVM 共享的池,被一个慢任务占满会连累所有用到它的地方。核心业务用独立、命名清晰的线程池做资源隔离,别共享、别吃默认。

记录后端技术的深水区:MySQL、并发、JVM、分布式。原理为主,实战为辅,能少踩一个坑是一个。 451

Spring Boot连接超时导致502错误的实战案例

主要给大家介绍了关于Spring Boot连接超时导致502错误的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前后端Bug定位分析:从请求链路到环境排查的实战方法论

在前后端分离架构下,HTTP协议是前后端通信的唯一桥梁,任何请求异常都会体现在这条链路上。理解浏览器开发者工具中的Network与Console面板、HTTP状态码语义以及后端日志分级原则,是快速判定问题归属的基础能力。通过请求参数、响应内容与异常堆栈的交叉印证,可以从偶发现象中剥离出真实原因,避免前端与后端互相推诿。跨域配置、依赖安装失败、环境差异等联调阶段的高频问题,同样需要系统化的排查脉络。围绕请求链路、状态码、日志与接口调试工具,这套前后端Bug定位分析方法能够帮助团队缩短故障恢复时间,提升协作效率

weixin_34175509的博客 396

Cisco Packet Tracer 9.0 工业网络模拟:3步配置OT协议与Purdue模型实战

本文详细介绍了如何使用Cisco Packet Tracer 9.0进行工业网络模拟,包括Purdue模型构建、三大OT协议(Modbus TCP/IP、CIP、PROFINET IO)配置及工业网络安全防护。通过实战演练,读者可掌握工业网络设计、配置与安全防护的核心技能,适用于智能制造和能源管理等场景。

weixin_28691741的博客 352

UM982模组在无人机精准农业中的实战应用:如何配置双天线RTK实现厘米级定位

本文深入解析了UM982双天线RTK模组在农业无人机中的实战应用。通过详细阐述其硬件集成、软件配置及抗干扰调试全流程,重点说明了如何利用双天线设计直接获取高精度航向,并结合BDS等多系统GNSS信号,实现农田复杂环境下的厘米级稳定定位,从而提升变量施肥、自动巡田等精准农业作业的效率与质量。

weixin_29304021的博客 504

Java 应用上 Kubernetes 的 20 条生产级必备条件。

这不是 Kubernetes 的问题,也不是 Java 的问题,而是 JVM 没有被当成“运行在容器里的 JVM”来治理。欢迎关注我的公众号「DevOps和k8s全栈技术」,进公众号【服务】栏,可以看到技术群,点击即可加入学习交流群。欢迎关注我的公众号「DevOps和k8s全栈技术」,进公众号【服务】栏,可以看到技术群,点击即可加入学习交流群。我们一直在用“物理机时代的 JVM 思维”,跑在“强边界的容器环境里”。一开始很自信,上线很顺利,半年后开始疲于救火。没有 Dump 的 OOM 排查,本质是猜谜。

weixin_38320674的博客 696

ArcGIS 泛克里金插值

按照如图所示的步骤填写参数,1处选择subset features。 2:输入数据。 3:输出训练数据。 4:输出测试数据。 5:80,表示80%的比例是训练数据,20%是测试数据。 6:输入的百分比。 1:选择geostatistical wizard。 2:插值方法,克里金插值 3:训练数据。 4:数据字段。 点击下一步: 1:表示泛克里金插值。 2:输出表面类型。 3:转换类型none。 4:趋势剔除的阶数。 点击下一步: 表示东北—西南方向变化平缓。 1:模型优化 2:模型类型(stabl.

yuanYW7556的博客 7275

Zabbix自定义监控实战:脚本编写、Agent配置与日志服务监控

Zabbix自定义监控是突破原生指标盲区、实现业务级可观测性的关键技术。其核心在于通过Shell/Python脚本构建可扩展的采集逻辑,解决端口检测失真、日志上下文缺失、连接池等关键指标不可见等痛点。原理上依赖UserParameter机制将脚本注册为Agent原生能力,结合幂等输出、超时控制与权限隔离保障稳定性。技术价值体现在故障定位效率提升3倍以上、MTTR显著缩短,并支撑微服务、K8s、高并发等复杂场景。典型应用场景包括Nginx健康检查、Spring Boot Actuator指标采集、MySQL连

weixin_33812433的博客 377

sentaurus学习笔记(VDMOS仿真)(三)

在Sentaurus中,这通常意味着在2D仿真中,x轴指向下,y轴指向右。定义了在2D模拟中,网格尺寸按照一定的增长率进行扩展,这里的增长率为2.0,意味着远离最小尺寸区域的网格单元大小将是最小尺寸的两倍。定义了2D模拟中网格单元的最小尺寸为0.001微米,这有助于控制网格的最小大小,从而影响仿真的精度和计算成本。表示启用中等级别的日志信息输出,这有助于用户了解仿真过程中发生的事件和可能的问题。表示启用保存调试文件,这可以帮助用户在仿真过程中检查和验证模型的状态。这行代码设置了仿真过程中使用的线程数。

qq_52640792的博客 1807

Spring Boot 与 Redisson 版本适配深度解析

Spring Boot 与 Redisson 的版本适配是一个动态演进的过程。开发者需要密切关注两者官方的版本更新日志,建立完善的版本验证机制。本文提供的适配方案基于当前最新技术状态(2024年1月),建议在实际生产环境中通过灰度发布策略验证版本兼容性。只有深入理解底层技术原理,才能在分布式系统的星辰大海中稳健航行。延伸阅读Spring Boot 官方迁移指南。

fudaihb的博客 1083

嵌入式启动流程深度解析:从复位向量到OTA回滚的完整指南

嵌入式系统的稳定性往往在启动阶段就已奠定。启动流程不仅仅是上电后的一段样板代码,而是涉及向量表、栈初始化、C运行时环境搭建、外设配置等一整套系统工程。理解从复位向量到main函数的完整链路,是定位启动失败、跑飞、反复复位等问题的基础。在真实工程中,看门狗时序、RTOS调度和OTA升级失败引发的启动异常,更是高频痛点。本文系统拆解启动的底层原理与技术价值,并深入分析基于双Bank分区与启动计数的自动回滚机制,帮助开发者构建从启动到运行、从升级到故障恢复的完整闭环,让固件从“能跑”走向“扛打”。

weixin_34337381的博客 305

从“能跑”到“好用”:一名 Python 开发者的工程化进阶之路【Python心得篇】

Python 早已不只是写脚本、跑数据的工具。后端服务AI Agent 编排层自动化平台核心语言数据与业务之间的“中枢层”区别只在于:你是用脚本方式,还是工程方式在写。如果你已经能写“能跑的 Python”,下一步,就是让它长期可跑、稳定可演进。Python 的真正价值不在于“写得快”,而在于能否支撑持续演进的工程实践。当代码从一次性脚本走向长期运行的系统,开发者必须从结构设计、职责拆分、性能意识和类型约束等方面进行系统性思考。

博客 1546

RPA中使用if组件判断Web元素:条件分支与流程设计指南

条件判断是流程自动化中的核心基础,尤其在 Web 自动化与RPA场景中,页面状态的多样性与不确定性使静态流程难以稳定运行。if组件的本质是一个布尔断言节点,它通过对目标元素的“存在、可见、文本、属性、数量”等状态做检测,将动态页面转化为可控分支,解决弹窗、加载超时、元素缺失等常见问题。结合元素定位(如XPath、CSS Selector)与合理的等待超时,if组件能有效完成登录分支、数据校验、空态识别等业务判断,极大提升自动化流程的健壮性。若判断项过多或嵌套过深,还需依赖状态映射、异常处理和日志规范来对分支

415

AD22等长布线规则

本文介绍了PCB布线中实现信号线等长的详细操作步骤:1.创建网络类(NetClass),将需要等长的信号线归入同一组;2.设置高速布线规则(High-SpeedRule),定义等长容差等参数;3.进行交互式等长布线(InteractiveLengthTuning),使用蛇形线调整线长;4.实时调整与最终检查,确保所有网络满足等长要求。文中还提供了实用技巧,如使用快捷键调整蛇形线参数、为关键信号设置更严格规则等。操作需在PCB设计软件中完成,通过统一管理、规则设置和精确调整来实现信号同步传输。

whm128的博客 1557

QT控件 参考Qt的PIMPL设计模式实现使用QWidget控件绘制3D饼状图表和3D柱状图表,使用QChartView绘制圆柱体图表

工作中之前遇到了绘制3D饼状图表的需求,通过Qt 实现3维饼状图 一文,成功迅速解决问题,现在闲下来了,之前看QtTreePropertyBrowser库的源代码,就想着学习学习Qt的PIMPL模式,于是就参照PIMPL模式实现通过QWidget控件的paintEvent函数重新绘制3D饼状图表和3D柱状图表统计数据的显示效果, 而使用QChartView绘制圆柱体图表完全是取巧了,为了紧急完成工作采用的方法,实际上使用3D柱状图表显示统计数据更加合理。

... 727
上一篇: HTTP/2 简介
下一篇: 2.4寸SPI串口ILI9341芯片彩色LCD驱动
帅帅兔子
博客等级 码龄24年 7粉丝 29原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅兔子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值