SpringCloud服务降级熔断

1. 服务故障场景分析

缓存雪崩是针对Redis出现大面积缓存失效导致请求批量拥堵到数据库导致数据卡顿,至使服务出现不可用的情况,对于在微服务的链式调用的场景下,其中一个服务出现问题,就会导致上下游整体卡在这个服务节点上,这个时候如果卡顿时间过久或出现内存溢出的情况,就会导致服务的整体卡死进而出现雪崩的情况,这就服务雪崩

1.1. 服务雪崩的场景分析

先看一下这个场景:

  • 首先我们有三组服务多外提供服务,服务C的压力最小所以只有一个节点
  • 从访问的线程池中来了5个请求到达服务,互相的调用关系如上图,会出现直接和间接调用关系

目前异常场景出现了:

  • 如果我们的服务C由于代码原因或数据库连接池耗光导致访问非常慢,那么调用服务C的业务就会收到timeout的响应
  • 这个时候所有调用服务C的业务都timeout了,如果我们必做管控,这个timeout 就会蔓延到服务B,进而到服务A,整条链路就会蔓延整个服务集群,所有请求的5个request直接over
  • 这个时候这种情况如果不对服务做任何处理,新进来的请求只能是加速系统崩溃

1.2. 线程池耗尽场景分析

场景分析:

  • 请求从Tomcat中发起服务调用,会同时调用多个
  • 这个时候服务C的应用处于一种时好时坏的状态,调用他的请求就会被夯在那里进行等待
  • 虽然调用C的同时也会调用其他服务,但由于C调用的等待时间较长,这就导致请求一直挂起
  • 挂起的请求多了以后,并发的连接增大,Tomcat的连接池资源就会耗尽

这种情况就需要通过线程隔离的方式来解决

1.3. 生产环境故障发生流程

在生产环境中系统发生故障的严重状态一般有以下几步

  • 访问延迟
  • 服务不可用 404/503/504
  • 造成资损

这里就要再次提供主链路的概念了,如果商品详情页的评价模块挂了几分钟,这没有问题,但如果商品下单流程挂了几分钟,那就会导致资金损失了

熔断和降级的核心目的就是为了保障系统的主链路稳定

如何降低故障带来的影响

  • 隔离异常服务:降级串联影响做到线程隔离
  • 服务减压:服务快速失败触发熔断机制
  • 备选方案:通过降级机制确保主链路可用的情况下实现系统最小可用性

2. Hystrix体系架构核心功能解析

《断舍离》,是日本作家山下英子的著作

对过往不留恋,拿得起放得下,这样的生活哲学可以帮助人们度过一些困难时期,我们知道Hystrix的作用也是帮助系统和服务节点度过他们的困难时期(缓解异常、服务雪崩带来的影响),对于Hystrix也有这一整套的设计理念,分别对应Hystrix中的三个特色功能

  • 断:熔断
  • 舍:降级
  • 离:线程隔离

2.1. 服务降级(舍)

微服务架构强调的是高可用,但并非高一致性,在一致性方面远比上银行的大型机系统。对于某个节点或业务模块依赖度过高,这个模块如果无法正常访问,如何在不影响其他调用方的情况下实现业务

这个时候就需要服务降级来应对这个问题了,假如HystrixClient调用目标服务发生异常,这个时候Hystrix会自动将这个请求转发到降级的逻辑中,由服务调用方编写异常处理逻辑。对于响应超时的场景来说,我们可以通过配置Hystrix的超时等待时间(和Ribbon的timeout是两个不同的配置),把超时响应的服务调用也当做是异常情况,转发到fallback逻辑中进行处理了

2.2. 服务熔断(断)

服务熔断是建立在服务降级之上的一个异常处理措施,你可以将它看做是服务降级的升级版。服务降级需要等待HTTP请求从服务节点返回异常或超时,再转向fallback逻辑,但是服务熔断引入了一种叫断路器/熔断器的机制,当断路器打开的时候,对服务的嗲用请求不会发送到目标服务节点,直接转向fallback逻辑

直接调用本地应用就是断路器/熔断器打开的情况下,这个断路器/熔断器是一直打开的吗?当然不是的,Hystrix有一定的规则来配置断路器的打开和关闭

2.3. 线程隔离(离)

web容器通常有一个线程池来接待来访的请求,如果并发量过高,线程池被打满了就会影响后面请求的响应,在我们的应用内部,假如我们提供3个微服务,分布是A、B、C。如果A服务调用量过多,我们就会发现可用的线程都会逐步被serviceA占用,接下来的现象是B和C没有系统资源可用了

