后端问题如何快速定位?

在这里插入图片描述
结合自己的工作经验,谈谈问题为什么会产生,已经定位后端问题的一些经验总结。这个只是个人观点,大家有啥补充的请在留言处发言。
01

Bug是如何产生的?

计算机是精确的,而人是非理性的。这是Bug之所以会产生,且一直烧之不尽的本质原因。如果将编程比喻成施咒,一个字符、一个停顿,没有与正确的形式一致,咒语就不会生效。

另外还有一个次要原因:开发目标、所需资源往往都是 由 他人提供的, 程序员很少能够自己控制工作环境和工作目标。

综上,程序员能做的只是不断逼近完美,但是并没有办法将Bug从软件中彻底清除。

02

后端开发的现状在这里插入图片描述
目前,搭建若干套环境是目前技术公司都会采用的方案。这里抽象为开发环境、测试环境、线上环境,三者之间共用一套程序,但是数据是隔离的。

开发环境由开发人员维护,主要用于验证方案,调试程序,变更频繁但是数据单一。由于开发能够直接介入,这个阶段出现的问题往往都能够被很快的解决。开发自测通过后,程序会被发布到测试环境。

测试环境相较于开发环境更加稳定,数据也更接近线上环境。开发收到的问题反馈大量的集中在这一阶段,而且由于不能直接介入,定位与解决问题的难度开始提升。测试人员测试通过后,程序正式向用户发布。

线上环境是直接面向用户的,流量大且请求多样。请求多样意味着正式环境能够暴露前两个阶段未能发现的问题,流量大意味着出现问题往往就会造成重大影响。与测试环境一样不允许开发直接介入,但对于定位问题的速度要求更高。

03

一个请求在哪会出问题?
在这里插入图片描述
一个典型的单点服务模型

单 点服务模型 的优点是运行稳定。 但是运行稳定并不意味着不会出错,如果某次请求产生了意料之外的结果,很大的可能是发生在Service内部或者客户端与服务器交互,极少数情况下发生于Nginx、DB以及其他系统之间的交互。

单 点服务模型 的缺点也很明显,就是容易遇到性能瓶颈 。优化性能的措施有很多,比如DB的读写分离、引入缓存、水平扩展Service、多台服务器DNS轮询等等。但是每引入一项措施,都会损失一部分系统稳定性。优化后的系统相较于单点模型,组件内部及组件之间的出现问题的可能性均在增加。

04

如何快速定位问题?
在这里插入图片描述
还记得初中学到的如何做实验吗?

定位问题也遵循上面的流程。 知道了为什么 会出现问题,以及 在哪会经常出现问题 之后 ,遇到问题 ,就可以 根据 问题表现 做到有的放矢。

我自己建了个群,对 JAVA 开发有兴趣的朋友欢迎加入QQ群:322708204 进行技术讨论,里面资深架构师会分享一些整理好的BATJ面试题:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。

一、 客户端到服务器之间的问题
在这里插入图片描述
客户端到服务器之间问题因为牵扯到请求消息内容、网络环境等因素,往往需要引入工具来帮助定位。

• 如果怀疑网络不通, ping/telnet命令 能够很快速的判断客户端与服务器之间的网络是否正常。

• 浏览器的 开发者工具(F12) 是快速定位网页问题的利器。

• APP与服务器之间的交互往往都是API, Postman 除了支持主流的Restful,最近的版本也引入了对Graph的支持。

• Pc所有的网络流量在 Wireshark 面前都无所遁形。

• 手机请求不能像浏览器一样容易抓包,HTTP抓包利器 Fiddler 的代理模式值得一试。

二、
在这里插入图片描述
服务器内部问题不同客户端的地方在于不可见,无法像客户端一样通过引入工具可视化的定位问题。此时能够帮助快速定位问题的一是 Shell命令 ,二是 运行日志 。
05

总结

定位问题不要只盯着问题,要多思考问题是怎么来的,问题之间有没有共性,如何才能避免类似问题的发生。

<think> 我们分析前端代码中两个关键调用:`$.dm.op`和`$.dm.getList`,这两个调用都通过`oid`指定了后端操作。根据后端代码,我们已知`ACT_LTE_UPDATE_CELLINFO`对应后端函数`rsl_lte_update_cellinfo`。另一个`oid`为`DEV2_X_TP_SIGNAL_TEST`的`getList`操作,虽然没有直接给出后端代码,但我们可以根据命名和上下文推测其功能。 ### 1. `$.dm.op({oid: 'ACT_LTE_UPDATE_CELLINFO', ...})` 对应的后端操作 - **前端调用**:`$.dm.op` 通常表示执行一个操作(operation),这里指定`oid`为`'ACT_LTE_UPDATE_CELLINFO'`。 - **后端映射**:根据提供的后端代码片段: ```c {rsl_lte_update_cellinfo, ACT_LTE_UPDATE_CELLINFO}, ``` 这个映射表明,当`oid`为`ACT_LTE_UPDATE_CELLINFO`时,后端会执行函数`rsl_lte_update_cellinfo`。 - **函数功能**:从函数名和代码逻辑看,`rsl_lte_update_cellinfo`的作用是更新小区信息(Update Cell Info)。具体来说: - 它调用`UpdateCellInfo(&ret)`函数,并检查返回值。 - 如果更新失败(返回非`MP_ERR_SUCCESS`),则记录错误日志。 - 返回操作结果(`ret`)。 - **执行目的**:在用户点击搜索时,前端首先调用此操作来更新当前的基站小区信息,确保获取的信号数据是最新的。 ### 2. `$.dm.getList({oid: 'DEV2_X_TP_SIGNAL_TEST', ...})` 对应的后端操作 - **前端调用**:`$.dm.getList` 通常用于获取数据列表,这里指定`oid`为`'DEV2_X_TP_SIGNAL_TEST'`。 - **后端映射**:虽然未直接给出映射,但从命名规则推测: - `DEV2_X_TP_SIGNAL_TEST` 可能对应后端一个查询信号测试数据的函数(如`rsl_dev2_x_tp_signal_test`或类似)。 - **函数功能推测**: - 根据`oid`名称,它可能从设备(DEV2)的测试点(TP)获取信号测试(SIGNAL_TEST)的历史记录。 - 返回的数据是一个列表(List),每条记录包含信号测试的各个字段(如信号强度、时间戳等)。 - **执行流程**: 1. 前端在`ACT_LTE_UPDATE_CELLINFO`的`success`回调中调用此操作。 2. 获取到的数据(`data`)被过滤,排除`id=0`的记录(`signalHistory = data.filter(...)`)。 3. 按时间戳排序后取最新一条记录(`lastRecord`),传递给`finishMeasureSignal`处理。 ### 前后端交互流程总结 用户点击搜索按钮后,前端按以下顺序触发后端操作: ```mermaid sequenceDiagram participant 前端 participant 后端 前端->>后端: 调用ACT_LTE_UPDATE_CELLINFO (更新小区信息) 后端-->>前端: 返回更新结果(成功/失败) 前端->>后端: 调用DEV2_X_TP_SIGNAL_TEST (获取信号测试列表) 后端-->>前端: 返回信号测试数据列表 前端->>前端: 处理数据(过滤、排序、取最新记录) 前端->>前端: 执行finishMeasureSignal(lastRecord) ``` ### 问题分析:为什么一直处于“搜索中”? 根据上述流程,可能卡住的环节包括: 1. **更新小区信息失败**:`rsl_lte_update_cellinfo`执行出错(如`UpdateCellInfo`内部失败),但前端未处理`error`回调,导致后续的`getList`未被调用。 2. **获取信号测试列表超时**:`DEV2_X_TP_SIGNAL_TEST`对应的后端函数执行缓慢或阻塞,前端一直等待响应。 3. **数据处理异常**:前端对返回的`data`进行过滤或排序时发生JavaScript错误(如`data`为`undefined`),阻塞后续步骤。 #### 调试建议 - **检查后端日志**:重点查看`rsl_lte_update_cellinfo`的执行日志,确认`UpdateCellInfo`是否成功。 - **验证`getList`调用**:在浏览器开发者工具的Network面板中,查看`DEV2_X_TP_SIGNAL_TEST`请求是否发出,以及响应状态。 - **前端错误捕获**:在`$.dm.op`和`$.dm.getList`中添加`error`回调,例如: ```javascript $.dm.op({ oid: 'ACT_LTE_UPDATE_CELLINFO', callback: { success: function() { /* ... */ }, error: function(xhr, status, error) { console.error("更新小区信息失败:", error); } } }); ``` - **模拟数据测试**:暂时绕过`ACT_LTE_UPDATE_CELLINFO`,直接调用`getList`,验证是否能正常返回数据。 ### 总结 - **`ACT_LTE_UPDATE_CELLINFO`**:触发后端更新基站小区信息,确保数据新鲜度。 - **`DEV2_X_TP_SIGNAL_TEST`**:获取设备信号测试历史数据,用于前端分析。 问题可能源于任一环节的后端执行失败或前端回调缺失。优先检查后端日志和网络请求状态可快速定位。 §§相关问题§§ 1. 如何调试前端未捕获的AJAX错误? 2. 后端函数`UpdateCellInfo`可能遇到哪些常见错误? 3. 如何优化信号测试数据查询的性能? </think>### 前端代码分析:后端执行操作解析 根据您的前端代码,我们分析 `$.dm.op` 和 `$.dm.getList` 这两个关键调用需要后端执行的操作: #### 1. `$.dm.op({oid: 'ACT_LTE_UPDATE_CELLINFO'})` 的后端操作 ```javascript $.dm.op({ oid: 'ACT_LTE_UPDATE_CELLINFO', // ... }); ``` **后端对应操作**: ```c {rsl_lte_update_cellinfo, ACT_LTE_UPDATE_CELLINFO}, CMM_RET rsl_lte_update_cellinfo(void) { CMM_ERR("rsl_lte_update_cellinfo Start!"); MP_Ret ret = MP_ERR_SUCCESS; if (!UpdateCellInfo(&ret) || ret != MP_ERR_SUCCESS) { CMM_ERR("fail to update cell info!"); } return ret; } ``` **后端执行流程**: 1. 记录开始日志:`CMM_ERR("rsl_lte_update_cellinfo Start!");` 2. 调用核心函数:`UpdateCellInfo(&ret)` (实际更新小区信息的函数) 3. 错误处理: - 如果更新失败或返回非成功状态:`CMM_ERR("fail to update cell info!");` 4. 返回操作结果:`return ret;` **功能分析**: - 这是一个 **小区信息更新操作** - 主要功能是刷新基站小区信息(如信号强度、邻区列表等) - 关键函数 `UpdateCellInfo` 完成实际的数据采集和更新 - 返回状态码表示操作结果(成功/失败) #### 2. `$.dm.getList({oid: 'DEV2_X_TP_SIGNAL_TEST'})` 的后端操作 ```javascript $.dm.getList({ oid: 'DEV2_X_TP_SIGNAL_TEST', callback: { success: function (data) { // 处理信号测试数据 } } }); ``` **后端对应操作(推测)**: 虽然未提供具体实现,但根据命名规范可推断: ```c // 伪代码示意 {rsl_dev2_signal_test, DEV2_X_TP_SIGNAL_TEST}, CMM_RET rsl_dev2_signal_test(void) { // 1. 查询设备信号测试数据 signal_data[] = QuerySignalTestData(); // 2. 格式化数据为前端需要的结构 formatted_data = FormatForWeb(signal_data); // 3. 返回数据 return formatted_data; } ``` **后端执行流程**: 1. **数据查询**:从设备(DEV2)读取信号测试数据 - 可能来源:硬件设备接口、数据库存储的历史记录 - 数据内容:信号强度、信噪比、时间戳等指标 2. **数据处理**: ```javascript signalHistory = data.filter(function (record) { return record.id != 0; // 过滤无效记录 }); ``` - 后端可能进行类似的数据清洗 - 排除异常值(如 id=0 的测试记录) 3. **数据排序**: ```javascript var lastRecord = $.sortList(signalHistory, 'timestamp', true)[0]; ``` - 后端可能按时间戳倒序排列 - 返回最新测试记录 #### 完整工作流程 ```mermaid sequenceDiagram participant 前端 participant 后端 前端->>后端: 请求小区信息更新(ACT_LTE_UPDATE_CELLINFO) 后端->>后端: 执行UpdateCellInfo() 后端-->>前端: 返回操作状态 前端->>后端: 请求信号测试数据(DEV2_X_TP_SIGNAL_TEST) 后端->>后端: 查询设备信号数据 后端->>后端: 过滤无效记录(id=0) 后端->>后端: 按时间戳排序 后端-->>前端: 返回最新信号记录 前端->>前端: 执行finishMeasureSignal() ``` #### 问题定位建议 根据您描述的"一直搜索中无法返回结果"问题,建议优先检查: 1. `UpdateCellInfo()` 是否正常返回 2. 信号测试数据查询是否存在阻塞 3. 后端对 `id=0` 记录的过滤逻辑是否导致空数据集 4. 时间戳排序操作是否处理大数据集时性能不足
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值