C++服务开发入门指南
  • 序言
  • 前言
  • 一、一个简单的服务
    • 1 什么是服务
    • 2 服务可以用来做什么
    • 3 简单服务框架
  • 二、网络通信服务框架
    • 1 网络服务的基本概念
    • 2 增加监听端口
    • 3 处理客户端会话
    • 小结
  • 三、添加基础模块
    • 1 日志模块
    • 2 定时器
    • 3 事件机制
    • 4 线程池
    • 5 线程安全
    • 小结
  • 四、一个聊天服务
    • 1 需求描述及分析
    • 2 概要设计
    • 3 创建服务项目
    • 4 ClientUser实现
    • 5 RoomMgr实现
    • 6 ChatRoom实现
    • 7 RoomIDMgr实现
    • 小结
  • 五、测试、迭代及重构
    • 1 测试
    • 2 迭代
    • 3 重构
    • 4 版本号
  • 六、架构设计
    • 1 单点服务
    • 2 分布式服务
  • 七、部署及发布
    • 1 部署环境
    • 2 编译环境
    • 3 部署服务
    • 4 发布服务
  • 八、线上问题处理
    • 1 线上问题
    • 2 问题处理
  • 九、程序员的职业规划
    • 职业规划
Powered by GitBook
On this page
  • 1、回退服务版本
  • 2、回退配置版本
  • 3、重启服务
  • 4、用户补偿
  • 5、提高问题解决效率
  • 6、故障复盘
  • 7、系统优化
  • 8、奖惩措施
  1. 八、线上问题处理

2 问题处理

线上问题的处理原则是:尽量减少经济损失。

因此,故障发生后,需要尽量缩小影响范围,做好用户沟通,降低用户的不满意度。

出现问题后的处理思路大体相同,主要是消除变化带来的影响,下面我们结合实际场景介绍一些常用的处理手段。

1、回退服务版本

发布过程中,比较容易出现问题,此时最优的操作一般是回退版本。

老版本的服务V1.0一直在线上稳定运行,本次迭代发布了V1.1,虽然灰度发布前做了很多测试,但仍无法做到发布时完全不出错。

当发布时出现问题,最好立即回退到稳定版本V1.0,然后再慢慢确认问题原因。

问题修正后,再走验证流程,执行新的发布操作。

除非万不得已,不建议直接在新版本上修复问题,迭代发布。一个是确认问题、修复、打包、验证、发布整个操作下来时间较长,在这段时间内的用户都会受到影响;二是容易忙中出错,上述环节如果执行效果不好,可能会出现没能解决问题的情况,需要再次修改迭代修复。

稳妥起见,先回退,再解决,然后重新发布。

在全网发布时,更应如此,除非能够立即确认,不是代码原因,修改环境配置可以更快解决。

2、回退配置版本

有时候服务稳定运行了一段时间,产品需求,需要调整业务运维的策略,通过调整服务配置可以达到目的。

运维在操作配置的时候,没有按照规范修改,导致业务异常,用户反馈。此时最优的解决方案是回退配置,由运维和开发确认好配置方式,验证后再重新调整线上配置。

后续应该更新维护配置操作文档,避免类似问题重复发生。

3、重启服务

服务稳定运行了一段时间,突然宕机或卡死。

此时,线上服务和配置并没有做任何调整,可能碰到了一些极端情况导致服务异常。

开发人员也不能很快确定异常问题的原因,先将服务重启,恢复基本业务,再继续查询问题并修正,可能是个较好的方案。

毕竟服务已经运行了一段时间,有些问题需要积累才会触发,短时间问题不大。但这类问题需要尽快定位,并提供修复版本,不然容易再次出现。

如果重启后,仍旧频繁宕机,已经无法提供服务,可以考虑先将相关产品下架,再查询问题。此时,解决问题的优先级提到最高。

4、用户补偿

线上业务服务出现问题,必然影响一部分线上用户。

如果对用户造成了经济损失,需要做出相应的补偿,以求得用户的谅解。如用户参与某场比赛交付了报名费,或者用户已经在比赛中取得较好成绩,可以预期获得较好的系统奖励等,却因服务异常蒙受损失。

一个合适的补偿策略,既可以减少公司的经济损失,也能保证用户的满意度,不会因为这些异常而离开平台。

