从零到日志采集索引可视化、监控报警、rpc trace跟踪-系统上下线监控

github开源  欢迎一起维护~~
  1. 之前说到注册中心的设计,zookeeper中的节点部署如下:
    1. kafkaAppender初始化向zk进行app节点注册,并写入相关的信息
    2. kafkaAppender发生异常暂停工作会向app节点写入相关信息,以便监控系统能够实时感知并发送报警
    3. app正常或者异常退出后,zk中的app临时节点会消失,shutdownhook会正常运行,监控系统能够实时感知并发送报警(这里就需要我们在自定义的log appender中写好相应的hook,防止对接系统无法正常释放资源,项目不要用kill -9 pid,应该使用kill pid)
    4. zk中有永久节点用来记录app的最近一次部署信息
从零到日志采集索引可视化、监控报警、rpc trace跟踪-系统上下线监控_第1张图片
那么我们只需要监控zk节点的变化,即可知道对接的系统上下线情况,以及内嵌的采集器是否存活,具体代码如下(curator框架和zkclient一起混用):
public class  ScrollChildrenChangeListener  implements PathChildrenCacheListener  {

    private static final Logger  LOGGER = LoggerFactory. getLogger( ScrollChildrenChangeListener. class) ;

    private RabbitmqService  rabbitmqService ;

    private ZkClient  zkClient ;

    private AppInfoService  appInfoService ;

    public  ScrollChildrenChangeListener(RabbitmqService rabbitmqService ZkClient zkClient AppInfoService appInfoService) {
        this. rabbitmqService = rabbitmqService ;
        this. zkClient = zkClient ;
        this. appInfoService = appInfoService ;
    }

    @Override
    public void  childEvent(CuratorFramework client PathChildrenCacheEvent event)  throws Exception {
        switch (event.getType()) {
            case  CHILD_ADDED:
                PathChildrenCache pathChildrenCache =  new PathChildrenCache(client event.getData().getPath() , true) ;
                pathChildrenCache.start(PathChildrenCache.StartMode. POST_INITIALIZED_EVENT) ;
                pathChildrenCache.getListenable().addListener( new AppChildrenChangeListener( this. rabbitmqService , this. zkClient , this. appInfoService)) ;
                LOGGER.info( "app added: " + event.getData().getPath()) ;
                break;
            case  CHILD_REMOVED:
                LOGGER.info( "app removed: " + event.getData().getPath()) ;
                break;
        }
    }
}


public class AppChildrenChangeListener  implements PathChildrenCacheListener {

    private static final Logger  LOGGER = LoggerFactory. getLogger(AppChildrenChangeListener. class) ;

    private RabbitmqService  rabbitmqService ;

    private ZkClient  zkClient ;

    private AppInfoService  appInfoService ;

    public  AppChildrenChangeListener(RabbitmqService rabbitmqService ZkClient zkClient AppInfoService appInfoService) {
        this. rabbitmqService = rabbitmqService ;
        this. zkClient = zkClient ;
        this. appInfoService = appInfoService ;
    }