Hystrix可以通过线程隔离的方式,将执行服务调用的代码与容器本身的线程池进行隔离,我们可以配置每隔服务所需要的线程的最大的数量,这样一来,即便一个服务的线程池被吃满,也不会影响其他的服务

3. 服务降级的常用方案

3.1. 静默处理

所谓的静默处理,就是什么都不干,在fallback逻辑中直接返回一个Null

我们使用try-catch一样能处理异常,try-catch不能做超时判断

3.2. 默认值处理

在真实结果无法返回的情况下,返回一个提前准备好的默认值,这种情况在主链路上建议不用使用默认值处理

3.3. 恢复服务才是王道

  • 缓存异常:假如在调用缓存的时候,缓存中间件出现问题无法访问了,可以在fallback的降级处理中直接访问底层数据库(这个方法不能使用在热点数据上),反过来讲如果数据库发生故障,可以在fallback里访问缓存,但要注意数据的一致性
  • 切换备库:如果主库的从库都无法访问的情况下,可以通过fallback主动范围备库来实现数据的调用,但这个一般是应用在主链路上,不要动不动就去访问备库,以免造成数据的脏读和幻读
  • 重试:Ribbon可以处理超时重试,可以在fallback中自己尝试重试发起其他接口或应用的调用
  • 人工干预:有些极其重要的接口,对异常不能容忍的,这里可以借助fallback启动人工干预流程,比如日志打点,通过监控组件触发报警,通知人工介入

3.4. 一错再错-多次降级

在某种情况下,fallback里由于各种问题又出现了一个异常。这个时候我们只能做二次降级,也就是在fallback里再引入一个fallback

3.5. Request Cache

Request Cache并不是让你在fallback里访问缓存,他是Hystrix的一个特殊功能。我们可以通过@CacheResult和@CacheKey两个注解实现

@CacheResult
@HystrixCommand
public Friend requestCache(@CacheKey Integer id){}

@CacheResult注解的意思是该方法的结果可以被Hystrix缓存起来,@CacheKey指定了缓存结果的业务ID是什么,在一个Hystrix上下文范围内,如果使用相同的参数对@CacheResult修饰的方法发起了多次调用,Hystrix只会在首次调用时向服务节点发送请求,后面的几次调用实际上是从Hystrix的本地缓存里读取数据。

4. Feign+Hystrix实现fallback降级方案

创建一个新的目录hystrix,在这个目录下创建hystrix-fallback-consumer的项目模块

这个模块还是一个服务调用者,导入POM依赖

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>com.michael</groupId><artifactId>feign-client-intf</artifactId><version>${project.version}</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency></dependencies>

我们需要定义一个可以抛出异常的Feign接口调用

先去feign-client-intf里新建一个error接口

    @GetMapping("/error")String error();

再去feign-client里实现这个方法

    @Overridepublic String error() {throw new RuntimeException("mouse droppings");}

回到hystrix-fallback-consumer项目中创建application

package com.michael.springcloud;import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
//断路器
@EnableCircuitBreaker
public class HystrixfallbackConsumerApplication {public static void main(String[] args) {new SpringApplicationBuilder(HystrixfallbackConsumerApplication.class).web(WebApplicationType.SERVLET).run(args);}
}

在hystrix-fallback-consumer中新建一个service包,在里面创建一个MyService的接口去继承IService

package com.michael.springcloud.service;import org.springframework.cloud.openfeign.FeignClient;@FeignClient(name="feign-client")
public interface MyService extends IService {}

在hystrix-fallback-consumer中创建一个hystrix的package,在里面创建一个业务类Fallback

package com.michael.springcloud.hystrix;import com.michael.springcloud.pojo.PortInfo;
import com.michael.springcloud.service.MyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class Fallback implements MyService {@Overridepublic String error() {log.info("********* local data **********");return "I am so sorry! is local data!";}@Overridepublic String sayHello() {return null;}@Overridepublic PortInfo sayPortInfo(PortInfo portInfo) {return null;}@Overridepublic String retry(int timeout) {return null;}
}

回到MyService接口里加上降级处理的实现类

@FeignClient(name="feign-client",fallback = Fallback.class)
public interface MyService extends IService {}

创建controller的调用实现

