完成告警切换的功能
This commit is contained in:
parent
fb2d7d554c
commit
3d5a652d23
|
|
@ -0,0 +1,88 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.ai.cloud</groupId>
|
||||||
|
<artifactId>skywalking-alarm</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>skywalking-alarm</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>Company</id>
|
||||||
|
<url>http://10.1.228.199:18081/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.4.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
<version>2.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.mail</groupId>
|
||||||
|
<artifactId>javax.mail</artifactId>
|
||||||
|
<version>1.5.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.freemarker</groupId>
|
||||||
|
<artifactId>freemarker</artifactId>
|
||||||
|
<version>2.3.23</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.curator</groupId>
|
||||||
|
<artifactId>curator-framework</artifactId>
|
||||||
|
<version>2.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.zookeeper</groupId>
|
||||||
|
<artifactId>zookeeper</artifactId>
|
||||||
|
<version>3.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.curator</groupId>
|
||||||
|
<artifactId>curator-recipes</artifactId>
|
||||||
|
<version>2.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>5.1.37</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.7</source>
|
||||||
|
<target>1.7</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.dao.AlarmMessageDao;
|
||||||
|
import com.ai.cloud.skywalking.alarm.model.ApplicationInfo;
|
||||||
|
import com.ai.cloud.skywalking.alarm.model.UserInfo;
|
||||||
|
import com.ai.cloud.skywalking.alarm.zk.ZKUtil;
|
||||||
|
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
public class AlarmMessageProcessThread extends Thread {
|
||||||
|
private int rank;
|
||||||
|
private String threadId;
|
||||||
|
private Logger logger = LogManager.getLogger(AlarmMessageProcessThread.class);
|
||||||
|
private boolean isChanged = false;
|
||||||
|
private List<InterProcessMutex> locks;
|
||||||
|
private List<UserInfo> toBeProcessUsers;
|
||||||
|
|
||||||
|
public AlarmMessageProcessThread() {
|
||||||
|
threadId = UUID.randomUUID().toString();
|
||||||
|
registerServer(threadId);
|
||||||
|
rank = ballot(threadId);
|
||||||
|
ZKUtil.watch(AlarmServerRegisterWatcher.getInstance());
|
||||||
|
toBeProcessUsers = getToBeProcessUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
lockAllUsers();
|
||||||
|
while (true) {
|
||||||
|
for (UserInfo userInfo : toBeProcessUsers) {
|
||||||
|
for (ApplicationInfo applicationInfo : userInfo.getApplicationInfos()) {
|
||||||
|
System.out.println(threadId + applicationInfo.getAppId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChanged) {
|
||||||
|
unlockAllUsers();
|
||||||
|
rank = ballot(threadId);
|
||||||
|
toBeProcessUsers = getToBeProcessUsers();
|
||||||
|
lockAllUsers();
|
||||||
|
isChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Sleep failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unlockAllUsers() {
|
||||||
|
for (InterProcessMutex lock : locks) {
|
||||||
|
try {
|
||||||
|
lock.release();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to release lock[{}]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockAllUsers() {
|
||||||
|
locks = new ArrayList<InterProcessMutex>(toBeProcessUsers.size());
|
||||||
|
InterProcessMutex tmpLock;
|
||||||
|
for (UserInfo userInfo : toBeProcessUsers) {
|
||||||
|
tmpLock = ZKUtil.getProcessUserLock(userInfo.getUserId());
|
||||||
|
locks.add(tmpLock);
|
||||||
|
try {
|
||||||
|
tmpLock.acquire();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to lock ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<UserInfo> getToBeProcessUsers() {
|
||||||
|
List<UserInfo> userInfos = AlarmMessageDao.selectAllUserInfo();
|
||||||
|
List<String> allServerIds = ZKUtil.selectAllServerIds();
|
||||||
|
int step = (int) Math.ceil(userInfos.size() * 1.0 / allServerIds.size());
|
||||||
|
int start = rank * step;
|
||||||
|
int end = (rank + 1) * step;
|
||||||
|
if (end > userInfos.size()) {
|
||||||
|
return new ArrayList<UserInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UserInfo> toBeProcessUsers = userInfos.subList(start, end);
|
||||||
|
for (UserInfo userInfo : toBeProcessUsers) {
|
||||||
|
userInfo.setApplicationInfos(AlarmMessageDao.selectAllApplicationsByUserId(userInfo.getUserId()));
|
||||||
|
}
|
||||||
|
return toBeProcessUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void registerServer(String serverId) {
|
||||||
|
InterProcessMutex registerLock = ZKUtil.getRegisterLock();
|
||||||
|
try {
|
||||||
|
registerLock.acquire();
|
||||||
|
ZKUtil.register(serverId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to lock.", e);
|
||||||
|
} finally {
|
||||||
|
if (registerLock != null) {
|
||||||
|
try {
|
||||||
|
registerLock.release();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to release lock.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ballot(String threadId) {
|
||||||
|
List<String> serverIds = ZKUtil.selectAllServerIds();
|
||||||
|
int rank = 0;
|
||||||
|
for (String tmpServerId : serverIds) {
|
||||||
|
if (tmpServerId.hashCode() < threadId.hashCode()) {
|
||||||
|
rank++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setChanged(boolean changed) {
|
||||||
|
isChanged = changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.conf.Config;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AlarmProcessServer {
|
||||||
|
|
||||||
|
private static Logger logger = LogManager.getLogger(AlarmProcessServer.class);
|
||||||
|
|
||||||
|
private static List<AlarmMessageProcessThread> processThreads =
|
||||||
|
new ArrayList<AlarmMessageProcessThread>();
|
||||||
|
|
||||||
|
public static void main(String[] main) {
|
||||||
|
logger.info("Begin to start alarm process server....");
|
||||||
|
logger.info("Begin to start process thread...");
|
||||||
|
AlarmMessageProcessThread tmpThread;
|
||||||
|
for (int i = 0; i < Config.Server.PROCESS_THREAD_SIZE; i++) {
|
||||||
|
tmpThread = new AlarmMessageProcessThread();
|
||||||
|
tmpThread.start();
|
||||||
|
processThreads.add(tmpThread);
|
||||||
|
}
|
||||||
|
logger.info("Successfully launched {} processing threads.", Config.Server.PROCESS_THREAD_SIZE);
|
||||||
|
logger.info("Begin to start user inspector thread....");
|
||||||
|
new UserInfoInspector().start();
|
||||||
|
logger.info("Start user inspector thread success....");
|
||||||
|
logger.info("Alarm process server successfully started.");
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(Config.Server.DAEMON_THREAD_WAITE_INTERVAL);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Sleep failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<AlarmMessageProcessThread> getProcessThreads() {
|
||||||
|
return processThreads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.zk.ZKUtil;
|
||||||
|
import org.apache.curator.framework.api.CuratorWatcher;
|
||||||
|
import org.apache.zookeeper.WatchedEvent;
|
||||||
|
import org.apache.zookeeper.Watcher;
|
||||||
|
|
||||||
|
public class AlarmServerRegisterWatcher implements CuratorWatcher {
|
||||||
|
|
||||||
|
private static AlarmServerRegisterWatcher watcher = new AlarmServerRegisterWatcher();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(WatchedEvent watchedEvent) throws Exception {
|
||||||
|
if (watchedEvent.getType() == Watcher.Event.EventType.NodeChildrenChanged) {
|
||||||
|
for (AlarmMessageProcessThread thread : AlarmProcessServer.getProcessThreads()) {
|
||||||
|
thread.setChanged(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZKUtil.watch(getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AlarmServerRegisterWatcher getInstance() {
|
||||||
|
return watcher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.dao.AlarmMessageDao;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
public class UserInfoInspector extends Thread {
|
||||||
|
|
||||||
|
private Logger logger = LogManager.getLogger(UserInfoInspector.class);
|
||||||
|
|
||||||
|
private int preUserSize;
|
||||||
|
|
||||||
|
public UserInfoInspector() {
|
||||||
|
preUserSize = AlarmMessageDao.selectUserCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int currentUserSize;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10 * 1000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Sleep Failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUserSize = AlarmMessageDao.selectUserCount();
|
||||||
|
|
||||||
|
if (currentUserSize != preUserSize) {
|
||||||
|
logger.info("Total user has been changed. Notice all process thread to change process date.");
|
||||||
|
for (AlarmMessageProcessThread thread : AlarmProcessServer.getProcessThreads()) {
|
||||||
|
thread.setChanged(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.conf;
|
||||||
|
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
public static class Server {
|
||||||
|
public static int PROCESS_THREAD_SIZE = 2;
|
||||||
|
|
||||||
|
public static long DAEMON_THREAD_WAITE_INTERVAL = 50000L;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ZKPath {
|
||||||
|
|
||||||
|
public static String CONNECT_STR = "127.0.0.1:2181";
|
||||||
|
public static int CONNECT_TIMEOUT = 1000;
|
||||||
|
public static int RETRY_TIMEOUT = 1000;
|
||||||
|
public static int RETRY_TIMES = 3;
|
||||||
|
|
||||||
|
public static String NODE_PREFIX = "/skywalking";
|
||||||
|
|
||||||
|
public static String SERVER_REGISTER_LOCK_PATH = "/alarm-server/register";
|
||||||
|
public static String REGISTER_SERVER_PATH = "/alarm-server/servers";
|
||||||
|
public static String USER_REGISTER_LOCK_PATH = "/alarm-server/users";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DB {
|
||||||
|
public static String PASSWORD = "devrdbusr13";
|
||||||
|
public static String USER_NAME = "devrdbusr13";
|
||||||
|
public static String DRIVER_CLASS = "com.mysql.jdbc.Driver";
|
||||||
|
public static String URL = "jdbc:mysql://10.1.228.200:31306/test";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Alarm {
|
||||||
|
|
||||||
|
public static String REDIS_SERVER = "127.0.0.1:6379";
|
||||||
|
|
||||||
|
public static int REDIS_MAX_IDLE = 10;
|
||||||
|
|
||||||
|
public static int REDIS_MIN_IDLE = 1;
|
||||||
|
|
||||||
|
public static int REDIS_MAX_TOTAL = 20;
|
||||||
|
|
||||||
|
public static boolean ALARM_OFF_FLAG = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MailSender {
|
||||||
|
|
||||||
|
public static String HOST = "";
|
||||||
|
|
||||||
|
public static String TRANSPORT_PROTOCOL = "";
|
||||||
|
|
||||||
|
public static boolean SMTP_AUTH = true;
|
||||||
|
|
||||||
|
public static String USER_NAME = "";
|
||||||
|
|
||||||
|
public static String PASSWORD = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.conf;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ConfigInitializer {
|
||||||
|
private static Logger logger = Logger.getLogger(ConfigInitializer.class.getName());
|
||||||
|
|
||||||
|
public static void initialize() {
|
||||||
|
InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/sky-walking.auth");
|
||||||
|
if (inputStream == null) {
|
||||||
|
logger.log(Level.ALL, "No provider sky-walking certification documents, buried point won't work");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(inputStream);
|
||||||
|
initNextLevel(properties, Config.class, new ConfigDesc());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.log(Level.ALL, "Parsing certification file failed, buried won't work");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.log(Level.ALL, "Failed to read the certification file, buried won't work");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initNextLevel(Properties properties, Class<?> recentConfigType, ConfigDesc parentDesc) throws NumberFormatException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
for (Field field : recentConfigType.getFields()) {
|
||||||
|
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
|
||||||
|
String configKey = (parentDesc + "." +
|
||||||
|
field.getName()).toLowerCase();
|
||||||
|
String value = properties.getProperty(configKey);
|
||||||
|
if (value != null) {
|
||||||
|
if (field.getType().equals(int.class))
|
||||||
|
field.set(null, Integer.valueOf(value));
|
||||||
|
if (field.getType().equals(String.class))
|
||||||
|
field.set(null, value);
|
||||||
|
if (field.getType().equals(long.class))
|
||||||
|
field.set(null, Long.valueOf(value));
|
||||||
|
if (field.getType().equals(boolean.class))
|
||||||
|
field.set(null, Boolean.valueOf(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Class<?> innerConfiguration : recentConfigType.getClasses()) {
|
||||||
|
parentDesc.append(innerConfiguration.getSimpleName());
|
||||||
|
initNextLevel(properties, innerConfiguration, parentDesc);
|
||||||
|
parentDesc.removeLastDesc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigDesc {
|
||||||
|
private LinkedList<String> descs = new LinkedList<String>();
|
||||||
|
|
||||||
|
void append(String currentDesc) {
|
||||||
|
descs.addLast(currentDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeLastDesc() {
|
||||||
|
descs.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (descs.size() == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuilder ret = new StringBuilder(descs.getFirst());
|
||||||
|
boolean first = true;
|
||||||
|
for (String desc : descs) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ret.append(".").append(desc);
|
||||||
|
}
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.dao;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.conf.Config;
|
||||||
|
import com.ai.cloud.skywalking.alarm.model.ApplicationInfo;
|
||||||
|
import com.ai.cloud.skywalking.alarm.model.UserInfo;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AlarmMessageDao {
|
||||||
|
|
||||||
|
private static Logger logger = LogManager.getLogger(AlarmMessageDao.class);
|
||||||
|
private static Connection con;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Class.forName(Config.DB.DRIVER_CLASS);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
logger.error("Failed to found DB driver class.", e);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
con = DriverManager.getConnection(Config.DB.URL, Config.DB.USER_NAME, Config.DB.PASSWORD);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.error("Failed to connect DB", e);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<UserInfo> selectAllUserInfo() {
|
||||||
|
List<UserInfo> result = new ArrayList<UserInfo>();
|
||||||
|
try {
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT user_info.uid FROM user_info WHERE sts = ?");
|
||||||
|
ps.setString(1, "A");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
UserInfo userInfo;
|
||||||
|
while (rs.next()) {
|
||||||
|
userInfo = new UserInfo(rs.getString("uid"));
|
||||||
|
result.add(userInfo);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.error("Failed to select all user info", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int selectUserCount() {
|
||||||
|
try {
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT count(user_info.uid) as totalNumber FROM user_info WHERE sts = ?");
|
||||||
|
ps.setString(1, "A");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
return rs.getInt("totalNumber");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.error("Failed to select all user info", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ApplicationInfo> selectAllApplicationsByUserId(String userId) {
|
||||||
|
List<ApplicationInfo> result = new ArrayList<ApplicationInfo>();
|
||||||
|
try {
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT alarm_rule.app_id, alarm_rule.uid,alarm_rule.is_global, alarm_rule.todo_type," +
|
||||||
|
" alarm_rule.config_args FROM alarm_rule WHERE uid = ? AND sts = ?");
|
||||||
|
ps.setString(1, userId);
|
||||||
|
ps.setString(2, "A");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
ApplicationInfo globalConfig = null;
|
||||||
|
ApplicationInfo tmpApplication;
|
||||||
|
while (rs.next()) {
|
||||||
|
if ("1".equals(rs.getString("is_global"))) {
|
||||||
|
globalConfig = new ApplicationInfo();
|
||||||
|
globalConfig.setConfigArgs(rs.getString("config_args"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmpApplication = new ApplicationInfo();
|
||||||
|
tmpApplication.setAppId(rs.getString("app_id"));
|
||||||
|
tmpApplication.setUId(rs.getString("uid"));
|
||||||
|
tmpApplication.setConfigArgs(rs.getString("config_args"));
|
||||||
|
tmpApplication.setToDoType(rs.getString("todo_type"));
|
||||||
|
result.add(tmpApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalConfig == null) {
|
||||||
|
//
|
||||||
|
throw new IllegalArgumentException("Can not found the global config");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApplicationInfo> allApplication = new ArrayList<ApplicationInfo>();
|
||||||
|
ps = con.prepareStatement("SELECT application_info.app_id, application_info.uid FROM application_info WHERE uid = ? AND sts = ?");
|
||||||
|
ps.setString(1, userId);
|
||||||
|
ps.setString(2, "A");
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
ApplicationInfo applicationInfo;
|
||||||
|
while (rs.next()) {
|
||||||
|
applicationInfo = new ApplicationInfo();
|
||||||
|
applicationInfo.setAppId(rs.getString("app_id"));
|
||||||
|
applicationInfo.setUId(rs.getString("uid"));
|
||||||
|
allApplication.add(applicationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
allApplication.removeAll(result);
|
||||||
|
|
||||||
|
for (ApplicationInfo app : allApplication) {
|
||||||
|
app.setConfigArgs(globalConfig.getConfigArgs());
|
||||||
|
app.setToDoType(globalConfig.getToDoType());
|
||||||
|
result.add(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.error("Failed to query applications.", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.model;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class ApplicationInfo {
|
||||||
|
private String appId;
|
||||||
|
private String configArgs;
|
||||||
|
private String UId;
|
||||||
|
private String toDoType;
|
||||||
|
private ConfigArgsDescriber configArgsDescriber;
|
||||||
|
|
||||||
|
public ApplicationInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppId() {
|
||||||
|
return appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppId(String appId) {
|
||||||
|
this.appId = appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigArgs(String configArgs) {
|
||||||
|
this.configArgs = configArgs;
|
||||||
|
configArgsDescriber = new Gson().fromJson(configArgs, ConfigArgsDescriber.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigArgsDescriber getConfigArgsDescriber() {
|
||||||
|
return configArgsDescriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfigArgs() {
|
||||||
|
return configArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUId(String UId) {
|
||||||
|
this.UId = UId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUId() {
|
||||||
|
return UId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToDoType(String toDoType) {
|
||||||
|
this.toDoType = toDoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToDoType() {
|
||||||
|
return toDoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ApplicationInfo)) return false;
|
||||||
|
|
||||||
|
ApplicationInfo that = (ApplicationInfo) o;
|
||||||
|
|
||||||
|
if (getAppId() != null ? !getAppId().equals(that.getAppId()) : that.getAppId() != null) return false;
|
||||||
|
return !(getUId() != null ? !getUId().equals(that.getUId()) : that.getUId() != null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = getAppId() != null ? getAppId().hashCode() : 0;
|
||||||
|
result = 31 * result + (getUId() != null ? getUId().hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.model;
|
||||||
|
|
||||||
|
public class ConfigArgsDescriber {
|
||||||
|
private int period;
|
||||||
|
|
||||||
|
public int getPeriod() {
|
||||||
|
return period;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeriod(int period) {
|
||||||
|
this.period = period;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UserInfo {
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
private List<ApplicationInfo> applicationInfos;
|
||||||
|
|
||||||
|
public UserInfo(String userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationInfo> getApplicationInfos() {
|
||||||
|
return applicationInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationInfos(List<ApplicationInfo> applicationInfos) {
|
||||||
|
this.applicationInfos = applicationInfos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.redis;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.conf.Config;
|
||||||
|
import com.ai.cloud.skywalking.alarm.model.ApplicationInfo;
|
||||||
|
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import redis.clients.jedis.JedisPool;
|
||||||
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RedisUtil {
|
||||||
|
private static Logger logger = LogManager.getLogger(RedisUtil.class);
|
||||||
|
private static JedisPool jedisPool;
|
||||||
|
private static String[] config;
|
||||||
|
private static RedisInspector connector = new RedisInspector();
|
||||||
|
private static Object lock = new Object();
|
||||||
|
|
||||||
|
static {
|
||||||
|
GenericObjectPoolConfig genericObjectPoolConfig = buildGenericObjectPoolConfig();
|
||||||
|
String redisServerConfig = Config.Alarm.REDIS_SERVER;
|
||||||
|
if (redisServerConfig == null || redisServerConfig.length() <= 0) {
|
||||||
|
logger.error("Redis server is not setting. Switch off alarm module. ");
|
||||||
|
} else {
|
||||||
|
config = redisServerConfig.split(":");
|
||||||
|
if (config.length != 2) {
|
||||||
|
logger.error("Redis server address is illegal setting, need to be 'ip:port'. Switch off alarm module. ");
|
||||||
|
Config.Alarm.ALARM_OFF_FLAG = true;
|
||||||
|
} else {
|
||||||
|
jedisPool = new JedisPool(genericObjectPoolConfig, config[0],
|
||||||
|
Integer.valueOf(config[1]));
|
||||||
|
// Test connect redis.
|
||||||
|
Jedis jedis = null;
|
||||||
|
try {
|
||||||
|
jedis = jedisPool.getResource();
|
||||||
|
} catch (Exception e) {
|
||||||
|
handleFailedToConnectRedisServerException(e);
|
||||||
|
logger.error("can't connect to redis["
|
||||||
|
+ Config.Alarm.REDIS_SERVER + "]", e);
|
||||||
|
} finally {
|
||||||
|
if (jedis != null) {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getAlarmMessage(ApplicationInfo applicationInfo) {
|
||||||
|
Jedis jedis = null;
|
||||||
|
try {
|
||||||
|
jedis = jedisPool.getResource();
|
||||||
|
return new ArrayList<String>(jedis.hgetAll(generateAlarmKey(applicationInfo)).values());
|
||||||
|
} catch (Exception e) {
|
||||||
|
handleFailedToConnectRedisServerException(e);
|
||||||
|
logger.error("Failed to set data.", e);
|
||||||
|
} finally {
|
||||||
|
if (jedis != null) {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateAlarmKey(ApplicationInfo applicationInfo) {
|
||||||
|
return applicationInfo.getUId() + "-" + applicationInfo.getAppId() + "-"
|
||||||
|
+ ((System.currentTimeMillis() / (10000 * 6))
|
||||||
|
- applicationInfo.getConfigArgsDescriber().getPeriod());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GenericObjectPoolConfig buildGenericObjectPoolConfig() {
|
||||||
|
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
|
||||||
|
genericObjectPoolConfig.setTestOnBorrow(true);
|
||||||
|
genericObjectPoolConfig.setMaxIdle(Config.Alarm.REDIS_MAX_IDLE);
|
||||||
|
genericObjectPoolConfig.setMinIdle(Config.Alarm.REDIS_MIN_IDLE);
|
||||||
|
genericObjectPoolConfig.setMaxTotal(Config.Alarm.REDIS_MAX_TOTAL);
|
||||||
|
return genericObjectPoolConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleFailedToConnectRedisServerException(Exception e) {
|
||||||
|
if (e instanceof JedisConnectionException) {
|
||||||
|
// 发生连接不上Redis
|
||||||
|
if (connector == null || !connector.isAlive()) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (!connector.isAlive()) {
|
||||||
|
// 启动巡检线程
|
||||||
|
connector.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RedisInspector extends Thread {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
logger.debug("Connecting to redis....");
|
||||||
|
Jedis jedis;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
jedisPool = new JedisPool(buildGenericObjectPoolConfig(),
|
||||||
|
config[0], Integer.valueOf(config[1]));
|
||||||
|
jedis = jedisPool.getResource();
|
||||||
|
jedis.get("ok");
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof JedisConnectionException) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000L);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
logger.error("Sleep failed", e);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.debug("Connected to redis success. Open alarm function.");
|
||||||
|
Config.Alarm.ALARM_OFF_FLAG = false;
|
||||||
|
// 清理当前线程
|
||||||
|
connector = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.ai.cloud.skywalking.alarm.zk;
|
||||||
|
|
||||||
|
import com.ai.cloud.skywalking.alarm.AlarmServerRegisterWatcher;
|
||||||
|
import com.ai.cloud.skywalking.alarm.conf.Config;
|
||||||
|
import org.apache.curator.RetryPolicy;
|
||||||
|
import org.apache.curator.framework.CuratorFramework;
|
||||||
|
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||||
|
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
|
||||||
|
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ZKUtil {
|
||||||
|
|
||||||
|
private static Logger logger = LogManager.getLogger(ZKUtil.class);
|
||||||
|
|
||||||
|
private static CuratorFramework client;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
RetryPolicy retryPolicy = new ExponentialBackoffRetry(Config.ZKPath.RETRY_TIMEOUT,
|
||||||
|
Config.ZKPath.RETRY_TIMES);
|
||||||
|
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().
|
||||||
|
connectString(Config.ZKPath.CONNECT_STR)
|
||||||
|
.connectionTimeoutMs(Config.ZKPath.CONNECT_TIMEOUT).retryPolicy(retryPolicy);
|
||||||
|
client = builder.build();
|
||||||
|
client.start();
|
||||||
|
|
||||||
|
createIfNotExists(getRegisterLockPath());
|
||||||
|
createIfNotExists(getUserLockPathPrefix());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to connect zookeeper.", e);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InterProcessMutex getRegisterLock() {
|
||||||
|
return new InterProcessMutex(client, getRegisterLockPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InterProcessMutex getProcessUserLock(String uid) {
|
||||||
|
return new InterProcessMutex(client, getUserLockPath(uid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(String serverId) {
|
||||||
|
try {
|
||||||
|
client.create().creatingParentsIfNeeded().forPath(getRegisterServerPathPrefix() + "/" + serverId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to register server", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> selectAllServerIds() {
|
||||||
|
try {
|
||||||
|
return client.getChildren().forPath(getRegisterServerPathPrefix());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to get children of Path[" + getRegisterServerPathPrefix() + "].", e);
|
||||||
|
}
|
||||||
|
return new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void watch(AlarmServerRegisterWatcher instance) {
|
||||||
|
try {
|
||||||
|
client.getChildren().usingWatcher(instance).forPath(getRegisterServerPathPrefix());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to get children for path[" + getRegisterServerPathPrefix() + "].", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String getRegisterLockPath() {
|
||||||
|
return Config.ZKPath.NODE_PREFIX + Config.ZKPath.SERVER_REGISTER_LOCK_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getUserLockPath(String uid) {
|
||||||
|
return getUserLockPathPrefix() + "/" + uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getUserLockPathPrefix() {
|
||||||
|
return Config.ZKPath.NODE_PREFIX + Config.ZKPath.USER_REGISTER_LOCK_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void createIfNotExists(String path) throws Exception {
|
||||||
|
if (client.checkExists().forPath(path) == null) {
|
||||||
|
client.create().creatingParentsIfNeeded().forPath(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getRegisterServerPathPrefix() {
|
||||||
|
return Config.ZKPath.NODE_PREFIX + Config.ZKPath.REGISTER_SERVER_PATH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||||
|
|
||||||
|
<log4j:configuration>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern"
|
||||||
|
value="%d - %c -%-4r [%t] %-5p %x - %m%n" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="debug" />
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
|
||||||
|
</log4j:configuration>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="debug">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="debug">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
Loading…
Reference in New Issue