服务监控以及服务降级基础组件 java-meerkat

未知
Java
跨平台
2017-06-11
ChanningBJ

meerkat 是爱奇艺移动服务端团队开发的服务监控以及服务降级基础组件,主要为了解决调用外部接口的时候进行成功率,响应时间,QPS指标的监控,同时在成功率下降到预设的阈值以下的时候自动切断外部接口的调用,外部接口成功率恢复后自动恢复请求。

主要功能

  1. 监控操作的成功率以及响应时间指标

  2. log文件和Grafhite两种监控指标上报方式,支持扩展其他的上报方式

  3. (可选功能)成功率下降到预设的阈值以下触发熔断保护,暂定对外部接口的访问,成功率恢复以后自动恢复访问

更详细的文档说明请参见 Wiki

通过日志的方式查看监控结果

type=GAUGE, name=com.qiyi.mbd.test.GetPlayCountCommand.normal-rate, value=0.0
type=GAUGE, name=com.qiyi.mbd.test.GetPlayCountCommand.success-rate, value=61.0
type=TIMER, name=com.qiyi.mbd.test.GetPlayCountCommand.time, count=25866500, min=0.0, max=0.001, mean=3.963926781047921E-5, stddev=1.951102156677818E-4, median=0.0, p75=0.0, p95=0.0, p98=0.001, p99=0.001, p999=0.001, mean_rate=649806.0831335272, m1=1665370.7316699813, m5=2315813.300713087, m15=2446572.324069477, rate_unit=events/second, duration_unit=milliseconds

通过上报Grafana查看监控结果 

Maven

<dependency>
    <groupId>com.github.qiyimbd</groupId>
    <artifactId>meerkat</artifactId>
    <version>1.0</version>
</dependency>

如何使用

基本使用

假设我们的服务中需要从HTTP接口查询一个节目的播放次数,为了防止这个HTTP接口大量超时影响我们自身服务的质量,可以定义一个查询Command:

public class GetPlayCountCommand extends FusingCommand<Long> {    private final Long videoID;    public GetPlayCountCommand(Long videoID) {        this.videoID = videoID;
    }        
    protected Optional<Long> run() {        Long result = 0l;
        // 调用HTTP接口获取视频的播放次数信息
        // 如果调用失败,返回 null 或者抛出异常,会将这次操作记录为失败
        // 如果ID非法,返回 Optional.absent(),会将这次操作记录为成功
        return Optional.fromNullable(result);
    }
}

执行查询:

//获取视频ID为123的视频的播放次数GetPlayCountCommand command = new GetPlayCountCommand(123l);Long result = command.execute(); // 执行查询操作,如果执行失败或者处于熔断状态,返回 null

默认情况下,操作成功率每10秒更新一次,开启通断以后当成功率小于90%的时候进入熔断状态,熔断状态下调用execute()函数会返回null,熔断状态持续50秒,终端终止以后恢复正常访问。

定义熔断状态下的返回结果

当处于熔断或者命令执行失败的时候execute()函数会返回null,可以通过Override getFallback这个函数对失败/熔断情况下的返回值进行修改。例如我们希望在播放次数请求失败的情况下默认播放次数是47,可以这样实现:

public class GetPlayCountCommand extends FusingCommand<Long> {    private final Long videoID;    public GetPlayCountCommand(Long videoID) {        this.videoID = videoID;
    }        
    protected Optional<Long> run() {        Long result = 0l;
        // 调用HTTP接口获取视频的播放次数信息
        // 如果调用失败,返回 null 或者抛出异常,会将这次操作记录为失败
        // 如果ID非法,返回 Optional.absent(),会将这次操作记录为成功
        return Optional.fromNullable(result);
    }    
    /**     *     * @param isFusing 当前是否处于熔断状态     * @param e        run函数抛出的异常     * @return 熔断或者请求出现错误的时候execute()函数的返回值     */
    @Override
    protected Long getFallback(boolean isFusing, Exception e) {
        return 47l;
    }
}

配置监控上报

定义配置文件

首先定义一个接口,继承自GraphiteReporterConfig,通过这个接口定义配置文件的加载路径。配置文件路径的定义方法请参照 owner 文档, 下面是一个例子:

@Config.Sources("classpath:config.properties")public interface MyConfig extends GraphiteReporterConfig {
}

配置文件中需要定义下列内容:

下面这个例子是在192.168.0.0.1和192.168.0.0.2两台服务器上开启监控数据上报,上报监控指标的前缀是project_name.dc:

meter.reporter.enabled.hosts = 192.168.0.0.1,192.168.0.0.2
meter.reporter.perfix = project_name.dc
meter.reporter.carbon.host = hostname.graphite

由于相同机房的不同服务器对外部接口的访问情况一般比较类似,所以仅选取部分机器上报,也是为了节省资源。仅选择部分机器上报不影响熔断效果。