package com.michael.springcloud.controller;import com.michael.springcloud.service.MyService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
public class HystrixController {@Resourceprivate MyService myService;@GetMapping("/fallback")public String fallbcak(){return myService.error();}}

配置properties

spring.application.name=hystrix-consumer
server.port=30080
# 允许bean注解的重载
spring.main.allow-bean-definition-overriding=true
eureka.client.serviceUrl.defaultZone=http://localhost:10080/eureka/
# 开启feign下的hystrix功能
feign.hystrix.enabled=true
# 开启服务降级
hystrix.command.default.fallback.enabled=true

启动测试顺序:eureka-server、feign-client、hystrix-fallback-consumer

5. Hystrix实现timeout降级

在hystrix-fallback-consumer项目里

在controller里加入一个timeout的方法,还是使用之前的retry方法

    @GetMapping("/timeout")public String timeout(int second){return myService.retry(second);}

在fallback类里实现retry的降级方法

    @Overridepublic String retry(int timeout) {return "You are late !!!";}

properties里配置超时降级的机制

# 配置全局超时
hystrix.command.default.execution.timeout.enabled=true
# 全局超时,默认是1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
# 超时以后终止线程
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
# 取消的时候终止线程
hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=true# 每台机器最大的重试次数
feign-client.ribbon.MaxAutoRetries=0
# 可以重试的机器数量
feign-client.ribbon.MaxAutoRetriesNextServer=0
# 连接的请求超时时长
feign-client.ribbon.ConnectTimeout=1000
# 业务处理的时长
feign-client.ribbon.ReadTimeout=5000
# HTTP Method的重试开关,可以配置GET、POST、PUT、DELETE
feign-client.ribbon.OkToRetryOnAllOperations=false

基于具体方法实现的降级配置

# 具体方法的超时时间
hystrix.command.MyService#retry(int).execution.isolation.thread.timeoutInMilliseconds=4000

如果不知道这个方法签名,可以通过Feign提供的一个调用来输出一下

    public static void main(String[] args) throws NoSuchMethodException {System.out.println(Feign.configKey(MyService.class,MyService.class.getMethod("retry",int.class)));}

当同时配置了全局超时和方法超时的降级,以方法的降级为准

6. Request Cache降级实现

Request Cache并不是由调用异常导或超时导致的,而是一种主动的可预知的降级手段,严格的讲,更像是一种性能优化措施而非降级措施

package com.michael.springcloud.service;import com.michael.springcloud.pojo.PortInfo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Slf4j
@Service
public class RequestCacheService {@Resourceprivate MyService service;//将结果缓存并根据参数值来进行k-v的缓存对应@CacheResult@HystrixCommand(commandKey = "cacheKey")public PortInfo requestCache(@CacheKey String name){log.info("request cache name "+name);PortInfo portInfo = new PortInfo();portInfo.setName(name);portInfo.setPort("2020");portInfo = service.sayPortInfo(portInfo);log.info("after request cache name "+name);return portInfo;}
}

超时降级方法的另一种配置

# 上面配置的@HystrixCommand(commandKey = "cacheKey")
# 这个cacheKey就可以用在具体的方法超时配置,但注意还是需要配套fallbackMethod的方法使用
hystrix.command.cacheKey.execution.isolation.thread.timeoutInMilliseconds=4000

