7.5 对于HyStrix和Ribbon的设置


Zuul天生就拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。

但是需要注意,当使用path与ur1的映射关系来配置路由规则的时候,对于路由转发的请求不会采用HystrixCommand来包装,所以这类路由请求没有线程隔离和断路器的保护,并且也不会有负载均衡的能力。因此,我们在使用Zuul的时候尽量使用path和serviceId的组合来进行配置,这样不仅可以保证API网关的健壮和稳定,也能用到Ribbon的客户端负载均衡功能。

  • 1.启用hystrix配置

hystrix.metrics.enabled=true

  • 2.设置API网关中路由转发请求的HystrixCommand执行超时时间,单位为毫秒

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000

当路由转发请求的命令执行时间超过该配置值之后,Hystrix 会将该执行命令标记为TIMEOUT并抛出异常,Zuul会对该异常进行处理并返回如下JSON信息给外部调用方。

{

“timestamp”: “2021-07-15T07:25:21.723+00:00”,

“status”: 504,

“error”: “Gateway Timeout”,

“message”: “”

}

  • 3.路由转发请求时,创建请求连接的超时时间 ,单位ms

ribbon.ConnectTimeout=3000

注意:当ribbon.ConnectTimeout的配置值小于hystrix.command.default.execution.isolation.thread. timeoutInMilliseconds配置值的时候,若出现路由请求出现连接超时,会自动进行重试路由请求,如果重试依

然失败,Zuul会返回如下JSON信息给外部调用方。

{

“timestamp”:1481352582852,

“status”:500,

“error”:“Internal Server Error”,

“exception”:“com. netflix. zuul. exception. ZuulException”,

“message”:“NUMBEROF RETRIES NEXTSERVER EXCEEDED”

}

如果ribbon .ConnectTimeout的配置值大于hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds配置值的时候,当出现路由请求连接超时时,由于此时对于路由转发的请求命令已经超时,所以不会进行重试路由请求,而是直接按请求命令超时处理,返回TIMEOUT的错误信息。

{

“timestamp”: “2021-07-15T07:42:51.028+00:00”,

“status”: 500,

“error”: “Internal Server Error”,

“message”: “”

}

  • 4.设置路由的重试机制 默认是true

zuul.retryable=false

指定路由的重试机制进行关闭

zuul.routes..retryable=false

注意:route就是你的服务名,比如zuul.routes.hello-service.retryable=false

7.6 异常处理


首先,我们尝试创建一个pre类型的过滤器,并在该过滤器的run方法实现中抛出一个异常。比如下面的实现,在run方法中调用的doSomething方法将抛出Runt imeException异常。

import com.netflix.zuul.ZuulFilter;

import com.netflix.zuul.exception.ZuulException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

@Component

public class ThrowExceptionFilter extends ZuulFilter {

private static Logger log = LoggerFactory.getLogger(ThrowExceptionFilter.class);

@Override

public String filterType() {

return “pre”;

}

@Override

public int filterOrder() {

return 0;

}

@Override

public boolean shouldFilter() {

return true;

}

@Override

public Object run() throws ZuulException {

log.info(“这是一个pre过滤器,将会抛出异常”);

this.doSomething();

return null;

}

private void doSomething() {

throw new RuntimeException("Exist some errors… ");

}

}

在添加了上面的过滤器之后,我们可以将该应用以及之前的相关应用运行起来,并根据网关配置的路由规则访问服务接口,比如http://localhost:5555/api-a/hello此时我们会发现,在API网关服务的控制台中输出了ThrowExceptionFilter的过滤逻辑中的日志信息。

在这里插入图片描述

但是返回给页面的信息中却拿不到我们想打印的信息

在这里插入图片描述

try-catch 处理

在catch异常的处理逻辑中并没有做任何输出操作,而是向请求上下文中添加了一些error相关的参数,主要

有下面三个参数。

  • error.status_code: 错误编码。

  • error.exception: Exception异常对象。

  • error.message: 错误信息。

其中,error.status_ code 参数就是SendErrorFilter过滤器用来判断是否需要执行的重要参数。分析到这里,实现异常处理的大致思路就开始明朗了,实现对ThrowExceptionFilter的run方法做一些异常处理的改造,具体如下:

@Component

public class ThrowExceptionFilter extends ZuulFilter {

private static Logger log = LoggerFactory.getLogger(ThrowExceptionFilter.class);

@Override

public String filterType() {

return “pre”;

}

@Override

public int filterOrder() {

return 0;

}

@Override

public boolean shouldFilter() {

return true;

}

@Override

public Object run() throws ZuulException {

log.info(“这是一个pre过滤器,将会抛出异常”);

RequestContext ctx = RequestContext.getCurrentContext();

try {

doSomething();

} catch (Exception e) {

e.printStackTrace();

ctx.set(“error.status_code”, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

ctx.set(“error.exception”, e);

}

return null;

}

private void doSomething() throws Exception {

throw new Exception("Exist some errors… ");

}

}

禁用过滤器

在Zuul中特别提供了-一个参数来禁用指定的过滤器,该参数的配置格式如下:

zuul...disable=true

比如

zuul.AccessFilter.pre.disable=true

7.7 服务的降级


import com.cloud.apigateway.filter.ThrowExceptionFilter;

import com.netflix.hystrix.exception.HystrixTimeoutException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

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.InputStream;

@Component

public class FallBackConfig implements org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider {

private static Logger log = LoggerFactory.getLogger(FallBackConfig.class);

/**

  • 定义构造函数

**/

public ClientHttpResponse fallbackResponse() {

return response(HttpStatus.INTERNAL_SERVER_ERROR);

}

@Override

public String getRoute() {

return “*”;

}

@Override

public ClientHttpResponse fallbackResponse(String route, Throwable cause) {

// 捕获超时异常,返回自定义信息

if (cause instanceof HystrixTimeoutException) {

return response(HttpStatus.GATEWAY_TIMEOUT);

} else {

return fallbackResponse();

}

}

private ClientHttpResponse response(final HttpStatus status) {

return new ClientHttpResponse() {

@Override

public HttpStatus getStatusCode() {

return status;

}

@Override

public int getRawStatusCode() {

return status.value();

}

@Override

public String getStatusText() {

return status.getReasonPhrase();

}

@Override

public void close() {

log.warn(“连接服务关闭,无法进行访问”);

}

@Override

public InputStream getBody() {

String message =

“{\n” +

““code”: 500,\n” +

““message”: “微服务飞出了地球”\n” +

“}”;

return new ByteArrayInputStream(message.getBytes());

}

@Override

public HttpHeaders getHeaders() {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面

小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>

image

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

image

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

image

image

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

册>,可以瞬间查漏补缺

[外链图片转存中…(img-CZRf6HDl-1712244845929)]

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

[外链图片转存中…(img-g1tlWndM-1712244845929)]

[外链图片转存中…(img-Vw6g3maQ-1712244845930)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