初始化配置上报

在服务初始化的时候需要对监控上报进行设置。下面的例子中开启了监控数据向日志文件的打印,同时通过MyConfig指定的配置文件加载Graphite配置信息。

MeterCenter.INSTANCE
    .enableReporter(new EnablingLogReporter("org.apache.log4j.RollingFileAppender"))
    .enableReporter(new EnablingGraphiteReporter(MyConfig.class))
    .init();

查看统计结果

统计结果会以熔断命令类名为进行分组。例如前面我们定义的 GetPlayCountCommand 类,package name 是 com.qiyi.mbd.test,那么在日志中的输出将会是这个样子:

type=GAUGE, name=com.qiyi.mbd.test.GetPlayCountCommand.normal-rate, value=0.0
type=GAUGE, name=com.qiyi.mbd.test.GetPlayCountCommand.success-rate, value=61.0
type=TIMER, name=com.qiyi.mbd.test.GetPlayCountCommand.time, count=25866500, min=0.0, max=0.001, mean=3.963926781047921E-5, stddev=1.951

如果配置了Graphite上报,可以看到下面的监控图

关于Graphite+Grafana的配置,可以参考文章:使用graphite和grafana进行应用程序监控

配置熔断的阀值和持续时间

首先创建一个接口,继承自FusingConfig,用于指定配置文件的加载路径,同时还可以设定配置文件的刷新时间,具体定义方法请参照 owner 文档

@Config.Sources("classpath:app_config.properties")@Config.HotReload(        value = 1, unit = java.util.concurrent.TimeUnit.MINUTES,        type = Config.HotReloadType.ASYNC)public interface APPFusingConfig extends FusingConfig {
}

创建查询Command的时候在构造函数中传入

public class GetPlayCountCommand extends FusingCommand<Long> {    private final Long videoID;    public GetPlayCountCommand(Long videoID) {        super( APPFusingConfig.class);        this.videoID = videoID;
    }        
    protected Optional<Long> run() {        Long result = 0l;
        // 调用HTTP接口获取视频的播放次数信息
        // 如果调用失败,返回 null 或者抛出异常,会将这次操作记录为失败
        // 如果ID非法,返回 Optional.absent(),会将这次操作记录为成功
        return Optional.fromNullable(result);
    }
}

配置文件定义:

配置文件中的 CommandClassName 是每个操作类的名称,可以为每个操作单独设置上述参数。同时,这个配置文件支持动态加载,乐意通过修改fusing.[CommandClassName].mode 手工触发或者关闭熔断。

加载中

评论(0)

暂无评论

暂无资讯

暂无问答

Java实例教程

Java当前日期/时间 Java将字符串转换为日期 Java当前工作目录 Java正则表达式 Java立方体 编译并执行Java Online 用于连接两个数组的Java程序 Java添加两个数组 字符串的Java字符 Java多字符...

11/02 10:28
0
0
em

https://localhost:1158/em/console/logon/logon <java-config classpath-suffix="" debug-options="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9009" system-classpat...

2014/07/31 16:42
27
0
分享java教程~

学习Java一 配置环境变量 学习Java二 开发第一个Java程序 学习Java三 Java的注释 学习Java四 Java标识符 学习Java五 数据类型 学习Java六 Java的浮点精度 学习Java七 Java数组 学习Java八 Ja...

2010/09/23 22:14
125
0
编程字典-Java学习线路图

Java学习线路图 Java教程 Java 教程 Java 简介 Java 开发环境配置 Java 基础语法 Java 对象和类 Java 基本数据类型 Java变量类型 Java修饰符 Java运算符 Java循环结构 Java分支结构 Java Num...

10/10 17:50
2
0
ThreadLocal in Java - Example Program and Tutorial

ThreadLocal in Java is another way to achieve thread-safety apart from writing immutable classes. If you have been writing multi-threaded or concurrent code in Java then you mus...

2014/12/10 17:30
109
0
Java干货分享:新手如何理解常说的JDK、JRE、JVM

很多刚刚学习Java的初学者对于JDK、JRE、JVM的概念还很模糊 ,于是笔者整理了一些相关的知识点,从三者的本质出发,给大家总结一下这三者到底有何区别于作用!先对这三者理一下关系,有一个大...

10/11 21:16
0
0
opensuse下jdk8的安装步骤

opensuse linux jdk8 安装

2014/04/04 00:31
77
0
Ubuntu 10.10 下安装配置 JDK 7

第一步 wget -c http://download.Oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586.tar.gz (注:如果下载不下来,建议使用迅雷下载,然后拷贝到Linux系统上。) 第二步:解压安装 sudo tar z...

2012/05/13 07:13
141
1
Ubuntu 14 安装jdk7

Ubuntu 14 安装jdk7

2014/10/27 22:12
153
0

没有更多内容

加载失败,请刷新页面

返回顶部
顶部