前车之鉴,后车之师

问题 分类 具体解释 可能导致的后果 解决方法 备注
主从延迟 数据库 写后立即读的场景,比如订单落地成功抛消息,消息接收方再读订单推订单中心、发触达、落地数据等场景,再读数据时走从库,可能读不到数据。 脏数据业务逻辑有问题 延迟消费。方案简单,但无法保证彻底解决。强制走主库。底层服务提供方需要注意,强制走主库的逻辑要收口,主库不能被拉挂。 收口的意思是只是部分的appkey允许走主库?需要告知提供方走主库的需求
水平越权 业务逻辑 如果未进行数据权限校验,则可能会出现A用户能看到B用户数据的场景,会造成严重的数据泄漏。如订单详情页把订单ID参数改一下,就可以看到别人的订单。 数据泄漏 所有私密数据的访问,都需要做水平越权防护,而且用来校验的ID来源一定要是前端Token解析出来的,而不是直接传的。 根据id查询用户信息、poi信息等隐私数据时,不能根据前端传递来的参数就直接rpc查询,需要向kms申请权限校验。即获取司机手机号,获取的加密后的token。需要解密才能拿到具体的手机号
表情符号支持 数据库 如果数据库charset为utf8,则不支持字符串中的表情符号 插入数据失败 数据库charset改为utf8mb4。插入数据库时做过滤。
长度截断 数据库 备注之类的字符串字段,一般建表语句会限制长度,偶尔有某些数据超过了长度限制,插入时会被截断。虽然可能有些业务前端会做一些拦截,但并不能保证所有的地方都会有。 数据丢失 建表时字段选长点,但该方法不能真正完全解决问题。插入数据前手工数据截断,但数据一致性要求不高,但数据不能丢的场景适用,如插入新客资。接口进来时检查长度,过长向前端提示错误。无论何种处理方法,都不应该有数据库截断异常抛出来。 1.字段设计的时候,长度要限制住2.接口进来时检查长度,过长向前端提示错误区别list过大,插入数据库存在性能问题,需要list.partion截断
Limit深分页 数据库 全量向外部同步数据的场景,有时会写代码根据查询条件并limit,但如果limit到最后可能会出现慢查询。 慢查询 不要使用limit,使用主键,每次查询的时候都主键id>上次返回的主键id即可。 criteria.andIdGreaterThan*(id)*
消息重复 消息组件 一般的消息中间件,比如Kafka,会保证消息的必达性,但不会保证消息的唯一性,有可能消息会被重复消费。 脏数据逻辑重复执行 底层接口支持幂等。这个要注意,但凡是监听消息做某事的,逻辑一定要能幂等。 使用分布式redi将key比如orderId记录在redis中实现幂等疑惑:分布式系统,redis存入了,别的微服务能拿到对应的key-val么
MapiGet重复请求 前端相关 mapi接口如果是Get请求,客户端如果请求超时的话会发起重复请求的,这样后端可能就会连续收到两次请求,导致重复处理。 逻辑重复执行 写逻辑使用Post协议,否则一定要考虑好幂等问题。
强流程型业务中断无重试 业务逻辑 审核等强流程型的业务,中间某一步执行失败无重试、告警、定时扫描等处理,导致失败的流程永远无法再执行,如一直处于审核中。 业务流程问题,引起ASK 强流程型业务失败接入Redo重试。流程失败时打告警。定时扫描失败的业务数据,如超期审核中的数据。 1.可以将失败的key发送至队列中,定时消费一下2.swan异步重试机制
链接配置HTTPS 前端相关 目前iOS限制链接都要为HTTPS,且公司各平台也都支持了HTTPS,在各种地方配置链接,如前端页面链接、触达跳转链接、推送订单中心链接等,都要配置HTTPS而不是HTTP。 全业务不可用,页面打不开 配置场景的链接一定要为HTTPS,如果一定要走HTTP,要有充足的理由并且要做说明。
类静态变量不要被修改 代码相关 有时我们会在Bean里面定义一些做为常量使用的静态变量,该静态变量如果是个对象,而业务代码中去修改该对象的内容,会导致不同请求的内容串掉。 业务脏数据 静态变量不要被修改。静态变量一般应该是基础类型,对象类型的可以考虑每次new一个。 共享变量只能读,不要写
重复数据提交 并发控制 分布式场景,添加数据时,如果依赖查询是否有数据然后在做业务逻辑,比如插入,预约频次限制,强走主库没有作用,需要分布式锁控制,数据锁等手段 业务脏数据 大流量分布式锁做校验(推荐)小流量,影响数据行数少的情况,数据库锁一些场景采用重复提交校验组件 1.小流量使用乐观锁2.大流量使用redis分布式锁、zk分布式锁(t1、t2查询发送给供应商的消息时候都不存在,所有都可以执行insert,t1执行了insert,t2执行相同的insert语句的时候会抛出异常么?)
事务提交(写场景) 高并发 同一个逻辑代码,如果采用了事务,事务存在先查后做逻辑判断的场景,高并发情况下需要考虑事务的可见性,未提交的事务在例外一个机器上是不可见的。由于不可见可能导致重复插入,逻辑判断错误等异常情况 业务脏数据 1.队列技术,kafka 按照ID 路由同一个partition,消费单线程处理(同一个供应商的msg,发送到同一个partion中,有序的消费)2.分布式控制3.数据库排他锁
关键业务异常,增加异常处理重试 可用性 如果触达或者客资服务突然完全不可用了,是否有最快的办法解决丢失的流量,回放流量问题 服务异常时间过长,服务不可用 1.方案设计可以采用WAH 思路,先记录消息。比如kafaka 消息等形式。
SimpleDateFormat 非线程安全 代码相关 不要在多线程情况下用SimpleDataFormat ,容易导致异常 业务异常 1.线程新建,不要共享此变量2.使用LocalDateTime工具类。 使用LocalDate类
SimpleDateFormat格式化错误 代码相关 格式化YYYY是指基于周的年,所以2020-12-31这一天所在的周已经是2021年,所以使用YYYY-MM-dd格式化的时候会变成2021-12-31,这个只有一年最后一周才可能会出问题,极其隐蔽。另外DD指的是一年中的第几天,dd指的是一月中的第几天 业务异常 一般情况下应该使用yyyy及dd,不要使用大写的。LocalDateTime,放弃老式时间格式化类 使用LocalDate类
时间边界问题 代码相关 前端向后端传的筛选条件如果为时间类型,比如按日期筛选订单,则可能只传了2021-01-01及2021-01-10,后端如果直接将OrderDate与这两个时间判断,可能2021-01-10的数据就筛选不出来。 业务异常 最后一天的日期在转化为时间戳时,要转化为当天的23:59:59,而不是00:00:00 01-01 00:00:00 - 01-02 00:00:0001-09 00:00:00 -01-10 00:00:0001-10 00:00:00 - 01-11 00:00:00这样10的数据也能覆盖
价格数据类型 代码相关 1.使用浮点表示价格会有精度问题。2.使用整型表示价格,单位要统一,否则有些为元,有些分分,不对齐可能会有单位错误。 资损 统一使用整型,以分为单位,上下游接口沟通注意对齐。 1元 = 100分1.2元 = 120分遇到时,具体内容要学习他人代码或网上搜一下
MySQL updatetime字段 数据库、代码相关 建表的时候必须设置该字段,并且设置更新赋值。同时,再做变更时注意updatetime字段会被同步更新。 排查问题时为了缩小范围,往往会有updatetime字段进行限制,如果没有更新会影响排查过程。 建表的时候指定更新时变更更新数据时,保证updatetime字段被更新 updatetime字段的类型要注意 change_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
相关推荐
DieSnowK4 天前
[Redis][事务]详细讲解
数据库·redis·缓存·事务·redis事务·新手向·事务操作
砖业洋__10 天前
Spring高手之路24——事务类型及传播行为实战指南
java·spring·事务·nested·事务传播行为
极客先躯10 天前
高级java每日一道面试题-2024年9月15日-架构篇[分布式篇]-如何在分布式系统中实现事务?
java·数据库·分布式·面试·架构·事务·分布式篇
王彬泽10 天前
【RabbitMQ】消息分发、事务
rabbitmq·事务·消息分发
问老大2 个月前
MySQL学习2之事务ACID特性以及实现机制
数据库·学习·mysql·事务·acid
马剑威(威哥爱编程)2 个月前
分布式事务Seata的4种模式详解
java·分布式·spring cloud·事务·seata·威哥爱编程
相忘于江湖-mfc2 个月前
SQLite批量INSERT
数据库·sqlite·事务·批量插入
装不满的克莱因瓶2 个月前
Spring @Transactional事务传播行为详解
java·后端·spring·系统架构·springboot·事务·事务传播行为
_错错错2 个月前
MySQL 事务
数据库·mysql·事务
jupiter_8883 个月前
spring tx @Transactional 详解 `Advisor`、`Target`、`ProxyFactory
spring·事务·aop