From 19db20f00d7f8334de67d03f90ead22bf998530c Mon Sep 17 00:00:00 2001
From: Eric Zhao
- * Degrade is used when the resources are in an unstable state, these resources
- * will be degraded within the next defined time window. There are three ways to
- * measure whether a resource is stable or not:
- *
- *
- *
- * Note: When degrading by {@link RuleConstant#DEGRADE_GRADE_EXCEPTION_COUNT}, time window - * less than 60 seconds will not work as expected. Because the exception count is - * summed by minute, when a short time window elapsed, the degradation condition - * may still be satisfied. - *
- * - * @author Carpenter Lee - */ -public class ExceptionCountDegradeDemo { - private static final String KEY = "abc"; - - private static AtomicInteger total = new AtomicInteger(); - private static AtomicInteger pass = new AtomicInteger(); - private static AtomicInteger block = new AtomicInteger(); - private static AtomicInteger bizException = new AtomicInteger(); - - private static volatile boolean stop = false; - private static final int threadCount = 1; - private static int seconds = 60 + 40; - - public static void main(String[] args) throws Exception { - tick(); - initDegradeRule(); - - for (int i = 0; i < threadCount; i++) { - Thread entryThread = new Thread(new Runnable() { - - @Override - public void run() { - int count = 0; - while (true) { - count++; - Entry entry = null; - try { - Thread.sleep(20); - entry = SphU.entry(KEY); - // token acquired, means pass - pass.addAndGet(1); - if (count % 2 == 0) { - // biz code raise an exception. - throw new RuntimeException("throw runtime "); - } - } catch (BlockException e) { - block.addAndGet(1); - } catch (Throwable t) { - bizException.incrementAndGet(); - Tracer.trace(t); - } finally { - total.addAndGet(1); - if (entry != null) { - entry.exit(); - } - } - } - } - - }); - entryThread.setName("working-thread"); - entryThread.start(); - } - - } - - private static void initDegradeRule() { - List- * Degrade is used when the resources are in an unstable state, these resources - * will be degraded within the next defined time window. There are three ways to - * measure whether a resource is stable or not: - *
- * Degrade is used when the resources are in an unstable state, these resources - * will be degraded within the next defined time window. There are two ways to - * measure whether a resource is stable or not: - *
* 1529399827825,total:0, pass:0, block:0 * 1529399828825,total:4263, pass:100, block:4164 - * 1529399829825,total:19179, pass:4, block:19176 - * 1529399830824,total:19806, pass:0, block:19806 //begin degrade + * 1529399829825,total:19179, pass:4, block:19176 // circuit breaker opens + * 1529399830824,total:19806, pass:0, block:19806 * 1529399831825,total:19198, pass:0, block:19198 * 1529399832824,total:19481, pass:0, block:19481 * 1529399833826,total:19241, pass:0, block:19241 @@ -66,95 +47,114 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; * 1529399836826,total:19490, pass:0, block:19492 * 1529399837828,total:19355, pass:0, block:19355 * 1529399838827,total:11388, pass:0, block:11388 - * 1529399839829,total:14494, pass:104, block:14390 //After 10 seconds, the system is restored, and degraded very - * quickly + * 1529399839829,total:14494, pass:104, block:14390 // After 10 seconds, the system restored * 1529399840854,total:18505, pass:0, block:18505 * 1529399841854,total:19673, pass:0, block:19676 ** * @author jialiang.linjl + * @author Eric Zhao */ -public class RtDegradeDemo { +public class SlowRatioCircuitBreakerDemo { - private static final String KEY = "abc"; + private static final String KEY = "some_method"; + private static volatile boolean stop = false; + private static int seconds = 120; + + private static AtomicInteger total = new AtomicInteger(); private static AtomicInteger pass = new AtomicInteger(); private static AtomicInteger block = new AtomicInteger(); - private static AtomicInteger total = new AtomicInteger(); - - private static volatile boolean stop = false; - private static final int threadCount = 100; - private static int seconds = 60 + 40; public static void main(String[] args) throws Exception { - - tick(); initDegradeRule(); - - for (int i = 0; i < threadCount; i++) { - Thread entryThread = new Thread(new Runnable() { - - @Override - public void run() { - while (true) { - Entry entry = null; - try { - TimeUnit.MILLISECONDS.sleep(5); - entry = SphU.entry(KEY); - // token acquired - pass.incrementAndGet(); - // sleep 600 ms, as rt - TimeUnit.MILLISECONDS.sleep(600); - } catch (Exception e) { - block.incrementAndGet(); - } finally { - total.incrementAndGet(); - if (entry != null) { - entry.exit(); - } + registerStateChangeObserver(); + startTick(); + + int concurrency = 8; + for (int i = 0; i < concurrency; i++) { + Thread entryThread = new Thread(() -> { + while (true) { + Entry entry = null; + try { + entry = SphU.entry(KEY); + pass.incrementAndGet(); + // RT: [40ms, 60ms) + sleep(ThreadLocalRandom.current().nextInt(40, 60)); + } catch (BlockException e) { + block.incrementAndGet(); + sleep(ThreadLocalRandom.current().nextInt(5, 10)); + } finally { + total.incrementAndGet(); + if (entry != null) { + entry.exit(); } } } - }); - entryThread.setName("working-thread"); + entryThread.setName("sentinel-simulate-traffic-task-" + i); entryThread.start(); } } + private static void registerStateChangeObserver() { + EventObserverRegistry.getInstance().addStateChangeObserver("logging", + (prevState, newState, rule, snapshotValue) -> { + if (newState == State.OPEN) { + System.err.println(String.format("%s -> OPEN at %d, snapshotValue=%.2f", prevState.name(), + TimeUtil.currentTimeMillis(), snapshotValue)); + } else { + System.err.println(String.format("%s -> %s at %d", prevState.name(), newState.name(), + TimeUtil.currentTimeMillis())); + } + }); + } + private static void initDegradeRule() { - List