效果图:

文章目录

  • 一、实现原理
    • 1. 原理设计图示
    • 2. 原理流程
  • 二、代码实战
    • 2.1. 错误收集对象
    • 2.2. 模拟方法
    • 2.3. aop拦截
    • 2.4. 异常信息收集队列
    • 2.5. 发送微信模板
    • 2.6. 微信告警模板
    • 2.7. redis存储图
    • 2.8. 效果图
一、实现原理
1. 原理设计图示

2. 原理流程

1.浏览器或者app发起请求,在处理逻辑时发生异常,.
2.aop异常通知捕获,收集异常信息,存入队列中。
3.全局异常捕获,拼接错误json数据,将封装好的json返回前端
4.单独的线程每隔1秒,就去队列中获取异常消息。
5.调用微信公众号模板接口发送模板.
6.先判断此通知在1分钟之内是否已经发起通知,若发起,则流程结束。
7.若未发起,则,拼装模板异常信息调用微信公众号接口
8.推送告警通知。

二、代码实战
2.1. 错误收集对象
package com.mayikt.main.alarm.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** 错误收集对象** @author gblfy* @Date 2022-09-13**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AlarmEntity {/*** 类的名称*/private String className;/*** 方法名称*/private String methodName;/*** 服务名称*/private String serviceName;/*** 服务IP*/private String ip;/*** 端口号码*/private String port;/*** 错误行号*/private int wrongLineNumber;/*** 错误内容*/private String errorMsg;/*** 发生错误时间*/private Date errorTime;
}
2.2. 模拟方法
@RestController
public class TestSecurityServiceImpl implements TestSecurityService {@GetMapping("/insert")@Overridepublic String insert(int age) {int j = 1 / age;return "insert"+j;}
}
2.3. aop拦截
package com.mayikt.main.alarm;import com.mayikt.main.alarm.entity.AlarmEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Enumeration;/*** 告警通知aop** @author gblfy* @Date 2022-09-13**/
@Slf4j
@Aspect
@Component
public class AopInterceptionError {@Value("${spring.application.name}")private String serviceName;@Value("${server.port}")private String serverPort;/*** 通过aop异常通知拦截系统日志*/@Pointcut("execution(public * com.mayikt.main.api.impl..*.*(..))")public void aopInterceptionError() {}//异常通知:在方法出现异常时进行通知,可以范文异常防撞对象,且可以指定在出现特定异常时执行通知@AfterThrowing(value = "aopInterceptionError()", throwing = "e")public void afterThrowing(JoinPoint joinpoint, Exception e) throws UnknownHostException {//aop 异常通知获取栈帧 方法名称 参数值 累的名称 等 ip 和端口号码 服务名称log.info("joinpoint->{}", joinpoint);//报错内容String errorMsg = e.getMessage();StackTraceElement stackTraceElement = e.getStackTrace()[0];//类的名称String className = stackTraceElement.getClassName();//错误行号int lineNumber = stackTraceElement.getLineNumber();//方法名称String methodName = stackTraceElement.getMethodName();AlarmEntity alarmEntity = new AlarmEntity(className,methodName,serviceName,getLocalHostLANAddress().getHostAddress(),serverPort,lineNumber,errorMsg,new Date());//将该对象直接存放入队列中AlarmContainer.addAlarm(alarmEntity);}/*** ip获取方案:* 第一种情况:非容器部署,直接获取服务器ip地址* 第二种情况:docker容器部署,获取容器启动传递的参数即可* docker run (加上参数==指定服务器ip地址)*/public InetAddress getLocalHostLANAddress() {try {InetAddress candidateAddress = null;// 遍历所有的网络接口for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {NetworkInterface iface = (NetworkInterface) ifaces.nextElement();// 在所有的接口下再遍历IPfor (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址if (inetAddr.isSiteLocalAddress()) {// 如果是site-local地址,就是它了return inetAddr;} else if (candidateAddress == null) {// site-local类型的地址未被发现,先记录候选地址candidateAddress = inetAddr;}}}}if (candidateAddress != null) {return candidateAddress;}// 如果没有发现 non-loopback地址.只能用最次选的方案InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();return jdkSuppliedAddress;} catch (Exception e) {e.printStackTrace();}return null;}}
2.4. 异常信息收集队列
package com.mayikt.main.alarm;import com.mayikt.main.alarm.entity.AlarmEntity;
import com.mayikt.main.manage.WechatTemplateManage;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.concurrent.LinkedBlockingDeque;/*** 异常信息收集队列** @author gblfy* @Date 2022-09-13**/
@Component
public class AlarmContainer {@Autowiredprivate WechatTemplateManage wechatTemplateManage;public AlarmContainer() {new SendAlarmThread().start();}/*** 缓存告警错误内容*/private static LinkedBlockingDeque<AlarmEntity> alarmEntityDeque = new LinkedBlockingDeque<>();/*** 添加告警*/public static void addAlarm(AlarmEntity alarmEntity) {alarmEntityDeque.offer(alarmEntity);}// /**//  * 获取告警内容//  */// public static AlarmEntity getAlarm() {//     return alarmEntityDeque.poll();// }//// /**//  * 移除告警//  */// public static void removeAlarm() {//     alarmEntityDeque.remove();// }class SendAlarmThread extends Thread {@SneakyThrows@Overridepublic void run() {while (true) {//获取告警内容AlarmEntity alarmEntity = alarmEntityDeque.poll();if (alarmEntity != null) {//    调用微信公众号末班接口发送模板wechatTemplateManage.sendAlarmTemplate(alarmEntity);}//    为了避免cpu飚高,延迟1sThread.sleep(1000);}}}
}
2.5. 发送微信模板
/*** 发送警告模板** @param alarmEntity* @return*/public boolean sendAlarmTemplate(AlarmEntity alarmEntity) {/*** 高并发避免重复发的方案* redis key=服务名称+ip+端口号+类的名称+方法名称+错误行号 value=报错的参数值(内容) 设置过期时间比如:1分钟 一分钟内同样的报错只会通知一次**/String serviceName = alarmEntity.getServiceName();String ip = alarmEntity.getIp();String port = alarmEntity.getPort();String className = alarmEntity.getClassName();String methodName = alarmEntity.getMethodName();int wrongLineNumber = alarmEntity.getWrongLineNumber();String errorMsg = alarmEntity.getErrorMsg();String errorRepeatKey = serviceName + "_" + ip + "_" + port + "_" + className + "_" + methodName + "_" + wrongLineNumber;String errorRepeatValue = errorRepeatKey + "_" + errorMsg;//判断key是否存在String redisErrorMsg = RedisUtil.getString(errorRepeatKey);if (!StringUtils.isEmpty(redisErrorMsg)) {return false;}//将错误发送记录存储redisRedisUtil.setString(errorRepeatKey, errorRepeatValue, 60L);WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();wxMpTemplateMessage.setTemplateId(alarmTemplateId);wxMpTemplateMessage.setToUser("oD8nF5jpNF9KXU_j49uvqOPVdiEU");List<WxMpTemplateData> data = new ArrayList<>();data.add(new WxMpTemplateData("first", serviceName));data.add(new WxMpTemplateData("keyword1", ip + ":" + port));data.add(new WxMpTemplateData("keyword2", "报错的类:" + className));data.add(new WxMpTemplateData("keyword3", "报错的方法:" + methodName));data.add(new WxMpTemplateData("keyword4", "报错的行号:" + wrongLineNumber));data.add(new WxMpTemplateData("keyword5", "报错的内容:" + errorMsg));data.add(new WxMpTemplateData("keyword6", SimpleDateFormatUtils.getFormatStrByPatternAndDate(alarmEntity.getErrorTime())));wxMpTemplateMessage.setData(data);//点击模板指定跳转地址// wxMpTemplateMessage.setUrl("http://www.mayikt.com");try {String appId = wxMpProperties.getConfigs().get(0).getAppId();System.out.println("appId" + appId);WxMpTemplateMsgService templateMsgService = WxMpConfiguration.getMpServices().get(appId).getTemplateMsgService();templateMsgService.sendTemplateMsg(wxMpTemplateMessage);return true;} catch (Exception e) {log.error("e->{}", e);e.printStackTrace();return false;}}
2.6. 微信告警模板
模板标题:告警通知2
模板内容:
服务名称:{{first.DATA}}
IP和端口:{{keyword1.DATA}}
报错的类:{{keyword2.DATA}}
报错方法:{{keyword3.DATA}}
报错行号:{{keyword4.DATA}}
报错内容:{{keyword5.DATA}}
错误时间:{{keyword6.DATA}}
发生了系统错误,请您及时登录服务器查看并解决
模板ID(用于接口调用):   _axxxxxxxxxxxxxxx3jMYdF4

2.7. redis存储图

2.8. 效果图

微服务整合公众号告警系统相关推荐

  1. 速递!MongoDB最新书籍出版啦:MongoDB进阶与实战-微服务整合、性能优化、架构管理

    新书速递 近期,MongoDB中文社区核心成员之一唐卓章老师出了一本MongoDB最新书籍--<MongoDB进阶与实战:微服务整合.性能优化.架构管理>,全面涵盖了MongoDB的基本原 ...

  2. 商城前端模板_如何理解微信小程序和微商城,微信公众号以及APP之间的关系?一张图看懂了!...

    老张的一位粉丝,花了几天时间把知乎里面分享的一些关于微信小程序,微信商城,微信公众号,以及APP的相关介绍全看完了. 然后用他自己的话描述了微信小程序和微商城,微信公众号以及APP之间的关系,如下图所 ...

  3. 安装并使用微擎管理公众号

    微擎是一款基于WEB2.0(PHP+Mysql)技术架构,免费开源的公众平台管理系统,一款致力于将小程序和公众号商业化.智慧化.场景化的自助引擎. 这里选择的环境为LAMP,它是 Linux + Ap ...

  4. Alibaba微服务整合SkyWalking实现应用性能监控

    1. 概述 SkyWalking是一个国产的开源框架,用于分布式系统应用程序的性能监控,专门为微服务.云原生架构和基于容器(Docker.K8s.Mesos)架构而设计,包括了分布式追踪.性能指标分析 ...

  5. SpringCloudAlibaba 微服务整合分布式事务Seata

    基于AT模式 创建undo_log(回滚日志表)表, 每个数据库需要创建 注意:UNDO_LOG Table:不同数据库在类型上会略有差别.详见官网 -- 注意此处0.7.0+ 增加字段 contex ...

  6. Hexo 博客快速整合公众号导流工具,不用互推也能实现粉丝躺增!

    readmore 插件简介 Hexo 整合 OpenWrite 平台的 readmore 插件,实现博客的每一篇文章自动增加效果,关注公众号后方可解锁全站文章,从而实现博客流量导流到微信公众号粉丝目的 ...

  7. sleuth微服务整合Zipkin

    首先 我们需要依赖sleuth 和 sleuth与zipkin的整合依赖: <dependency> <groupId>org.springframework.cloud< ...

  8. 微擎微信公众号小程序框架v2.7.3去sq一键安装纯净商业版

    介绍: 1.系统LOGO更新,换成微擎新LOGO. 2.修复公众号平台下本地图文同步为公众号图文后,图片不显示的问题. 3.修复微信公众号视频素材上传栏点击后提示不友好报错的问题. 4.修复授权绑定的 ...

  9. Spring Cloud Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    文章目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashbo ...

最新文章

  1. Hibernate:不容易理解的 lock 和 merge
  2. 【Flutter】Flutter 混合开发 ( 安卓端向 Flutter 传递数据 | FlutterFragment 数据传递 | FlutterActivity 数据传递 )
  3. 【计算机网络】数据链路层 : 轮询访问 介质访问控制 ( 轮询协议 | 令牌传递协议 )
  4. 跨链(5)“蚂蚁区块链”之跨链系统框架
  5. windows nginx c++读取请求数据_震撼!全网第一张源码分析全景图揭秘Nginx
  6. linux查看进程占用pcu,Linux运维:如何使用ss代替netstat命令
  7. 一个计算机台式机的组装方案,既能带又便宜的电脑组装方案,华擎deskmini310组装晒单...
  8. 35岁,搞过超高并发架构,依然没看懂字节的推荐系统!
  9. sql server 群集_部署具有群集共享卷SQL Server –第2部分
  10. Exception Type: IntegrityError 数据完整性错误
  11. linux管道和tee命令
  12. 虚拟机里面主要涉及哪些功能,虚拟机管理需要哪些功能
  13. 色 彩 RGB 值 对 照 表
  14. 宝塔利用同一个ip的不同端口号架设多个网站
  15. 纹理识别——GLCM空间灰度共生矩阵
  16. 气导耳机有哪些品牌?南卡、韶音、cleer、索尼气传导耳机评测分享
  17. php获取时间到微妙,php 获取毫秒时间戳
  18. 开题报告:基于java电子书阅读系统 毕业设计论文开题报告模板
  19. 【发车优化】基于遗传算法的公交车调度排班优化的研究与实现附Matlab代码
  20. 2021-07-11谓词执行

热门文章

  1. C#调用Halcon并输出圆心坐标
  2. 安裝wgt文件失败[-1205]:WGT安装包中manifest.json文件的version版本不匹配
  3. 视频营销—网络营销的一种有效形式
  4. Android蓝牙初始名称修改(高通平台)
  5. win10或win7计算机右键管理打不开
  6. 樱花未开(更新完毕)
  7. Locust使用手册--编写一个locustfile
  8. VBA 关键字匹配查找
  9. 圣诞节装饰LED灯串亚马逊UL588测试报告办理标准
  10. Linux磁盘分区论文3000字,磁盘分区对齐详解与配置 – Linux篇