hystrix--服务隔离与熔断框架介绍

xiaoxiao2021-02-27  263

概述

            hystrix是netflix公司开发的一套具有熔断功能的服务隔离开源框架。

            在一般的互联网公司,各种基础数据都是由专门的接口提供,这也是soa思想的一种体现。如果一个应用调用的接口多了,变会有雪崩效应。什么是雪崩效应?比如说应用调用了5个外部接口,每个接口的调用成功率是99.9%, 那么从理论上来说,应用的成功率就是99.9%的五次方。如果调用的服务多了,这种放大效应会更加明显。 hystrix就是为了应对这种情况的框架。他的原理就是将各种服务分割开,外部接口的调用不会相互影响。

             hystrix具有如下特点:

             1. 服务分割。

              2.自动熔断。

maven引入

<dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>${hystrix.version}</version> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-metrics-event-stream</artifactId> <version>${hystrix-metrics-event-stream.version}</version> </dependency>

写一个command

package com.liang.hystrix.helloworld; import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPoolKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloServiceHystrixCommand extends HystrixCommand<String> { private final String _name; private final Service service; private int i; private Logger logger = LoggerFactory.getLogger(HelloServiceHystrixCommand.class); public static final int MIN_SIZE = 5; public static final int MAX_SIZE = 10; public HelloServiceHystrixCommand(String name) { super(setter()); _name = new String(name);//unmutable service = new HelloService(); } public HelloServiceHystrixCommand(String name, int i) { super(setter()); _name = new String(name);//unmutable service = new HelloService(); this.i = i; } @Override protected String getFallback() { logger.info("run failed.execute callback"); return null; } @Override protected String run() { if (sleep(i)) { try { Thread.sleep(1200); } catch (InterruptedException e) { logger.error(e.getMessage()); } } logger.info("execute command" + i); return service.getHelloName(_name); } private static HystrixCommand.Setter setter() { return HystrixCommand.Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("service")) .andCommandKey(HystrixCommandKey.Factory.asKey("hello")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) .withExecutionIsolationThreadInterruptOnTimeout(true) .withExecutionIsolationThreadTimeoutInMilliseconds(1000) .withCircuitBreakerEnabled(true) .withRequestLogEnabled(true) .withMetricsRollingPercentileWindowBuckets(5) .withMetricsRollingStatisticalWindowBuckets(5) .withCircuitBreakerRequestVolumeThreshold(3) .withCircuitBreakerErrorThresholdPercentage(30) .withCircuitBreakerSleepWindowInMilliseconds(5000)) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("thread-pool")); } public static boolean sleep(int i) { return i > MIN_SIZE && i < MAX_SIZE; }

其中Service, HelloService模拟的是具体的业务代码。代码如下:

package com.liang.hystrix.helloworld; public interface Service { public String getHelloName(String name); }

package com.liang.hystrix.helloworld; public class HelloService implements Service { public String getHelloName(String name) { return "Hello " + name; } }

单元测试

package hystrix; import static org.junit.Assert.assertEquals; import com.liang.hystrix.helloworld.HelloServiceHystrixCommand; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloServiceHystrixCommandTest { private Logger logger = LoggerFactory.getLogger(HelloServiceHystrixCommandTest.class); @Test public void testExecute() { HelloServiceHystrixCommand c = new HelloServiceHystrixCommand("World"); assertEquals("Hello World", c.execute()); try { String result = new HelloServiceHystrixCommand("World").queue().get(30000, TimeUnit.SECONDS); assertEquals("Hello World", result); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); } } @Test public void testRun() throws ExecutionException, TimeoutException { HelloServiceHystrixCommand c = null; AtomicInteger j = new AtomicInteger(0); for (int i = 0; i < 100; i++) { try { c = new HelloServiceHystrixCommand("" + i, j.getAndIncrement()); String result = c.queue().get(3, TimeUnit.MILLISECONDS); logger.info(c.getMetrics().getHealthCounts().getErrorPercentage() + " " + c.getMetrics().getHealthCounts().getErrorCount() + " " + c.getMetrics().getHealthCounts().getTotalRequests()); logger.info("CircuitBreaker is " + (c.isCircuitBreakerOpen() ? "open" : "closed")); if (HelloServiceHystrixCommand.sleep(i) || c.isCircuitBreakerOpen()) { assertEquals(null , result); } else { assertEquals("Hello " + i , result); } if (c.isCircuitBreakerOpen()) { Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } }

转载请注明原文地址: https://www.6miu.com/read-3399.html

最新回复(0)