    @Override
    public void  childEvent(CuratorFramework client PathChildrenCacheEvent event)  throws Exception {
        String node = Constants. EMPTY_STR ;
        String app = Constants. EMPTY_STR ;
        String host = Constants. EMPTY_STR ;
        String info = Constants. EMPTY_STR ;
        String[] datas =  null;
        switch (event.getType()) {
            case  CHILD_ADDED:
                node = event.getData().getPath() ;
                app =  this.getApp(node) ;
                host =  this.getHost(node) ;
                if (!CacheService. appHosts.contains(node)) {
                    datas =  this. zkClient.readData(Constants. ROOT_PATH_PERSISTENT + Constants. SLASH + app + Constants. SLASH + host).toString().split(Constants. SEMICOLON) ;

                    info =  this.buildMsg(DateUtil. format( new Date(System. currentTimeMillis()) DateUtil. YYYYMMDDHHMMSS) app ,
                            this.getHost(node) datas[ 1] Constants. APP_START) ;

                    // add to the queue
                    this. rabbitmqService.sendMessage(info datas[ 0]) ;
                    LOGGER.info(info) ;
                    CacheService. appHosts.add(node) ;
                    this. appInfoService.add(host app Constants. ZK_NODE_TYPE_EPHEMERAL LogCollectionStatus. RUNNING) ;
                }
                this. appInfoService.add(host app Constants. ZK_NODE_TYPE_PERSISTENT LogCollectionStatus. HISTORY) ;
                break;
            case  CHILD_REMOVED:
                node = event.getData().getPath() ;
                app =  this.getApp(node) ;
                host =  this.getHost(node) ;
                datas =  this. zkClient.readData(Constants. ROOT_PATH_PERSISTENT + Constants. SLASH + app + Constants. SLASH + host).toString().split(Constants. SEMICOLON) ;

                info =  this.buildMsg(DateUtil. format( new Date(System. currentTimeMillis()) DateUtil. YYYYMMDDHHMMSS) app ,
                        this.getHost(node) datas[ 1] Constants. APP_STOP) ;

                // add to the queue
                this. rabbitmqService.sendMessage(info datas[ 0]) ;
                LOGGER.info(info) ;
                if (CacheService. appHosts.contains(node)) {
                    CacheService. appHosts.remove(node) ;
                    this. appInfoService.delete(host app Constants. ZK_NODE_TYPE_EPHEMERAL) ;
                }
                break;
            case  CHILD_UPDATED:
                node = event.getData().getPath() ;
                datas =  this. zkClient.readData(node).toString().split(Constants. SEMICOLON) ;
                app =  this.getApp(node) ;
                host =  this.getHost(node) ;

                info =  this.buildMsg(DateUtil. format( new Date(Long. parseLong(datas[ 0])) DateUtil. YYYYMMDDHHMMSS) app ,
                        this.getHost(node) datas[ 1] Constants. APP_APPENDER_STOP) ;

                // add to the queue
                this. rabbitmqService.sendMessage(info , this. zkClient.readData(Constants. ROOT_PATH_PERSISTENT + Constants. SLASH + app + Constants. SLASH + host).toString().split(Constants. SEMICOLON)[ 0]) ;
                LOGGER.info(info) ;
                this. appInfoService.update(host app Constants. ZK_NODE_TYPE_EPHEMERAL LogCollectionStatus. STOPPED) ;
                break;
        }
    }

    /**
     *  根据 node 获取 app
     *  @param  node
      @return
      */
    private String  getApp(String node) {
        String tmp = node.substring( 0 node.lastIndexOf(Constants. SLASH)) ;
        return this.getLast(tmp) ;
    }

    /**
     *  根据 node 获取 host
     *  @param  node
      @return
      */
    private String  getHost(String node) {
        return this.getLast(node) ;
    }

    /**
     *  返回末尾字符串
      @param  line
      @return
      */
    private String  getLast(String line) {
        return line.substring(line.lastIndexOf(Constants. SLASH) +  1) ;
    }

    /**
     *  构造报警 msg
     *  @param  time
      @param  app
      @param  host
      @param  deploy
      @param  msg
      @return
      */
    private String  buildMsg(String time String app String host String deploy String msg) {
        AlertDto alertDto =  new AlertDto(time app host deploy msg) ;
        return alertDto.toString() ;
    }
}


@Service
public class AppInfoService {

    @Autowired
    private ZkClient  zkClient ;
    @Autowired
    private AppInfoRepository  appInfoRepository ;

    /**
     *  保存 appInfo
     *  @param  host
      @param  app
      @param  type
      @param  logCollectionStatus
      */
    public void  add(String host String app , int type LogCollectionStatus logCollectionStatus) {
        AppInfo appInfo =  new AppInfo() ;
        AppInfoPK appInfoPK =  new AppInfoPK(host app type) ;
        appInfo.setAppInfoPK(appInfoPK) ;
        appInfo.setStatus(logCollectionStatus.symbol()) ;
        if (logCollectionStatus.symbol().equals(LogCollectionStatus. HISTORY.symbol())) {
            appInfo.setDeploy( this.getDeploy(Constants. ROOT_PATH_PERSISTENT + Constants. SLASH + app + Constants. SLASH + host)) ;
        else {
            appInfo.setDeploy( this.getDeploy(Constants. ROOT_PATH_EPHEMERAL + Constants. SLASH + app + Constants. SLASH + host)) ;
        }
        this. appInfoRepository.save(appInfo) ;
    }

    /**
     *  修改记录的收集日志状态
      @param  host
      @param  app
      @param  type
      @param  logCollectionStatus
      */
    public void  update(String host String app , int type LogCollectionStatus logCollectionStatus) {
        AppInfo appInfo =  this. appInfoRepository.findOne( new AppInfoPK(host app type)) ;
        appInfo.setStatus(logCollectionStatus.symbol()) ;
        this. appInfoRepository.save(appInfo) ;
    }

    /**
     *  根据 host app 进行删除
      @param  host
      @param  app
      @param  type
      */
    public void  delete(String host String app , int type) {
        AppInfo appInfo =  this. appInfoRepository.findOne( new AppInfoPK(host app type)) ;
        if ( null != appInfo) {
            this. appInfoRepository.delete(appInfo) ;
        }
    }

    /**
     *  删除所有的数据
      */
    public void  deleteAll() {
        this. appInfoRepository.deleteAll() ;
    }

    /**
     *  获取 app 的部署位置
      @param  path
      @return
      */
    private String  getDeploy(String path) {
        String data =  this. zkClient.readData(path) ;
        return data.split(Constants. SEMICOLON)[ 1] ;
    }
}


