Spring Cloud微服务 服务消费者

来源:互联网 发布:99宿舍客服软件 编辑:程序博客网 时间:2024/06/08 08:45

创建服务消费者


Feign

Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

断路器Hystrix

在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,最终导致自身服务的瘫痪。

举个例子,在一个电商网站中,我们可能会将系统拆分成,用户、订单、库存、积分、评论等一系列的服务单元。用户创建一个订单的时候,在调用订单服务创建订单的时候,会向库存服务来请求出货(判断是否有足够库存来出货)。此时若库存服务因网络原因无法被访问到,导致创建订单服务的线程进入等待库存申请服务的响应,在漫长的等待之后用户会因为请求库存失败而得到创建订单失败的结果。如果在高并发情况之下,因这些等待线程在等待库存服务的响应而未能释放,使得后续到来的创建订单请求被阻塞,最终导致订单服务也不可用。

在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器模式。
断路器模式源于Martin Fowler的Circuit Breaker一文。“断路器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

Netflix Hystrix

在Spring Cloud中使用了Hystrix 来实现断路器的功能。Hystrix是Netflix开源的微服务框架套件之一,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。

pom.xml配置:

<parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.1.RELEASE</version>    <relativePath/></parent><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>Camden.SR5</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-eureka</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-zuul</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-ribbon</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-hystrix</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-feign</artifactId>    </dependency></dependencies>

application.properties配置:

spring.application.name=consumer-testinfo.version=@project.version@server.port=3333eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka/# 启用hystrix熔断器feign.hystrix.enabled=true# 熔断器触发时间hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

java代码:
在应用主类中通过@EnableFeignClients注解开启Feign功能

@SpringBootApplication@EnableDiscoveryClient@EnableFeignClientspublic class ConsumerTestApplication {    public static void main(String[] args) {        SpringApplication.run(ConsumerTestApplication.class, args);    }    /**     * feign超时时间     *     * @return     */    @Bean    public Request.Options options() {        Request.Options options = new Request.Options(5 * 1000, 5 * 1000);        return options;    }}

使用@FeignClient(“provider-test”)注解来绑定该接口对应provider-test服务

@FeignClient(value = "provider-test", fallback = RpcServiceFallback.class)public interface RpcService {    @RequestMapping(method = RequestMethod.GET, value = "/add")    Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);}

当请求超时时,熔断器hystrix调用RpcServiceFallback返回异常结果,避免线程阻塞出现故障,导致故障蔓延,最终导致整个系统的瘫痪

/** * 熔断器Fallback */@Componentpublic class RpcServiceFallback implements RpcService {    @Override    public Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {        return -1;    }}
@RestControllerpublic class ConsumerController {    @Autowired    private RpcService rpcService;    @RequestMapping(value = "/add", method = RequestMethod.GET)    public String add() {        Integer integer = rpcService.add(1, 2);        return integer.toString();    }}
0 0
原创粉丝点击