From b33687f03cb7cbc8c81716bfc47bd22e116a64e3 Mon Sep 17 00:00:00 2001 From: Calvin Date: Wed, 16 Oct 2013 14:59:18 +0800 Subject: [PATCH] add hystrix demo back, and improve the usage to follow the layers --- .../DependencyResourceController.java | 2 +- .../demos/hystrix/service/GetUserCommand.java | 4 +- .../demos/hystrix/service/UserService.java | 52 +++++++++------- .../hystrix/web/HystrixDemoController.java | 36 +++++++++++ .../src/main/webapp/WEB-INF/layouts/left.jsp | 1 + .../webapp/WEB-INF/views/story/hystrix.jsp | 60 +++++++++++++++++++ 6 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/web/HystrixDemoController.java create mode 100644 examples/showcase/src/main/webapp/WEB-INF/views/story/hystrix.jsp diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/dependency/DependencyResourceController.java b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/dependency/DependencyResourceController.java index 6fd8a3b3..5dc55439 100644 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/dependency/DependencyResourceController.java +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/dependency/DependencyResourceController.java @@ -22,7 +22,7 @@ import org.springside.modules.utils.Threads; public class DependencyResourceController { public static final int TIMEOUT = 15000; - private String status = "normal"; + public static String status = "normal"; @Autowired private AccountEffectiveService accountService; diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/GetUserCommand.java b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/GetUserCommand.java index e555251b..ad501032 100644 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/GetUserCommand.java +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/GetUserCommand.java @@ -16,11 +16,9 @@ public class GetUserCommand extends HystrixCommand { private Long id; protected GetUserCommand(Setter config, RestTemplate restTemplate, Long id) { - // 配置Command super(config); - // 传入 + this.restTemplate = restTemplate; - // 传入请求参数 this.id = id; } diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/UserService.java b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/UserService.java index e5b364d7..8853b9c9 100644 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/UserService.java +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/service/UserService.java @@ -5,6 +5,7 @@ import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import org.springside.examples.showcase.webservice.rest.UserDTO; @@ -15,17 +16,24 @@ import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; import com.netflix.hystrix.HystrixThreadPoolProperties; +/** + * 使用Hystrix 封装的Service。原来直接调用restTemplate改为调用Hystrix Command的封装. + * + * @author calvin + */ +@Service public class UserService { private static Logger logger = LoggerFactory.getLogger(UserService.class); - private Boolean runInNewThread = true; - private Setter config; - private RestTemplate restTemplate = new RestTemplate(); + private boolean runInNewThread = true; + + private Setter commandConfig; + private RestTemplate restTemplate; public UserDTO getUser(Long id) throws Exception { - GetUserCommand command = new GetUserCommand(config, restTemplate, id); + GetUserCommand command = new GetUserCommand(commandConfig, restTemplate, id); try { return command.execute(); @@ -36,7 +44,7 @@ public class UserService { } /** - * 演示Command的各种配置项,构造RestTemplate. + * 演示Command的各种配置项, 并构造Thread-Safed的RestTemplate. */ @PostConstruct private void init() { @@ -44,41 +52,39 @@ public class UserService { restTemplate = new RestTemplate(); // 设置Command名称 // - config = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")).andCommandKey( + commandConfig = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")).andCommandKey( HystrixCommandKey.Factory.asKey("GetUserCommand")); + HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); + commandConfig.andCommandPropertiesDefaults(commandProperties); + // 设置短路计算规则 // - config.andCommandPropertiesDefaults(HystrixCommandProperties.Setter() + commandProperties // 多少百分比的失败在rolling windows内发生,计算为短路。默认为50%,无改变。 .withCircuitBreakerErrorThresholdPercentage(50) // 至少多少请求在rolling window内发生,才开始触发短路的计算,默认为20, 设为3方便演示。 .withCircuitBreakerRequestVolumeThreshold(3) - // rolling windows 长度,默认为20秒,改为60秒方便演示。同时相应改变桶的数量。 - .withMetricsRollingStatisticalWindowInMilliseconds(60000) - .withMetricsRollingStatisticalWindowBuckets(60)); + // rolling windows 长度,默认为20秒,改为180秒方便演示。同时相应改变桶的数量。 + .withMetricsRollingStatisticalWindowInMilliseconds(180000) + .withMetricsRollingStatisticalWindowBuckets(180); - // 设置短路后的保护时间 // - config.andCommandPropertiesDefaults(HystrixCommandProperties.Setter() - .withCircuitBreakerSleepWindowInMilliseconds(20000)); + // 设置短路后的保护时间 ,默认为5秒,改为20秒方便演示// + commandProperties.withCircuitBreakerSleepWindowInMilliseconds(20000); // 设置超时与并发控制 // if (runInNewThread) { - // 使用Hystrix线程池的异步执行方式 - config.andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // 线程超时,默认为1秒,设为2秒方便演示 - .withExecutionIsolationThreadTimeoutInMilliseconds(2000)) + commandProperties.withExecutionIsolationThreadTimeoutInMilliseconds(2000); // 线程池属性, 线程池大小,默认为10,无改变。待执行队列的大小,默认为5,无改变。 - .andThreadPoolPropertiesDefaults( - HystrixThreadPoolProperties.Setter().withCoreSize(10).withQueueSizeRejectionThreshold(5)); + commandConfig.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10) + .withQueueSizeRejectionThreshold(5)); } else { - // 使用Invoker原有线程的方式, 设置使用信号量模式而不是默认的线程池模式,设置并发,默认为10,无改变 - config.andCommandPropertiesDefaults(HystrixCommandProperties.Setter() - .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE) - .withExecutionIsolationSemaphoreMaxConcurrentRequests(10)); - // RestTemplate设置为10秒超时 ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(10000); + // 设置使用信号量模式而不是默认的线程池模式,设置并发,默认为10,无改变 + commandProperties.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE) + .withExecutionIsolationSemaphoreMaxConcurrentRequests(10); } } diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/web/HystrixDemoController.java b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/web/HystrixDemoController.java new file mode 100644 index 00000000..f102555f --- /dev/null +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/demos/hystrix/web/HystrixDemoController.java @@ -0,0 +1,36 @@ +package org.springside.examples.showcase.demos.hystrix.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springside.examples.showcase.demos.hystrix.service.UserService; +import org.springside.examples.showcase.webservice.rest.RestException; +import org.springside.examples.showcase.webservice.rest.UserDTO; + +@Controller +public class HystrixDemoController { + + private static Logger logger = LoggerFactory.getLogger(HystrixDemoController.class); + + @Autowired + private UserService userService; + + @RequestMapping(value = "/hystrix/user/{id}", method = RequestMethod.GET) + @ResponseBody + public UserDTO getUser(@PathVariable("id") Long id) { + + try { + return userService.getUser(id); + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw new RestException(HttpStatus.SERVICE_UNAVAILABLE); + } + } + +} diff --git a/examples/showcase/src/main/webapp/WEB-INF/layouts/left.jsp b/examples/showcase/src/main/webapp/WEB-INF/layouts/left.jsp index 069d131f..2819d864 100644 --- a/examples/showcase/src/main/webapp/WEB-INF/layouts/left.jsp +++ b/examples/showcase/src/main/webapp/WEB-INF/layouts/left.jsp @@ -11,6 +11,7 @@