Spring Cloud 学习 (五) Zuul

Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用,主要体现在以下 6 个方面:

  1. Zuul, Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能,Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例
  2. 网关将所有服务的 API 接口统一聚合,并统一对外暴露。外界系统调用 API 接口时,都是由网关对外暴露的 API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的 API 接口 , 防止其被外界直 接调用,导致服务的敏感信息对外暴露
  3. 网关服务可以做用户身份认证和权限认证,防止非法请求操作 API 接口,对服务器起到保护作用
  4. 网关可以实现监控功能,实时日志输出,对请求进行记录
  5. 网关可以用来实现流量监控,在高流量的情况下,对服务进行降级
  6. API 接口从内部服务分离出来,方便做测试

Zuul 的核心是一系列过滤器,可以在 Http 请求的发起和响应返回期间执行一系列的过滤器:

  1. PRE 过滤器:在请求路由到具体的服务之前执行,这种类型的过滤器可以做安全验证,例如身份验证、 参数验证等
  2. ROUTING 过滤器:用于将请求路由到具体的微服务实例。在默认情况下,它使用 Http Client 进行网络请求
  3. POST 过滤器:在请求己被路由到微服务后执行。 一般情况下,用作收集统计 信息、指标,以及将响应传输到客户端
  4. ERROR 过滤器:在其他过滤器发生错误时执行

Zuul 采取了动态读取、编译和运行这些过滤器。过滤器之间不能直接相互通信,而是通过 RequestContext 对象来共享数据,每个请求都会创建一个 RequestContext 对象。Zuul 过滤器具有以下关键特性:

  1. Type (类型): Zuul 过滤器的类型,这个类型决定了过滤器在请求的哪个阶段起作用,例如 Pre、Post 阶段等
  2. Execution Order (执行顺序): 规定了过滤器的执行顺序,Order 的值越小越先执行
  3. Criteria (标准): Filter 执行所需的条件
  4. Action (行动): 如果符合执行条件,则执行 Action (即逻辑代码)

使用 Zuul

新建 spring-cloud-eureka-zuul-client

pom

<parent><artifactId>spring-cloud-parent</artifactId><groupId>com.karonda</groupId><version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion><artifactId>spring-cloud-eureka-zuul-client</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

application.yml

server:port: 8051eureka:client:service-url:defaultZone: http://localhost:8001/eureka/spring:application:name: zuul-clientzuul:routes:hiapi:path: /hiapi/**serviceId: eureka-clientribbonapi:path: /ribbonapi/**serviceId: ribbon-clientfeignapi:path: /feignapi/**serviceId: feign-client

启动类

@EnableZuulProxy // 开启 Zuul
@SpringBootApplication
public class EurekaZuulClientApp {public static void main(String[] args){SpringApplication.run(EurekaZuulClientApp.class, args);}
}

测试

  1. 启动 eureka-server
  2. 启动 eureka-client (两个实例:一个 8011 端口,一个 8012 端口)
  3. 启动 eureka-ribbon-client
  4. 启动 eureka-feign-client
  5. 启动 eureka-zuul-client

多次访问 http://localhost:8031/hiapi/hi?name=victor 可以看到 8011 和 8012 端口交替出现 (Zuul 默认 与 Ribbon 结合实现了负载均衡)

多次访问 http://localhost:8031/ribbonapi/hi?name=victor 可以看到 8011 和 8012 端口交替出现

多次访问 http://localhost:8031/feignapi/hi?name=victor 可以看到 8011 和 8012 端口交替出现

在 Zuul 上配置熔断器

实现 FallbackProvider 接口

@Component
public class MyFallbackProvider implements FallbackProvider {@Overridepublic String getRoute() {return "eureka-client"; // 如果所有的路由服务都加熔断功能,返回 "*"}@Overridepublic ClientHttpResponse fallbackResponse(String route, Throwable cause) {return new ClientHttpResponse() {@Overridepublic HttpStatus getStatusCode() throws IOException {return HttpStatus.OK;}@Overridepublic int getRawStatusCode() throws IOException {return 200;}@Overridepublic String getStatusText() throws IOException {return "OK";}@Overridepublic void close() {}@Overridepublic InputStream getBody() throws IOException {return new ByteArrayInputStream("error, fallback".getBytes());}@Overridepublic HttpHeaders getHeaders() {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);return headers;}};}
}

测试

