最近因部門須要,對 Eureka 服務上下線進行監控併發送郵件,因而便有了以下代碼的產生。java
application.ymlweb
environments: dev spring: application: name: eureka-server mail: isMailServer: true default-encoding: UTF-8 host: mail.my00.com username: My00ComServer password: ****** mailFrom: Server@my00.com port: 25 mailTo: havent@qq.com mailCc: a@os1.cc,b@os1.cc
EurekaStateChangeListener.javaspring
package com.d.eurekaserver; import com.netflix.appinfo.InstanceInfo; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaServerStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; /** * @author: havent.liu(havent@qq.com) * @Description * @Date 2018/10/17 */ @Component public class EurekaStateChangeListener { @Autowired private JavaMailSender mailSender; @Value("${environments}") private String environment; @Value("${spring.mail.isMailServer}") private boolean isMailServer; @Value("${spring.mail.mailFrom}") private String mailFrom; @Value("${spring.mail.mailTo}") private String mailTo; @Value("${spring.mail.mailCc}") private String mailCc; private Map<String, String> serverList = new HashMap<String, String>(); @EventListener public void listen(EurekaInstanceCanceledEvent event) { //HH: 服務下線事件 //if (event.isReplication()) { // return; //} String appName = event.getAppName(); String serverId = event.getServerId(); String serverKey = appName + "." + serverId; String oldStatus = serverList.get(serverKey); if (StringUtils.isBlank(oldStatus)) { oldStatus = ""; } if (!oldStatus.equals("OUT_OF_SERVICE")) { serverList.put(serverKey, "OUT_OF_SERVICE"); long timeStamp = System.currentTimeMillis(); String title = "[" + appName + "] Eureka 服務下線通知"; String msg = getMessage("已下線", appName, serverId, "OUT_OF_SERVICE", timeStamp); sendEmail(title, msg); } } @EventListener public void listen(EurekaInstanceRegisteredEvent event) { //HH: 服務註冊事件 //if (event.isReplication()) { // return; //} InstanceInfo instanceInfo = event.getInstanceInfo(); if (instanceInfo == null) { return; } if (instanceInfo.getStatus() != null && instanceInfo.getStatus() != InstanceInfo.InstanceStatus.UP && instanceInfo.getStatus() != InstanceInfo.InstanceStatus.STARTING) { return; } String appName = instanceInfo.getAppName(); String serverId = instanceInfo.getId(); String serverKey = appName + "." + serverId; String oldStatus = serverList.get(serverKey); serverList.put(serverKey, "UP"); long timeStamp = System.currentTimeMillis(); if (StringUtils.isBlank(oldStatus)) { String title = "[" + appName + "] Eureka 服務上線通知"; String msg = getMessage("已上線", appName, serverId, "UP", timeStamp); sendEmail(title, msg); } else if (!oldStatus.equals("UP")) { String title = "[" + appName + "] Eureka 服務從新上線通知"; String msg = getMessage("已從新上線", appName, serverId, "UP", timeStamp); sendEmail(title, msg); } } @EventListener public void listen(EurekaInstanceRenewedEvent event) { //HH: 服務續約事件 //if (event.isReplication()) { // return; //} InstanceInfo instanceInfo = event.getInstanceInfo(); if (instanceInfo == null) { return; } InstanceInfo.InstanceStatus status = instanceInfo.getStatus(); String appName = event.getAppName(); String serverId = event.getServerId(); String serverKey = appName + "." + serverId; String oldStatus = serverList.get(serverKey); String currentStatus = status.toString(); if (currentStatus.equals(oldStatus)) { return; } if (StringUtils.isBlank(oldStatus)) { oldStatus = ""; } boolean isDown = true; if (oldStatus.equals("UP") || oldStatus.equals("STARTING")) { isDown = false; } serverList.put(serverKey, status.toString()); long timeStamp = System.currentTimeMillis(); if (status == InstanceInfo.InstanceStatus.UP || status == InstanceInfo.InstanceStatus.STARTING) { if (isDown) { String title = "[" + appName + "] Eureka 服務恢復通知"; String msg = getMessage("已恢復", appName, serverId, status.toString(), timeStamp); sendEmail(title, msg); } } else { if (!isDown) { String title = "[" + appName + "] Eureka 服務離線通知"; String msg = getMessage("已離線", appName, serverId, status.toString(), timeStamp); sendEmail(title, msg); } } } @EventListener public void listen(EurekaRegistryAvailableEvent event) { //HH: 註冊中心啓動事件 SimpleDateFormat currentDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.S"); System.out.println(currentDate.format(System.currentTimeMillis()) + " INFO " + "註冊中心啓動"); //sendEmail("EurekaServer 註冊中心啓動", "EurekaServer 註冊中心已啓動"); } @EventListener public void listen(EurekaServerStartedEvent event) { // HH: Server 啓動事件 SimpleDateFormat currentDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.S"); System.out.println(currentDate.format(System.currentTimeMillis()) + " INFO " + "EurekaServer 啓動"); //sendEmail("EurekaServer 服務啓動", "EurekaServer Started"); } private String getMessage(String content, String appName, String serverId, String status, long timeStamp) { SimpleDateFormat currentDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.S"); String message = "微服務:" + appName + " [ " + serverId + " ] " + content + " " + status + "\r\n時間戳:" + currentDate.format(timeStamp) + " [" + timeStamp + "]" + "\r\n微環境:" + environment; System.out.println(currentDate.format(timeStamp) + " INFO " + "微服務:" + appName + " [ " + serverId + " ] " + content + " " + status + " 微環境:" + environment); return message; } // 發送郵件 @Async protected void sendEmail(String title, String msg) { if (!isMailServer) { return; } SimpleDateFormat currentDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.S"); long timeStamp = System.currentTimeMillis(); title = "[" + environment + "]" + title; try { // DONE: 線程沉睡5秒 //Thread.sleep(1000 * 5); //用於封裝郵件信息的實例 SimpleMailMessage smm = new SimpleMailMessage(); //郵件主題 smm.setSubject(title); //郵件內容 smm.setText(msg); //由誰來發送郵件 smm.setFrom(mailFrom); //接受郵件 smm.setTo(mailTo.split(",")); if (StringUtils.isNotBlank(mailCc)) { smm.setCc(mailCc.split(",")); } // DONE: 開啓郵件發送功能 mailSender.send(smm); System.out.println(currentDate.format(timeStamp) + " INFO 郵件發送成功:" + msg); } catch (Exception e) { System.err.println(currentDate.format(timeStamp) + " ERROR 郵件發送異常:" + e.getMessage()); System.err.println(currentDate.format(timeStamp) + " ERROR 郵件發送標題: " + title); System.out.println(currentDate.format(timeStamp) + " ERROR 郵件發送內容: \r\n" + msg); } } }
由於發送郵件啓用了異步功能,因此還須要在 Application.java 開啓 @EnableAsyncapache
package com.havent.eurekaserver; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import org.springframework.scheduling.annotation.EnableAsync; @EnableAsync @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } }