这是一篇我职业生涯总结的 OpenIM 故障排查指南

如果你想在寻找一篇针对 OpenIM 并且准备好具体的问题想来这里找到答案的话。那么很遗憾的告诉你,这篇并不是记录问题和编写答案的,这篇是读者经过开发和业务实战中以 OpenIM 为例总结出来的故障排查的方法,以及调试的技巧。如果你想从我这里学习到故障的排查以及问题定位的经验,那么请你继续读下去。 我将会从工作中经常出现的一些情况总结成类型来分析。 一个小小的玩笑,或许我比较逆人性,其他人都很害怕遇到 bug 的时候,我倒是对出现 bug 比较兴奋,我们后期读代码的时间和维护代码的时间其实是远远高于写代码的时间的。所以面对 bug, 我们的思考和总结尤其是非常重要,尤其是帮我们在写代码的时候也思考,代码的扩展性,和错误处理,是否可以禁得起考验 ~ 故障排查的基本概念 故障排查,我主要是分为几种情况,分别是,编译的故障排查,启动的故障排查,以及服务运行故障排查。这几种情况的故障排查思路都是大同小异的。 首先,我们需要发现问题,然后定位问题。我们可能需要经过多轮分析排查才能定位到问题的根因,最后去解决问题。排障流程如下图所示: 开始 | V 发现问题 ------> 记录问题的症状和相关情况 | V 定位问题 | V 进行初步分析 --------> 确定可能的原因 | | V | 是否需要深入分析?-----> 是 ------> 进行深入分析 | | | | | V | | 确定具体原因 | | | | | V | <-------- 是否已找到根本原因? | | | 否 | V 是否解决了问题? | 是 ------> 记录解决过程和解决方案 | | 否 ------> 调整策略或寻求帮助 | V 结束 如果想排查问题并解决问题,你还需要具备以下两个基本能力: 能够找到组件日志,并理解错误日志的内容; 根据错误日志,找出解决方案。 发现问题 要排查问题,我们首先要发现问题,我们通常用下面这几种方式来发现问题: 代码审查:在开发过程中进行代码审查可以发现代码中的问题和潜在的错误; 安全审计:通过安全审计可以发现软件或系统中的安全漏洞和风险; 服务状态检查:可以通过检查服务的运行状态,来发现问题。例如:如果是 linux-system 模式部署 openim,那么启动 openim-api 服务后,执行 ``systemctl status openim-api 发现 openim-api 启动失败,即 Active 的值不为 active (running)`; 代码测试:通过进行各种类型的测试,如单元测试(util-test)、集成测试(api-test)、系统测试(e2e-test)等,可以发现软件或系统中的问题。例如:访问 openim-api 服务,发现接口返回异常错误码、接口值返回不对等; 自动化测试:我们也可以通过运行自动化测试,来帮助我们快速发现问题; 日志记录:在服务或接口异常时,我们需要排查日志。通过在日志中发现一些 WARN、ERRORV、PANIC、FATAL 等级别的错误日志来发现问题; 监控告警:通过监控指标、告警等,也可以发现问题。如果通过日志,能发现已经发生的问题,通过监控,还可以发现一些潜在的问题; 用户反馈:产品或功能发布后,用户在使用过程中,也可能会发现一些问题,并将问题反馈给开发人员。 上面发现问题的途径多种多样,有些发现问题的途径,通常发生在特定的软件阶段,例如:测试阶段,我们可以通过测试、质量保障团队来发现问题。产品发布后,可以通过用户反馈来发现问题。 ...

四月 16, 2024 · 8 分钟 · 1504 字 · 熊鑫伟,我
Go 调试和 dlv 工具学习

Go 调试测试以及调试工具 dlv 学习

调试Go工程 ::: tip prepare: vscode golang 1.92 ::: demo go mod init test In main.go file package main import ( "fmt" ) // Swap functions func swap(x, y *string) (string, string) { //XOR exchange *x, *y = *y, *x } func main() { fmt.Println("Hello, world!") //Swap functions for i := 0; i < 10; i++ { a := "a" b := "b" swap(&a, &b) fmt.Println(a, b) } } vscode一键生成测试 >gotest for package/function ::: tip 分别是为包生成测试单元,为函数生成测试单元。 ::: 生成如下: package main import ( "testing" ) func Test_main(t *testing.T) { tests := []struct { name string }{ // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { main() }) } } func Test_swap(t *testing.T) { type args struct { x *string y *string } tests := []struct { name string args args want string want1 string }{ // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, got1 := swap(tt.args.x, tt.args.y) if got != tt.want { t.Errorf("swap() got = %v, want %v", got, tt.want) } if got1 != tt.want1 { t.Errorf("swap() got1 = %v, want %v", got1, tt.want1) } }) } } 我们在 TODO: Add test cases. 那边给出测试就好了: ...

六月 19, 2023 · 10 分钟 · 1939 字 · 熊鑫伟,我