分布式05SpringCloudHystrix熔断机制

编程

 

1.什么是Hystrix

     Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。为了实现容错和自我保护

2.为什么要使用Hystrix

    Hystrix是为了避免在分布式系统中,由于某个应用出现故障,导致整个系统被拖累导致雪崩效应。Hystrix可以及时打开熔断器,如保险丝一样在出现电压过载的情况下及时断开,这样可以避免不可挽回的局面。也和壁虎断尾一样断开某个服务器的应用或者停止某个服务响应来保全整体系统的安全性。

3.雪崩效应常见场景

硬件故障:如服务器宕机,机房断电,光纤被挖断等。
流量激增:如异常流量,重试加大流量等。(秒杀,达到服务上限可以快速限流避免cpu,内存,流量,IO崩溃拖垮整体系统)
缓存穿透:一般发生在应用重启,所有缓存失效时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用。(缓存服务器挂了,快速限流避免数据库被查询崩溃导致系统宕机)
程序BUG:如程序逻辑导致内存泄漏,JVM长时间FullGC等。(FULLGC很久而且CPU有飙高可能,一般会导致tomcat请求数满了,整体系统宕机)
同步等待:服务间采用同步调用模式,同步等待造成的资源耗尽。(tomcat请求数满了,整体系统宕机)

4.代码实现

zuul使用可以看之前的文章。这里我们使用到了回退机制

分布式04-Spring Cloud Zuul Api网关 一

分布式04-Spring Cloud Zuul 二 Zuul拦截器

分布式04-Spring Cloud Zuul 三 Fallback 回退机制

一.Zuul应用代码

引入依赖包

compile "org.springframework.cloud:spring-cloud-starter-zuul:1.4.4.RELEASE"

二.Application

@EnableZuulProxy

三.application.properties

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000#timeout时间

hystrix.command.default.execution.isolation.strategy=THREAD#隔离策略 有线程和信号量2种

hystrix.command.default.circuitBreaker.requestVolumeThreshold=3#熔断触发的最小个数/10s 默认20.

hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=10000 熔断多少秒后去尝试请 ,默认5000ms

#ribbon针对具体服务设置,超时时间:(2000+1000)*2=6000:

ribbon.ReadTimeout=2000

ribbon.ConnectTimeout=1000

zuul.routes.eureka-server.path=/public/*

zuul.routes.eureka-server.service-id=eureka-server

#zuul.routes.eureka-server.url=localhost:12000 #或者直接使用 URL转发,类是Nginx service-id与url 2选用1

zuul.routes.eureka-server.strip-prefix=false

timeoutInMilliseconds 与ribbon.ReadTimeout,ribbon.ConnectTimeout 是互相冲突,具体以哪个时间短取哪个。

四.Fallback代码zuul回退代码

import com.netflix.hystrix.exception.HystrixTimeoutException;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.MediaType;

import org.springframework.http.client.ClientHttpResponse;

import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.nio.charset.Charset;

@Component

public class TestFallbackProvider implements FallbackProvider {

@Override

public String getRoute() {

//处于所有的服务

// return "*";

// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退

return "eureka-server";

}

@Override

public ClientHttpResponse fallbackResponse(String route, Throwable cause) {

return this.response(HttpStatus.OK);

}

private ClientHttpResponse response(final HttpStatus status) {

return new ClientHttpResponse() {

@Override

public HttpStatus getStatusCode() throws IOException {

return status;

}

@Override

public int getRawStatusCode() throws IOException {

return status.value();

}

@Override

public String getStatusText() throws IOException {

return status.getReasonPhrase();

}

@Override

public void close() {

}

@Override

public InputStream getBody() throws IOException {

String returnMsg = " {

" +

" "code": "400",

" +

" "message": "服务发生异常",

" +

" "data": ""

" +

" }";

//回退操作

return new ByteArrayInputStream(returnMsg.getBytes());

}

@Override

public HttpHeaders getHeaders() {

// headers设定

HttpHeaders headers = new HttpHeaders();

MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));

headers.setContentType(mt);

return headers;

}

};

}

}

 

二.服务提供者代码

提供服务的接口

@RequestMapping(value = "/getPort", method = RequestMethod.GET )

public Msg getport() throws Exception{

ThreadUtil.sleep(10000);#提供一个接口返回应用的端口号

return Msg.MsgSuccess(port);

}

 

三.消费者接口

1使用Feign 调用上面的接口

@FeignClient(value = "eureka-zuul" )

public interface VoteFeignClient {

@GetMapping("/public/getPort")

Object getPort();

}

2.再定义一个消费服务的接口调用Feign。

@RequestMapping(value = "/getport", method = RequestMethod.GET )

public Msg getport() throws Exception{

Object o = voteFeignClient.getPort();

return Msg.MsgSuccess(o);

}

3.eureka

EUREKA-SERVER  负责消费和提供服务(应用A和B)。 EUREKA-ZUUL 负责API转发和熔断处理

测试结果

案例一

不休眠10秒

能够正常返回。

案例二

接口休眠10秒,超时时间是5秒

 

可以看系统发生超时并且触发了上面的回退机制

连续请求3次,(3次/20秒)看zuul的配置

可以看到请求时间只用了39ms,这个因为触发了熔断机制 zuul已经不再转发请求,而是直接回退数据给客户端。

过了10秒后zuul还是会再次转发接口,如果第一次不成功会继续进入熔断状态10秒。看zuul的配置

以上是 分布式05SpringCloudHystrix熔断机制 的全部内容, 来源链接: utcz.com/z/515426.html

回到顶部