服务都挂了你还在打代码?

服务挂了?

线上服务在疯狂的报错,你还在悠哉悠哉的打代码,等到用户开始反馈问题,这时候才去线上查日志,黄花菜都凉了。老板:“去财务结一下账吧”。

异常告警

对于很多基础设施比较完善的公司,都会有比较完善的日志采集、分析、告警等组件,包括服务健康检查、接口拨测等等。但是对于刚起步的产品,我们可能啥也没有,追求的就是一个快速上线,那怎么优雅快速的实现异常告警呢?

异常分级

在处理异常之前,首先我们需要先对异常做分级,哪些是业务上定义的可接受的异常,比如参数校验的异常、权限异常等等;哪些是非预期的异常,比如空指针、数据库异常、缓存异常等等。我们一般重点关注的是非预期的异常。
业务异常我们一般会定义自己的异常基类:

/*** 异常基类,所有业务异常继承自此类*/
@Getter
public class BaseException extends RuntimeException{private final Integer code;private final String message;public BaseException(Integer code, String message) {super(message);this.code = code;this.message = message;}
}

AOP

AOP真是一个好东西,可以减少代码侵入性,重用逻辑减化开发工作量。这么好用的特性那我们肯定也要用上:


/*** 异常告警Aspect,打印对应异常日志并推送告警*/
@Aspect
@Component
@Slf4j
public class ExceptionAspect {@Resourceprivate ExceptionNotice exceptionNotice;@Value("${notice.bz.ex}")private String bizEx;@Value("${notice.ex.enable}")private boolean enable;@Around("execution(* com.demo.service.*.*(..))")public Object around(ProceedingJoinPoint pjp) throws Throwable {try {return pjp.proceed();} catch (Throwable e) {//处理异常handleException(pjp, e);//处理完还要继续向上抛throw e;}}private void handleException(ProceedingJoinPoint pjp, Throwable e) {//如果没开启告警,则直接返回if (!enable) {return;}try {//如果是非业务异常,或者是配置中的业务异常,才进行打印和告警boolean needToNotice = !(e instanceof BaseException) || bizEx.contains(((BaseException)e).getCode().toString())if (needToNotice) {//打印异常Object[] args = pjp.getArgs();log.error("异常参数: {}", ArrayUtil.toString(args));log.error(e.getMessage(), e);//异常告警通知,注意:这里需要异步发送消息!!exceptionNotice.send(formatMsg(e));}}catch(Exception e) {//告警处理不能影响正常流程,忽略异常,只打印log.error("handleException处理异常", e);}}/*** 格式化异常信息*/private String formatMsg(Throwable e) {String template = "【业务名称】接口异常啦,请马上处理:traceId: %s, message: %s, \n %s";//全局traceId,用于后续定位问题String traceId = ServerContext.getTraceId();String ex = ExceptionUtil.getMessage(e);String trace = ExceptionUtil.stacktraceToString(e);return String.format(template, traceId, ex, trace);}
}

逻辑很简单,我们在代理类中捕获对应方法中的所有异常,然后再根据异常分级和配置,来决定是否要打印告警信息并且通过邮件、短信或企微告警。里面比较重要的几个点:

