SpringCloud中Zuul网关原理及其配置,看它就够了(1)

Zuul是一个微服务网关,首先是一个微服务。也是会在Eureka注册中心中进行服务的注册和发现。也是一个网关,请求应该通过Zuul来进行路由。

Zuul网关不是必要的。是推荐使用的。

使用Zuul,一般在微服务数量较多(多于10个)的时候推荐使用,对服务的管理有严格要求的时候推荐使用,当微服务权限要求严格的时候推荐使用。

一、Zuul网关的作用

===============================================================================

网关有以下几个作用:

  • 统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。

  • 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。

  • 动态路由:动态的将请求路由到不同的后端集群中。

  • 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。

SpringCloud中Zuul网关原理及其配置,看它就够了

二、Zuul网关的应用

===============================================================================

1、网关访问方式

============================================================================

通过zuul访问服务的,URL地址默认格式为: http://zuulHostIp:port/ 要访问的服务名称/服务中的URL

服务名称:properties配置文件中的spring.application.name。

服务的URL:就是对应的服务对外提供的URL路径监听。

2、网关依赖注入

============================================================================

     

org.springframework.cloud

spring-cloud-starter-eureka

     

org.springframework.cloud

spring-cloud-starter-zuul

        

org.springframework.retry

spring-retry

 

3、网关启动器

===========================================================================

/**

* @EnableZuulProxy - 开启Zuul网关。

*  当前应用是一个Zuul微服务网关。会在Eureka注册中心中注册当前服务。并发现其他的服务。

*  Zuul需要的必要依赖是spring-cloud-starter-zuul。

*/

@SpringBootApplication

@EnableZuulProxy

public class ZuulApplication {

public static void main(String[] args) {

SpringApplication.run(ZuulApplication.class, args);

}

}

4、网关全局变量配置

==========================================================================

4.1 URL路径匹配

# URL pattern

# 使用路径方式匹配路由规则。

# 参数key结构:zuul.routes.customName.path=xxx

# 用于配置路径匹配规则。

# 其中customName自定义。通常使用要调用的服务名称,方便后期管理

# 可使用的通配符有: * ** ?

# ? 单个字符

# * 任意多个字符,不包含多级路径

# ** 任意多个字符,包含多级路径

