需求:监控指定系统的实例数量,在有节点掉线时进行钉钉消息推送
监听代码:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.extrotec.entity.SendMessageIn;
import com.extrotec.utils.DingTalkUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
public class ServiceStatusListner {
@Value("${dingtalk.webhook}")
private String webhook;
@Value("${dingtalk.secret}")
private String secret;
@Value("${dingtalk.userMobil}")
private String[] userMobil;
@Value("${spring.cloud.nacos.discovery.server-addr}")
private String nacosUrl;
private static Map<String, Integer> cache = new ConcurrentHashMap<>();
@PostConstruct
public void init() throws Exception {
List<String> mobileList = new ArrayList<>();
for(String mobile : userMobil){
mobileList.add(mobile);
}
Properties properties = System.getProperties();
properties.setProperty("serverAddr", nacosUrl);
properties.setProperty("namespace", "public");
NamingService naming = NamingFactory.createNamingService(properties);
List<String> serviceNames = new ArrayList<>();
serviceNames.add("xxx");
serviceNames.add("xxxcenter");
serviceNames.add("xxxgateway");
for(String service : serviceNames) {
naming.subscribe(service, event -> {
List<Instance> instances = ((NamingEvent)event).getInstances();
String serviceName = ((NamingEvent)event).getServiceName();
cache.computeIfAbsent(serviceName, k -> instances.size());
if(cache.get(serviceName) <instances.size()){
cache.put(serviceName, instances.size());
}
if(instances.size() <cache.get(serviceName)) {
SendMessageIn error = new SendMessageIn();
error.setAtAll(false);
error.setMsgType("text");
error.setSecret(secret);
error.setWebhook(webhook);
error.setMobileList(mobileList);
error.setText(serviceName +"服务下线,"+"服务异常下线告警,当前节点数:"+instances.size());
DingTalkUtil.sendMessage(error);
log.info("============服务下线"+ serviceName);
cache.put(serviceName, instances.size());
}else {
log.info("============服务上线"+ serviceName+",当前节点数量:"+instances.size());
}
});
}
}
}
钉钉推送工具类:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>1.0.1</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
@Data
public class SendMessageIn {
private String msgType;
private String webhook;
private String secret;
private String text;
private List<String> mobileList;
private boolean isAtAll;
}
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.extrotec.entity.SendMessageIn;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class DingTalkUtil {
private static final String TEXT = "text";
public static void sendMessage(SendMessageIn in){
try {
log.info("开始推送钉钉消息:" + in);
Long timestamp = System.currentTimeMillis();
String secret = in.getSecret();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
DingTalkClient client = new DefaultDingTalkClient(in.getWebhook() + "×tamp=" + timestamp + "&sign=" + sign);
OapiRobotSendRequest request = new OapiRobotSendRequest();
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
if (in.isAtAll() || in.getMobileList() == null || in.getMobileList().size() == 0) {
at.setIsAtAll(true);
} else {
at.setAtMobiles(in.getMobileList());
at.setIsAtAll(false);
}
request.setAt(at);
if (TEXT.equals(in.getMsgType())) {
request.setMsgtype(TEXT);
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
text.setContent(in.getText());
request.setText(text);
}
OapiRobotSendResponse response = client.execute(request);
log.info("钉钉推送返回结果:" + response);
}catch (Exception e){
log.error("钉钉通知异常");
}
}
public static void main(String[] args){
List<String> mobileList = new ArrayList<>();
mobileList.add("1811111111");
SendMessageIn in = new SendMessageIn();
in.setMsgType(TEXT);
in.setAtAll(false);
in.setMobileList(mobileList);
in.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=9xxxxxxxx");
in.setSecret("SEC2ca0e08d0b19");
in.setText("桃花坞里桃花庵,桃花庵下桃花仙");
sendMessage(in);
}
}
结果
