线上崩了?一招教你快速定位问题。

news2024/11/24 9:58:16

👏 背景

正浏览着下班后去哪家店撸串,结果隔壁组同事囧着脸过来问我:大哥,赶紧过去帮忙看个问题!客户反馈很多次了,一直找不出问题出在哪里!!!

我:能不能有点周五的样子!你小子耽误我下班啊!!

过去简单的了解一下,据说是个历史遗留问题,极难复现!

  • 后端同学:数据绝对没问题,都仔细校对过了!😳😳
  • 前端同学:线上报错信息啥也看不出来,我本地是好的!要不你们再试试?🤔🤔
  • 测试同学:复现纯靠缘分!😰😰

我:这么说看来是有鬼了,要不你们在座位上摆个香炉烧根香?

坐下后我一顿操作猛如虎,五分钟后就定位出了问题,老板在知晓这件事后:

😥 背后原因分析

思考这背后的原因,根本在于是大家不知道怎么调试线上问题,都是靠猜。猜对了皆大欢喜,猜错了换个方向继续猜,直到陷入怀疑自我的情绪中......

今天借此机会,我决定祭出独门绝技,教大家一招 bug 定位消失术!彻底摆脱线上问题恐惧症!

说回正题

线上问题大致可以分两类:一类是接口数据导致的另一类是数据正常,前端哪里疏忽了导致的

  • 数据不同:本地更多的是用的测试环境的数据,而线上用的真实环境的数据。不同数据,页面的渲染以及交互可能不同;
  • 代码疏忽:可能是某些场景的边界情况没有处理好,再或者是未做容错降级处理等;

💁 模拟线上环境

文中所涉及到的代码均放到个人 github 仓库中:github.com/noBaldAaa/o…

通过 create-react-app 初始化一个项目(你也可以用 vue-cli,都一样):

npx create-react-app my-app --template typescript
复制代码

接着在控制台运行 yarn eject,把 Webpack 的配置暴露出来(用其他构建工具也一样,这里以 Webpack 为例),此时项目目录结构:

├── build # 打包后的文件夹
├── config # webpack配置信息
|    └── webpack.config.js
├── node_modules
├── public
├── package-lock.json
├── package.json
└── src # 源码目录
     └── index.tsx
复制代码

在 index.tsx 中写一段错误的代码模拟报错:

import React, { useEffect } from "react";
import ReactDOM from "react-dom/client";

function App() {
  const obj: any = {
    author: "不要秃头啊",
  };
  useEffect(() => {
    //报错代码在这里!!!!!!!!!!!
    obj.abc.map((item: any) => item === "1111");
  });
  return (
    <div className="App">
      <h1>hello world</h1>
    </div>
  );
}

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
复制代码

模拟生产环境打包,修改 config/webpack.config.js 中的配置:

   mode: "production",
   devtool: false,
复制代码
  • mode: "production" 表示采用生产模式打包,会启用代码压缩等插件
  • devtool: false 表示不生成 source-map文件

接着在控制台运行 yarn build 命令,生成打包后的文件:/build

为了模拟线上,这里用一个第三方库:http-server,根据官方介绍:它是是一个简单的、零配置的命令行静态 HTTP 服务器。下面是官方介绍图,确实挺形象......

该说不说,确实很简单,这点没吹牛比👍,一行代码就可以起一个静态的 HTTP 服务器:

npx http-server ./build
复制代码

点击静态服务器地址,打开页面发现确实报错了:

所有代码都被压缩成了一行,确实啥都看不出来。

💣 小型必杀技

上面我们提到,本地没问题,线上有问题,一部分原因就是因为后端数据有问题,这里先祭出一个小型必杀技:Ajax Interceptor。

它是一个谷歌插件,可以拦截页面上的 Ajax 请求,并把返回结果替换成任意文本。这对 mock 数据、排查线上问题 来说简直就是神器!!!

Charles 等抓包软在它面前就是个弟弟(我没有侮辱 Charles 的意思,大家各有长处)。当我知道了这个插件之后,才发现以前的操作都花里胡哨的!!!

示范一下,把我的掘金等级改成 8 级,掘力值和关注者加几个 999,这不过分吧!

此处 @掘金运营 @优弧,叫你们开发来改 bug 啦,这小子数据已经爆表了。

使用方式:

(1)点击插件图标

(2)把你想要修改的接口 URL 地址复制到输入框中,然后把返回的内容放到下面的文本框

拍了个视频教程:

友情提示:不需要用的时候别忘记关掉!!!要不然有可能分析半天,最后发现忘关插件了......

🚀 终极必杀技

上面那个小工具可以解决大部分场景的问题,但万一不是后端数据的问题,是我们自己的问题呢? 

这个时候再说:我本地是好的,你再试试?

此时老板要拿刀过来了......

