技术干粮

SpringCloud Hystrix 定义服务降级

2019-01-08  本文已影响0人  壳叔
image
本文由黑壳博客原创

本文来源 SpringCloud Hystrix 定义服务降级

壳叔搞笑时间

imagepng

正文

前言

在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延最终导致整个系统的瘫痪。如果这样的架构存在如此严重的隐患,那么相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器等一系列的服务保护机制。

针对上述问题,在Spring Cloud Hystrix中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于Netflix的开源框架 Hystrix实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。

接下来,我们就从一个简单示例让你了解服务降级

对外提供了一个服务中心地址 http://api.blackdir.com:8000/eureka/ 可用于日常学习使用,请勿用于生产服务

参考项目 https://coding.net/u/ykz200/p/pace/git
懒人命令行专用 git clone https://git.coding.net/ykz200/pace.git
运行项目 运行项目主类Application
eureka-server 服务注册中心 eureka-client 服务提供者
创建maven子项目模块 命名为~eureka-consumer-ribbon-hystrix [这个随意就好,反正我是挺随意的,当时没想着展示]

    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <spring-cloud.version>Brixton.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
                
                <!-- spring-cloud-starter-hystrix 依赖项 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

#命名
spring.application.name=eureka-consumer-ribbon-hystrix  
#运行端口
server.port=9000  
#服务中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/    
 

*** 第三步 在应用主类中使用@EnableCircuitBreaker或@EnableHystrix注解开启Hystrix的使用


/**  
 * pom.xml的dependencies节点中引入spring-cloud-starter-hystrix依赖 
 * 在应用主类中使用@EnableCircuitBreaker或@EnableHystrix注解开启Hystrix的使用 
 */
@EnableCircuitBreaker  
@EnableDiscoveryClient  
@SpringBootApplication  
public class Application {  
  
 /**  
  * 创建RestTemplate 的springbean实例 
  * 通过@LoadBalanced 注解开启客户端负载均衡 
  * @return  
  */  
 @Bean  
 @LoadBalanced  RestTemplate restTemplate() {  
      return new RestTemplate();  
  }  
  
 //这个就不解释了,这个要是不理解,那我只能说请你回炉重学吧
 public static void main(String[] args) {  
     SpringApplication.run(Application.class, args);  
 }  
}

创建类ConsumerController

在类里创建内部类 ConsumerService

接下来看代码~~~


@RestController  
public class ConsumerController {  
  
  @Autowired  
  ConsumerService consumerService;  
  
  @GetMapping("/consumer")  
    public String consumer() {  
        return consumerService.consumer();  
  }  
  
  @Service  
  class ConsumerService {  
  
  @Autowired  
  RestTemplate restTemplate;  
  
 /**  
  * 具体执行逻辑的函数上增加@HystrixCommand  注解来指定服务降级方法, 
  * fallbackMethod定义回退方法的名称 
  * @return  
  */  
  @HystrixCommand(fallbackMethod = "fallback")  
  public String consumer() {  
    // 如果报异常 则会调用fallbackMethod 指定方法 “fallback”  
    //int error = Integer.parseInt("error");  
    String result = restTemplate.getForEntity("http://EUREKA-CLIENT/hello",                 String.class).getBody();  
  System.out.println(result);  
 return result;  
  }  
  
 /**  
  * 此处可能是另一个网络请求来获取,所以也可能失败 \* @return  
  */  
  @HystrixCommand(fallbackMethod = "fallbackSEC")  
        String fallback() {  
            return "Execute raw fallback";  
  }  
  
  String fallbackSEC() {  
            return "Execute raw fallback";  
  }  
  
  }  
  
}

第四步则是用注解的方式来实现服务降级,如果将consumer的//int error = Integer.parseInt("error");如果将注释取消掉,则会立马进入 fallback 方法来实现服务降级逻辑。

对于fallback方法的访问修饰符没有特定要求,这个可以放心。
但是需要一点 fallback方法 需要与@HystrixCommand 在同一个类中。

这是我认为SpringCloud 服务容错保护学习过程中,看代码更容易理解的一个阶段~。

关于我们

程序员是个辛苦的职业

请善待你们身边的每一位程序员~

欢迎在评论写下你的程序员趣事,程序员不是一个死板的职业~~

欢迎扫描二维码加入我们的小组织 ,大家都叫我壳叔,很期待你的到来。
黑壳网交流群 Q 群:200408242

11a84075a304ac57f6d37323512fd24cde9836350b9d80148b282eeaa188b196c2358d4ffd7006cbpng
上一篇下一篇

猜你喜欢

热点阅读