1. 对外服务的难题
微服务架构的应用系统的体系非常庞大的,光是需要独立部署的基础组件就有注册中心、配置中心和服务总线、Turbine异常聚合和监控大盘、调用链追踪和链路聚合,还用kafka和MQ之类的消息中间件,加上按照业务域拆分的微服务组件和模块,一个小的系统非常轻松的就能弄出20多个module,会有这么多的部署包。
我们前面都是采用localhost加端口的方式直接访问,如果这些服务一并都要提供给外部用户访问那该怎么处理?开发在各个页面给不同的请求配置URL和端口号,但是一大堆的URL在我们的前端进行配置,需要我们开发人员自己手动配置一套路由表,因此就需要引入一套机制来降低路由表的维护成本。
还有一个问题就是安全性,需要进行安全验证,如果让没有提供对外服务的接口都自己实现一定非常浪费资源,这个时候就需要一个中间件统一来进行安全处理并对外进行数据的安全验证。
我们如何对外提供服务、还能管好路由规则,并做好访问控制,在这样的背景下,API网关应运而生,他就像一个传达室的角色,接待所有来访的请求。
2. 微服务的传达室
在计算机领域,有一个设计理论:任何问题都可以通过引入一个中间件来解决。如果一个不够那就两个
我们去到别的公司办事,第一道关就是传达室/前台,它们会做两件事
- 访问控制:看你是不是有权限进行访问,拒绝未授权的来访者
- 引导指路:问清楚你要办的事情,指导你如何到达,找到你想要访问的内容
网关层作为唯一的对外服务,外部请求不直接访问服务层,由网关层承接所有HTTP请求,在实际的应用里,我们也会将网关服务和Nginx一同使用
3. 访问控制
访问控制住要包含两个方面,具体实现不是由网关层提供的,但是网关作为一个载体承载了两个任务
- 拦截请求:有的接口需要登录用户才能范围,对于这类接口,网关成可以检查访问请求中是否携带令牌等身份信息,比如HTTP Header中的Authorization或token属性,如果没有携带令牌,则说明没有登录,这时候可以返回403
- 鉴权:对于有携带令牌的服务,我们需要验证令牌的真假,否则用户可以通过伪造令牌进行通信,对于令牌过期或失效的服务要进行拒绝
4. 路由规则
路由规则包含两个方面,分别是URL映射和服务寻址
- URL映射:在大多数情况下,客户端访问的HTTP URL往往不是我们在conroller里配置的真实路径,比如客户端可以发起请求/password/update来修改密码,但后台没有这个服务,这个时候就需要网关层做一个路由规则,来访问URL映射真的服务路径
- 服务寻址:URL映射好了之后,网关层就需要找到可以提供服务的服务器地址,对于服务集群的话,还需要实现负载均衡策略(在springcloud中gateway是借助eureka服务发现机制实现服务寻址的,负载均衡依靠的Ribbon)
5. 第二代网关Gateway
Gateway的标签
- Gateway是spring官方主推的组件
- 底层是基于Netty构建
- 由spring开源社区直接贡献开源力量
Gateway可以做什么
- 路由寻址
- 负载均衡
- 限流
- 鉴权
Gateway VS Zuul
# | Gateway | Zuul 1.x | Zuul 2.x |
---|---|---|---|
靠谱性 | 官方背书支持 | 开创者,曾经靠谱 | 一直跳票,终于发布了 |
性能 | Netty | 同步阻塞,性能慢 | Netty |
QPS | 超30000 | 20000左右 | 20000-30000 |
Spring Cloud | 已整合到组件库 | 已整合到组件库 | 暂无整合到组件库的计划,但可以引用 |
长连接 | 支持 | 不支持 | 支持 |
编程体验 | 略复杂 | 同步模型,比较简单 | 略复杂 |
调试&链路追踪 | 异步模型,略复杂 | 同步方式,比较容易 | 异步模型,略复杂 |
综上对比分析,新项目果断选择Gateway