zuul.routes.eureka-application-service.path=/api/**

# 参数key结构:zuul.routes.customName.url=xxx

# url用于配置符合path的请求路径路由到的服务地址。

zuul.routes.eureka-application-service.url=http://127.0.0.1:8080/

4.2 服务名称匹配

# service id pattern 通过服务名称路由

# key结构 :zuul.routes.customName.path=xxx

# 路径匹配规则

zuul.routes.eureka-application-service.path=/api/**

# key结构 :zuul.routes.customName.serviceId=xxx

# serviceId用于配置符合path的请求路径路由到的服务名称。

zuul.routes.eureka-application-service.serviceId=eureka-application-service

服务名称匹配也可以使用简化的配置:

# simple service id pattern 简化配置方案

# 如果只配置path,不配置serviceId。则customName相当于服务名称。

# 符合path的请求路径直接路由到customName对应的服务上。

zuul.routes.eureka-application-service.path=/api/**

4.3 路由排除配置

# ignored service id pattern

# 配置不被zuul管理的服务列表。多个服务名称使用逗号’,'分隔。

# 配置的服务将不被zuul代理。

zuul.ignored-services=eureka-application-service

# 此方式相当于给所有新发现的服务默认排除zuul网关访问方式,只有配置了路由网关的服务才可以通过zuul网关访问

# 通配方式配置排除列表。

zuul.ignored-services=*

# 使用服务名称匹配规则配置路由列表,相当于只对已配置的服务提供网关代理。

zuul.routes.eureka-application-service.path=/api/**

# 通配方式配置排除网关代理路径。所有符合ignored-patterns的请求路径都不被zuul网关代理。

zuul.ignored-patterns=//test/

zuul.routes.eureka-application-service.path=/api/**

4.4 路由前缀配置

# prefix URL pattern 前缀路由匹配

# 配置请求路径前缀,所有基于此前缀的请求都由zuul网关提供代理。

zuul.prefix=/api

# 使用服务名称匹配方式配置请求路径规则。

# 这里的配置将为:http://ip:port/api/appservice/**的请求提供zuul网关代理,可以将要访问服务进行前缀分类。

# 并将请求路由到服务eureka-application-service中。

zuul.routes.eureka-application-service.path=/appservice/**

5 Zuul网关配置总结

================================================================================

网关配置方式有多种,默认、URL、服务名称、排除|忽略、前缀。

网关配置没有优劣好坏,应该在不同的情况下选择合适的配置方案。扩展:大公司为什么都有API网关?聊聊API网关的作用

zuul网关其底层使用ribbon来实现请求的路由,并内置Hystrix,可选择性提供网关fallback逻辑。使用zuul的时候,并不推荐使用Feign作为application client端的开发实现。毕竟Feign技术是对ribbon的再封装,使用Feign本身会提高通讯消耗,降低通讯效率,只在服务相互调用的时候使用Feign来简化代码开发就够了。而且商业开发中,使用Ribbon+RestTemplate来开发的比例更高。

三、Zuul网关过滤器

===============================================================================

Zuul中提供了过滤器定义,可以用来过滤代理请求,提供额外功能逻辑。如:权限验证,日志记录等。

Zuul提供的过滤器是一个父类。父类是ZuulFilter。通过父类中定义的抽象方法filterType,来决定当前的Filter种类是什么。有前置过滤、路由后过滤、后置过滤、异常过滤。

  • 前置过滤:是请求进入Zuul之后,立刻执行的过滤逻辑。

  • 路由后过滤:是请求进入Zuul之后,并Zuul实现了请求路由后执行的过滤逻辑,路由后过滤,是在远程服务调用之前过滤的逻辑。

  • 后置过滤:远程服务调用结束后执行的过滤逻辑。

  • 异常过滤:是任意一个过滤器发生异常或远程服务调用无结果反馈的时候执行的过滤逻辑。无结果反馈,就是远程服务调用超时。

3.1 过滤器实现方式

===============================================================================

继承父类ZuulFilter。在父类中提供了4个抽象方法,分别是:filterType, filterOrder, shouldFilter, run。其功能分别是:

filterType:方法返回字符串数据,代表当前过滤器的类型。可选值有-pre, route, post, error。

  • pre - 前置过滤器,在请求被路由前执行,通常用于处理身份认证,日志记录等;

  • route - 在路由执行后,服务调用前被调用;

  • error - 任意一个filter发生异常的时候执行或远程服务调用没有反馈的时候执行(超时),通常用于处理异常;

  • post - 在route或error执行后被调用,一般用于收集服务信息,统计服务性能指标等,也可以对response结果做特殊处理。

filterOrder:返回int数据,用于为同filterType的多个过滤器定制执行顺序,返回值越小,执行顺序越优先。

shouldFilter:返回boolean数据,代表当前filter是否生效。

run:具体的过滤执行逻辑。如pre类型的过滤器,可以通过对请求的验证来决定是否将请求路由到服务上;如post类型的过滤器,可以对服务响应结果做加工处理(如为每个响应增加footer数据)。

3.2 过滤器的生命周期

================================================================================

SpringCloud中Zuul网关原理及其配置,看它就够了

3.3 代码示例

============================================================================

/**

* Zuul过滤器,必须继承ZuulFilter父类。

* 当前类型的对象必须交由Spring容器管理。使用@Component注解描述。

* 继承父类后,必须实现父类中定义的4个抽象方法。

* shouldFilter、 run、 filterType、 filterOrder

*/

@Component

public class LoggerFilter extends ZuulFilter {

private static final Logger logger = LoggerFactory.getLogger(LoggerFilter.class);

/**

* 返回boolean类型。代表当前filter是否生效。

* 默认值为false。

* 返回true代表开启filter。

*/

@Override

public boolean shouldFilter() {

return true;

}

/**

* run方法就是过滤器的具体逻辑。

* return 可以返回任意的对象,当前实现忽略。(spring-cloud-zuul官方解释)

* 直接返回null即可。

*/

@Override

public Object run() throws ZuulException {

// 通过zuul,获取请求上下文

RequestContext rc = RequestContext.getCurrentContext();

HttpServletRequest request = rc.getRequest();

logger.info(“LogFilter1…method={},url={}”,

request.getMethod(),request.getRequestURL().toString());

// 可以记录日志、鉴权,给维护人员记录提供定位协助、统计性能

return null;

}

/**

* 过滤器的类型。可选值有:

* pre - 前置过滤

* route - 路由后过滤

* error - 异常过滤

* post - 远程服务调用后过滤

*/

@Override

public String filterType() {

return “pre”;

}

/**

* 同种类的过滤器的执行顺序。

* 按照返回值的自然升序执行。

*/

@Override

public int filterOrder() {

return 0;

}

}

四、Zuul网关的容错(与Hystrix的无缝结合)

==============================================================================================

在spring cloud中,Zuul启动器中包含了Hystrix相关依赖,在Zuul网关工程中,默认是提供了Hystrix Dashboard服务监控数据的(hystrix.stream),但是不会提供监控面板的界面展示。可以说,在spring cloud中,zuul和Hystrix是无缝结合的。

