第二十四章 Spring cloud 如何在Zuul中使用fallback功能

如何在Zuul中使用fallback功能

我们在项目中使用Spring cloud zuul的时候,有一种这样的需求,就是当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来。

项目结构如下:


SrpingCLoudFallBack

package com.example.demo.fallback;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 自定义Zuul回退机制处理器。
 *
 * Provides fallback when a failure occurs on a route 英文意思就是说提供一个回退机制当路由后面的服务发生故障时。
 */
@Component
public class SrpingCLoudFallBack implements ZuulFallbackProvider{
	/**
     * 返回值表示需要针对此微服务做回退处理(该名称一定要是注册进入 eureka 微服务中的那个 serviceId 名称);
     *
     * @return
     */
    @Override
    public String getRoute() {
        return "spring-cloud-user";//api服务id,如果需要所有调用都支持回退,则return "*"或return null
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
    		/**
			 * 网关向api服务请求是失败了,但是消费者客户端向网关发起的请求是OK的,
			 * 不应该把api的404,500等问题抛给客户端
			 * 网关和api服务集群对于客户端来说是黑盒子
			 */
			@Override
			public HttpStatus getStatusCode() throws IOException {
				
				return HttpStatus.OK;
			}

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

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

            @Override
            public void close() {
            }

            /**
             * 当 springms-provider-user 微服务出现宕机后,客户端再请求时候就会返回 fallback 等字样的字符串提示;
             *
             * 但对于复杂一点的微服务,我们这里就得好好琢磨该怎么友好提示给用户了;
             * 
             * 如果请求用户服务失败,返回什么信息给消费者客户端
             * @return
             * @throws IOException
             */
            @Override
            public InputStream getBody() throws IOException {
				JSONObject r = new JSONObject();
				try {
					r.put("state", "9999");
					r.put("msg", "系统错误,请求失败");
				} catch (JSONException e) {
					e.printStackTrace();
				}
				return new ByteArrayInputStream(r.toString().getBytes("UTF-8"));
             //   return new ByteArrayInputStream((getRoute() + " :fallback").getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
				//和body中的内容编码一致,否则容易乱码
		        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
		        return headers;
            }
        };
    }
}

EurekaApplication

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@SpringBootApplication  //开启启动程序入口类
public class EurekaApplication {
  public static void main(String[] args) {
    SpringApplication.run(EurekaApplication.class, args);
  }
}

application.yml配置

server:
  port: 8040
spring:
  application:
    name: spring-cloud-zuul-api-gateway-fallback
eureka:
  client:
    serviceUrl:
      defaultZone: http://user:123456@localhost:8761/eureka
  instance:
    prefer-ip-address: true

zuul: 
  routes:
    users:    #此处可以随便定义一个,只要唯一就行
      path: /user-path/**     # 一个*号只能匹配一个级别的路径,比如只能访问:/user-path/order  而两个*表示可以匹配多个层级,例如项目访问路径为:http://loaclhost:8084/user-path/user/1
      serviceId: spring-cloud-user  #反向代理到这个服务


pom.xml配置

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example.demo</groupId>
	<artifactId>spring-cloud-zuul-api-gateway-fallback</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>spring-cloud-zuul-api-gateway-fallback</name>
	<description>spring-cloud-zuul-api-gateway-fallback</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.1.RELEASE</version>
	</parent>

	<properties>
		<!-- 文件拷贝时的编码 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<!-- 编译时的编码 -->
		<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
		<!-- jdk版本 -->
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId>
		</dependency>
			<!-- 注册中心 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>		
		<!-- 用于热部署 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<!-- 版本依赖管理,故之后添加依赖无需指定version -->
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Camden.SR2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<!-- 用以为integration-test提供支持。 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值