geek的技术日志,记录每一次技术思考的闪光点。

Spring Cloud微服务架构中使用zuul的fallback来实现服务降级和熔断功能

服务降级和熔断功能场景说明

我们Spring Cloud的微服务架构体系中,就是当我们使用zuul进行路由分发时,如果后端服务没有启动,或者调用超时,或者服务挂掉了,这时候我们是不希望直接把这些错误和异常这么简单粗暴的暴露出来给前端的,这样不安全不美观也不友好,Zuul提供一种服务降级功能,使得实际的微服务无响应时,可以使用zuul网关中定义的响应返回给客户端。这就是服务降级和熔断,在zuul中是通过实现ZuulFallbackProvider接口来达到这个目的的。看代码吧~

 

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回退机制处理器。

* log4geek.cc

* 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(){

returnnew ClientHttpResponse() {

/**

* 网关向api服务请求是失败了,但是消费者客户端向网关发起的请求是OK的,

* 不应该把api的404,500等问题抛给客户端

* 网关和api服务集群对于客户端来说是黑盒子

*/

@Override

public HttpStatus getStatusCode()throws IOException {

return HttpStatus.OK;

}

@Override

publicintgetRawStatusCode()throws IOException {

return HttpStatus.OK.value();

}

@Override

public String getStatusText()throws IOException {

return HttpStatus.OK.getReasonPhrase();

}

@Override

publicvoidclose(){

}

/**

* 当 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();

}

returnnew 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//开启启动程序入口类

publicclassEurekaApplication{

publicstaticvoidmain(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配置

<projectxmlns="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>

<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>

<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>

<plugin>

<groupId>org.springframework.boot<groupId>

<artifactId>spring-boot-maven-plugin<artifactId>

<plugin>

<plugins>

<build>

<project>

 

打赏作者

未经允许不得转载:极客技术 » Spring Cloud微服务架构中使用zuul的fallback来实现服务降级和熔断功能

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址