SpringClound-服务消费与断路器

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。为了解决这个问题,业界提出了断路器模型。当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
接下来我们这篇文章就说一下服务消费与断路器。

Ribbon

这里写图片描述
ribbon是一个负载均衡客户端,可以很好的控制http和tcp的一些行为。Feign默认集成了ribbon。
我们在RibbonApplication 中添加SpringCloudApplication 注解将此项目作为微服务注册再Eureka,并开启Hystrix功能,通过LoadBalancedBean 实例化RestTemplate 并开启负载均衡功能(访问服务提供者集群)

/**
 * 服务Ribbon消费
 * 2018年6月15日09:26:54
 * yangzhap
 */
@RestController
@SpringCloudApplication
/**
 * 相当于这三个注解
 * @SpringBootApplication
   @EnableDiscoveryClient
   @EnableCircuitBreaker//开启熔断器(@EnableHystrix)
 */

public class RibbonApplication {

    @Bean
    @LoadBalanced//开启负载均衡
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

}

我们编写服务消费方法


@Service
public class RIbbonService {

    @Autowired
    RestTemplate restTemplate;


    @HystrixCommand(fallbackMethod = "addServiceFallback")//处理熔断
    public String add(Integer a,  Integer b) {
        return restTemplate.getForObject("http://service-provider/add?a="+a+"&b="+b, String.class);//url指定调用的服务以及接口
    }

    //放生错误进入熔断方法
    //com.netflix.hystrix.contrib.javanica.exception.FallbackDefinitionException(add方法要和熔断方法参数一致)
    public String addServiceFallback(Integer a,  Integer b) {
        return a+b+"error";
    }
}

可以看到我们通过RestTemplate 对象访问服务的应用名(service-provider)以及具体的服务(add)即可实现服务消费
通过再add方法中加上service-provider 并指定fallbackMethod 属性,即服务提供者down掉时,执行addServiceFallback 方法
我们创建一个controller 来调用消费方法

@RestController
public class RibbonCustomer {

    @Autowired
    RIbbonService ribbonService;

    @RequestMapping(value = "/add" ,method = RequestMethod.GET)
    public String add(@RequestParam Integer a, @RequestParam Integer b) {
        return ribbonService.add(a,b);
    }

}
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8763
spring:
  application:
    name: service-ribbon

这里写图片描述
启动项目,访问http://localhost:8763/add?a=4&b=2
这里写图片描述
可以看到我们成功消费了provider
接下来我们测试断路器,我们将provider停掉
接着访问http://localhost:8763/add?a=4&b=2
这里写图片描述

Feign

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
这里写图片描述

配置文件:
Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码:feign.hystrix.enabled=true

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8764
spring:
  application:
    name: service-feign
feign:
  hystrix:
    enabled: true

我们通过EnableFeignClients 开启Feign功能,并注册到Eureka(EnableDiscoveryClient)

/**
 * feign消费者(自带断路器)
 * 2018年6月15日10:16:22
 * yangzhao
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//加上此注解开启Feign功能
public class FeignApplication {

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

编写IFeignCustomer 接口消费服务

@FeignClient(value = "SERVICE-PROVIDER" ,fallback = FeignError.class)//指定调用哪个服务 指定熔断回调类实现接口
public interface IFeignCustomer {

    @RequestMapping(value = "/add",method = RequestMethod.GET)//指定接口
    String add(@RequestParam(value = "a")Integer a,@RequestParam(value = "b") Integer b);

}

通过FeignClient 注解的属性value 指明要消费的服务,并通过fallback 属性指明熔断方法的实现类,通过RequestMapping 注解指明要消费的服务中的哪个接口

我们看一下熔断方法(接口的实现类中)

@Component
public class FeignError implements IFeignCustomer {

    @Override
    public String add(@RequestParam(value = "a")Integer a, @RequestParam(value = "b") Integer b){
        return a+b+"errorFeign";
    };
}

我们编写controller 调用消费方法

@RestController
public class FeginController {

    @Autowired
    IFeignCustomer iFeignCustomer;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(@RequestParam Integer a, @RequestParam Integer b) {
        return iFeignCustomer.add(a,b);
    }
}

启动项目
这里写图片描述

访问http://localhost:8764/add?a=1&b=2
这里写图片描述

已经成功消费提供者
我们关掉提供者的服务
这里写图片描述

猜你喜欢

转载自blog.csdn.net/yz357823669/article/details/80792615
今日推荐