zuul 里面写controller_手把手教你写一个网关服务

什么是网关?为什么需要使用网关?

如图所示,在不使用网关的情况下,我们的服务是直接暴露给服务调用方。当调用方增多,势必需要添加定制化访问权限、校验等逻辑。当添加 API 网关后,再第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制。

78bff087411ae6f6cdfe0c317b7be82c.png

本文所实现的网关源码抄袭了--- Oh,不对,是借鉴。借鉴了 Zuul 网关的源码,提炼出其核心思路,实现了一套简单的网关源码,博主将其改名为 Eatuul。

设计思路

先大致说一下,就是定义一个 Servlet 接收请求。然后经过 preFilter (封装请求参数), routeFilter (转发请求),postFilter (输出内容)。三个过滤器之间,共享request、response以及其他的一些全局变量。如下图所示。

ab7e3d4861c62fe1a2eb5be4e3aade67.png

与真正的 Zuul 的区别?

1)Zuul 中在异常处理模块,有一个 ErrorFilter 来处理,博主在实现的时候偷懒了,略去。

2)Zuul 中 PreFilters,RoutingFilters,PostFilters 默认都实现了一组,具体如下表所示。

7dc23ef52f2fbbc770474d436f0e39aa.png

博主总不可能每一个都给你们实现一遍吧。所以偷懒了,每种只实现一个。但是调用顺序还是不变,按照 PreFilters->RoutingFilters->PostFilters 的顺序调用。

3)在 RouteFilters 确实有转发请求的 Filter,然而博主偷天换日了,改用RestTemplate 实现。

代码结构

大家去 Spring 官网上搭建一套 Springboot 的项目,博主就不展示 pom 的代码了。直接将项目结构展示一下,如下图所示。

898c5996b11c866be36af2315be93057.png

EatuulServlet.java

这个是网关的入口,逻辑也十分简单,分为三步。

1) 将 request,response 放入 threadlocal 中;

2) 执行三组过滤器;

3) 清除 threadlocal 中的的环境变量。

05a7905287b29fb74d0646d99151d95e.png

EatuulRunner.java

这个是具体的执行器。需要说明一下,在 Zuul 中,ZuulRunner 在获取具体有哪些过滤器的时候,有一个 FileLoader 可以动态读取配置加载。博主在实现我们自己的 EatuulRunner 时候,略去动态读取的过程,直接静态写死。

d8fc01dd6bf4bf5dee0526f5930e3009.png

EatuulFilter.java

接下来就是一系列Filter的代码了,先上父类EatuulFilter的源码。

821e7cbebf7908defddc4b02f03a34fc.png

RequestWrapperFilter.java

这个是PreFilter,前置执行过滤器,负责封装请求。步骤如下所示。

1) 封装请求头;

2) 封装请求体;

3) 构造出 RestTemplate 能识别的 RequestEntity;

4) 将 RequestEntity 放入全局 threadlocal 之中。

703b31fe28c52d5217a44cfe909c52de.png
3c68c9b526aab902b544c13379011e3c.png

RoutingFilter.java

这个是 RouteFilter,这里我偷懒了,直接做转发请求,并且将返回值ResponseEntity放入全局 threadlocal 中。

675bc6367d5f6f386e6be2621ba54a5c.png

SendResponseFilter.java

这个是 postFilters,将 ResponseEntity 输出即可。

3e54af42d1728d4aa7f4f5e1e5e6e9c2.png
9947478bede42ac3990e13e9379c35bd.png

RequestContext.java

最后是一直在说的全局 threadlocal 变量。

3de9767b4d90360cd31368564cfa111d.png
28a2b2e57b65c13f55a25e35637b4af2.png

如何测试?

自己另外起一个server端口为9090如下所示。

9f7790d88d164f73e7fd0b3d990e21fa.png

再来一个 controller。

92c46b83987fb952971ea926af1321d4.png

然后,你就发现可以从 localhost:8080/index 进行跳转访问了。

结论

本文模拟了一下 zuul 网关的源码,借鉴了一下其精髓的部分。

作者:孤独烟转载:https://www.cnblogs.com/rjzheng/p/9220437.html

免费分享java技术资料,需要的朋友在关注后私信我

2661782fd2a47442c70823f38c01075f.png
da6e6206e65a4b3413939adfceaa0700.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值