下一代服务型流量网关
云原生应用
今天,所有的软件架构都在迁移到云原生架构。云原生架构具有以下特点:
- 它由具有弹性设计的微服务架构构建。
- 按需性能的扩展能力。
- 完全解耦控制逻辑和业务逻辑。
- 旨在实现高可用性和 >99.9% 的正常运行时间 SLA。
并且有四个关键性的东西要很好地通过云原生方式构建并被调度
基础设施运行时资源。底层的计算节点、存储、网络,目前,这些资源在都由容器和Kubernetes来管理和调度。
应用程序数据和状态。应用程序数据和状态需要持久化或在集群范围内同步。我们可以看到主流的数据库(SQL/NoSQL)、缓存、队列等现在都支持分布式集群和高可用解决方案。
应用服务。这些服务现在由 Kubernetes 编排并由微服务架构管理,其中包括服务发现、服务配置管理、服务网关/代理、弹性和容错、存活和健康检查、可观察性(指标、日志、跟踪)、等等组成。
流量编排。大多数在线服务需要处理来自世界各地的用户请求。这些流量将用于不同的目的并访问不同的资源。因此,管理这些流量并将其与云原生后端服务保持一致非常重要。
流量调度
关于流量编排,作为云原生网关,必须具备以下特点。
- 与微服务架构保持一致。
- 分布式系统技术的高可用性。
- 使用各种过滤器和 API 聚合的管道来编排流量。
- 符合云原生架构,如 Service Mesh、FaaS 等。
- 服务可观察性 - 跟踪、指标(吞吐量、延迟、错误等)、访问日志。
为了实现这一点,在这里,我们将介绍一个下一代服务流量网关 - Easegress 该软件是用Go编写的开源软件(Apache 2.0 许可证),采用 Go 编程语言,天然具备在高并发场景下提供高性能服务的能力。
Easegress
在说明Easegress的功能之前,想先说一下,为什么我们要从头做一个这样的网关。其实,我们在解决用户的一些性能问题的时候需要用到一个流量调度的控制系统。在一开始的时候,我们主要是使用Nginx + Lua的方式,但在解决用户问题的过程中发现,对于一个流量调度网关,有两个非常重要的特点是我们无法避开的。
流量调度和编排,而不是一个反向代理。对此,我们需要的是一个 Cloud Native 架构软件,也就是说,其必须是一个高可用的集群,而且,需要能够对流量进行着色,以及对流量的功能能够动态编排,有 Admin API 和非常好的监控观测能力。这个方面,Nginx在集群方面并不够好,需要借助其它第三方的能力来完成。
会有各种各样的业务逻辑的侵入,所以需要非常容易的扩展。需要易扩展,一般来说会有三种技术方案:
源代码修改。这需要软件使用的语言门槛要足够低,可以让业务开发的开发人员能够扩展代码。所以,对于 Nginx 的 C + Lua 的方式,我们觉得并不够好。C 太晦涩也太容易出错,Lua的表现能力又不够复杂。所以,我们使用了 Go 语言。
集成其它语言。Nginx 使用 Lua 的能力可以扩展很多代码能力。Lua 很不错,但是我们觉得对业务功能的表现力不够,所以,我们想到了WebAssembly 引擎,这样就可以扩展到所有的高级语言代码上了。
第三方集成。通过像 FaaS 这样的技术进行第三方集成。做到真正的控制逻辑和业务逻辑分离。而且,业务逻辑分离到 FaaS 服务中可以由Kubernetes进行伸缩。
这三种方案各有千秋,适用于不同的场景。
第一种需要重编译,扩展能力很强,但需要重新发,而且业务逻辑入侵控制逻辑,也会影响稳定性。
第二种可以动态加载,没有部署负担,但扩展能力受限。
第三种在体外扩展,有性能损失,架构逻辑也很复杂,但是分离的很好,性能有损的业务逻辑在 FaaS 的管理内可以自由水平扩展。
我们认为,要支持好上述的这些功能,目前整个开源社区中基本没有,最接近的是Envoy,但可惜是 C++ 的。所以,我们决定用 Go 语言写一个。
Easegress 的架构构图如下所示:
Easegress 功能设计
Easegress 的主要设计如下:
流量处理功能或过滤器可以通过插件机制开发。
可以通过管理 API 在运行时运态地将功能或过滤器组织到 Pipeline 中。
可以很自由的扩展和注入用户的自定义和业务逻辑代码。
有两种类型的控制器有助于管理和集成到整个云原生架构。
- 流量控制器 - 服务网格、函数即服务 等。
- 系统控制器 - 服务发现、监控、集群等。
应用级协议支持
- HTTP 1/2/3
- WebSocket
- MQTT
此外,Easegress 还具有以下 Cloud Native 功能
微服务架构合规
- Spring Cloud 兼容性
- Restful API 协议 - API 路由和 API 聚合。
- 服务发现集成 - Eureka、Consul、Nacos、Etcd 和 Zookeeper。
- 弹性和容错(从resilience4j 项目移植)-断路器、速率限制器、重试器、超时等。
云原生架构集成
- Kubernetes 入口控制器
- Service Mesh - 边车和入口控制器
- FaaS - Knative
高可用性和高性能
- 内置的 Raft 共识和领导者选举提供 99.99% 的可用性。
- 负载平衡 - 轮询、随机、加权随机、根据IP/HTTP头部 哈希。
- 缓存 - 缓存后端服务响应。
可观察性
- 服务跟踪 - 内置 Open Zipkin 和针对供应商中立 API 的分布式跟踪。
- 吞吐量 - QPS/TPS m1、m5、m15 和错误率
- 延迟 - P999、P99、P98、P95、P75、P50、P25
- 带宽 - 请求和响应数据大小
- 响应 - HTTP 状态代码统计信息。
Easegress 扩展性
最后,Easegress 具有很好的可扩展性,可以很容易地将自定义特性或功能添加到 Easegress 中,有三种方法可以做到这一点。
过滤器或控制器。按照开发指南,您可以使用 Go 语言开发过滤器和控制器。但是这需要重新编译软件。
WebAssembly。Easegress 支持 WASM 运行时引擎,因此,您可以使用任何支持 WASM 的编程语言开发过滤器,并且 Easegress 可以在运行时加载它。
函数即服务 FaaS。Easegress 支持 Knative 集成,因此您可以部署 Easegress 之外的函数服务。这种方式看起来有点重,但在Kubernetes的加持下,它是一个可水平扩展的解决方案。
因此,Easegress 可以是一个开发框架或一个二次开发平台,您可以在之上专注于自己的业务逻辑。
Easegress 示例
Easegress有能力胜任如下工作(包括并不限于)。
反向代理(负载平衡)–负载平衡的若干策略 [示例]
服务代理
Pipeline — 编排若个HTTP 请求/响应 过滤器,形成一个管道处理。 [示例]
API 聚合 - 将许多 API 聚合到一个 API 中。 [示例]
弹性与容错 - 断路器、速率限制器、回流器、时间限制器等。 [示例]
分布式跟踪 - 支持APM跟踪 - Zipkin。 [示例]
高性能
Service Mesh - 这是由 EaseMesh (我们的另一个开源项目) 一个与Spring Cloud兼容的服务网格结构系统所利用的。通过EaseMesh,我们可以做到非常厉害的事。
工作流(IFTTT) - 以工作流的形式运行一些API。 [示例]
WebAssembly 扩展 - 使用 AssemblyScript 来扩展Easegress。 [示例]
等等。
今天,我们期待您对这个新的流量网关提出建议或关注,甚至帮助我们把这个网关做得更好。请随意提交问题或在我们的 Github 中贡献代码 — https://github.com/megaease/easegress