常见问题归类
逻辑缺陷:例如NPE、死循环、边界情况未覆盖(校验不全,幂等未处理、数据一致性未保证等)。
性能瓶颈:例如接口RT陡增、吞吐率上不去。
内存异常:例如OOM、内存泄露、频繁FGC、GC卡顿。
并发/分布式:例如存在竞争条件、时钟不同步。
数据问题:例如出现脏数据、序列化失败。
安全问题:例如DDoS攻击、数据泄露、敏感数据未加密等。
环境故障:例如宿主机宕机、网络不通、丢包。(8)操作失误:例如配置推错(jar包推错环境、jone/jdos覆盖文件不同步等)、删库跑路。
排查流程
快速止血
发布问题:回滚
部分机器:隔离
入口流量:流控
下游依赖:降级
资源问题:重启
保留现场
应用、中间件日志
GC、内核日志
线程、堆栈Dump
堆内存映射Dump
监控、Metrics数据
定位原因
关联近期变更
全链路追踪分析
还原事件时间线
找到根本原因
尝试复现
解决问题
修复走流程:回归、灰度
修复后验证:对比、回归
故障复盘:找到根本解、避免再发生
性能优化—指标&分析&原则
指标&分析&原则性能优化—优化手段
简化:业务层面(流程精简、需求简化)、编码层面(循环内减少高开销操作)、架构层面(减少没必要的抽象/分层)、数据层面(数据清洗、提取、聚合);
并行:单机并行(多线程)、多机并行(分布式),充分利用机器资源,不好的一点会造成同步开销、线程开销、数据倾斜。
异步:消息队列+任务线程+通知机制,好处是提升吞吐量、组件解耦、削峰填谷,缺点是排队延迟。
批量:多次单一操作—>合并为单次批量操作,好处是能避免单次操作的固有开销,均摊后总开销更低,缺点是等待延迟+聚合延迟,比如DB批量读写。
时间空间互换:空间换时间,可以避免重复计算、拉近传输距离、分流减少压力,比如缓存、CDN、索引、只读副本,时间换空间有时候也能达到“更快”的效果(数据量减少——》传输时间减少),比如数据压缩传输。
数据结构与算法优化:多了解数据结构和一些简单的算法思想(递归、分治、贪心、动态规划)。
池化&局部化:池化:减少资源创建和销毁开销,比如线程池、内存池、DB连接池等;局部化:避免共享资源竞争开销,比如多级缓存(本地局部缓存——》共享全局缓存;
更多优化手段: SQL优化,超时降级,数据更新避免流量高峰期等。
稳定性优化—指标&测量&原则
稳定性优化—指标&测量&原则稳定性优化—优化手段
避免单点:集群部署、数据副本、多机房容灾,需要具备故障转移的能力;
流控/限流:避免意料之外的突增流量,粒度:接口级,用户级,全局,类型:QRS流控、并发度流控;工具:nginx,反爬,Hystrix等;
熔断:防止连锁故障(雪崩效应),止损,工具:ppfb(Hystrix)4.降级:流控、熔断、负载过高时触发。常见降级方式:关闭非核心功能,停止应用日志打印;牺牲数据时效性:返回缓存中旧数据;牺牲数据精确性,降低数据采集频率,返回托底数据等。
超时/重试:超时:设置超时时间,避免调用端长时间等待,造成阻塞;重试:jsf重试,mq重试,但是确保重试操作的幂等性;
资源设限:防止资源被异常流量耗尽,保护资源,使用一些资源池化、有界对列方式,比如线程、队列、DB连接会设置池子大小和队列大小;
资源隔离:防止资源被部分异常流量耗尽,采用队列划分、独立集群部署等方式;
安全生产:程序动态性:开关、配置、热升级等,减少开发,实时生效,降低风险;审核机制:代码Review、发布审核;灰度发布;分批部署;上线步骤,回滚预案;
可维护性优化—可维护性优化
衡量指标:
1.复杂度:是否可控?编码:简洁度、命名一致性、代码行数等;架构:组件耦合度、层次清晰度、职责单一性等。
2.可扩展性:是否易于变更?需要变更代码或配置时,是否简单优雅、不易出错。
3.可运维性:是否方便运维?日志、监控是否完善;部署、扩容是否容易。
4.重要性:整个软件的生命周期:维护周期远远大于开发周期;破窗效应、熵增定律:可维护性会趋向于越来越差;遗留系统的危害:理解难度,修改成本,变更风险;陷入不断踩坑、填坑、又挖坑的循环,所以可维护性是非常非常重要的。
优化原则:遵循KISS原则、DRY原则、各种代码可读性和架构设计原则等,避免引入过多临时性、Hack代码;认为功能能跑起来就OK,欠下一堆技术债,而我们要记住出来混迟早是要还的,产生上述大大小小的问题、救火。
优化手段:
1.遵循编码规范;
2.代码重构:当发现代码不规范、难以维护、性能差等等时进行重构,小步迭代、回归验证;但是是重构还是重写:综合考虑成本、风险、并行版本维护等因素,选择适合自己的;
3.数据驱动:系统数据:监控覆盖广,对于理解系统、排查问题至关重要;业务数据:一致性校验、旧数据清理、归档等。
4.技术演进:对于一种技术架构,是死守阵地,还是跟随新潮流,综合评估风险、生产力、学习成本。
网友评论