Zuul 简介和使用

Zuul

    • 背景
    • Zuul的作用
    • Zuul API网关
    • Zuul请求过滤
    • Zuul路由规则
    • Zuul异常处理

背景

通过之前的学习,我们知道注册中心Eureka,可以讲服务注册到该注册中心,Ribbon和Feign可以实现服务负载均衡地调用,Hystrix可以实现服务熔断,但我们还缺点什么?

微服务架构图:
在这里插入图片描述

  • 外部调用方:浏览器、其他客户端
  • 负载均衡:nginx
  • OpenService:开放服务,服务消费者。集群部署
  • ServiceA/B:内部服务,服务提供者。两个服务进行集群部署,每个服务有三个实例。
  • 虚线框内服务调用可以使用Ribbon进行负载均衡访问,通过Eureka注册中心进行服务注册与订阅

现在还有一些问题需要解决:

  1. 如果我们的微服务中有很多独立的服务都要对外提供服务,那么我们要如何去管理这些接口?特别是当项目非常庞大的情况下要如何让管理?
  2. 在微服务中,一个独立的系统被拆分成很多个独立的服务,为了确保安全,权限管理也是一个不可回避的问题,如果在每个服务商都添加上相同的权限验证代码来确保系统不被非法访问,那么工作量也太大了,且维护也不方便。

为了解决上述问题,微服务架构中提出了API网关的概念,它就像一个安检站一样,所有的外部请求都需要经过它的调度与过滤,然后API网关来实现全球路由、负载均衡、权限验证等功能。

Spring Cloud这个一站式的微服务开发框架基于Netflix Zuul实现了Spring Cloud Zuul,采用了Spring Cloud Zuul即可实现一套基于API网关服务。

Zuul的作用

  1. 按照不同策略,将请求转发到不同的服务上去;

  2. 聚合API接口,统一对外暴露,提高系统的安全性;

  3. 实现请求统一的过滤,以及服务的熔断降级;

项目结构:

Zuul API网关

  1. 创建普通SpringBoot工程
  2. 添加依赖 spring-cloud-starter-netflix-eureka-clientspring-cloud-starter-netflix-zuul
  3. 主入口激活 @EnableEurekaClient@EnableZuulProxy
  4. application.properties文件中配置路由规则
server.port=9001#指定该服务的名字,该名称将在服务被调用时使用
spring.application.name=zuul-eureka-client-gateway#Eureka配置:服务注册到哪里
eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka#Zuul配置:api_zuul 可任意写
#path:表示请求的拦截规则,以/api-zuul开头的任意目录以及子目录中所有请求都会被拦截
zuul.routes.api-zuul.path=/api-8001/**
#service-id:指定服务名字,用于对这个服务下的某个特定请求进行拦截
zuul.routes.api-zuul.serviceId=zuul-eureka-client-provider
  1. 通过 http://localhost:8001/api-zuul/test 可以访问端口号是8001的服务提供者zuul-eureka-client-provider的test方法(相当于是请求http://localhost:8001/test )。

Zuul请求过滤

  1. 定义一个过滤器并继承自ZuulFilter,并将该Filter作为一个Bean;
/*** 自定义网关过滤器类并继承过滤器父类*/
@Component
public class AuthFilter extends ZuulFilter {//返回值决定当前过滤器的类型(执行时间)@Overridepublic String filterType() {//pre:前置过滤器,在执行转发(访问服务提供者)之前执行,通常用作身份认证return "pre";}//过滤器序号:根据返回值大小决定执行的先后顺序,数字越小执行越先级越高@Overridepublic int filterOrder() {return 0;}//过滤器是否启动:true启动,false不启动@Overridepublic boolean shouldFilter() {return true;}//过滤器执行方法:返回值目前版本没有特殊作用,因此可写null@Overridepublic Object run() throws ZuulException {//获取当前请求上下文对象RequestContext context = RequestContext.getCurrentContext();//获取用户请求对象HttpServletRequest request = context.getRequest();//获取请求中的请求参数token(身份令牌用于请求身份验证)String token = request.getParameter("token");//验证身份有效性(实际应用中从数据库取数据进行验证)if(token==null || !"123".equals(token)){//设定false表示请求不继续执行(不转发给服务器)context.setSendZuulResponse(false);//设置响应码401表示权限不足也可设置500或其他编码context.setResponseStatusCode(401);//设置响应类型及编码格式context.addZuulResponseHeader("context-type","text/html;charset=utf-8");//设置响应内容context.setResponseBody("非法请求");}else{System.out.println("请求合法继续执行请求准备进入服务或下一个过滤器");}return null;}
}
  1. 合法请求:http://localhost:8001/api-zuul/test?token=123
    非法请求:http://localhost:8001/api-zuul/test

  2. 基于Zuul的这些过滤器,可以实现各种丰富的功能,而这些过滤器类型则对应于请求的典型生命周期。

    • PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

    • ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache
      HttpClient或Netfilx Ribbon请求微服务。

    • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP

    • Header、收集统计信息和指标、将响应从微服务发送给客户端等。

    • ERROR:在其他阶段发生错误时执行该过滤器。

    除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

  3. Zuul中默认实现的Filter
    在这里插入图片描述