  */
@Service
public class  AppStatusMonitorService  implements InitializingBean {

    @Autowired
    private CuratorFramework  curatorFramework ;
    @Autowired
    private RabbitmqService  rabbitmqService ;
    @Autowired
    private ZkClient  zkClient ;
    @Autowired
    private AppInfoService  appInfoService ;

    @Override
    public void  afterPropertiesSet()  throws Exception {
        PathChildrenCache pathChildrenCache =  new PathChildrenCache( curatorFramework Constants. ROOT_PATH_EPHEMERAL , true) ;
        pathChildrenCache.start(PathChildrenCache.StartMode. POST_INITIALIZED_EVENT) ;
        pathChildrenCache.getListenable().addListener( new ScrollChildrenChangeListener( this. rabbitmqService , this. zkClient , this. appInfoService)) ;
    }
}


@Service
public class CacheService  implements InitializingBean {

    private static final Logger  LOGGER = LoggerFactory. getLogger(CacheService. class) ;

    public static List  appHosts new ArrayList() ;

    @Autowired
    private CuratorFramework  curatorFramework ;
    @Autowired
    private AppInfoService  appInfoService ;
    @Autowired
    private ZkClient  zkClient ;

    @Override
    public void  afterPropertiesSet()  throws Exception {
        //  mysql 数据进行清空
        this. appInfoService.deleteAll() ;
        List apps =  curatorFramework.getChildren().forPath(Constants. ROOT_PATH_EPHEMERAL) ;

        //  启动时获取所有的节点数据 写入本地缓存和 mysql
        for (String app : apps) {
            List hosts =  curatorFramework.getChildren().forPath(Constants. ROOT_PATH_EPHEMERAL + Constants. SLASH + app) ;
            for (String host : hosts) {
                appHosts.add(Constants. ROOT_PATH_EPHEMERAL + Constants. SLASH + app + Constants. SLASH + host) ;
                this. appInfoService.add(host app Constants. ZK_NODE_TYPE_EPHEMERAL , this.calLogCollectionStatus(app host)) ;
            }
        }

        apps =  curatorFramework.getChildren().forPath(Constants. ROOT_PATH_PERSISTENT) ;
        for (String app : apps) {
            List hosts =  curatorFramework.getChildren().forPath(Constants. ROOT_PATH_PERSISTENT + Constants. SLASH + app) ;
            for (String host : hosts) {
                this. appInfoService.add(host app Constants. ZK_NODE_TYPE_PERSISTENT LogCollectionStatus. HISTORY) ;
            }
        }
    }

    /**
     *  根据 app host 计算 LogCollectionStatus
     *  @param  app
      @param  host
      @return
      */
    private LogCollectionStatus  calLogCollectionStatus(String app String host) {
        String[] datas =  this. zkClient.readData(Constants. ROOT_PATH_EPHEMERAL + Constants. SLASH + app + Constants. SLASH + host).toString().split(Constants. SEMICOLON) ;
        if (datas[ 0].equals(Constants. APPENDER_INIT_DATA)) {
            return LogCollectionStatus. RUNNING ;
        }
        return LogCollectionStatus. STOPPED ;
    }
}

代码较为简单,不再赘述,主要就是监听zk节点的变化情况,并且将app和host信息采集进入了mysql(同时本项目进程中缓存了一份用来提高速度)。

你可能感兴趣的:(zookeeper,es,日志采集,kafka,rpc,trace跟踪,rpc性能分析,监控报警,监控报警)