66 Spring Boot Admin监控告警服务
微服务架构下,服务的数量少则几十,多则上百,所以对服务的监控必不可少。如果是以前的单体项目,启动了多少个项目是固定的,可以通过第三方监控工具对其进行监控,然后实时告警。
在微服务下,由于服务数量太多,并且可以随时扩展,这个时候第三方的监控功能就不适用了,不过我们可以通过 Spring Boot Admin 连接注册中心来查看服务状态,这个只能在页面查看。
很多时候我们更希望能够自动监控,通过邮件告警,比如发出“某某服务下线了”这样的功能。在 Spring Boot Admin 中其实已经有这样的功能了,我们只需要配置一些邮件的信息就可以使用。
邮件警报
引入邮件所需要的依赖,代码如下所示。
1 2 3 4 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> |
然后在配置文件中增加邮件服务器的信息:
1 2 3 4 5 6 7 8 9 10 | spring.mail.host=smtp.qq.com spring.mail.username=xxx@qq.com spring.mail.password=qq 邮箱的授权码 spring.mail.properties.mail.smtp.auth= true spring.mail.properties.mail.smtp.starttls.enable= true spring.mail.properties.mail.smtp.starttls.required= true # 发送给谁 spring.boot.admin.notify.mail.to=xxx@126.com # 是谁发送出去的 spring.boot.admin.notify.mail. from =xxx@qq.com |
配置好之后就可以收到监控邮件了。
自定义钉钉警报
目前很多公司都是用钉钉来办公,通过钉钉可以发送监控消息,非常方便。Spring Boot Admin 中默认是没有钉钉警报这个功能的,我们可以自己去扩展使用钉钉来发送监控信息。
首先我们编写一个发送钉钉消息的工具类,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | public class DingDingMessageUtil { public static String access_token = "填写你自己申请的token" ; public static void sendTextMessage(String msg) { try { Message message = new Message(); message.setMsgtype( "text" ); message.setText( new MessageInfo(msg)); URL url = new URL( "https://oapi.dingtalk.com/robot/send?access_token=" + access_token); // 建立 http 连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput( true ); conn.setDoInput( true ); conn.setUseCaches( false ); conn.setRequestMethod( "POST" ); conn.setRequestProperty( "Charset" , "UTF-8" ); conn.setRequestProperty( "Content-Type" , "application/Json; charset=UTF-8" ); conn.connect(); OutputStream out = conn.getOutputStream(); String textMessage = JsonUtils.toJson(message); byte [] data = textMessage.getBytes(); out .write(data); out .flush(); out .close(); InputStream in = conn.getInputStream(); byte [] data1 = new byte [ in .available()]; in .read(data1); System. out .println( new String(data1)); } catch (Exception e) { e.printStackTrace(); } } } class Message { private String msgtype; private MessageInfo text; public String getMsgtype() { return msgtype; } public void setMsgtype(String msgtype) { this .msgtype = msgtype; } public MessageInfo getText() { return text; } public void setText(MessageInfo text) { this .text = text; } } class MessageInfo { private String content; public MessageInfo(String content) { this .content = content; } public String getContent() { return content; } public void setContent(String content) { this .content = content; } } |
通过继承 AbstractStatusChangeNotifier 实现钉钉发送机制,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class DingDingNotifier extends AbstractStatusChangeNotifier { public DingDingNotifier(InstanceRepository repository) { super(repository); } @Override protected Mono<Void> doNotify(InstanceEvent event , Instance instance) { String serviceName = instance.getRegistration().getName(); String serviceUrl = instance.getRegistration().getServiceUrl(); String status = instance.getStatusInfo().getStatus(); Map<String, Object> details = instance.getStatusInfo().getDetails(); StringBuilder str = new StringBuilder(); str.append( "【" + serviceName + "】" ); str.append( "【服务地址】" + serviceUrl); str.append( "【状态】" + status); str.append( "【详情】" + JsonUtils.toJson(details)); return Mono.fromRunnable(() -> { DingDingMessageUtil.sendTextMessage(str.toString()); }); } } |
最后启用 DingDingNotifier 就可以了,代码如下所示。
1 2 3 4 | @Bean public DingDingNotifier dingDingNotifier() { return new DingDingNotifier(); } |
前我们已经配置好了警报功能,当服务上下线的时候就会发送警报,当网络发生波动的时候也有可能会触发警报。当前的警报只会发送一次,也就是说你的服务挂掉之后你会收到一条警报。如果是网络引起的警报也会收到一条警报,这个时候你就无法判断服务是不是真正出问题了。
我们的需求也很简单,当服务真正挂掉的时候,警报可以发送多条,比如每 10 秒发送一条,这样连续性的警报就很容易让维护人员关注和辨别。
可以通过配置 RemindingNotifier 来实现上面的需求:
1 2 3 4 5 6 7 8 | @Primary @Bean(initMethod = "start" , destroyMethod = "stop" ) public RemindingNotifier remindingNotifier(InstanceRepository repository) { RemindingNotifier notifier = new RemindingNotifier(dingDingNotifier(repo - sitory), repository); notifier.setReminderPeriod(Duration.ofSeconds(10)); notifier.setCheckReminderInverval(Duration.ofSeconds(10)); return notifier; } |
这里设置的时间间隔是 10 秒一次,当服务出问题的时候就会每隔 10 秒发送一次警报,直到服务正常才会停止。
这个功能还会引发一个别的问题,如果你的服务是运行在 Docker 中,采用动态端口的话,当你每次重新发布服务的时候,端口发生变化,Spring Boot Admin 就会认为你的服务一直处于不可用的状态,这点不是特别好解决,笔者能想到的方法是在正常项目发布成功之后把 Spring Boot Admin 重启下,获取最新的服务信息。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~