  1. 关闭所有的 eureka-client
  2. 重启 eureka-zuul-client

在 Zuul 中使用过滤器

继承 ZuulFilter

@Component
public class MyFilter extends ZuulFilter {private static Logger logger = LoggerFactory.getLogger(MyFilter.class);@Overridepublic String filterType() {return PRE_TYPE;}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();Object accessToken = request.getParameter("token");if(accessToken == null){logger.warn("token is empty");ctx.setSendZuulResponse(false);ctx.setResponseStatusCode(401);try {ctx.getResponse().getWriter().write("token is empty");} catch (IOException e) {return null;}}logger.info("ok");return null;}
}

测试

  1. 重启 eureka-zuul-client

访问 http://localhost:8051/hiapi/hi?name=victor

访问 http://localhost:8051/hiapi/hi?name=victor&token=xx

完整代码:GitHub

本人 C# 转 Java 的 newbie, 如有错误或不足欢迎指正,谢谢

转载于:https://www.cnblogs.com/victorbu/p/11017272.html

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

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

相关文章

如何利用445端口进行入侵渗透 445端口入侵原因详细解析。大家在进行入侵渗透个人电脑的时候,经常会碰到各种各样的端口,比如135,1433,445,3306等端口,现在小编就给大家讲解下445端口如

如何利用445端口进行入侵渗透 445端口入侵原因详细解析。大家在进行入侵渗透个人电脑的时候&#xff0c;经常会碰到各种各样的端口&#xff0c;比如135&#xff0c;1433&#xff0c;445&#xff0c;3306等端口&#xff0c;现在小编就给大家讲解下445端口如何入侵。 445端口入侵…

项目复盘

前言 最近一年半多一直在做一个CMS项目&#xff0c;做了快两年了也没有上线&#xff0c;而且开发还走了不少&#xff0c;其中有不少原因是因为开发中频繁改动需求导致开发人员失去耐心&#xff0c;但是其中还有一个重要的原因就是架构设计的不好&#xff0c;导致很多服务的边界…

父、子页面之间页面元素的获取,方法的调用

一、在iframe页面上调取父级页面元素 1.在父页面上获取iframe页面元素(在父页面修改子页面div的背景色为红色) js代码如下&#xff1a; 1 <script type"text/javascript"> 2 window.onload function(){ 3 var iframe document.getElementById(iframeId)…

fiddler,他和其他抓包软件有什么区别,如何使用fiddler进行抓包

前言&#xff1a;本文章是搭配《批量获取微信公众号》一文&#xff0c;介于群里朋友很热情&#xff0c;我就趁着上班测完bug 来撰写该文章&#xff0c;那么读完本文&#xff0c;你会学习到什么呢&#xff1f; 什么是fiddler&#xff0c;他和其他抓包软件有什么区别&#xff0c…

Vue导入非模块化的第三方插件功能无效解决方案

一、问题&#xff1a; 最近在写vue项目时&#xff0c;想引入某些非模块化的第三方插件时&#xff0c;总是发现会有报错。且在与本地运行插件测试对比时发现插件根本没有注入到jQuery中&#xff08;console.log($.fn)查看当前jq有哪些方法&#xff09;&#xff0c;例如&#xff…

ES6笔记 -- 字符串拓展

字符串拓展 Unicode 相关 JS 允许使用/uxxxx的Unicode方式显示字符, 但是只限于码点在/u0000~/uFFFF之间, 超过该范围的码点必须用双字节形式表示ES6 中, 将码点放入大括号内, 就可以解读JS 不能处理4个字节的字符, 字符串长度会被误判为2ES6 提供了codePointAt方法, 能够正确处…

android 转发短信

通过这些代码也可以对远程手机实现短信控制。有兴趣的可以自己改一下&#xff0c;说一下简单的原理&#xff0c;要实现控制的话&#xff0c;必须得走一个固定的号码&#xff0c;固定的格式&#xff0c;然后通过得到此号码的内容&#xff0c;然后通过固定的内容&#xff0c;就可…

[Noi2016]区间

传送门 Code /* 线段树 尺取法 */ #include<bits/stdc.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)>(b)?(b):(a)) #define reg register inline int read() {int x0,f1;char chgetchar();while(ch<0||ch>9){if(…

安装CentOS6.8并配置网络图文解说亲测全过程

安装环境&#xff1a; 本文是在win10系统安装上VMWare并配置Centos6.8虚拟机。 准备工作 1.安装VMWare虚拟机 1.1下载VMWare12资源链接&#xff1a;https://pan.baidu.com/s/1AhfMSDXLO-aA0eMqnuMWHg 提取码&#xff1a;iftd 1.2安装VMWare&#xff0c;在安装过程中需要输入密钥…

Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法。

