Spring Cloud 入门——4.3 Zuul 分布式路由实现服务降级(fallback)

24 篇文章 0 订阅
22 篇文章 3 订阅

代码信息

本篇文章涉及代码版本

组件版本
Spring Boot2.0.8.RELEASE
Spring CloudFinchley.SR1

本篇文章涉及应用

应用说明
base-eureka服务发现
base-zuul-fallbackZuul服务降级
base-producer提供服务的最基础的应用
base-producer-upload提供文件上传的应用

查看Zuul内部的依赖关系可以看到下面内容

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

可以看到Zuul内部其实已经添加了hystrix。这样zuul也可以实现服务降级。

创建一个支持服务降级的zuul应用

构建maven依赖

其实hystrix依赖不是必须的,就像上面看到了,zuul默认依赖已经引入了hystrix。

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

参数配置application.yml

因为这次我们要实现不同项目使用不同的降级策略,所以我们使用了两个项目base-producerbase-producer-upload,其中base-producer是我们最基础的服务端项目。base-producer-upload是我们刚创建的支持上传的服务端项目

spring:
  application:
    name: base-zuul-fallback
server:
  port: 8302
eureka:
  client:
    service-url: 
      defaultZone: http://localhost:8000/eureka/
logging:
  file: ${spring.application.name}.log
zuul:
  routes:
    consumer:
      path: /client/**
      serviceId: base-producer
    consumerV2:
      path: /client-update/**
      serviceId: base-producer-upload
consumer:
  ribbon:
    listOfServers: http://localhost:8100/
consumerV2:
  ribbon:
    listOfServers: http://localhost:8105/

代码编写

主类

主类很简单就是打开相关功能的注解。

@EnableZuulProxy
@SpringBootApplication
@EnableCircuitBreaker
public class ZuulApplication {

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

服务降级代码

要实现服务降级只需要在容器中创建实现FallbackProvider(之前版本是ZuulFallbackProvider)接口的对象。

@Component
public class ClientFallbackProvider implements FallbackProvider {
    @Override 
    public String getRoute() {
        // 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
        return "base-producer";
    }

    /**
     * 回退逻辑
     * @param route
     * @param cause
     * @return
     */
    @Override 
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.BAD_GATEWAY;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.BAD_REQUEST.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(("fallback-base-producer:" + ClientFallbackProvider.this.getRoute()).getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}
@Component
public class ClientV2FallbackProvider implements FallbackProvider {
    @Override 
    public String getRoute() {
        // 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
        return "base-producer-upload";
    }

    /**
     * 回退逻辑
     * @param route
     * @param cause
     * @return
     */
    @Override 
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.BAD_GATEWAY;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.BAD_REQUEST.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(("fallback-base-producer-upload:" + ClientV2FallbackProvider.this.getRoute()).getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

接口中getRoute指的是此处理工具处理那个微服务。假如返回null或者*表示处理所有的微服务。所以上面代码中我们让ClientFallbackProvider处理base-producer服务。让ClientV2FallbackProvider处理base-producer-upload

测试

现在我们依次启动base-eurekabase-producerbase-producer-uploadbase-zuul-fallback项目。

首先我们测试两个接口是否可以调用

在这里插入图片描述

在这里插入图片描述

首先两个接口已经可以正常发起请求,然后现在我们关闭掉base-producerbase-producer-upload项目。

在这里插入图片描述

在这里插入图片描述

可以看到输出的内容已经有所不同,两个微服务成功应用了不同的处理策略。


本篇文章并未贴出所有代码,涉及的源码下载地址:https://gitee.com/daifylearn/cloud-learn

ps.上述的所有项目都是可以成功运行的。但是在后期为了实现每个应用端口尽量不冲突会有些许调整,而后续某次作死调整结构和名称可能会导致部分项目无法运行o(╯□╰)o,如果发现请留言我进行修改。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值