Springcloud 微服务实战笔记 Zuul

优点

  1. 解决路由规则与服务实例维护问题。
  2. 对于类似签名校验、登录校验在微服务架构中的冗余问题。

入门使用

构建网关

  1. pom.xml引入 spring-cloud-starter-netflix-zuul

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    
  2. 应用主类增加@EnableZuulProxy注解

  3. 增加配置信息,主要是路由规则信息

    由于zuul已实现与eureka无缝整合,配置路由规则时候无需配置具体的URL,而是映射到具体的服务即可。比如: /api1/** 对应的就是请求SPRING-CLOUD-STUDY-DEMO服务

    通过指定Eureka Server服务注册中心的位置,除了将自己注册成服务之外,还可以让Zuul能够获取微服务实力清单,以实现path映射服务,再从服务中挑选实例来进行请求转发的完整路由机制。

    server:port: 7777spring:application:name: spring-cloud-study-zuulzuul:
    #需要忽略的头部信息,不在传播到其他服务sensitive-headers: Access-Control-Allow-Originignored-headers: Access-Control-Allow-Origin,H-APP-Id,Token,APPTokenroutes:apis1:path: /api1/**#serviceId: spring-cloud-study-demoserviceId: SPRING-CLOUD-STUDY-DEMOapis2:path: /api2/**url: http://127.0.0.1:9999/apis3:path: /api23/**url: https://www.baidu.com/
    

请求过滤

Zuul允许开发者在API网关上通过自定义过滤器来实现对请求的拦截与过滤,实现的方式很简单,只需要继承ZuulFilter抽象类并实现抽象方法即可。比如:

@Component
public class WebSocketFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() {RequestContext context = RequestContext.getCurrentContext();HttpServletRequest request = context.getRequest();String upgradeHeader = request.getHeader("Upgrade");if (null == upgradeHeader) {upgradeHeader = request.getHeader("upgrade");}if (null != upgradeHeader && "websocket".equalsIgnoreCase(upgradeHeader)) {context.addZuulRequestHeader("connection", "Upgrade");}return null;}
}
package com.didispace.filter;import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;/*** 校验请求中是否包含accessToken参数,如果没有包含则返回401*/
public class AccessFilter extends ZuulFilter  {private static Logger log = LoggerFactory.getLogger(AccessFilter.class);@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());Object accessToken = request.getParameter("accessToken");if(accessToken == null) {log.warn("access token is empty");ctx.setSendZuulResponse(false);ctx.setResponseStatusCode(401);return null;}log.info("access token ok");return null;}}

●filterType:过滤器的类型,它决定过滤器在请求的哪个生命周期中执行。这里定义为pre,代表会在请求被路由之前执行。 ●filterOrder:过滤器的执行顺序。当请求在一个阶段中存在多个过滤器时,需要根据该方法返回的值来依次执行。 ●shouldFilter:判断该过滤器是否需要被执行。这里我们直接返回了 true,因此该过滤器对所有请求都会生效。实际运用中我们可以利用该函数来指定过滤器的有效范围。 ● run : 过 滤 器 的 具 体 逻 辑 。 这 里 我 们 通 过ctx.setSendZuulResponse(false)令 zuul 过滤该请求,不对其进行路由,然后通过 ctx.setResponseStatusCode(401)设置了其返回的错误码 , 当 然 也 可 以 进 一 步优 化 我 们 的 返 回 , 比 如 , 通 过ctx.setResponseBody(body)对返回的body内容进行编辑等。

总结

●它作为系统的统一入口,屏蔽了系统内部各个微服务的细节。 ●它可以与服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发。 ●它可以实现接口权限校验与微服务业务逻辑的解耦。 ●通过服务网关中的过滤器,在各生命周期中去校验请求的内容,将原本在对外服务层做的校验前移,保证了微服务的无状态性,同时降低了微服务的测试难度,让服务本身更集中关注业务逻辑的处理。

进阶使用

