性能问题诊断
背景
单点操作功能,如单据打开、点击按钮操作卡顿,如果只看日志,很难能定位到问题。如果卡顿较明显,可以使用堆栈查询功能进行分析
monitor站点: https://域名/monitor/
使用堆栈查询(集群范围)或找到指定节点打开线程堆栈
按照功能的关键字或traceId找到可疑线程,traceId可通过浏览器network获取请求参数得到
每隔几秒刷新,另存网页信息保留堆栈,关注:
DB次数,大量访问数据库通常是在循环取数,需要修改为批量查询
Redis次数,大量存取缓存也会产生性能问题,需要优化减少查询次数或增加本地线程缓存减少对Redis压力
如果堆栈并未卡在Redis、DB等IO操作,关注高频出现的堆栈点,排查可能存在的代码死循环
根据traceid,查询日志,排查可能存在的慢查询sql
接口设计上,必须优先定义批量接口:即使暂时不提供批量处理逻辑,也要先定义好接口,为日后优化提供空间,避免调用方改代码。 批量处理可以节省大量公共数据的准备时间
补充知识点 BusinessDataServiceHelper/QueryServiceHelper
*BusinessDataServiceHelper.loadSingle 取单据推荐
实时读取数据库,传入pk不存在时,会中断
输出单条符合单据结构的数据包,可以修改后调用save保存入库
不方便取单据体字段值、基础资料下级属性值
*BusinessDataServiceHelper.loadSingleFromCache 取基础资料推荐
优先从缓存中读取,缓存没有则实时取数据库,并压入缓存
读取的数据包,经过缓存处理,少了状态信息,不能调用save保存入库
数据保存会自动刷新缓存,不需担心缓存取的是旧数据
*BusinessDataServiceHelper.load 取单据推荐
先根据条件取pks,再根据pks实时取数
没有符合条件数据时返回空集合,不报错
*BusinessDataServiceHelper.loadFromCache 取基础资料推荐
先到缓存中取条件对应的pks,再使用pks到缓存中取数据包
条件和数据包都压入缓存
保存数据时会自动刷新数据缓存,清除条件缓存
*QueryServiceHelper.query 返回拉平的数据包,方便取单据体字段、基础资料属性值
输出的DynamicObject和单据实体结构不同,不能save
*QueryServiceHelper.queryOne 返回第一条符合条件的数据,没有符合条件的数据返回null
数据结构同query,不能save
*QueryServiceHelper.queryDataSet
流式取数,性能最快
返回拉平的数据行,方便取单据体字段、基础资料属性值
需要使用try (DataSet ds xxx){} 包起,确保取完数据后及时关闭数据库连接
服务 | 适用场景 | 缓存 | 数据结构 | 能否保存 |
BusinessDataServiceHelper.loadSingle | 取单张单据 | 单据结构一致 | 能 | |
BusinessDataServiceHelper.loadSingleFromCache | 取单条基础资料 | 有 | 单据结构一致 | 不能 |
BusinessDataServiceHelper.load | 取一批单据 | 单据结构一致 | 能 | |
BusinessDataServiceHelper.loadFromCache | 取一批基础资料 | 有 | 单据结构一致 | 不能 |
QueryServiceHelper.query | 取一批数据 | 拉平 | 不能 | |
QueryServiceHelper.queryOne | 取一行数据 | 拉平 | 不能 | |
QueryServiceHelper.queryDataSet | 取个别字段值 | 拉平 | 不能 |
性能是持续优化的过程,高手也会犯低级错误,共勉 【emoji】
性能问题诊断
本文2024-09-23 00:23:29发表“云苍穹知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-cangqiong-139163.html