Paxos算法是莱斯利兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法。Paxos算法解决的问题是一个分布式系统如何就某个值&#xff08;决议&#xff09;达成一致。在工程实践意义上来说&#xff0c;就是可以通过Paxos实现多副本一致性&#xff0c;分布式锁&…

09、策略模式

2019独角兽企业重金招聘Python工程师标准>>> 策略模式与工厂模式最大的区别在于&#xff0c;策略模式注重的是对算法的维护&#xff0c;也可以理解为对算法的封装。而工厂模式&#xff0c;则只是负责创建类&#xff0c;在刚接触策略模式时候&#xff0c;往往与工厂模…

Linux创建、删除文件和文件夹命令

https://www.cnblogs.com/c-x-m/p/9794082.html转载于:https://www.cnblogs.com/sun-ldy/p/10279025.html

Java编写代理服务器(Burp拦截Demo)一

大家都知道大名鼎鼎的BurpSuite代理神器&#xff0c;对于抓取HTTP请求非常好用&#xff0c;偶然&#xff0c;一朋友问我Java应该如何去编写代理服务器&#xff08;因为他想做某些东西&#xff09;&#xff0c;有没有相关的API 去实现&#xff0c;我想说&#xff0c;差不多你能想…

mysql实战33 | 我查这么多数据,会不会把数据库内存打爆?

我经常会被问到这样一个问题&#xff1a;我的主机内存只有 100G&#xff0c;现在要对一个 200G 的大表做全表扫描&#xff0c;会不会把数据库主机的内存用光了&#xff1f;这个问题确实值得担心&#xff0c;被系统 OOM&#xff08;out of memory&#xff09;可不是闹着玩的。但…

[BZOJ2125]最短路

Description 给一个N个点M条边的连通无向图&#xff0c;满足每条边最多属于一个环&#xff0c;有Q组询问&#xff0c;每次询问两点之间的最短路径。 Input 输入的第一行包含三个整数&#xff0c;分别表示N和M和Q 下接M行&#xff0c;每行三个整数v&#xff0c;u&#xff0c;w表…

Rabbit MQ windows下安装

Rabbit MQ 是建立在强大的Erlang OTP平台上&#xff0c;因此安装Rabbit MQ的前提是安装Erlang。通过下面两个连接可以下载安装最新的版本&#xff1a; 下载并安装 Eralng OTP For Windows otp_win64_18.3.exe&#xff08;erlang的环境&#xff09;运行安装 Rabbit MQ Serve…

spark集群配置以及java操作spark小demo

spark 安装配置使用java来操作sparkspark 安装 tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz rm spark-2.4.0-bin-hadoop2.7.tgz mv spark-2.4.0-bin-hadoop2.7 sparksudo vim /etc/profileexport SPARK_HOME/usr/local/stormexport PATH$PATH:$SPARK_HOME/binsource /etc/profile…

C++笔记(3)——string.h相关的一些小知识

strlen() 用于得到字符数组中第一个\0前的字符的个数&#xff0c;格式如下&#xff1a; strlen(数组); 例子&#xff1a; #include <stdio.h> #include <string.h>int main(){char str[10];gets(str);int len strlen(str);printf("%d\n", len);return 0…

最近发现系统rabbitmq丢消息比较严重,于是想了些方案来查找原因,给将消息发送方式添加确认机制。 我们在本地模拟了wms发送打标消息的场景. 1. 有事务 2. 先发点对点队列, 再发订

最近发现系统rabbitmq丢消息比较严重&#xff0c;于是想了些方案来查找原因&#xff0c;给将消息发送方式添加确认机制。 我们在本地模拟了wms发送打标消息的场景. 1. 有事务 2. 先发点对点队列, 再发订阅队列 3. 批量发送 4. 在生产环境与测试环境的RabbitMQ都进行了测试 …

uoj#388. 【UNR #3】配对树(线段树合并)

传送门 先考虑一个贪心&#xff0c;对于一条边来说&#xff0c;如果当前这个序列中在它的子树中的元素个数为奇数个&#xff0c;那么这条边就会被一组匹配经过&#xff0c;否则就不会 考虑反证法&#xff0c;如果在这条边两边的元素个数都是偶数&#xff0c;那么至少有两组匹配…