move hystrix to deprecate
This commit is contained in:
@@ -188,18 +188,6 @@
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Netflix Hystrix -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
</dependency>
|
||||
<!-- only for hystrix dashboard -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CACHE begin -->
|
||||
<dependency>
|
||||
<groupId>net.spy</groupId>
|
||||
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
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;
|
||||
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.web.HystrixController;
|
||||
import org.springside.examples.showcase.entity.User;
|
||||
import org.springside.examples.showcase.service.AccountEffectiveService;
|
||||
import org.springside.examples.showcase.webservice.rest.UserDTO;
|
||||
import org.springside.modules.mapper.BeanMapper;
|
||||
import org.springside.modules.utils.Threads;
|
||||
|
||||
/**
|
||||
* 被Service所依赖的Resource.
|
||||
*/
|
||||
@Controller
|
||||
public class DependencyResourceController {
|
||||
public static final int TIMEOUT = 10000;
|
||||
|
||||
@Autowired
|
||||
private AccountEffectiveService accountService;
|
||||
|
||||
/**
|
||||
* 根据控制器中的状态而演示不同的行为,如正常返回,20秒无返回或直接报错
|
||||
*/
|
||||
@RequestMapping(value = "/hystrix/resource/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public UserDTO getUser(@PathVariable("id") Long id) {
|
||||
if ("normal".equals(HystrixController.status)) {
|
||||
return handleRequest(id);
|
||||
}
|
||||
|
||||
if ("timeout".equals(HystrixController.status)) {
|
||||
Threads.sleep(TIMEOUT);
|
||||
return handleRequest(id);
|
||||
}
|
||||
|
||||
if ("fail".equals(HystrixController.status)) {
|
||||
throw new ServiceException("Server Exception");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 备用的节点,永远返回正确结果。
|
||||
*/
|
||||
@RequestMapping(value = "/hystrix/resource/standby/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public UserDTO getUserOnStandby(@PathVariable("id") Long id) {
|
||||
return handleRequest(id);
|
||||
}
|
||||
|
||||
private UserDTO handleRequest(Long id) {
|
||||
User user = accountService.getUser(id);
|
||||
UserDTO dto = BeanMapper.map(user, UserDTO.class);
|
||||
dto.setTeamId(user.getTeam().getId());
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package org.springside.examples.showcase.demos.hystrix.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springside.examples.showcase.demos.hystrix.web.HystrixController;
|
||||
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;
|
||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||
|
||||
public class GetUserCommand extends HystrixCommand<UserDTO> {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(GetUserCommand.class);
|
||||
|
||||
private Long id;
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
protected GetUserCommand(Long id) {
|
||||
|
||||
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
|
||||
.andCommandKey(HystrixCommandKey.Factory.asKey("GetUserCommand"))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
|
||||
// 线程超时,默认为1秒,设为2秒方便演示
|
||||
.withExecutionIsolationThreadTimeoutInMilliseconds(2000)
|
||||
// 至少多少请求在rolling window内发生,开始触发短路的计算,默认为20, 设为3方便演示。
|
||||
.withCircuitBreakerRequestVolumeThreshold(3)
|
||||
// 多少百分比的fail在rolling windows内发生,计算为短路。默认为50%,无改变。
|
||||
.withCircuitBreakerErrorThresholdPercentage(50)
|
||||
// 被置成短路后,多久才会重新尝试访问资源。默认为5秒,改为20秒方便演示。
|
||||
.withCircuitBreakerSleepWindowInMilliseconds(20000)
|
||||
// rolling windows 长度,默认为20秒,改为60秒方便演示。
|
||||
.withMetricsRollingStatisticalWindowInMilliseconds(60000)
|
||||
// rolling Windows的桶的数量,默认为10,无为20,因为rolling window增大,需相应增加以保持秒的精度。
|
||||
.withMetricsRollingStatisticalWindowBuckets(60)
|
||||
// 计算短路的时间间隔,默认是500毫秒,无改变。
|
||||
.withMetricsHealthSnapshotIntervalInMilliseconds(500))
|
||||
// 线程池属性
|
||||
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
|
||||
// 线程池大小,默认为10,无改变。
|
||||
.withCoreSize(10)
|
||||
// 待执行队列的大小,默认为5,无改变。
|
||||
.withQueueSizeRejectionThreshold(5)));
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDTO run() throws Exception {
|
||||
logger.info("Access restful resource");
|
||||
return restTemplate.getForObject("http://localhost:8080/showcase/hystrix/resource/{id}", UserDTO.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserDTO getFallback() {
|
||||
if ("exception".equals(HystrixController.fallback)) {
|
||||
throw new RuntimeException("HystrixException");
|
||||
}
|
||||
|
||||
if ("dummy".equals(HystrixController.fallback)) {
|
||||
UserDTO dummyUser = new UserDTO();
|
||||
dummyUser.setId(0L);
|
||||
dummyUser.setLoginName("dummy");
|
||||
dummyUser.setName("Dummy");
|
||||
return dummyUser;
|
||||
}
|
||||
|
||||
if ("standby".equals(HystrixController.fallback)) {
|
||||
return restTemplate.getForObject("http://localhost:8080/showcase/hystrix/resource/standby/{id}",
|
||||
UserDTO.class, id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 使用Hystrix访问资源的服务。
|
||||
*/
|
||||
@Controller
|
||||
public class HyStrixServiceController {
|
||||
private static Logger logger = LoggerFactory.getLogger(HyStrixServiceController.class);
|
||||
|
||||
@RequestMapping(value = "/hystrix/service/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public UserDTO getUser(@PathVariable("id") Long id) {
|
||||
GetUserCommand command = new GetUserCommand(id);
|
||||
|
||||
try {
|
||||
return command.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
throw new RestException(HttpStatus.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.springside.examples.showcase.demos.hystrix.web;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class HystrixController {
|
||||
|
||||
public static String status = "normal";
|
||||
public static String fallback = "exception";
|
||||
|
||||
@RequestMapping(value = "/story/hystrix/status/{status}")
|
||||
public String updateStatus(@PathVariable("status") String newStatus) {
|
||||
HystrixController.status = newStatus;
|
||||
return "redirect:/story/hystrix";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/story/hystrix/fallback/{fallback}")
|
||||
public String updateFallback(@PathVariable("fallback") String newFallback) {
|
||||
HystrixController.fallback = newFallback;
|
||||
return "redirect:/story/hystrix";
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
<pattern>/static/*</pattern>
|
||||
<pattern>/cxf/*</pattern>
|
||||
<pattern>/api/*</pattern>
|
||||
<pattern>/hystrix/*</pattern>
|
||||
</excludes>
|
||||
|
||||
<decorator name="default" page="default.jsp">
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<div class="submenu">
|
||||
<a id="web-tab" href="${ctx}/story/web">Web演示</a>
|
||||
<a id="webservice-tab"href="${ctx}/story/webservice">WebService演示</a>
|
||||
<a id="hystrix-tab" href="${ctx}/story/hystrix">Hystrix演示</a>
|
||||
<a id="jmx-tab" href="${ctx}/story/jmx">JMX演示</a>
|
||||
</div>
|
||||
<h1>演示说明</h1>
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||
<%@ page import="org.springside.examples.showcase.demos.hystrix.web.HystrixController,com.netflix.hystrix.*,com.netflix.hystrix.HystrixCommandMetrics.HealthCounts,com.netflix.hystrix.util.*" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%! %>
|
||||
|
||||
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
|
||||
<html>
|
||||
<head>
|
||||
<title>Web Service高级演示</title>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#hystrix-tab").addClass("active");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Hystrix 演示</h1>
|
||||
|
||||
<p><a href="https://github.com/Netflix/Hystrix" target="_blank">Netflix Hystrix</a> 是一个延迟与容错类库,通过独立访问远程系统、服务和第三方库的节点,在复杂的分布式系统里停止雪崩及提供恢复能力。</p>
|
||||
|
||||
<h2>演示操作</h2>
|
||||
<ul>
|
||||
<li>依赖资源当前状态为<%= HystrixController.status %>:切换为<a href="${ctx}/story/hystrix/status/normal">正常</a>、<a href="${ctx}/story/hystrix/status/timeout">超时</a>、<a href="${ctx}/story/hystrix/status/fail">失败</a>。</li>
|
||||
<li>Hystrix服务当前异常处理方式为<%= HystrixController.fallback %>:切换为<a href="${ctx}/story/hystrix/fallback/exception">抛出异常</a>、<a href="${ctx}/story/hystrix/fallback/dummy">返回默认用户</a>、<a href="${ctx}/story/hystrix/fallback/standby">访问备用节点</a>。</li>
|
||||
<li>访问服务:<a href="${ctx}/hystrix/service/1" target="_blank">Hystrix服务</a>、<a href="${ctx}/hystrix/resource/1" target="_blank">依赖资源</a>、<a href="${ctx}/hystrix/resource/standby/1" target="_blank">资源的备用节点</a>。</li>
|
||||
</ul>
|
||||
<h2>主要用户故事</h2>
|
||||
<ul>
|
||||
<li> 在默认的正常状态,访问Hystrix服务和依赖资源,均返回正常结果。</li>
|
||||
<li> 将资源状态切换为"超时",访问依赖资源,需要在10秒后才返回结果。</li>
|
||||
<li> 访问Hystrix服务,2秒后超时,返回503。</li>
|
||||
<li> 三次超时后满足短路条件(60秒滚动窗口内起码有3个请求,50%失败),再次刷新服务,立即返回503。</li>
|
||||
<li> 10秒短路保护期内,所有访问都立即返回503,不会访问依赖资源。</li>
|
||||
<li> 保护期过后,会放行一个请求,如果还是超时,则继续保持短路状态。如果成功则重置所有计数器。</li>
|
||||
</ul>
|
||||
|
||||
<h2>其他用户故事</h2>
|
||||
<ul>
|
||||
<li> 将资源状态切换为"失败",访问依赖资源,立即返回500错误,访问Hystrix服务,即时返回503错误。</li>
|
||||
<li> 将异常处理方式切换为"返回默认用户",访问Hystrix服务,返回默认用户。</li>
|
||||
<li> 将异常处理方式切换为"访问备用节点",访问Hystrix服务,返回正确结果。</li>
|
||||
</ul>
|
||||
|
||||
<h2>监控结果 </h2>
|
||||
<form><input type="submit" value="刷新"/></form>
|
||||
<%
|
||||
HystrixCommandKey key = HystrixCommandKey.Factory.asKey("GetUserCommand");
|
||||
HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(key);
|
||||
if (metrics!=null){
|
||||
HealthCounts counts = metrics.getHealthCounts();
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
|
||||
|
||||
|
||||
%>
|
||||
<ul>
|
||||
<li>是否短路:<%= circuitBreaker.isOpen() %></li>
|
||||
<li>窗口内请求:<%= counts.getTotalRequests()%>,失败百分比:<%= counts.getErrorPercentage() %>%
|
||||
<li>窗口成功:<%= metrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS) %>, 超时:<%= metrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT) %>,失败:<%= metrics.getRollingCount(HystrixRollingNumberEvent.FAILURE) %>,短路:<%= metrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED) %></li>
|
||||
<li>50%延时:<%= metrics.getTotalTimePercentile(50) +"ms"%>,90%延时:<%= metrics.getTotalTimePercentile(90) +"ms"%>,100%延时:<%= metrics.getTotalTimePercentile(100) +"ms"%></li>
|
||||
</ul>
|
||||
<%} %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -79,16 +79,6 @@
|
||||
<servlet-name>RemoteContentServlet</servlet-name>
|
||||
<url-pattern>/remote-content</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- only for hystrix dashboard -->
|
||||
<servlet>
|
||||
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
|
||||
<servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
|
||||
<url-pattern>/hystrix/hystrix.stream</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Filter 定义 -->
|
||||
<!-- Character Encoding filter -->
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
<jedis.version>2.1.0</jedis.version>
|
||||
<ehcache.version>2.6.6</ehcache.version>
|
||||
<spymemcached.version>2.9.1</spymemcached.version>
|
||||
<hystrix.version>1.2.17</hystrix.version>
|
||||
<hibernate-validator.version>4.3.1.Final</hibernate-validator.version>
|
||||
<jolokia.version>1.1.2</jolokia.version>
|
||||
<jackson.version>2.1.5</jackson.version>
|
||||
@@ -365,19 +364,6 @@
|
||||
<version>${jedis.version}</version>
|
||||
</dependency>
|
||||
<!-- NOSQL end-->
|
||||
|
||||
<!-- Netflix Hystrix -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- CACHE begin -->
|
||||
<!-- memcached -->
|
||||
|
||||
Reference in New Issue
Block a user