Spring cloud gateway

时间:2022-10-26 08:07:25

==================================
为什么需要API gateway?
==================================
企业后台微服务互联互通, 因为在内网, 安全基本没问题, 再配合使用Basic Auth就足够了, 同时也能利用上服务注册的优点, 有效隔离微服务之间的相互依赖. 但如果通过javascript/原生app直接访问微服务, 就会有下面的问题:
1. 接口安全问题, 很容易就能查看到js调用微服务api的代码, api肯定不能再裸奔, 需要加入安全检查机制. 每个微服务都要加同样的安全机制, 重复工作量很大.
2. 网络安全问题, 我们不应该将所有的微服务机器都暴露到外网, 网络风险较大.
3. 前后端耦合问题, 在调用api时候, 必须写死微服务ip信息, 如果微服务IP有变动, 前端也要及时更改才行.
4. 容易有单点问题, js 无法利用服务注册机制, 必须写死一个微服务主机ip, 即使我们的微服务往往会部署多套, 也有单点问题.

引入 api 网关就是要解决上述问题, api 网关作为对外服务的 facade 层. 另外, api 网关还可以实现智能路由功能, 以及动态扩容缩容, 甚至上可以聚合一些微服务操作, 以减少网络交互次数, 改善用户体验, 这个 ESB 的作用类似, 当然要谨慎使用, 比如体量较大的To C应用, 如果提供web/手机不同的访问形式, 可以考虑使用这一优化手段.

API 网关的管理范围:
1. 仅仅管理API访问(无状态的那部分), 并不负责管理普通web服务器.
2. 仅仅管理对外服务的API, 不负责微服务内部的数据请求, 如果要将微服务内部通讯管起来, API 网关的网络压力太大, 会是性能的瓶颈.

API 网关使用场景:
1. 开放平台, 比如微信或微博的开放平台, 这样的平台是专门针对第三方应用接入的, 提供 API 接入是最优选择.
2. 支持大型原生app, 大型原生app后台需要很多微服务项目, 通过 api 网关和这些微服务对接是比较方便的.
3. 网页js埋点采集, 埋点采集api不需要关心权限, 引入api网关主要是利用其自动扩容特性, 比如引入kong.

下图是引入 api 网关后的架构图(不含 WebUI 项目)

Spring cloud gateway

==================================
企业内部微服务架构有必要引入 API gateway 吗?
==================================
企业内部一般情况是: 仅仅有web应用, 没有移动端应用, 所有的用户都在局域网内部.
针对这样的情形, 我认为引入 API 网关的意义并不大, 理由是: web 项目肯定会有一个Web 后台应用服务器, 后台应用服务器可以承担api网关的主要职责, 包括api流量转发和安全检查.

简答一个常见的疑问:
典型 web 项目的 UI 往往是由后端模板渲染+前端ajax调用api组成. 后端模板肯定是本应用的web 后台提供, 但ajax调用的api是本应用后台提供, 还是其他微服务项目提供呢?
我的答案是: ajax调用的api最好还是本应用的web后台提供, 这样 jquery 和 api 属于同域, ajax 请求会自动带上本域的cookie, 这台web服务器本身也有相应的 session 信息, 所以ajax请求能通过 session-cookie 完成身份验证, 整个过程非常自然. 如果 ajax调用的api 是另一个微服务提供的, 为了保证微服务无状态特性, 同时避免api不会被滥用, 需要完善方案, 可选方案如下:
1. 在微服务项目中引入 redis集群来共享session存储, 将状态转移到redis集群中. 这个方案比较重, 并且 jquery 和 微服务不是同源, 需要在ajax调用时加上cookie, 可参考: https://blog.csdn.net/wzl002/article/details/51441704
2. 微服务项目不使用session做身份验证, 而是引入 jwt. 本方案的缺点: 想想有那么多的微服务项目都要加上jwt机制, 肯定比较麻烦, 另外js 调用微服务的url, 无法利用上服务注册的好处.
3. 引入api 网关, 将jwt身份验证前移到api网关层. 该方案能避免方案2的缺点, 但因为引入了新的一层, 整体架构变得复杂了.

下图是一个基于微服务的 WebUI 项目架构图,

Spring cloud gateway

==================================
API 网关的选型
==================================
常用的API网关候选, 主要有 Kong/Netflix Zuul/Spring Cloud Gateway, 详见下面博客
https://www.cnblogs.com/savorboard/p/api-gateway.html

Kong 是一个非常优秀的开源 API 网关产品, 基于 OpenResty + Cassandra/PostgreSQL, 以插件的形式提供很多功能(身份认证/权限控制/日志/流量控制), 也可以使用 Lua 编写插件, 底层是 Nginx , 所以性能非常好, 社区插件也较多, 但要定制插件难度较大, 需要使用 Lua 编写.

Spring 社区主要是 Netflix Zuul 和 Spring Cloud Gateway, Netflix Zuul 是基于Servlet 2.5, 使用阻塞 API, 它不支持任何长连接, 如 WebSocket. Spring Cloud Gateway 是Spring社区主推的解决方案, 采用了更新的技术, 它基于Spring framework 5, Project Rector 和 Spring Boot 2, 使用的是非阻塞API, 支持 Websocket.

对于企业内应用, 研发主导的话推荐是使用 Spring Cloud Gateway, 运维主导的话推荐 kong.
对于大型互联网开放平台, 推荐性能更好的 kong.

买单侠微服务的API网关演化之路
https://blog.csdn.net/omnistack/article/details/77185188
https://blog.csdn.net/OmniStack/article/details/77881185

==================================
Spring Cloud Gateway 参考
==================================
Spring Cloud Gateway 入门
https://www.jianshu.com/p/598f302dadba
https://www.jianshu.com/p/76d2da1d0dd7
Spring Cloud(十三):Spring Cloud Gateway(路由)
https://windmt.com/tags/API-Gateway/
Spring Gateway配置使用(一)
https://www.jianshu.com/p/d011a0e5539d
Spring Cloud Gateway入门案例
https://www.jianshu.com/p/44a0d6adcdea
Spring Cloud(十八):Spring Cloud Gateway(读取、修改 Request Body)
http://www.liuhaihua.cn/archives/549430.html