spring cloud zuul实践
一、 描述
Spring Cloud Zuul是基于Netflix开源的Zuul项目构建而成,它作为微服务架构中的网关服务,主要用于实现动态路由、负载均衡和请求过滤等功能。
动态路由:Zuul根据预设的路由规则将进来的请求路由到相应的服务实例上。路由规则可以通过配置文件或代码进行定义,接收到请求后,Zuul会解析请求的URL,并根据配置的路由规则找到对应的服务地址,将请求转发到目标服务。
负载均衡:Zuul内置了Ribbon负载均衡器,可以对请求进行负载均衡。当一个服务有多个实例时,Zuul可以使用负载均衡算法将请求均匀地分发到不同的实例上,以提高系统的性能和可扩展性。
请求过滤:Zuul支持自定义过滤器,在请求被路由之前或之后对请求进行处理。过滤器可以用于在路由前进行身份验证、请求统计、参数校验等操作,也可以在路由后处理响应结果,比如修改返回数据、添加自定义的响应头等。开发者可以根据需求创建不同类型的过滤器,并定义过滤器的执行顺序。
整合服务注册中心:Zuul可以与服务注册中心(如Zookeeper、Eureka)进行整合,实现动态路由和负载均衡。通过与服务注册中心交互,Zuul能够动态地获取服务实例的信息,并根据需要进行路由和负载均衡。
高可用和容错:Zuul支持配置多个实例运行在不同的机器上,以实现高可用性。当一个Zuul实例发生故障时,其他实例可以接管请求处理,确保系统的稳定性和容错性。
Spring Cloud Zuul通过动态路由、负载均衡和请求过滤等机制,提供了一个强大且灵活的网关服务。它能够统一管理微服务的入口,实现请求的转发和过滤,简化了微服务架构中的通信和调用方式,提高了系统的可伸缩性和可维护性。
下面是使用Spring Cloud Zuul的一般实践步骤
二、添加依赖
引入zuul的依赖spring-cloud-starter-netflix-zuul

1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
4 </dependency>
三、创建启动类:
创建一个启动类,并使用@EnableZuulProxy注解开启Zuul代理功能。

1 @SpringBootApplication
2 @EnableZuulProxy
3 public class GatewayApplication {
4
5 public static void main(String[] args) {
6 SpringApplication.run(GatewayApplication.class, args);
7 }
8
9 }
四、 配置
在配置文件(如application.yml)中定义Zuul的路由规则。可以使用Zuul的zuul.routes前缀来配置不同的路由规则。

1 server:
2 port: 9000
3 management:
4 endpoints:
5 web:
6 exposure:
7 include: '*'
8 server:
9 port: 12345
10 zuul:
11 routes:
12 configserver:
13 path: /myConfig/**
14 serviceId: config
15 user:
16 path: /myUser/**
17 serviceId: provider
18 ignored-patterns: #忽略指定的路由
19 - /config/**
20 - /gateway/**
21 sensitive-headers:
22 # ignore-local-service: true # 忽略原来自身的路由。比如,true: 原来的config/xxx/xxx不可再访问
上述配置将/myConfig/**的请求转发到config服务,将/myUser/**的请求转发到provider服务。
还可以将网关注册到注册中心实现高可用。创建bootstrap.yml文件

1 spring:
2 application:
3 name: gateway
4 cloud:
5 zookeeper:
6 discovery:
7 register: true
8 enabled: true
9 connect-string: 192.168.3.100:2181
10 config:
11 discovery:
12 service-id: config
13 enabled: true
五、配置过滤器
通过zuul添加过滤器,对请求进行拦截或校验等等

1 package com.mike.study.gateway.fiter;
2
3 import com.netflix.zuul.ZuulFilter;
4 import com.netflix.zuul.context.RequestContext;
5 import com.netflix.zuul.exception.ZuulException;
6 import org.apache.commons.lang.StringUtils;
7 import org.springframework.http.HttpStatus;
8 import org.springframework.stereotype.Component;
9
10 import javax.servlet.http.HttpServletRequest;
11
12 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
13 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
14
15 /**
16 * @Classname ParameterFilter
17 * @Created by Michael
18 * @Date 2023/7/12
19 * @Description 自定义过滤器
20 */
21 @Component
22 public class ParameterFilter extends ZuulFilter {
23 /**
24 * 前置过滤
25 * @return
26 */
27 @Override
28 public String filterType() {
29 return PRE_TYPE;
30 }
31
32 /**
33 * 数值越小,优先级越高
34 * @return
35 */
36 @Override
37 public int filterOrder() {
38 return PRE_DECORATION_FILTER_ORDER - 1;
39 }
40
41 @Override
42 public boolean shouldFilter() {
43 return true;
44 }
45
46 @Override
47 public Object run() throws ZuulException {
48
49 // 获取请求对象
50 RequestContext context = RequestContext.getCurrentContext();
51 HttpServletRequest request = context.getRequest();
52 // 获取地址栏传入的参数
53 String token = request.getParameter("token");
54 System.out.println("token ===>"+token);
55 //模拟校验token,没有token则终止转发
56 if (StringUtils.isEmpty(token)) {
57 context.setSendZuulResponse(false);
58 context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
59 }
60 return null;
61 }
62 }
ParameterFilter.java
以上代码时在转发请求服务前,对参数进行校验,如果没有token参数,则停止转发,并且返回401错误
六、测试
测试网关转发主要需要请求发起方,网关和请求处理方。这里在原来demo的基础上,增加网关,所以看到有配置中心,以往的文章有项目的搭建介绍。如果不想那么复杂,可以去掉配置中心,将配置放置各个module即可,项目组如下

