#232 基于Hystrix的系统保护,Day2. 演示
This commit is contained in:
+6
-2
@@ -2,7 +2,9 @@ package org.springside.examples.quickstart.rest;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
@@ -15,7 +17,9 @@ public class RestExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = { ConstraintViolationException.class })
|
||||
public final ResponseEntity<?> handleException(ConstraintViolationException ex, WebRequest request) {
|
||||
return new ResponseEntity(BeanValidators.extractPropertyAndMessage(ex.getConstraintViolations()),
|
||||
HttpStatus.BAD_REQUEST);
|
||||
String body = BeanValidators.extractPropertyAndMessage(ex.getConstraintViolations()).toString();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.TEXT_PLAIN);
|
||||
return handleExceptionInternal(ex, body, null, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
package org.springside.examples.showcase.demos.hystrix.resource;
|
||||
|
||||
import org.hibernate.service.spi.ServiceException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -18,7 +19,7 @@ import org.springside.modules.utils.Threads;
|
||||
*/
|
||||
@Controller
|
||||
public class ResourceController {
|
||||
public static final int TIMEOUT = 20000;
|
||||
public static final int TIMEOUT = 10000;
|
||||
|
||||
@Autowired
|
||||
private AccountEffectiveService accountService;
|
||||
@@ -39,7 +40,7 @@ public class ResourceController {
|
||||
}
|
||||
|
||||
if ("fail".equals(HystrixController.status)) {
|
||||
throw new RuntimeException("Server Exception");
|
||||
throw new ServiceException("Server Exception");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+16
-1
@@ -5,6 +5,8 @@ import org.springside.examples.showcase.webservice.rest.UserDTO;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
|
||||
public class GetUserCommand extends HystrixCommand<UserDTO> {
|
||||
|
||||
@@ -13,7 +15,20 @@ public class GetUserCommand extends HystrixCommand<UserDTO> {
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
protected GetUserCommand(Long id) {
|
||||
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
|
||||
|
||||
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
|
||||
.andCommandKey(HystrixCommandKey.Factory.asKey("GetUserCommand"))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
|
||||
// 线程超时,默认为1秒,设为3秒,
|
||||
.withExecutionIsolationThreadTimeoutInMilliseconds(3000)
|
||||
// 至少多少请求在rolling window内发生,开始触发短路的计算,默认为20, 设为3
|
||||
.withCircuitBreakerRequestVolumeThreshold(3)
|
||||
// 多少百分比的fail在rolling windows内发生,计算为短路。默认为50%
|
||||
.withCircuitBreakerErrorThresholdPercentage(50)
|
||||
// 被置成短路后,多久才会重新尝试访问资源。默认为5秒,设为10秒
|
||||
.withCircuitBreakerSleepWindowInMilliseconds(10000)
|
||||
// rolling windows 长度,默认为10秒,设为20秒。
|
||||
.withMetricsRollingStatisticalWindowInMilliseconds(20000)));
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -1,10 +1,14 @@
|
||||
package org.springside.examples.showcase.demos.hystrix.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.webservice.rest.RestException;
|
||||
import org.springside.examples.showcase.webservice.rest.UserDTO;
|
||||
|
||||
/**
|
||||
@@ -12,10 +16,18 @@ import org.springside.examples.showcase.webservice.rest.UserDTO;
|
||||
*/
|
||||
@Controller
|
||||
public class ServiceController {
|
||||
private static Logger logger = LoggerFactory.getLogger(ServiceController.class);
|
||||
|
||||
@RequestMapping(value = "/hystrix/service/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public UserDTO getUser(@PathVariable("id") Long id) {
|
||||
GetUserCommand command = new GetUserCommand(id);
|
||||
return command.execute();
|
||||
|
||||
try {
|
||||
return command.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
throw new RestException(HttpStatus.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.springside.examples.showcase.webservice.rest;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public class RestException extends RuntimeException {
|
||||
|
||||
public HttpStatus status;
|
||||
|
||||
public RestException() {
|
||||
}
|
||||
|
||||
public RestException(HttpStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public RestException(HttpStatus status, String message) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package org.springside.examples.showcase.webservice.rest;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
import org.springside.modules.beanvalidator.BeanValidators;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = { ConstraintViolationException.class })
|
||||
public final ResponseEntity<?> handleException(ConstraintViolationException ex, WebRequest request) {
|
||||
String body = BeanValidators.extractPropertyAndMessage(ex.getConstraintViolations()).toString();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.TEXT_PLAIN);
|
||||
return handleExceptionInternal(ex, body, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = { RestException.class })
|
||||
public final ResponseEntity<?> handleException(RestException ex, WebRequest request) {
|
||||
String body = ex.getMessage();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.TEXT_PLAIN);
|
||||
|
||||
HttpStatus status = (ex.status != null) ? ex.status : HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
|
||||
return handleExceptionInternal(ex, body, headers, status, request);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
<body>
|
||||
<h1>Hystrix 演示</h1>
|
||||
|
||||
<p><a href="https://github.com/Netflix/Hystrix" target="_blank">Netflix Hystrix</a> 是一个延迟与容错类库,通过独立访问远程系统、服务和第三方库的节点,在复杂的分布式系统里停止雪崩及提供恢复能力。</p>
|
||||
|
||||
<h2>当前资源状态为<%= HystrixController.status %></h2>
|
||||
<ul>
|
||||
@@ -22,6 +24,8 @@
|
||||
<li><a href="${ctx}/story/hystrix/fail">切换为Fail</a></li>
|
||||
<li><a href="${ctx}/story/hystrix/normal">切换为Normal</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>访问Hystrix服务</h2>
|
||||
<a href="${ctx}/hystrix/service/1" target="_blank"> ${ctx}/hystrix/service/1</a>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user