5、提高问题解决效率

我们很难完全杜绝问题的发生,但在问题发生后需要有手段进行快速定位,并能及时修复。

5.1 dump文件

C++服务如果在异常退出的时候,可以产生dump文件,并保存了最后的调用堆栈信息,对解决问题帮助极大。

编译服务文件时,需要保存对应的map和pdb文件,并在代码中加入dump生成需要的捕获函数。当异常发生后,通过dump文件进行调试,查看调用堆栈信息,审查出问题的函数代码。

5.2 日志文件

有些情况无法生成dump文件,或者生成的dump文件是无效的,对定位问题不能产生帮助。这时就需要日志帮助定位问题。

日志记录了服务运行的流程和状态,通过分析问题发生前后的日志内容,可以粗略定位问题大体范围,再结合梳理代码逻辑,确认问题点,修复后验证。

如果日志打印的不够详细,无法从日志中得到有效信息,就需要先完善日志,再尝试复现问题。所以,在开发时期就保留关键的日志信息,是一个好的编程习惯。

5.3 准确描述问题

有时候问题发生后,咨询经验丰富的老员工是解决问题的一个快捷方式。

咨询问题时,能够准确描述问题,是非常重要的。

沟通时要抓住重点,先描述现象再说自己的分析,不要直接拿自己分析出来的问题,去询问解决方案。

解决问题时,要先做一些基础的调查,比如问题发生时间、是否获取日志并看到异常输出、有没有dump文件和调用堆栈等。

不能一出现问题,立即去问人,当别人询问情况时却一问三不知。

5.4 总结问题文集

每次问题解决后,最好都记录下来,就像是记录一个错题本。当下次发生类似的问题时,能够快速回忆起之前问题的细节,帮助我们定位问题。而且总结问题的文集,可以作为一个团队的积累,而不是只有团队内的老员工才掌握这些经验。

有一句话是:好脑瓜不如烂笔头。

大脑会随着时间的推移,慢慢淡忘一些事情。有些问题的细节,只有记录在纸面上,才能准确无误。

6、故障复盘

问题解决后,需要组织相关人员进行复盘。

复盘的目的不是追究问题责任人,而是回顾哪些环节出问题了,如何操作才能避免类似问题的发生。

一件事的正常运行,不应该完全依赖于某个人,而是在完善流程的操作下,必然不会出现异常。如果是一个人的操作失误造成的故障,就应该考虑是否缺少某个环节的监督和校验。

这样流程的不断完善,会使一件事务的推进趋向于复杂化,逐渐失去小公司小团队的灵活,事务操作周期变长,但效率并不一定变低。因为这样能够尽量减少因为人的原因导致的问题。

7、系统优化

我们不仅要做好事故发生后的善后措施,更应做好故障发生前的准备工作。

一类系统优化是故障流程处理的自动化,比如一场比赛故障,原来需要人工查找日志提取参赛名单,分析用户当前所在比赛阶段,并根据运营人员提供的补偿公式计算补偿金额,然后交给客服人员逐个发放。整个周期很长,中间也占用了很多开发、运维和客服资源。

系统自动化之后,再出现相同故障,异常处理系统可以自动提取名单,计算补偿金额并交付后台自动发放补偿。原本半天到一天的补偿周期变为几分钟,用户很快收到系统通知,并拿到满意的补偿,就不会再去纠结这个问题。

另一类系统优化,是提高整体业务系统的健壮性,单个服务节点出问题后,可以由其他节点代为处理,用户完全无感知。比如用户访问的web节点挂掉了,客户端通过重新请求,从其他节点获得了正确的响应,用户从表现层是无感知的。

8、奖惩措施

在解决问题以及复盘的时候,一般都不会追究责任人。但最终业务出现问题,为公司造成了经济损失,还是会体现在某些人的绩效上面。

有些问题如果是因为员工违反工作纪律或者玩忽职守等重大责任时,一般会有相应的处罚,直属领导也会有相应的连带领导责任。

相应处罚无法挽回公司的损失,奖惩的目的也更多是警醒和督促其他人,不要再犯相同的错误。当然,对员工自身来说,受到通报批评并处罚,对后续的绩效评定和职级升迁都会产生严重影响。

Previous1 线上问题Next九、程序员的职业规划

Last updated 2 years ago