分布式系统中一定会遇到的一个问题:服务雪崩效应或者叫级联效应
什么是服务雪崩效应呢?
  在一个高度服务化的系统中,我们实现的一个业务逻辑通常会依赖多个服务,比如:
商品详情展示服务会依赖商品服务, 价格服务, 商品评论服务. 调用三个依赖服务会共享商品详情服务的线程池. 如果其中的商品评论服务不可用, 就会出现线程池里所有线程都因等待响应而被阻塞, 从而造成服务雪崩. 如图所示:

简单理解: 就是商品评论服务耗时假如是15S,那么在高并发的时候,其他服务很快就做出响应并把线程回收但是商品评论服务需要10S。在这10S内100个线程都会集中被消耗在商品评论服务,就造成商品评论服务没有线程对外提供服务了。
服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过
程,就叫服务雪崩效应

导致服务不可用的原因有几点: 程序Bug,大流量请求,硬件故障,缓存击穿
【大流量请求】:在秒杀和大促开始前,如果准备不充分,瞬间大量请求会造成服务提供者的不可用.
【硬件故障】:可能为硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问.
【缓存击穿】:一般发生在缓存应用重启, 缓存失效时高并发, 所有缓存被清空时,以及短时间内大量缓存失效时. 大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用。
用户重试/代码逻辑重试,用户重试:在服务提供者不可用后, 用户由于忍受不了界面上长时间的等待,会不断刷新页面甚至提交表单,或者是代码有重试策略等等
那么,归根结底导致雪崩效应的最根本原因是:大量请求线程同步等待造成的资源耗尽

解决方案
1. 超时机制
2. 服务限流
3. 服务熔断
4. 服务降级 

先启动Eureka 注册中心,代码就不上了,截图:


order微服务工程

pom.xml :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tuling.cloud</groupId>
<artifactId>microservice-consumer-order-ribbon-hystrix-fallback</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>06-ms-consumer-order-ribbon-hystrix-fallback</name> <!-- 引入spring boot的依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties> <dependencies> <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> <!-- <artifactId>spring-cloud-starter-eureka</artifactId> 依赖了 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> -->
<!-- 此包包含了eurekaclient,ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <!-- hystrix 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency> <!-- feign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> </dependencies> <!-- 引入spring cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <!-- 添加spring-boot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

  OrderController.java:

package com.jiagoushi.cloud.study.user.controller;

import com.jiagoushi.cloud.study.user.entity.User;
import com.jiagoushi.cloud.study.user.feign.UserFeignClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; /**
* 演示 user服务挂了超时和执行请求超时
*/
@RestController
public class OrderController {
private static final Logger logger = LoggerFactory.getLogger(OrderController.class); @Autowired
private UserFeignClient userFeignClient; @Autowired
private RestTemplate restTemplate; /**
* Hystrix调用接口默认1秒超时,超时后会自动执行降级方法,可在文件配置,配置文件配置是全局的,
* @HystrixCommand(fallbackMethod = "findByIdFallback") 注解也可以配置超时
*/
@HystrixCommand(fallbackMethod = "findByIdFallback") // 基于注解的hystrix 推荐使用
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
logger.info("================请求用户中心接口==============");
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
} // 降级的方法
public User findByIdFallback(Long id) {
User user = new User();
user.setId(-1L);
user.setName("降级用户");
return user;
} }

  ConsumerOrderApplication.java:

package com.jiagoushi.cloud.study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @EnableDiscoveryClient
@SpringBootApplication
@EnableCircuitBreaker//开启断路器功能
public class ConsumerOrderApplication { @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} public static void main(String[] args) {
SpringApplication.run(ConsumerOrderApplication.class, args);
}
}

 


user微服务:

package com.tuling.cloud.study.controller;

import java.util.Random;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import com.tuling.cloud.study.entity.User;
import com.tuling.cloud.study.repository.UserRepository; @RestController
public class UserController { private final Logger logger = Logger.getLogger(getClass()); @Autowired
private UserRepository userRepository;
@Autowired
private Registration registration; @GetMapping("/{id}")
public User findById(@PathVariable Long id) throws Exception {
logger.info("用户中心接口:查询用户"+ id +"信息");
//模拟系统执行速度很慢的情况
Thread.sleep(5000); User findOne = userRepository.findOne(id);
return findOne;
} @GetMapping("/getIpAndPort")
public String findById() {
return registration.getHost() + ":" + registration.getPort();
}
}

  user微服务在停止或者阻塞5s 的时候,order服务会走降级方法

 

如何想修改接口超时间时间可以在order调用方修改yml 文件:

server:
port: 9010
spring:
application:
name: microservice-consumer-order
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #命令执行超时时间,默认1000ms,就是调接口的响应时间超过3S就执行降级,不管提供者是否挂机还是延迟超过时间就走降级