回归本质,线上不能定位到问题的原因是什么?不就是因为生产环境没有生成和上传 source-map 文件吗!!

那我们直接给线上环境添加上 source-map 文件不就可以了吗?

部分心急的同学请你把刀放下,我并不是说在生产环境上传 source-map 文件。

我的意思是:生产环境 + 本地的 source-map 文件

这里偷偷告诉大家一个小秘密(99%的人都不知道,勿外传):谷歌浏览器的 Sources 面板支持右键添加 source-map

有了方案后,现在只需把生产环境的代码按照如下配置在本地重新打包:

 output:{  path: path.resolve(__dirname, "build2") } //原build文件夹在模拟线上环境,这里改成build2防止影响之前的服务
 devtool:"source-map"
复制代码

然后用 http-server 起一个静态服务:

npx http-server ./build2
复制代码

拿到 source-map 的文件链接添加到浏览器中:

操作视频:

这是添加前的效果:

这是添加后的效果:

堆栈信息一目了然,一下就能看到是哪个文件下的哪行代码出了问题!

👋 总结

本文从一个团队小故事出发,详细讲述了当前端开发者遇到线上问题时的囧境。从以下两个场景剖析,给出了对应的解决方案:

  • 数据不同导致出错:在本地环境下使用 Ajax Interceptor 来模拟线上数据;
  • 代码疏忽导致出错:直接在线上环境添加 source-map 链接来定位问题;

什么?这两个方案还不够?这已经是我知道的最简单的方式啦!!我已经把我知道的全说了😭😭😭

什么?你们项目里集成了 sentry 等监控系统?那就当我没说!我闭嘴了!

什么?......

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用WPS功能破解及本地恢复密码

利用WPS功能破解及本地恢复密码 认识WPS功能 ​ WPS&#xff08;Wi-Fi Protected Setup&#xff09;是Wi-Fi保护设置的英文缩写。WPS是由Wi-Fi联盟组织实施的认证项目&#xff0c;主要致力于简化无线局域网安装及安全性能的配置工作。WPS并不是一项新增的安全性能&#xff0c;它…

数据结构之链表(单链表)

文章目录前言一、链表二、链表的八种结构1.单向或者双向2.带头或者不带头&#xff08;头&#xff1a;哨兵位&#xff09;3.循环或者不循环三、单链表1.接口2.接口的实现1.开辟一个新的节点1.打印单链表2.头插3.尾插4.头删5.尾删6.单链表的查找7.在pos位置之前插入数据8.在pos位…

MySQL8.0概述及新特性

文章目录学习资料常见的数据库管理系统排名&#xff08;DBMS&#xff09;SQL的分类DDL&#xff1a;数据定义语言DML&#xff1a;数据操作语言DCL&#xff1a;数据控制语言MySQL8.0新特性性能优化默认字符集DDL的原子化计算列宽度属性窗口函数公用表表达式索引新特性支持降序索引…

面试了20+前端大厂,整理出的面试题

事件是什么&#xff1f;事件模型&#xff1f; 事件是用户操作网页时发生的交互动作&#xff0c;比如 click/move&#xff0c; 事件除了用户触发的动作外&#xff0c;还可以是文档加载&#xff0c;窗口滚动和大小调整。事件被封装成一个 event 对象&#xff0c;包含了该事件发生…

RabbitMQ Windows 安装、配置、使用 - 小白教程

1、配套文件 下载erlang&#xff1a;http://www.erlang.org/downloads/ 下载RabbitMQ&#xff1a;http://www.rabbitmq.com/download.html 2、RabbitMQ服务端代码是使用并发式语言Erlang编写的&#xff0c;安装Rabbit MQ的前提是安装Erlang&#xff0c;双击otp_win64_21.1.ex…

计算机毕业设计springboot+vue+elementUI汽车车辆充电桩管理系统

项目介绍 随着我国汽车行业的不断发展&#xff0c;电动汽车已经开始逐步的领导整个汽车行业&#xff0c;越来越多的人在追求环保和经济实惠的同时开始使用电动汽车&#xff0c;电动汽车和燃油汽车最大的而不同就是 需要充电&#xff0c;同时我国的基础充电桩也开始遍及了大多数…

Java 异常处理

目录 一、异常的基本概念 二 、为何需要异常处理 三 、异常的处理 四 、异常类的继承架构 五 、抛出异常 5.1、程序中抛出异常 5.2、指定方法抛出异常 六 、自定义异常 不管使用的那种语言进行程序设计&#xff0c;都会产生各种各样的错误。 Java 提供有强大的异常处理…

商业银行普惠金融可持续发展综合能力呈现梯队化,专项领域各有所长