Zuul路由规则

  1. 在前面的例子中:
#Zuul配置:api_zuul 可任意写
#path:表示请求的拦截规则,以/api-zuul开头的任意目录以及子目录中所有请求都会被拦截
zuul.routes.api-zuul.path=/api-zuul/**
#service-id:指定服务名字,用于对这个服务下的某个特定请求进行拦截
zuul.routes.api-zuul.serviceId=zuul-eureka-client-provider#-----------------------------可以化简为---------------------------zuul.routes.zuul-eureka-client-provider=/api-8001/**
  1. 其他配置:
# 忽略某些请求:访问出现404资源不存在 如果需要同时忽略多个请求可以使用逗号分隔 也可以使用通配符*和**
zuul.ignored-patterns=/api-8001/test3
# 配置统一网关路由前缀:http://localhost:8001/myapi/api-8001/test3?token=123
zuul.prefix=/myapi
  1. 通配符
# 可使用的通配符有: * ** ?
# ? 单个字符
# * 任意多个字符,不包含多级路径
# ** 任意多个字符,包含多级路径
  1. 一般情况下API网关只是作为各个微服务的统一入口,但有时候我们可能也需要在API网关服务上做一些特殊的业务逻辑处理,那么我们也可以让请求到达API网关后,仔转发给自己本身,由API网关自己来处理,那么我们可以进行如下操作:
@RestController
public class GateWayController {@RequestMapping("/api/local")public Object test(){return "网关工程自己的控制器方法";}
}
#配置自我转发,将某些请求转发到当前的网关请求
#http://localhost:8001/myapi/gateway
zuul.routes.gateway.path=/gateway/**
zuul.routes.gateway.url=forward:/api/local

Zuul异常处理

Spring Cloud Zuul对异常的处理非常的方便,从Zuul请求的生命周期图中可以看到,异常过滤器是对前置过滤、路由过滤、后置过滤过程中出现的异常(图中虚线框内)进行处理:
在这里插入图片描述
方式一、禁用zuul默认的异常处理SendErrorFilter过滤器,然后自定义我们自己的ErrorFilter过滤器

# 禁用默认异常拦截器,启用自定义异常拦截器
zuul.SendErrorFilter.error.disable=true
//自定义异常过滤器
@Component
public class MyErrorFilter extends ZuulFilter {@Overridepublic String filterType() {//标明异常过滤器:其他过滤器出现异常,自动执行当前过滤器return "error";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {RequestContext context = RequestContext.getCurrentContext();ZuulException exception = (ZuulException) context.getThrowable();HttpServletResponse response = context.getResponse();response.setStatus(exception.nStatusCode);response.setContentType("test/html;charset=utf-8");PrintWriter writer = null;try {writer = response.getWriter();writer.println("出现异常了,异常码:"+exception.nStatusCode+"  异常信息:"+exception.getMessage());}catch(IOException e){e.printStackTrace();}finally {if(writer != null){writer.close();}}return null;}
}

方式二、自定义全局异常页面

/*** 自定义全局异常页面* 注意:自定义全局异常页面和自定义异常过滤器有冲突,二选一即可*/
@RestController
public class ErrorHandleController implements ErrorController {@Overridepublic String getErrorPath() {return "/error";}@RequestMapping("/error")public Object error(){RequestContext ctx = RequestContext.getCurrentContext();ZuulException exception = (ZuulException) ctx.getThrowable();return exception.nStatusCode+"---"+exception.getMessage();}}

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

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

