myJavaSE

集成Ribbon,Feign,和Hystrix

1.Ribbon,Feign的相关介绍

ribbon是负载均衡处理器,ribbon是属于springcloud的一个组件,当我们微服务要通过注册中心拉取到通信清单后,可以通过通信地址访问其他微服务器,但如果其他微服务器做了集群的话,有多个微服务,我们到底访问哪个微服务呢,如果都去访问一个微服务的话,被访问的微服务就会因为访问的线程过多而出现服务器爆炸的可能,而其他服务器却又闲置了,所以这是我们就需要负载均衡器帮我们处理这些请求,帮我们合理的分配这些请求,ribbon就是这个作用,ribbon默认的请求处理是轮询,还有其他如随机,一致性哈希,加权的方式实现请求分发。

feign也是负载均衡处理器,是基于ribbon的,Ribbon是一个基于 HTTP 和 TCP 客户端 的负载均衡的工具。
它可以 在客户端 配置 RibbonServerList(服务端列表),使用 HttpClient 或 RestTemplate 模拟http请求,步骤相当繁琐。

而feign

Feign 是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。
采用接口的方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方法即可, 不需要自己构建http请求。
然后就像是调用自身工程的方法调用,而感觉不到是调用远程方法,使得编写 客户端变得非常容易。

2.代码实现ribbon步骤

1.导入依赖

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

2.在返回restTemplate 的bean的方法上打上注解 @LoadBalanced,这个注解赋予了restTemplate有负载均衡的能力

@Configuration
public class BeanConfig {
    /**
     *   @LoadBalanced打了这个注解后restTemplate就有了ribbon的负载均衡能力
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

修改controller的调用方法 String url = "http://user-client/userclient/user/"+id,根据注册中心的通信地址名user-client,访问资源

@GetMapping("/order/{id}")
    public JsonResult queryById(@PathVariable Long id){
        //使用restTemplate发送http协议
        String url = "http://user-client/userclient/user/"+id;
        User user = template.getForObject(url, User.class);
        JsonResult jsonResult = new JsonResult();
        jsonResult.setData(user);
        return jsonResult;
    }

3.代码实现feign的步骤

1.导入依赖

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

2.编写feign的接口

/**
 * 编写feign的接口 user-client,注册中心注册的应用名
 */
@FeignClient(value = "user-client")
public interface UserFeignClient {
    /**
     * @PathVariable("id")这里面必须写"id"不然注入不了这个UserFeignClient
     * @param id
     * @return
     * /userclient/user/{id},是服务器需要调用的服务器的资源路径
     */
    @GetMapping("/userclient/user/{id}")
    User queryById(@PathVariable("id") Long id);
}

3.主配置类开启feign@EnableFeignClients("cn.learn.springcloud.feignclient")

/**
 * @EnableFeignClients("cn.learn.springcloud.feignclient")主配置类开启fenign
 */
@SpringBootApplication
@EnableFeignClients("cn.learn.springcloud.feignclient")
public class OrderClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderClientApplication.class);
    }

}

4.controller层注入接口,调用方法

@RestController
@RequestMapping("/orderclient")
public class UserController {
    @Autowired
    private UserFeignClient userFeignClient;
    @GetMapping("/order/{id}")
    public User queryById(@PathVariable Long id){
        //调用feign的接口的方法
        User user = userFeignClient.queryById(id);
        return user;
    }
}

3.Hystrix的相关介绍

hystrix是用来做熔断机制的框架,也是属于springcloud的组件,当我们的微服务通过注册中心访问其他微服务的时候,如果其他微服务挂掉了,访问不到,那么会造成雪崩效应,引起其他服务器的瘫痪,这种一个微服务的瘫痪引起其他微服务的瘫痪的现象我们就称它为雪崩效应,为了解决这个问题springcloud引入了熔断机制hystrix帮我们解决这种问题,当一个服务器挂掉后,如果要访问被挂掉的服务器,没有访问到,我们返回一个正常的友好的提示,告诉微服务,这个服务器出故障了,就像当于将这个挂掉的服务器隔离开,那么就不会引起要访问的服务器的瘫痪了,保证了一个服务器挂掉,其他服务器正常运行。

3.1在ribbon中集成hystrix

1.导入依赖

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

2.主配置类开启熔断机制@EnableCircuitBreaker

/**
 * @EnableCircuitBreaker开启熔断机制
 */
@SpringBootApplication
@EnableCircuitBreaker
public class OrderClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderClientApplication.class);
    }

}

3.以jsonResult的方式返回一个友好的提示,如果没有访问到服务的数据我们返回拖底方法的返回结果,方法上打注解@HystrixCommand(fallbackMethod = "getUserByIdFallback")

注意:托底方法的参数和返回结果要和原方法一致

@RestController
@RequestMapping("/orderclient")
public class UserController {
    @Autowired
    private RestTemplate template;
    /**
     * @HystrixCommand(fallbackMethod = "getUserByIdFallback"),打上拖底方法标签
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "getUserByIdFallback")
    @GetMapping("/order/{id}")
    public JsonResult queryById(@PathVariable Long id){
        //使用restTemplate发送http协议
        String url = "http://user-client/userclient/user/"+id;
        User user = template.getForObject(url, User.class);
        JsonResult jsonResult = new JsonResult();
        jsonResult.setData(user);
        return jsonResult;
    }
    /**
     * 降级方法,如果没有访问到user-client则返回方法中的拖底数据
     */
    public JsonResult getUserByIdFallback(@PathVariable Long id){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setSuccess(false);
        jsonResult.setMsg("对不起服务器系统繁忙,请稍后再试");
        jsonResult.setData(null);
        return jsonResult;
    }
}

3.2在feign中集成hystrix

1.导入依赖

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

2.修改feign客户端接口@FeignClient(value = "user-client",fallback = UserFeignClientFallback.class),fallback = UserFeignClientFallback.class表示访问失败后

调用UserFeignClientFallback这个类中的方法返回友好信息

3.编写UserFeignClientFallback,实现feign的接口,覆写feign接口中的方法(拖底实现)

@Component
public  class UserFeignClientFallback implements UserFeignClient {
    @Override
    public User queryById(Long id) {
        return new User(-1L,"对不起,服务器不可用",0);
    }
}

4.yml配置文件中启用熔断机制,feign默认是关闭熔断机制的

ureka:
  client:
    serviceUrl:
      defaultZone: http://peer0:1000/eureka/,http://peer1:1001/eureka/
  instance:
    prefer-ip-address: true #定义ip到注册中心注册
    instance-id: order-client:2001
server:
  port: 2001
spring:
  application:
    name: order-client-2001
feign:
  hystrix:
    enabled: true #开启熔断支持

posted on 2019-12-29 23:46  myJavaSE  阅读(884)  评论(0编辑  收藏  举报

导航