【实践】2025年线上问题解决与总结-3

这个是本系列的第三个文章,主要用于记录一下几个边缘业务的线上问题/核心业务的小问题的排查方案与解决

基本上排查思路就是技术保证基础参数的排查诊断,业务能力保证排查的流程思路是清晰的,精确找到对应出问题的业务节点进行解决。

我所在的业务组,除了一些关键业务我没有参与外(我参与了云存储和告警)其他的像是webRTC,信息平台,cdn这些都算是小业务点,这些有一些也有线上问题

系列文章见 【实践】2025年线上问题解决与总结-1

【实践】2025年线上问题解决与总结-2

三元运算符NPE问题

背景

环境上线发生NPE报错,造成紧急回退

有以下两方面需要查看

若connectMode.contains(1)报NPE,代表需要查看stream运算是否返回nullproductDocDO.getApScanCapacity()可能会有三元运算符的自动拆装箱产生的NPE

根因分析

触发了自动拆装箱,但是Integer对象是null,触发了NPE开发时在环境中配置了MySQL字段的非空默认值,但是测试完沟通后直接将默认值删除,没有验证没有默认值的情况,造成了NPE

  1. stream操作是否会引起NPE或者返回null对象?

  2. Arrays.stream(...):将数组转换为流。不会返回 null。productDocDO.getConnectMode():如果这个方法返回 null 或者 productDocDO 是 null,那么整个表达式将会抛出 NullPointerException。.split(SEMICOLON):将字符串按分号分割成数组。如果结果是空字符串(""),则会生成一个包含单个空字符串的数组([""])。.map(Integer::parseInt):将每个字符串转换为整数。如果遇到非数字字符串,会抛出 NumberFormatException。.collect(Collectors.toList()):将流中的元素收集到一个列表中。不会返回 null。

  3. 要看stream是否返回一个null对象,则可以直接看stream流表达式中的最后一个操作,也就是输出操作,其他的可以不用关注,stream流详细设置可以单独写一篇文档进行讲解

代表stream流不会返回null对象,信息来源Collectors(Java Platform SE 8)

  1. Collect.toList()方法只会返回一个新的List对象,因此使用stream流开发时不需要考虑会产生null对象,但是stream操作过程中可能会产生NPE或其他问题

三元运算符是否会引起NPE?

三元运算符在使用时会自动触发数据类型的拆装箱,如会将Integer变成int类型,如果对象数据类型是null,在拆装箱时会出现NPE问题

信息来源

自动拆装箱的原因为三目运算符两侧数据类型不一样时,为了确保信息一致,会进行拆装箱,这是为了确保三目运算符的结果类型一致。

信息来源 docs.oracle.com/javase/spec...

解决方案

三目运算符两侧类型保持一致/非空校验或填充默认值

  1. 不要在测试完成后随意修改一切相关文本,包括但不限于代码、表结构、配置文件信息等,如果修改则代表需要重新进行测试!

  2. 开发过程中如果使用基本数据类型,在调用链路中(如函数嵌套,对象在多个语句中等)需要尽量避免自动拆装箱三元运算符,要么冒号两侧类型是相同类型,如都是Integer或者都是int,或者是对象类型使用Optional进行包装

  3. 不太熟的API使用前需要详细查看使用时容易出现的问题

其他的小bug

  1. 【云存储】云存储套餐状态下发,有时会有状态异常,通过定时任务,对设备状态和套餐状态进行对比,发现异常

    原因是kafka下发乱序,比如我们这边有业务是通过kafka先下发关闭再下发开启,如果乱序,最终状态时关闭,与实际业务不符合,通过把deviceid作为kafka消息的key+粘性分区

    后续解决方案是对于顺序性要求高的,重要的业务,一律使用key+粘性分区

  2. 【云存储】云存储有时候有状态问题,造成脏数据(比如开启的套餐触发归档流程)

    解决方案是 通过幂等+状态机,解决该问题

    通过严格的状态调整,避免异常状态转换,避免后续脏数据的人工介入

  3. 【告警】告警的入库率有问题,也有重复

    因为主要是通过kafka进行消费,网关性能较好暂未关注,所以需要保证kafka生产->broker存储->consumer消费->进行业务处理->存储数据库这个链路不会有重复或者丢失

  4. 【云存储】批处理只有一个pod执行,且长时间执行,中途任务中断会导致进度丢失,影响业务

    解决方案:一个是对批处理任务进行进行存储,按照业务点(如我这边进行套餐的状态更新、将套餐和设备进行校验,基准是套餐,所以可以通过单次查询1000个套餐,进行业务处理),每完成一个小型批处理任务则可以往数据库中记录 任务,处理量,完成时间,任务对应日期等信息,这样重启尝试重新查看是否有遗漏时,可以直接通过这张表即时回溯,快速恢复到任务失败之前的状态

    为了解决多个pod进行批处理业务,通过redisson锁+偏移量实现,redisson表示记录偏移量时只能有一个pod修改,偏移量代表这个长时间任务的执行进度

相关推荐
雨中飘荡的记忆2 小时前
MyBatis参数处理模块详解
java·mybatis
Chloeis Syntax2 小时前
MySQL初阶学习日记(7)--- 事务
java·数据库·笔记·学习·mysql
幽络源小助理2 小时前
SpringBoot+Vue雅苑小区管理系统源码 | Java物业项目免费下载 – 幽络源
java·vue.js·spring boot
沛沛老爹2 小时前
2025年Java发展现状与趋势:稳踞企业开发核心,云原生与AI集成成为新引擎
java·云原生·企业开发·发展趋势·java生态
锐湃2 小时前
手写agp8自定义插件,用ASM实现路由跳转
java·服务器·前端
weixin_478433322 小时前
iluwatar 设计模式
java·开发语言·设计模式
花卷HJ2 小时前
Android 多媒体文件工具类封装(MediaFileUtils)
android·java
モンキー・D・小菜鸡儿2 小时前
Android 自定义粒子连线动画视图实现:打造炫酷背景效果
android·java
Java天梯之路2 小时前
# Spring Boot 钩子全集实战(四):`SpringApplicationRunListener.environmentPrepared()` 详解
java·spring·面试