Spring Cloud进阶之路 | 十五:服务网关集成断路器(zuul + hystrix)

​前言

之前已经讲过断路器组件的相关作用及集成方案,具体参见文章Spring Cloud进阶之路 | 六:断路器(hystrix)

那么,作为所有微服务的前置网关服务,承载了路由、身份认证、鉴权、审计、日志收集、统计、流控等重要功能,必须要保证高可靠性和稳定性。同时,为了实现上述的重要功能,也势必会通过远程调用的方式(rest、feign)依赖调用其它服务。

如此一来,就必须要集成断路器,以免依赖服务不可用造成网关服务停摆,进而造成整个服务大面积瘫痪。

准备工作

zuul已经集成了ribbon,所以,集成断路器也很简单。复用上篇文章Spring Cloud进阶之路 | 十四:服务网关重构(FactoryBean、动态配置、token解析、user传递)的全部工程:xmall-auth、xmall-product、xmall-zuul。

改造zuul


依赖改造

添加spring-cloud-starter-openfeign、spring-cloud-starter-netflix-hystrix依赖,修改后的pom文件如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
​
    <parent>
        <groupId>com.luas.cloud</groupId>
        <artifactId>java-boot-parent-2.1</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../../java-boot-parent-2.1</relativePath>
    </parent>
​
    <groupId>com.luas.xmall</groupId>
    <artifactId>xmall-zuul</artifactId>
    <version>1.0.0-SNAPSHOT</version>
​
    <name>xmall-zuul</name>
    <description>网关服务</description>
​
    <properties>
    </properties>
​
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
​
        <!-- nacos cloud -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
​
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
​
​
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
​
</project>

启动类改造

启动类分别添加注解@EnableCircuitBreaker、@EnableFeignClients以开启hystrix、feign

package com.luas.xmall.gateway;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.openfeign.EnableFeignClients;
​
@EnableFeignClients
@EnableCircuitBreaker
@EnableZuulProxy
@SpringBootApplication
public class XmallZuulApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(XmallZuulApplication.class, args);
    }
​
}

创建客户端

为方便记,不再创建其它工程,直接创建xmall-product服务的feign客户端,供zuul调用,以模拟断路器过程。

创建SkuService。

package com.luas.xmall.gateway.product.clients;
​
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
​
@FeignClient(name = "xmall-product", fallback = SkuFallbackService.class)
public interface SkuService {
​
    @RequestMapping(value = "/sku/{id}", method = RequestMethod.GET)
    Object info(@PathVariable("id") String skuId);
​
}

创建SkuFallbackService。

package com.luas.xmall.gateway.product.clients;
​
import cn.hutool.core.map.MapUtil;
import org.springframework.stereotype.Component;
​
@Component
public class SkuFallbackService implements SkuService {
​
    @Override
    public Object info(String skuId) {
        return MapUtil.builder()
                .put("skuId", "0000000")
                .put("name", "未知")
                .put("price", "99999")
                .put("port", "未知")
                .build();
    }
​
}

模拟调用

创建SkuFeignFilter,类型为前置过滤器,顺序在前置身份认证之后。因此,需要先申请授权,访问sku接口,然后该过滤器才能执行的到。

package com.luas.xmall.gateway.filter;
​
import com.luas.xmall.gateway.product.clients.SkuService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.Random;
​
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
​
@Component
public class SkuFeignFilter extends ZuulFilter {
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    @Autowired
    private SkuService skuService;
​
    @Override
    public String filterType() {
        return PRE_TYPE;
    }
​
    @Override
    public int filterOrder() {
        return 1;
    }
​
    @Override
    public boolean shouldFilter() {
        return true;
    }
​
    @Override
    public Object run() throws ZuulException {
        Object skuInfo = this.skuService.info("" + new Random().nextInt(4));
​
        this.logger.info("sku info is {}", skuInfo);
​
        return null;
    }
}

配置改造

添加feign hystrix开关配置。

feign:
  hystrix:
    enabled: true

验证

依次启动xmall-product、xmall-auth、xmall-zuul工程,端口分别为8080、7777、5566。

先申请授权。

访问sku接口,http://localhost:5566/gateway/product/sku/1122,可正常访问。

停止xmall-product服务,再次访问sku接口,已不能正常访问。

查看控制台,已经执行了快速失败策略,返回了默认信息。


之前文章中也有过提及,hystrix断路器触发条件为在5秒钟内出现20次故障。所以,连续访问sku接口20次,已触发熔断策略,断路器已经打开。

此时控制台也显示了断路器打开的相关信息。

在xmall-product服务恢复之前,后续请求会直接失败,不会出现请求堵塞、甚至大面积失败、崩溃的情况,有效的保障了网关服务及整个服务的稳定可靠。

源码

github

https://github.com/liuminglei/SpringCloudLearning/tree/master/15/

gitee

https://gitee.com/xbd521/SpringCloudLearning/tree/master/15/

本文系【银河架构师】原创,如需转载请在文章明显处注明作者及出处。

微信搜索【银河架构师】,发现更多精彩内容。

发布了29 篇原创文章 · 获赞 1 · 访问量 2221

猜你喜欢

转载自blog.csdn.net/liuminglei1987/article/details/104226711