springcloud(五) Hystrix 降级,超时的更多相关文章

  1. SpringCloud(6)---熔断降级理解、Hystrix实战

    SpringCloud(6)---熔断降级理解.Hystrix实战 一.概念 1.为什么需要熔断降级 (1)需求背景 它是系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案. 在一个分布 ...

  2. SpringCloud学习笔记(五、SpringCloud Netflix Hystrix)

    目录: Hystrix简介 线程隔离:线程池.信号量 服务降级.服务熔断.请求缓存.请求合并 Hystrix完整流程.Hystrix属性值 注解方式实现Hystrix Hystrix Dashboar ...

  3. SpringCloud(五)学习笔记之Hystrix

    在微服务架构中多层服务之间会相互调用,如果其中有一层服务故障了,可能会导致一层服务或者多层服务故障,从而导致整个系统故障.这种现象被称为服务雪崩效应. Hystrix组件就可以解决此类问题,Hystr ...

  4. 服务容错保护断路器Hystrix之一:入门示例介绍(springcloud引入Hystrix的两种方式)

    限流知识<高可用服务设计之二:Rate limiting 限流与降级> 在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的 ...

  5. springcloud之hystrix熔断器-Finchley.SR2版

    本篇和大家分享的是springcloud-hystrix熔断器,其主要功能是对某模块调用失败做断路和降级,简单点就当某个模块程序出问题了并达到某阈值就限制后面请求,并降级的方式提供一个默认返回数据.最 ...

  6. springcloud学习之路: (四) springcloud集成Hystrix服务保护

    Hystrix是一套完善的服务保护组件, 可以实现服务降级, 服务熔断, 服务隔离等保护措施 使用它可以合理的应对高并发的情况 做到保护服务的效果 1. 导入依赖 <dependency> ...

  7. SpringCloud之Hystrix集群及集群监控turbine

    目的: Hystrix集群及监控turbine Feign.Hystrix整合之服务熔断服务降级彻底解耦 集群后超时设置 Hystrix集群及监控turbine 新建一个springboot工程mic ...

  8. 高并发场景-请求合并(一)SpringCloud中Hystrix请求合并

    背景 在互联网的高并发场景下,请求会非常多,但是数据库连接池比较少,或者说需要减少CPU压力,减少处理逻辑的,需要把单个查询,用某些手段,改为批量查询多个后返回. 如:支付宝中,查询"个人信 ...

  9. SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级

    什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...

随机推荐

  1. Java中HashMap的put与get方法原理

    直接上代码 注: 代码来自于 Java 9 put方法 public V put(K key, V value) { return putVal(hash(key), key, value, fals ...

  2. wpf中把按钮变成圆角

      <Button x:Name="btn" Content="改变" Width="100" Height="50&quo ...

  3. hdu2516斐波那契博弈

    刚开始想用sg函数做,想了半天没一点思路啊. 原来这是一个新题型,斐波那契博弈 斐波那契博弈模型:有一堆个数为 n 的石子,游戏双方轮流取石子,满足:1. 先手不能在第一次把所有的石子取完:2. 之后 ...

  4. HDU-5492 Find a path (枚举+DP)

    Problem Description Frog fell into a maze. This maze is a rectangle containing N rows and M columns. ...

  5. 09_Git patch(补丁)操作

    Git打补丁,补丁操作一般在多人开发时才会用到,单人本地开发一般用不到,没必要.   应用场景举例: 我把我的更改打成一个补丁发给你,你来合并到你的代码中 或者,在家里电脑开发提交后,打一个补丁,拿到 ...

  6. Java中的HashMap的工作原理是什么?

    问答题23 /120 Java中的HashMap的工作原理是什么? 参考答案 Java中的HashMap是以键值对(key-value)的形式存储元素的.HashMap需要一个hash函数,它使用ha ...

  7. Linux wget auto login and backup database

    #!/bin/bash # 这是一份本来打算采用自动备份数据的代码,由于测试过程中出现了无法连接的问题,导致不能测试, # 于是最后放弃了这份代码的进一步的开发,但是记录还是有必要的 login_ur ...

  8. Jmeter-配置元件

    CSV Data Set Config(CSV数据集配置) 参考:http://www.cnblogs.com/yanzhe/p/7728139.html DNS Cache Manager(DNS缓 ...

  9. java面试题8

    java面试题08 1.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? short s1 = 1; s1 = s1 + 1;编译 ...

  10. bootstrap table教程--使用入门基本用法

    笔者在查询bootstrap table资料的时候,看了很多文章,发觉很多文章都写了关于如何使用bootstrap table的例子,当然最好的例子还是官网.但是对于某部分技术人员来说,入门还是不够详 ...