Springcloud-断路器Hystrix (三)

                        Springcloud-断路器Hystrix (三)

                                                                                                 文 / 汝淉

SpringCloud-消费端&服务端搭建,负载均衡Ribbon 和 Feign (二)

开启第三章的内容,断路由Hystrix
需求:
由于Feign的负载均衡,如果服务端的其中一个服务出现了异常,导致无法访问,访问失败,那在Feign负载过程中,肯定还是会有大量请求访问,会产生访问阻塞,单个响应请求超时,最终可能会牵扯到其他服务出现问题,
解决思路:----也是断路由的简介
为了解决这种情况,出现了断路由,把无法访问的服务,在接收到请求的时候,能够给予合理的响应,.就出现了断路由

Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 
在微服务架构中,一个请求需要调用多个服务是非常常见的  摘自方志明老师

,上图更直观…(这是正常情况下) 图片来源:方志明老师
Springcloud-断路器Hystrix (三)
这是发生了服务异常,导致其中一个服务受损,无法正常访问…图片来源:方志明老师
Springcloud-断路器Hystrix (三)

接下来进入准备工作 (我都是把这些加在client端,也就是图中 API上面的服务中的)
我是以Feign作为负载均衡的…
第一步:开启Hystrix.因为默认是关闭的..
application.properties文件中加上以下这句话

#开启断路由
feign.hystrix.enabled=true

第二步:pom中导入Hystrix的依赖

<!--   断路由依赖-->
  <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
     <version>2.0.0.RELEASE</version>  
     <!--   版本是我加上去的,不加版本我的是导入不了 --/>
  </dependency>

简单的服务架构如图:
Springcloud-断路器Hystrix (三)

1个client服务端的代码…
在接口 UserFeignService (Feign写的接口,有注解FeignClient的接口)中加入一个注解…
注意多加了一个 注解:fallback = UserFeignServiceHystric.class
fallback :的意思是,当访问出现异常的时候,就需要调用这个类,来进行回复响应异常…
上代码:

package hnrlcl.client.springclient1.service;

import hnrlcl.client.springclient1.model.UserVo;
import hnrlcl.client.springclient1.service.impl.UserFeignServiceHystric;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by RuGuo on 2018/10/24.
 */
@FeignClient(value = "compute-service",fallback = UserFeignServiceHystric.class )
public interface UserFeignService {

    @RequestMapping(value = "/select",method = RequestMethod.GET)
    UserVo select(@RequestParam("userId")String userId,@RequestParam("userName")String userName);
    //上面这个方法是访问2个server服务端接口的入口,,,


}

而后创建fallback 指向的类…UserFeignServiceHystric 来处理异常服务
并且 该类 实现 UserFeignService 接口
,…这里可以精细到为每个方法提供对应的异常服务请求处理…

package hnrlcl.client.springclient1.service.impl;

import hnrlcl.client.springclient1.model.UserVo;
import hnrlcl.client.springclient1.service.UserFeignService;
import org.springframework.stereotype.Component;

/**
 * Created by RuGuo on 2018/10/25.
 */
@Component
public class UserFeignServiceHystric implements UserFeignService {


    @Override
    public UserVo select(String userId, String userName) {
        UserVo userVo = new UserVo();
        userVo.setUserId("不好意思 "+userId);
        userVo.setUserName("网页开小差了 " + userName);
        return userVo;
    }

}

当被访问的一个server服务出现问题的时候,就会走UserFeignServiceHystric 中对应的方法,来做请求处理…而后的请求基本都会去访问正常的那个server服务…从而避免总是出现错误的提示…
2个server中的方法(这里的代码不做修改,拿出来用就行了.)

package hnrlcl.server.springserver1.controller;

import hnrlcl.server.springserver1.model.UserVo;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


/**
 * Created by RuGuo on 2018/10/24.
 */
@RestController
public class UserController {

      Logger logger = Logger.getLogger(UserController.class);

      @RequestMapping(value = "/select",method = RequestMethod.GET)
      public UserVo getUser(@RequestParam("userId") String userId,@RequestParam("userName")String userName){
            UserVo userVo= new UserVo();
            userVo.setUserId(userId);
            userVo.setUserName(userName);
            logger.info("执行了 userId: " + userId + " userName: " + userName);
            return userVo;
      }
}

如果停止server1: 访问出现的结果会是以下结果:
Springcloud-断路器Hystrix (三)

然后再继续多次访问这个地址,…就会去访问另一个正常的服务,这个异常服务就不会再访问了,如果中间断了一段时间,再去访问,…还是会访问到这个异常的服务,如果异常服务没有好,就还会继续去访问正常服务了…
到此…断路由 Hystric 就结束了…
要是有疑问的伙伴可以参考方志明老师的博客对应的技术页…
史上最简单的SpringCloud教程 | 第四篇:断路器(Hystrix)(Finchley版本)