路由详解

  1. 传统路由配置:直接path对应到具体的地址,多个地址则使用逗号分隔开
  2. 服务路由配置:path对应服务名即可,由于zuul整合了eureka,zuul可获取服务实例的地址清单,然后通过负载均衡策略,可在清单中选择一个具体的实例进行转发就能完成路由工作。
  3. 服务路由默认规则:zuul已经自动实现了zuul.routes.=/serviceId/** 路由规则配置,当然由于某些服务可能需要禁止可使用zuul.ignored-services=来排除服务

自定义路由映射规则

实现很简单,只需要在API网关工程中,增加Bean,比如:

@Bean
public PatternServiceRouteMapper serviceRouteMapper(){return new PatternServiceRouteMapper("(? <name>^.+)-(? <version>v.+$)","${version}/${name}");
}

通过上述代码就实现将userservice-v1和userservice-v2路径,修改为/v1/userservice/ 和 /v2/userservice/ 这样带有版本号前缀的路径。

忽略表达式

比如,以快速入门中的示例为基础,如果不希望/hello 接口被路由,那么我们可以这样设置:

zuul.ignored-patterns=/**/hello/**

路由前缀

为了方便全局地为路由规则增加前缀信息,Zuul提供了zuul.prefix 参数来进行设置,比如,希望为网关上的路由规则都增加/api前缀,那么我们可以在配置文件中增加配置:

zuul.prefix=/api

Cookie与头信息

默认情况下,Spring Cloud Zuul在请求路由时,会过滤掉HTTP请求头信息中的一些敏感信息,防止它们被传递到下游的外部服务器。默认的敏感头信息通过zuul.sensitiveHeaders参数定义,包括Cookie、SetCookie、Authorization三个属性。所以,我们在开发Web项目时常用的Cookie在Spring Cloud Zuul网关中默认是不会传递的,这就会引发一个常见的问题:如果我们要将使用了 Spring Security、Shiro等安全框架构建的Web应用通过Spring Cloud Zuul构建的网关来进行路由时,由于Cookie信息无法传递,我们的Web应用将无法实现登录和鉴权。怎么解决?

  1. 方式一:对指定路由开启自定义敏感头
    zuul.routes.<router>.customSensitiveHeaders=true
    
  2. 方式二:将指定路由的敏感头设置为空
    zuul.routes.<router>.sensitiveHeaders=
    

比较推荐使用这两种方法,仅对指定的Web应用开启对敏感信息的传递,影响范围小,不至于引起其他服务的信息泄露问题。

过滤器详解

过滤器

功能:请求的路由和过滤

路由:将外部请求转发到具体的微服务实例上,实现外部访问统一入口的基础。

过滤:负责对请求的处理过程进行干预,实现请求校验、服务聚合等功能的基础。

过滤器必须包含4个基本特征:过滤类型、执行顺序、执行条件、具体操作。对应4个抽象方法:

String filterType(); // 过滤器的类型
int filterOrder(); // 过滤器的执行顺序
boolean shouldFilter(); // 判断该过滤器是否要执行
Object run(); // 过滤器的具体逻辑

过滤器类型:

■pre:可以在请求被路由之前调用。 ■routing:在路由请求时被调用。 ■post:在routing和error过滤器之后被调用。 ■error:处理请求时发生错误时被调用。

请求生命周期

主要过程:

  1. pre,主要进行请求路由之前做一些前置加工,比如请求的校验等。
  2. routing,路由请求转发阶段,将外部请求转发到具体服务实例上去的过程。
  3. post,此时可以获取到请求信息,也可以获取到实例返回信息,在此阶段可进行一些加工或者转换等操作。
  4. error,此阶段只有在上述阶段中发生异常时候才会触发,最终流向哈市post,将最终结果返回给客户端。

核心过滤器

Spring cloud zuul默认实现了一批核心过滤器,主要如下图:

过滤器执行过程

com.netflix.zuul.http.ZuulServlet 实现如下:

@Overridepublic void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {try {init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);// Marks this request as having passed through the "Zuul engine", as opposed to servlets// explicitly bound in web.xml, for which requests will not have the same data attachedRequestContext context = RequestContext.getCurrentContext();context.setZuulEngineRan();try {preRoute();} catch (ZuulException e) {error(e);postRoute();return;}try {route();} catch (ZuulException e) {error(e);postRoute();return;}try {postRoute();} catch (ZuulException e) {error(e);return;}} catch (Throwable e) {error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));} finally {RequestContext.getCurrentContext().unset();}}

通过配置禁用过滤器

zuul.<SimpleClassName>.<filterType>.disable=true

代表过滤器的类名 比如:ErrorFilter

代表过滤器类型,比如:error。

参考资料:

《Spring Cloud微服务实战》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/322178.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hotspot源码解析-第十二章-线程栈保护页

了解保护页&#xff0c;先从几个问题开始吧 1、为什么线程栈有栈帧了&#xff0c;还要有保护页&#xff1f; 答&#xff1a;在操作系统中内存可以看成是一个大数组&#xff0c;这就有一个问题&#xff0c;线程之间可能会互相踩了别人的内存空间&#xff0c;所以栈空间也存在这…

一篇文章学会Vim

一篇文章学会Vim 声明&#xff1a;以下内容均为我个人的理解&#xff0c;如果发现错误或者疑问可以联系我共同探讨 简介 Vim是一个高度可定制的终端文本编辑器&#xff0c;它可以很方便的创建和修改任何类型的文本。作为vi的升级版&#xff0c;有许多新的特性(以下列出的特性…

leetcode:724. 寻找数组的中心下标

一、题目 二、函数原型 int pivotIndex(int* nums, int numsSize) 三、思路 首先要理解正确中心下标&#xff0c;中心下标左侧元素之和等于右侧元素之和&#xff0c;比较时是不包含中心下标所指元素的。 先将数组和求出来记为sum&#xff0c;再遍历数组&#xff0c;遍历到…

关于“Python”的核心知识点整理大全61

目录 注意 20.1.4 使用 jumbotron 设置主页的样式 index.html 20.1.5 设置登录页面的样式 login.html 20.1.6 设置 new_topic 页面的样式 new_topic.html 20.1.7 设置 topics 页面的样式 topics.html 元素&#xff0c;让它们在页面上显得大些&#xff08;见2&#xf…

在排序数组中查找元素的第一个和最后一个位置

在排序数组中查找元素的第一个和最后一个位置 题目解法一解法二&#xff08;二分查找&#xff09;代码展示原理剖析 题目 在排序数组中查找元素的第一个和最后一个位置 解法一 class Solution { public:vector<int> searchRange(vector<int>& nums, int targ…

突破技术边界:R与jsonlite库探秘www.snapchat.com的数据之旅

概述 Snapchat是一款流行的社交媒体应用&#xff0c;它允许用户发送和接收带有滤镜和贴纸的照片和视频&#xff0c;以及创建和观看故事和发现内容。Snapchat的数据是非常有价值的&#xff0c;因为它可以反映用户的行为、偏好和趋势。然而&#xff0c;Snapchat的数据并不容易获…

整除判断-判断正整数a能否被b整除,如果不能整除,输出商和余数 C语言xdoj42

问题描述 判断正整数a能否被b整除&#xff0c;如果不能整除&#xff0c;输出商和余数 输入说明 输入两个正整数a和b&#xff08;0<a, b<10000&#xff09;&#xff0c;a和b之间用空格分隔。 输出说明 如果a能被b整除&#xff0c;输出yes&#xff0c;否则在同…

Unity 使用 Plastic 同步后,正常工程出现错误

class Newtonsoft.Json.Linq.JToken e CS0433:类型"JToken"同时存在于"Newtonsoft.Json.Net20,Version3.5.0.0,Cultureneutral,,PublicKeyToken30ad4fe6b2a6aeed"和"Newtonsoft.Json, Version12.0.0.0,Cultureneutral,PublicKeyToken30ad4fe6b2a6aeed…

在Android设备上设置和使用隧道代理HTTP

随着互联网的深入发展&#xff0c;网络信息的传递已经成为人们日常生活中不可或缺的一部分。对于我们中国人来说&#xff0c;由于某些特殊的原因&#xff0c;访问国外网站时常常会遇到限制。为了解决这个问题&#xff0c;使用代理服务器成为了许多人的选择。而在Android设备上设…

「解析」Windows 如何优雅使用 Terminal

所谓工欲善其事必先利其器&#xff0c;对于开发人员 Linux可能是首选&#xff0c;但是在家学习的时候&#xff0c;我还是更喜欢使用 Windows系统&#xff0c;首先是稳定&#xff0c;其次是习惯了。当然了&#xff0c;我还有一台专门安装 Linux系统的小主机用于学习Linux使用&am…

Gin 项目引入热加载

Gin 项目引入热加载 文章目录 Gin 项目引入热加载一、什么是热加载二、Air2.1 介绍2.2 特性特性&#xff1a;2.3 相关文档2.4 安装推荐使用 install.sh使用 go install 2.5 配置环境变量2.6 使用 三、Fresh3.1 介绍3.2 相关文档3.3 安装与使用 四、bee4.1 介绍4.2 相关文档4.3 …

UE4 4.21使用编辑器蓝图EditorBlueprint方法

在UE4 4.21中&#xff0c;编辑器蓝图&#xff08;Editor Blueprint&#xff09;是一个强大的工具&#xff0c;允许开发者扩展和自定义Unreal编辑器的功能。通过编辑器蓝图&#xff0c;我们可以创建自定义的工具和功能&#xff0c;以优化开发流程。 本教程将指导您如何在UE4 4.…