易观分析&#xff1a;普惠金融有别于传统的金融体系&#xff0c;强调构建包容性、公平性的金融服务生态&#xff0c;商业银行提升可持续发展的综合能力需关注五个方面的因素&#xff1a;获客能力上以普惠客群的金融需求为锚点&#xff0c;增强银行服务生态的多样性&#xff0c;…

罗正雄:基于展开交替优化的盲超分算法DAN

SFFAI 90—超分辨率专题《罗正雄&#xff1a;基于展开交替优化的盲超分算法》 退化表达式为&#xff1a; 盲超分就是已知y&#xff0c;求x 这个求解过程可以表示为如下最优化问题&#xff1a;求出使得以下表达式最小的k和x值 盲超分存在的挑战 病态&#xff1a;退化过程会损…

Leetcode 891. 子序列宽度之和

一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。给你一个整数数组 nums &#xff0c;返回 nums 的所有非空 子序列 的 宽度之和 。由于答案可能非常大&#xff0c;请返回对 109 7 取余 后的结果。子序列 定义为从一个数组里删除一些&#xff08;或者不删除&#xf…

基于matlab目标雷达横截面建模(附源码)

目录 一、介绍 二、简单点目标 RCS 三、复杂目标RCS 四、四个散射体组成的目标进行建模 五、具有多个散射体的扩展目标的宽带RCS 六、波动目标RCS 七、偏振目标RCS 八、结论 九、程序 此示例演示如何以不断提高的保真度对雷达目标进行建模。该示例介绍了简单点目标的雷…

MYSQL索引详解和优化

索引的定义 我们在看书的时候&#xff0c;都知道有目录&#xff0c;我们可以通过目录快速的找到书中的内容&#xff0c;而书中的目录就是充当书的索引。在数据库中的索引也是一样的。 索引的定义&#xff1a; 索引是帮助存储引擎快速获取数据的一种数据结构&#xff0c;即数据…

flex设置为1后为什么要设置width为0,和布局超出省略号为什么会超出容器,为什么会没有用

前言 最近在做手机端的页面,制作过程出现了flex布局的一些问题,再次记录在解决办法关于在flex:1的情况下设置为width的效果 如果没有设置width,当内部元素的内容大小超过平均分配的剩余空间时,元素的宽度等于内容大小,如果设置了width并且这个width的大小小于平均分配的剩余空…

[Linux] 如何查看内核 Kernel 版本(查多个Kernel的方法)

上图来源于&#xff1a;turnoff.us&#xff0c;描述了Linux内核结构&#xff0c;有兴趣的同学可以访问原址看看 文章目录什么是Linux内核查看Linux内核Kernel的场景情况查看 Kernel 的几种方式1、使用 uname2、使用 hostnamectl 命令3、查看 /proc/version4、使用 rpm 命令5、使…

2.9 场景式文案,原来是这样子写的【玩赚小红书】

人的生活&#xff0c;就是一个场景连着另一个场景&#xff0c;循环往复&#xff0c;朝朝暮暮。 文案&#xff0c;只要切入了用户的场景&#xff0c;就可以切入他的生活&#xff0c;进而切入他的心。 什么是「 场景化文案」 &#xff1f;可以看一组对比&#xff1a; 非场景文…

Tomcat的概述、部署、优化

文章目录一、Tomcat概述1、Tomcat的概念2、Tomcat的核心组件3、Java Servlet 的概念4、JSP的概念5、Tomcat顶层架构6、Container 结构分析:7、Tomcat请求过程二、Tomcat服务部署1、Tomcat服务部署的步骤1.1 关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下1.2 安…

C语言第十课(上):编写井字棋游戏(综合练习1)

目录 前言&#xff1a; 一、文件建立&#xff1a; 1.头文件game.h&#xff1a; 2.函数定义文件game.c&#xff1a; 3.工程测试文件test.c&#xff1a; 二、编写井字棋游戏&#xff1a; 1.程序整体执行思路&#xff1a; 2.menu菜单函数实现&#xff1a; 3.game游戏函数逻辑&am…

Linux环境下基于VSCode和CMake实现C/C++开发

layout: post title: Linux环境下基于VSCode和CMake实现C/C开发 description: Linux环境下基于VSCode和CMake实现C/C开发 tag: 开发工具 文章目录Linux开发环境Linux目录结构常用指令选项ls&#xff1a;list directory contentscd&#xff1a;change directorytouch&#xff1a…

【附源码】计算机毕业设计JAVA校园讲座管理

【附源码】计算机毕业设计JAVA校园讲座管理 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA mybati…

linux驱动之mmap地址映射

应用场景 首先在linux中应用程序无法是直接访问驱动程序的数据的, 需要通过 copy_to_user 和 copy_from_user才能实现数据传输, 那么数据量大了以后如LCD的数据, 那么就会有很长的耗时, 为了解决这一问题, 引入mmap, 将底层物理地址映射出来, 让应用程序得以直接读写这一块内存…