编写controller实现

    @Autowiredprivate RequestCacheService requestCacheService;@GetMapping("/cache")public PortInfo requestCache(String name){//缓存存放在hystrix上下文中,需要初始化上下文,上下文打开后执行完还要进行关闭//使用try-cache-finally里的context.close();//也可以使用lombok里的@Cleanup注解,默认调用close方法//如果默认close方法不是关闭资源的,可以指定具体方法@Cleanup("shutup")@Cleanup HystrixRequestContext context = HystrixRequestContext.initializeContext();PortInfo portInfo = requestCacheService.requestCache(name);portInfo = requestCacheService.requestCache(name);return portInfo;}

启动服务前,要使用requestCache要确保开关打开

# 默认requestCache是打开状态
hystrix.command.default.requestCache.enabled=true

重启后进行测试,feign-client只被调用了一次,这样就相当于将远程调用通过k-v的方式放到hystrix的上下文中了,只要调用参数一样,无论调用多少次返回,返回值都是从上下缓存中来进行获取,这样就确保相同结果下提升访问性能

7. 多级降级实现

在进行降级判断的时候:如果调用缓存服务出现问题,如何处理?这个时候直接访问Redis,如果Redis也挂了,这个时候就需要直接访问数据库,如果数据库再挂了,这个时候应该返回一个提前准备好的数据集

去到Fallback类里再创建两个降级的实现方法

    @Override//降级方法的参数签名要和主方法保持一致@HystrixCommand(fallbackMethod = "error2")public String error() {log.info("********* sorry 1 **********");throw new RuntimeException("first+ fallback");}@HystrixCommand(fallbackMethod = "error3")public String error2() {log.info("********* sorry 2 **********");throw new RuntimeException("second+ fallback");}public String error3(){log.info("********* sorry 3 **********");return "success sorry again 3";}

通过注解配置实现timeout超时降级

去到controller里添加一个方法

    @GetMapping("/timeout2")@HystrixCommand(fallbackMethod = "timeoutfallback",//可以忽略不进行降级的异常ignoreExceptions = {IllegalArgumentException.class},//这个commandProperties是一个数组,可以配置多个HystrixPropertycommandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")})public String timeout2(int second){return myService.retry(second);}//写一个当前的降级方法public String timeoutfallback(int second){return "timeout success "+second;}

8. Hystrix超时配置和Ribbon超时重试公用的问题

Feign集成了Ribbon和Hystrix两个组件,它俩都有一套超时配置,到底哪个超时配置最终生效呢

我们先复习一下Ribbon的超时时间计算公式:

最大超时时间 = (连接超时时间+接口超时时间)*(当前节点重试次数+1)*(更换节点重试次数+1)

假如经过上述计算,Ribbon的超时时间是2000ms,那么Hystrix的超时时间应该设置成多少才合理

我们先看一下Hystrix的默认全局配置

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000

以上全局配置设置了Hystrix的熔断时间为1000ms,这里Hystrix的超时时间设置比Ribbon配置的时间短,那么不等Ribbon重试结束,Hystrix判定超时并进行熔断处理。因此Hystrix和Ribbon是共同作用的关系,谁先达到超时指标就会率先起作用

通常来讲,Hystrix的超时降级时间要比Ribbon的最长超时时间设置的略长一些,这样就可以让Ribbon的重试机制充分发挥作用,以免出现还没来得及重试就进入fallback逻辑的情况发生。

如果一些接口的响应要求特别高,就需要更细粒度的设置Hystrix的超时时间

  • 需要以方法为维度进行服务降级的设置而不是直接应用全局配置了
  • 方法级别的降级时间优先级高于全局应用的,即便方法超时时长>全局超时时长,也是按照方法走
# 具体方法的超时时间设置
hystrix.command.MyService#retry(int).execution.isolation.thread.timeoutInMilliseconds=4000
# 对方法设置了commandKey
hystrix.command.cacheKey.execution.isolation.thread.timeoutInMilliseconds=4000
  • 方法上实现超时时间配置有三种方式

    • 通过方法签名配置:MyService#retry(int)
    • 通过commandKey配置
    • 通过注解配置@HystrixProperty

9. 熔断器核心机制理解和分析

服务熔断是建立在降级之上的强力手段,是降级的一个升级,对于调用后进入降级处理的业务要进行fallback,如果重复fallback就需要启用熔断机制,不再进行远程调用了,待什么时候服务恢复了再恢复远程调用访问。

  1. 发起调用-切面拦截:由于熔断器是建立在服务降级的基础上,因此在前面的触发机制上和服务流程一模一样,在向@HystrixCommand注解修饰的方法发起调用时,将会触发Aspect切面逻辑
  2. 检查熔断器:当熔断状态开启的时候,直接进入fallback,不执行远程调用
  3. 发起远程调用-异常情况:调用会捕捉到异常情况
  4. 计算Metrics:这里的Metrics指的是衡量指标,在异常情况发生后,将会根据断路器的配置计算当前服务的健康程度,如果达到熔断标准,则开启断路开关,后续请求将直接进入fallback流程里

熔断器有三个状态阶段:

  1. 熔断器open状态:远程服务关闭状态,服务在一定时间内无法发起对外部的调用,访问服务调用者直接进入fallback里进行处理
  2. 熔断器half-open状态:请求在fallback里待久了,等待一个约定的周期,可以尝试发起真实的服务调用,但这一切都在监视下进行,一旦调用不成功无论是否达到熔断的阈值要求都会直接熔断,等待下次尝试调用的机会
  3. 熔断器closed:如果上一步尝试调用成功了,就会关闭熔断器,开始正常访问,待再次触发熔断阈值开启熔断器

熔断器的判断阈值:

主要从两个维度判断熔断器是否开启:

  • 在一定的时间窗口内,发生异常的请求数量达到临界值
  • 在一定的时间窗口内,发生异常的请求数量占请求总数的比例达到一定值

其中时间窗口的大小可以配置,而且我们还可以指定half-open判定的时间间隔,比如熔断开启10秒以后进入half-open状态,此时会让一个请求发起调用,如果成功就关闭熔断器

10. Feign集成Hystrix熔断器

# 熔断的前提条件(请求数量),在一定的时间窗口内,请求达到5个以后,才开始进行熔断判断
hystrix.command.default.circuitBreaker.requestVolumeThreshold=5
# 失败请求数达到50%则熔断开关开启
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
# 当熔断开启后经过多少秒再进入半开状态,放出一个请求去做远程调用验证,通过则关闭熔断,不通过则继续熔断
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=10000
# 配置时间窗口
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=20000# 开启或关闭熔断功能
hystrix.command.default.circuitBreaker.enabled=true
# 强制开启熔断开关
hystrix.command.default.circuitBreaker.forceOpen=false
# 强制关闭熔断开关
hystrix.command.default.circuitBreaker.forceClosed=false

上面的熔断配置启动的是全局配置

问题:

  • 如何设置基于某个方法的熔断机制?
  • 如何设置错误的具体个数?

11. 主链路降级熔断规划

  • 首先识别主链路
  • 根据主链路分析主线流程和业务底线得到降级标准
  • 一旦出现熔断降级就需要进行异常补偿和故障恢复

12. Turbine聚合信息服务

Turbine需要连接服务注册中心获取服务提供者列表以便进行相应的信息聚合内容

在hystrix目录下创建一个hystrix-turbine的module

导入POM依赖

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-turbine</artifactId></dependency></dependencies>

application设置

package com.michael.springcloud;import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.turbine.EnableTurbine;@EnableDiscoveryClient
@EnableHystrix
@EnableTurbine
@EnableAutoConfiguration
public class HystrixTurbineApplication {public static void main(String[] args) {new SpringApplicationBuilder(HystrixTurbineApplication.class).web(WebApplicationType.SERVLET).run(args);}
}

配置properties的配置文件

spring.application.name=hystrix-turbine
server.port=30081
eureka.client.serviceUrl.defaultZone=http://localhost:10080/eureka/# 指定需要监控的服务名
turbine.app-config=hystrix-consumer
turbine.cluster-name-expression="default"
# 将端口和hostname作为区分不同服务的条件,默认只用hostname,默认方式在本地一个IP下就区分不开了
turbine.combine-host-port=true
# turbine通过这个路径获取监控数据,所有监控的服务也要开放这个路径监控
turbine.instanceUrlSuffix.default=actuator/hystrix.stream
turbine.aggregator.cluster-config=default

去到hystrix-fallback项目中打开actuator的配置

# actuator暴露端口
management.security.enabled=false
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

去到浏览器打开项目hystrix-fallback-consumer的actuator路径进行查看

http://localhost:30080/actuator 可以看到所有监控的信息

http://localhost:30080/actuator/hystrix.stream 可以看到一个个的长连接ping在不断返回

现在启动hystrix-turbine项目

http://localhost:30081/turbine.stream 访问这个路径

从这个页面发现turbine自己并不产生数据,只是将数据进行收集

13. Turbine集成Dashboard

创建一个hystrix-dashboard的module

导入POM依赖

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency></dependencies>

创建application启动类

package com.michael.springcloud;import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardApplication {public static void main(String[] args) {new SpringApplicationBuilder(HystrixDashboardApplication.class).web(WebApplicationType.SERVLET).run(args);}
}

创建properties

spring.application.name=hystrix-dashboard
server.port=30082# 关联系统是在打开dashboard以后进行关联,在首页的文本框内填入
# 可以通过turbine关联多个hystrix服务进行集合展示
# https://turbine-hostname:port/turbine.stream
# 也可以对某一个hystrix应用进行展示
# https://hystrix-app:port/actuator/hystrix.stream

分别启动:eureka-server、feign-client、hystrix-fallback-consumer、hystrix-turbine、hystrix-dashboard

dashboard的登录地址: http://localhost:30082/hystrix

SpringCloud系列之六相关推荐

  1. Camera开发系列之六-使用mina框架实现视频推流

    章节 Camera开发系列之一-显示摄像头实时画面 Camera开发系列之二-相机预览数据回调 Camera开发系列之三-相机数据硬编码为h264 Camera开发系列之四-使用MediaMuxer封 ...

  2. J360-cloud SpringCloud系列二:服务发现Discovery Service

    2019独角兽企业重金招聘Python工程师标准>>> j360开源博客之 ----------------------------------------------------- ...

  3. SpringCloud系列——Zuul 动态路由

    前言 Zuul 是在Spring Cloud Netflix平台上提供动态路由,监控,弹性,安全等边缘服务的框架,是Netflix基于jvm的路由器和服务器端负载均衡器,相当于是设备和 Netflix ...

  4. 线程基础知识——Windows核心编程学习手札系列之六

    线程基础知识 --Windows核心编程学习手札系列之六 线程与进程一样由两部分构成:一是线程的内核对象,操作系统用它来对线程实施管理,也是系统用来存放线程统计信息的地方:二是线程堆栈,用于维护线程在 ...

  5. mongo 3.4分片集群系列之六:详解配置数据库

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  6. nginx系列之六:cache服务

    ** 前言 ** nginx系列之一:nginx入门 nginx系列之二:配置文件解读 nginx系列之三:日志配置 nginx系列之四:web服务器 nginx系列之五: 负载均衡 nginx系列之 ...

  7. 《视频直播技术详解》系列之六:延迟优化

    七牛云于 6 月底发布了一个针对视频直播的实时流网络 LiveNet 和完整的直播云解决方案,很多开发者对这个网络和解决方案的细节和使用场景非常感兴趣. 结合七牛实时流网络 LiveNet 和直播云解 ...

  8. .NET 并行(多核)编程系列之六 Task基础部分完结篇

    .NET 并行(多核)编程系列之六 Task基础部分完结篇 前言:之前的文章介绍了了并行编程的一些基本的,也注重的讲述了Task的一些使用方法,本篇很短,将会结束Task的基础知识的介绍. 本篇的主要 ...

  9. java mysql jsp分页代码_JAVA/JSP学习系列之六(MySQL翻页例子)

    JAVA/JSP学习系列之六(MySQL翻页例子) 更新时间:2006年10月13日 00:00:00   作者: 一.运行前准备 下载了mysql的jdbc驱动(一个jar文件)并加载在CLASSP ...

最新文章

  1. 同源注释工具GeneWise安装和使用
  2. 过拟合的原因以及解决办法(深度学习)
  3. pm2集群模式mysql配置_配置 PM2 一键部署
  4. 日志长度_Kafka 日志存储详解
  5. (十二)linux内核定时器
  6. 2017-2018-1 20155213 《信息安全系统设计基础》第十一周学习总结
  7. Objects.equals 有坑!!!
  8. arduino neo 定位不可用_arduino霹雳七彩灯
  9. bootstrap与jQuery结合的动态进度条
  10. 安装oracle失败,停止在76%
  11. 入选 Gartner 魔力象限,剖析华为云 GaussDB 数据库演进之路
  12. C++《STL全集》
  13. 初学Power bi项目财务与人力/利润表/人员结构-刘刘的第一篇学习记录文章
  14. SmartUpload应用
  15. javaScript 高级04 正则表达式(边界符、字符类、量词符)
  16. 中国古语中的十大智慧
  17. 微信开发之小程序分享设置图片标题
  18. 实现直播带货系统推流,你进行推流监控了吗?
  19. 西北工业大学遭到境外网络攻击,调查报告二发布
  20. Python函数的应用--汇率转换函数示例(第九章)

热门文章

  1. Ubuntu18.04 cuda安装
  2. 大数据告诉你:学历真的能改变命运
  3. BP神经网络用于波士顿房屋数据集上预测
  4. 普通话测试app怎么样可以不交钱_普通话水平测试攻略(西安)
  5. JAVA毕业设计HTML5“牧经校园疫情防控网站”设计与实现计算机源码+lw文档+系统+调试部署+数据库
  6. IC/FPGA一文练完
  7. 龙芯3a5000部署nacos 1.4低版本方法
  8. 深度学习的时间序列分类
  9. 新注册公众号没有留言评论功能怎么办?如何开通公众号留言功能?
  10. CSI笔记【8】:基于MUSIC Algorithm的DoA/AoA估计以及MATLAB实现