  1. 异常处理逻辑不能影响原有流程,因此需要catch住异常处理逻辑中的所有异常。
  2. 告警通知是一个较为耗时的操作,需要使用线程池异步处理,并且为了异常处理的逻辑不影响我们正常的服务,一定要设置线程池的队列大小和拒绝策略,拒绝策略应该是直接丢弃。
  3. 在发送异常告警需要考虑收敛,否则在某些情况下,邮件或短信可能会爆炸(别问我怎么知道的)。而且邮件算还好,但是短信是要钱的!!!

告警收敛可以根据一定的规则,比如根据告警信息、特定参数或者异常类型作为唯一标识,在时间范围内只告警N次。

总结

以上就可以简单快速且优雅的实现一个异常告警功能啦,对于缺乏基础设施建设,且需要快速上线的项目来说,这样最少可以保证我们项目前期的异常监控,不会等用户、运营、产品、老板都发现服务挂了,作为一个一线开发,你还在那笑嘻嘻的打代码,完全没有意识到,风雨欲来~

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

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

相关文章

ICC2删除所有电源的方法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?知识星球入口 remove_pg_patterns -all remove_pg_strategies -all remove_pg_strategy_via_rules -all remove_pg_via_master_rules -all remove_pg_regions -all remove_routes -net_types {p…

网安周报 | 银行业成为开源软件供应链攻击的目标

网安周报是棱镜七彩推出的安全资讯专栏,旨在通过展示一周内发生的与开源安全、软件供应链安全相关攻击事件,让用户了解开源及软件供应链威胁,提高对安全的重视,做好防御措施。 1、银行业成为开源软件供应链攻击的目标 网络安全研…

微服务入门---SpringCloud(二)

微服务入门---SpringCloud(二) 1.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置 1.2.配置热更新1.2.1.方式一1.2.2.方式二 1.3.配置共享1)添加一个环境共享配置2)在user-service中读取共享配置…

vue2+wangEditor5富文本编辑器(图片视频自定义上传七牛云/服务器)

1、安装使用 安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --save yarn add wangeditor/editor-for-vue # 或者 npm install wangeditor/editor-for-vue --save在main.js中引入样式 import wangeditor/editor/dist/css/style.css在使用编辑器的页…

Android 截图功能实现

Android 截图功能实现 简介效果图功能实现1. 截取当前可见范围屏幕2. 截取当前可见范围屏幕(不包含状态栏)3. 截取某个控件4. 截取ScrollView5. 长截图6. 截屏动画效果7. 显示截屏结果,自动消失6. 完整代码 简介 在Android应用中开发截图功能…

顺序表的实现

文章目录 1.概念及结构 2.接口实现 3.数组相关oj题 4.顺序表的问题及思考 文章内容 1.概念及结构 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序…

【物理】模拟粒子在电场和磁场中的轨迹研究(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 💥1 概述 模拟粒子在电场和磁场中的轨迹研究是物理学中的一个重要研究领域,涉及到电磁场、粒子运动、轨迹分析等多个方面。在这个研究中&…

Python爬虫实例之淘宝商品页面爬取(api接口)

可以使用Python中的requests和BeautifulSoup库来进行网页爬取和数据提取。以下是一个简单的示例: import requests from bs4 import BeautifulSoupdef get_product_data(url):# 发送GET请求,获取网页内容headers {User-Agent: Mozilla/5.0 (Windows NT…

前端CryptoJS-AES加解密 对应php的AES-128-CBC加解密踩坑(java也相同加解密)

前端部分注意看填充是pkcs7 有个前提,要看前端有没有转成hex格式,如果没转,php那边就不需要调用特定函数转hex格式的 const keyStr 5hOwdHxpW0GOciqZ;const iv 0102030405060708;//加密function Encrypt(word) {let key CryptoJS.enc.Ut…

今天你做代码检查了吗?

当下,各行各业都在寻找可以降本增效的效率途径,AI人工智能、机器学习等概念也被广泛应用至业务中;而广州云标局推出了一款智能ide代码工具——codigger,不仅项目体检能为开发项目提供快速代码检测,主要检测维度包括bug…

【Spring框架】Spring读取与存储综合练习

练习 在 Spring 项⽬中,通过 main ⽅法获取到 Controller 类,调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤ Service 类,Service 再通过注⼊的⽅式获取到 Repository 类,Repository 类⾥⾯有⼀个⽅法构建⼀个 User 对象,返…

抖音账号矩阵系统开发源码

一、技术自研框架开发背景: 抖音账号矩阵系统是一种基于数据分析和管理的全新平台,能够帮助用户更好地管理、扩展和营销抖音账号。 部分源码分享: ic function indexAction() { //面包屑 $breadcrumbs [ [tit…

虚拟机 RHEL8 安装 MySQL 8.0.34

目录 安装步骤一、清除所有残留的旧MySQL二、安装MySQL 报错问题1. 提示未找到匹配的参数: mysql-community-server2. 公钥问题 安装步骤 一、清除所有残留的旧MySQL 1. 关闭MySQL [rootlocalhost /]# service mysqld stop Redirecting to /bin/systemctl stop …

线程池与ThreadLocal同时使用读取到脏数据

问题&#xff1a;当线程池与ThreadLocal共用时&#xff0c;ThreadLocal读取数据出现错乱。 问题验证&#xff1a; public static void main(String[] args) {ExecutorService executorService Executors.newFixedThreadPool(2);final ThreadLocal<String> threadLocal…

【导入外部jar包到maven项目中--亲测可行】

若项目为springweb项目&#xff0c;则先将jar放到WEB-INF/lib 目录下选中对应的jar包&#xff0c;右键选项 add-lirrary &#xff1b;成功加入之后的jar包是一个项目的目录结构&#xff1a; 至此&#xff0c;项目能够正常运行&#xff0c;在代码周也能够进行导包 转折点&…

windows下若依vue项目部署

下载若依项目&#xff0c;前端后端项目本地启动前端打包&#xff0c;后端打包配置nginx.conf 需要注意的是&#xff1a;路径别用中文&#xff0c;要不然报错 #前台访问地址及端口80&#xff0c;在vue.config.js中可查看server {listen 80;server_name localhost; #后台…

一文谈谈Git

"And if forever lasts till now Alright" 为什么要有git&#xff1f; 想象一下&#xff0c;现如今你的老师同时叫你和张三&#xff0c;各自写一份下半年的学习计划交给他。 可是你的老师是一个极其"较真"的人&#xff0c;发现你俩写的学习计划太"水&…

QT:当登录成功时,关闭登录界面,跳转到新的界面中

1> 继续完善登录框&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;跳转到新的界面中 widget.h #include "widget.h" //#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent)//, ui(new Ui::Widget) {//ui->setu…

使用python部署chineseocr_lite

使用python部署chineseocr_lite 简介安装报错解决python调用结果 简介 项目地址&#xff1a;https://github.com/DayBreak-u/chineseocr_lite chineseocr_lite 是一个开源项目&#xff0c;用来实现中文的文字识别&#xff0c;支持竖排文字识别、繁体识别&#xff0c;总模型只…

机器学习分布式框架ray运行TensorFlow实例

使用Ray来实现TensorFlow的训练是一种并行化和分布式的方法&#xff0c;它可以有效地加速大规模数据集上的深度学习模型的训练过程。Ray是一个高性能、分布式计算框架&#xff0c;可以在集群上进行任务并行化和数据并行化&#xff0c;从而提高训练速度和可扩展性。 以下是实现…