4.1 Zuul中的服务降级处理

====================================================================================

在Edgware版本之前,Zuul提供了接口ZuulFallbackProvider用于实现fallback处理。从Edgware版本开始,Zuul提供了ZuulFallbackProvider的子接口FallbackProvider来提供fallback处理。

Zuul的fallback容错处理逻辑,只针对timeout异常处理,当请求被Zuul路由后,只要服务有返回(包括异常),都不会触发Zuul的fallback容错逻辑。

因为对于Zuul网关来说,做请求路由分发的时候,结果由远程服务运算的。那么远程服务反馈了异常信息,Zuul网关不会处理异常,因为无法确定这个错误是否是应用真实想要反馈给客户端的。

4.2 代码示例

============================================================================

/**

* 如果需要在Zuul网关服务中增加容错处理fallback,需要实现接口ZuulFallbackProvider

* spring-cloud框架,在Edgware版本(包括)之后,声明接口ZuulFallbackProvider过期失效,

* 提供了新的ZuulFallbackProvider的子接口 - FallbackProvider

* 在老版本中提供的ZuulFallbackProvider中,定义了两个方法。

*  - String getRoute()

*    当前的fallback容错处理逻辑处理的是哪一个服务。可以使用通配符‘*’代表为全部的服务提供容错处理。

*    如果只为某一个服务提供容错,返回对应服务的spring.application.name值。

*  - ClientHttpResponse fallbackResponse()

*    当服务发生错误的时候,如何容错。

* 新版本中提供的FallbackProvider提供了新的方法。

*  - ClientHttpResponse fallbackResponse(Throwable cause)

*    如果使用新版本中定义的接口来做容错处理,容错处理逻辑,只运行子接口中定义的新方法。也就是有参方法。

*    是为远程服务发生异常的时候,通过异常的类型来运行不同的容错逻辑。

*/

@Component

public class TestFallBbackProvider implements FallbackProvider {

/**

* return - 返回fallback处理哪一个服务。返回的是服务的名称

* 推荐 - 为指定的服务定义特性化的fallback逻辑。

* 推荐 - 提供一个处理所有服务的fallback逻辑。

* 好处 - 服务某个服务发生超时,那么指定的fallback逻辑执行。如果有新服务上线,未提供fallback逻辑,有一个通用的。

*/

@Override

public String getRoute() {

return “eureka-application-service”;

}

/**

* fallback逻辑。在早期版本中使用。

* Edgware版本之后,ZuulFallbackProvider接口过期,提供了新的子接口FallbackProvider

* 子接口中提供了方法ClientHttpResponse fallbackResponse(Throwable cause)。

* 优先调用子接口新定义的fallback处理逻辑。

*/

@Override

public ClientHttpResponse fallbackResponse() {

System.out.println(“ClientHttpResponse fallbackResponse()”);

List<Map<String, Object>> result = new ArrayList<>();

Map<String, Object> data = new HashMap<>();

data.put(“message”, “服务正忙,请稍后重试”);

result.add(data);

ObjectMapper mapper = new ObjectMapper();

String msg = “”;

try {

msg = mapper.writeValueAsString(result);

} catch (JsonProcessingException e) {

msg = “”;

}

return this.executeFallback(HttpStatus.OK, msg,

“application”, “json”, “utf-8”);

}

/**

* fallback逻辑。优先调用。可以根据异常类型动态决定处理方式。

*/

@Override

public ClientHttpResponse fallbackResponse(Throwable cause) {

System.out.println(“ClientHttpResponse fallbackResponse(Throwable cause)”);

if(cause instanceof NullPointerException){

List<Map<String, Object>> result = new ArrayList<>();

Map<String, Object> data = new HashMap<>();

data.put(“message”, “网关超时,请稍后重试”);

result.add(data);

ObjectMapper mapper = new ObjectMapper();

String msg = “”;

try {

msg = mapper.writeValueAsString(result);

} catch (JsonProcessingException e) {

msg = “”;

}

return this.executeFallback(HttpStatus.GATEWAY_TIMEOUT,

msg, “application”, “json”, “utf-8”);

}else{

return this.fallbackResponse();

}

}

/**

* 具体处理过程。

* @param status 容错处理后的返回状态,如200正常GET请求结果,201正常POST请求结果,404资源找不到错误等。

*  使用spring提供的枚举类型对象实现。HttpStatus

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

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

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

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

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

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

面试真题

Spring源码笔记

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
…(img-2EKZe4zM-1713328296119)]

[外链图片转存中…(img-UERIa405-1713328296120)]

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

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

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

[外链图片转存中…(img-F6JXNaNV-1713328296120)]

[外链图片转存中…(img-5mXi3WBU-1713328296120)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值