相关文章

技术动态 | 知识图谱上的实体链接

本文转载自公众号:知识工场 1、什么是实体链接实体链接(entity linking)就是将一段文本中的某些字符串映射到知识库中对应的实体上。比如对于文本“郑雯出任复旦大学新闻学院副院长”,就应当将字符串“郑雯”、“复旦大学…

卖萌屋学术站开放注册啦!寻募种子用户,超多特权放出!

文:夕小瑶消失一个多月的小夕又突然出现啦!要问小夕最近业余时间在做什么,那就是跟小伙伴们开发学术站啦~(等...等再肝一版,小夕就继续给大家写文章(。 ́︿ ̀。)众所周知,卖萌屋学术…

LeetCode 11. 盛最多水的容器(双指针)

文章目录1. 题目信息2. 解题1. 题目信息 给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。 找出其中的两条线,…

WSDM Cup 2020检索排序评测任务第一名经验总结

1.背景 第13届“国际网络搜索与数据挖掘会议”(WSDM 2020)于2月3日在美国休斯敦召开,该会议由SIGIR、SIGKDD、SIGMOD和SIGWEB四个专委会共同协调筹办,在互联网搜索、数据挖掘领域享有很高学术声誉。本届会议论文录用率仅约15%,并且WSDM历来注…

ltp︱基于ltp的无监督信息抽取模块

ltp︱基于ltp的无监督信息抽取模块:https://zhuanlan.zhihu.com/p/44890664 无监督信息抽取较多都是使用哈工大的ltp作为底层框架。那么基于ltp其实有了非常多的小伙伴进行了尝试,笔者私自将其归纳为:事件抽取(三元组…

Eureka 简介和使用

Eureka 服务注册与发现服务注册与发现Eureka与Zookeeper的比较ZooKeeper保证CPEureka保证APEureka是什么?Eureka原理SpringBoot、Spring Cloud 和 Eureka 版本选择Eureka单机搭建搭建Eureka服务端搭建Eureka客户端的服务提供者搭建Eureka客户端的服务消费者Eureka集…

论文浅尝 | XQA:一个跨语言开放域问答数据集

论文笔记整理:刘晓臻,东南大学计算机科学与工程学院本科生。Citation: Liu, J., Lin, Y., Liu, Z., & Sun, M. (2019,July). XQA: A Cross-lingual Open-domain Question Answering Dataset. InProceedings of the 57th Conference of the Associati…

深度CTR预估模型中的特征自动组合机制演化简史

文 | 杨旭东源 | 知乎众所周知,深度学习在计算机视觉、语音识别、自然语言处理等领域最先取得突破并成为主流方法。但是,深度学习为什么是在这些领域而不是其他领域最先成功呢?我想一个原因就是图像、语音、文本数据在空间和时间上具有一定的…

LeetCode 94. 二叉树的中序遍历(中序遍历)

文章目录1. 题目信息2. 解题2.1 递归2.2 循环,必须掌握1. 题目信息 给定一个二叉树,返回它的中序 遍历。 示例:输入: [1,null,2,3]1\2/3输出: [1,3,2]进阶: 递归算法很简单,你可以通过迭代算法完成吗? 来源:力扣&am…

想进美团不知道选哪个技术岗位?这里有一份通关秘籍!

春暖花开,美团春招已经启动,针对校招和社招开放了几千个职位,其中很大部分都是技术岗位。 随着互联网的高速发展,技术岗位在不断地细分,比如软件开发不仅分为前端和后端,前端会分为Web、iOS和Android三个方…

哈工大LTP本地安装及python调用

原文链接:https://blog.csdn.net/yangfengling1023/article/details/84559848 LTP即哈工大语言技术平台云,是基于云计算技术的中文自然语言处理服务平台 在线使用的网址:https://www.ltp-cloud.com/ github网址:https://github.c…

Nginx 简介和使用

Nginx简介Nginx发展介绍Nginx作者正向代理和反向代理概念网站代理服务器查看Nginx环境搭建下载安装前准备安装启动检测Nginx是否启动关闭重启Nginx核心配置文件说明Nginx主要功能1、静态网站部署2、负载均衡负载均衡概述负载均衡实现方式Nginx负载均衡策略负载均衡其他配置3、静…

论文浅尝 | 将文本建模为关系图,用于联合实体和关系提取

论文笔记整理:余海阳,浙江大学硕士,研究方向为知识图谱、自然语言处理。链接:https://www.aclweb.org/anthology/P19-1136动机本文提出了一种利用图卷积网络(GCNs)联合学习命名实体和关系抽取的端到端抽取模…

LeetCode 144. 二叉树的前序遍历(前序遍历)

文章目录1. 题目信息2. 解题2.1 递归2.2 循环,必须掌握1. 题目信息 给定一个二叉树,返回它的 前序 遍历。 示例:输入: [1,null,2,3] 1\2/3 输出: [1,2,3]进阶: 递归算法很简单,你可以通过迭代算法完成吗? 来源:力扣…

设计模式在外卖营销业务中的实践

一、前言 随着美团外卖业务的不断迭代与发展,外卖用户数量也在高速地增长。在这个过程中,外卖营销发挥了“中流砥柱”的作用,因为用户的快速增长离不开高效的营销策略。而由于市场环境和业务环境的多变,营销策略往往是复杂多变的&…

RabbitMQ 简介和使用

RabbitMQ一、RabbitMQ概述1、什么是消息队列2、为什么要使用消息队列3、RabbitMQ特点二、RabbitMQ安装1、安装前准备1.1 依赖包安装1.2 安装Erlang2、安装3、常用命令3.1. 启动和关闭3.2. 插件管理3.3. 用户管理3.4. 权限管理3.5. vhost管理三、RabbitMQ消息发送和接收1、 Rabb…

Transformer哪家强?Google爸爸辨优良!

文:Zilong2017年Attention is all you need横空出世,Transformer横扫机器翻译,隔年诞生的BERT建立在层层堆叠的Transformer之上,凭借这个平平无奇的Attention点乘模型一举刷新了各种沉积许久的榜单,一夜间仿佛不懂Tran…

CCKS 2019 | 百度 CTO 王海峰详解知识图谱与语义理解

本文转载自公众号:机器之心。; 8 月 24 日至 27 日在杭州召开的 2019 年全国知识图谱与语义计算大会(CCKS 2019)上,百度 CTO 王海峰发表了题为《知识图谱与语义理解》的演讲。CCKS 2019 由中国中文信息学会语言与知识计…

LeetCode 145. 二叉树的后序遍历(后序遍历总结)

文章目录1. 题目信息2. 解法2.1 递归2.2 循环,必须掌握a. 单栈b. 双栈解法3. 前中后序总结1. 题目信息 给定一个二叉树,返回它的 后序 遍历。 示例:输入: [1,null,2,3] 1\2/3 输出: [3,2,1]进阶: 递归算法很简单,你可以通过迭代算法完成吗…

云原生之容器安全实践

概述 云原生(Cloud Native)是一套技术体系和方法论,它由2个词组成,云(Cloud)和原生(Native)。云(Cloud)表示应用程序位于云中,而不是传统的数据中…