暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

技术专栏 | 深入理解Metrics(二):Counters

TalkingData 2017-12-14
645


本章会继续讲解Metrics的第二个工具:Counters。

1. Counters的使用 


在account内部使用Counters检测接口发生异常的次数,一段时间内如果超过阀值,会触发报警。 


下面的一段代码是account用来检测败发生的次数


public class MetricsCounterTest extendsTest0Abstract {

   private List<String> users;

   private String password;

 

   @Autowired

   @Qualifier("officialCustomerService")

   private LoginService loginService;

 

   @Before

   public void before() {

       password = "RIYU3ZOsYAThlfqfazyEbT+qe5ACN";

       users = new ArrayList<>();

        users.add("bingxin.li@tendcloud.com">bingxin.li@tendcloud.com");

       users.add("bingxin.li001@tendcloud.com">bingxin.li001@tendcloud.com");

       users.add("bingxin.li002@tendcloud.com">bingxin.li002@tendcloud.com");

       users.add("bingxin.li003@tendcloud.com">bingxin.li003@tendcloud.com");

       users.add("bingxin.li004@tendcloud.com">bingxin.li004@tendcloud.com");

       users.add("bingxin.li005@tendcloud.com">bingxin.li005@tendcloud.com");

       users.add("libingxin2013@outlook.com">libingxin2013@outlook.com");

    }

 

   @Test

   public void login() throws Exception {

       MetricRegistry metrics = new MetricRegistry();

       ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();

       reporter.start(1, TimeUnit.SECONDS);

 

       Counter counter = metrics.counter(

 

           MetricRegistry.name(MetricsCounterTest.class, "failed","size"));

 

       for (String user : users) {

           try {

               loginService.login(Base64.getEncoder().encodeToString(user.getBytes()),password);

           } catch (HttpUnauthorizedException e) {

                counter.inc();

                TimeUnit.SECONDS.sleep(2);

               Assert.assertTrue(counter.getCount() < 3);

           }

       }

    }

}


运行后输出:


17-11-28 17:35:30=============================================================

 

-- Counters --------------------------------------------------------------------

metrics.MetricsCounterTest.failed.size

            count = 3

 

java.lang.AssertionError

                   atorg.junit.Assert.fail(Assert.java:86)

                   atorg.junit.Assert.assertTrue(Assert.java:41)

                   atorg.junit.Assert.assertTrue(Assert.java:52)

                   atmetrics.MetricsCounterTest.login(MetricsCounterTest.java:66)

                   atsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                   atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

                   atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                   atjava.lang.reflect.Method.invoke(Method.java:498)

                   atorg.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

                   atorg.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

                   atorg.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

                   atorg.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

                   atorg.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)


从输出结果可以看出,ConsoleReporter每秒输出异常次数,当异常次数达到阀值3时,断言失败。

2. Counter 层级结构



Counter内部通过持有LongAdderAdapter的实例来实现Counting接口,而LongAdderAdapter内部依赖的是JDK1.8并发原子操作的LongAdder。


那么Counter是如何获取到LongAdderAdapter的实例呢?



3. LongAdder 工作原理


通过上面的创建和适配过程,并发原子操作最终交由LongAdder类完成,下面让我们来研究下LongAdder类的工作流程。



工作流程明:


1. LongAdder继承Striped64类,Striped64使用不安全的Unsafe类来进行原子操作。为了防止不可预测的情况发生,建议不要在代码中直接使用,除非你有Doug Lea的实力。 

2. LongAdder最核心的就是 add(long x) 方法,不管自增和自减都会调用此方法。 

3. add方法基于base的CAS操作返回值来验证是否发生并发。 

4. 未发生并发:后续的原子操作、返回值都是基于base。

5. 发生并发:通过Cell数组将原子操作分散到子项中进行,Cell是Striped64的内部类,里面有存储long值的value字段。 

6. Cell数组的索引:依赖与当前线程的threadLocalRandomProbe。


获取偏移量的代码解析:



是否生了并操作:



实际的并发操作:



4. 结束语 


Java除了并发包,还有很多集合类等都是Doug Lea编写的,他的个人主页:http://g.oswego.edu/ 
通过本章对Counters的讲解,相信你一定会有所收获。


文章转载自TalkingData,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论