准备请求发起方,即consumer,controller通过feign框架请求网关,网关转发请求provider。consumer的controller如下

1 import com.mike.study.orderconsumer.client.UserClient;
2 import com.mike.study.orderconsumer.vo.UserVo;
3 import org.springframework.web.bind.annotation.GetMapping;
4 import org.springframework.web.bind.annotation.PathVariable;
5 import org.springframework.web.bind.annotation.RequestParam;
6 import org.springframework.web.bind.annotation.RestController;
7
8 import javax.annotation.Resource;
9
10 /**
11 * @Classname UserRuttingController
12 * @Created by Michael
13 * @Date 2023/7/9
14 * @Description feign框架调用provider api
15 */
16 @RestController
17 public class UserRuttingController {
18 @Resource
19 private UserClient userClient;
20
21 @GetMapping("warp/user/2.1/{id}")
22 public UserVo getUser(@PathVariable("id") Integer userId, @RequestParam("token") String token) {
23 System.out.println("使用feign框架调用provide的api");
24 return userClient.getUser(userId, token);
25 }
26 }
controller
Feign接口

1 import com.mike.study.orderconsumer.vo.UserVo;
2 import org.springframework.cloud.openfeign.FeignClient;
3 import org.springframework.web.bind.annotation.GetMapping;
4 import org.springframework.web.bind.annotation.PathVariable;
5 import org.springframework.web.bind.annotation.RequestParam;
6
7 /**
8 * @Classname UserFeigClient
9 * @Created by Michael
10 * @Date 2023/7/9
11 * @Description feign client
12 */
13
14 @FeignClient("gateway")
15 public interface UserClient {
16
17 @GetMapping("myUser/user/{id}")
18 public UserVo getUser(@PathVariable("id") Integer userId,@RequestParam("token") String token);
19 }
UserClient
以上Feign接口配合注册中心zookeeper使用,访问的网关地址,而不是直接请求服务提供者的api。
provider module简单提供一个api查询用户信息。
六、测试结果
positive case:token参数有值

negative case:token参数i为空

总结,就是consumer不再直接请求provider server,而是通过zuul作为中转站,这样做的好处很多,比如,对consumer的请求进行拦截过滤,验证,降流等等。
spring cloud zuul实践的更多相关文章
- Spring Cloud Zuul 添加 ZuulFilter
紧接着上篇随笔Spring Cloud Zuul写,添加过滤器,进行权限验证 1.添加过滤器 package com.dzpykj.filter; import java.io.IOException ...
- Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
- 笔记:Spring Cloud Zuul 快速入门
Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...
- Spring Cloud Zuul 限流详解(附源码)(转)
在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. ...
- Spring Cloud Zuul 中文文件上传乱码
原文地址:https://segmentfault.com/a/1190000011650034 1 描述 使用Spring Cloud Zuul进行路由转发时候吗,文件上传会造成中文乱码“?”.1. ...
- spring cloud zuul参数调优
zuul 内置参数 zuul.host.maxTotalConnections 适用于ApacheHttpClient,如果是okhttp无效.每个服务的http客户端连接池最大连接,默认是200. ...
- Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...
- spring cloud: zuul(四): 正则表达式匹配其他微服务(给其他微服务加版本号)
spring cloud: zuul(四): 正则表达式匹配其他微服务(给其他微服务加版本号) 比如我原来有,spring-boot-user微服务,后台进行迭代更新,另外其了一个微服务: sprin ...
- spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关)
spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关) zuul: routes: #路由配置表示 myroute1: #路由名一 path: ...
- spring cloud: zuul: 微网关-简单使用与路由配置
spring cloud: zuul: 微网关-简单使用与路由配置 首先引入依赖 <dependency> <groupId>org.springframework.cloud ...
随机推荐
- flume基本安装与使用
解压flume包 到/usr/local/src/目录下 [root@hadoopha01 pack]# tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /usr ...
- Java中的自动装箱与自动拆箱
前言 在Java中,基本数据类型与其对应的封装类之间可以进行自动转换,这种特性称为自动装箱(autoboxing)和自动拆箱(unboxing).自动装箱和自动拆箱使得我们在使用基本数据类型时更加方便 ...
- 这可能是最全面的MySQL面试八股文了
什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...
- springCloud项目搭建版本选择
1.查看spring cloud的版本 https://spring.io/projects/spring-cloud#learn 选择spring boot版本 https://mvnreposit ...
- StarRocks 3.0 集群安装手册
本文介绍如何以二进制安装包方式手动部署最新版 StarRocks 3.0集群. 什么是 StarRocks StarRocks 是新一代极速全场景 MPP (Massively Parallel Pr ...
- vue将页面(dom元素)转换成图片,并保存到本地
1 npm install html2canvas --save <template> <div class="QRCode-box"> <img i ...
- Rsync文件同步及备份
Rsync文件同步及备份 目录 Rsync文件同步及备份 Rsync基本概述 远程文件传输 服务端口 Rsync的三种传输模式 本地方式(类似cp) 远程方式(类似scp) 守护进程(C/S结构) R ...
- 2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达彼此的代价都是7。 求,允许施展一次魔法
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7.施展魔法之后,A和B通过该边到达彼此的代价都是7. 求,允许施展一次魔法 ...
- SQL:DATEDIFF和DATEADD函数
DATEDIFF和DATEADD函数.DATEDIFF函数计算两个日期之间的小时.天.周.月.年等时间间隔总数.DATEADD函数计算一个日期通过给时间间隔加减来获得一个新的日期.要了解更多的DATE ...
- AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from
函数里面return response问题: 1.没有 2.写错 3.位置错 例如: return Response('确认成功')