微服务网关:从对比到选型,由理论到实践

338次阅读  |  发布于2年以前

常用API网关的对比和选型,并讲解我司自研的微服务网关,干货满满!

大家好, 微服务近几年非常火,围绕微服务的技术生态也比较多,比如微服务网关、Docker、Kubernetes等。

我是于2019年开始接触微服务网关,当时和公司的一位同事一起开发,由于技术能力有限,我只负责网关后台,后续微服务网关的迭代,我其实没有参与,不过后来抽空看了微服务网关前台的代码,所以对这套微服务网关的实现原理算是基本掌握。

最近在写技术栈相关的文章,刚好写到微服务网关,就把之前学习的知识进行简单总结,同时也把市面上常用的微服务网关进行梳理,一方面便于后续技术选型,另一方面也算是给自己一个交代。下面是文章目录:

API网关基础

什么是API网关

API网关是一个服务器,是系统的唯一入口。 从面向对象设计的角度看,它与外观模式类似。

API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、协议转换、限流熔断、静态响应处理。

API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。

网关的主要功能

微服务网关作为微服务后端服务的统一入口,它可以统筹管理后端服务,主要分为数据平面和控制平面:

API网关选型

常用API网关

先简单看一下市面上常用的API网关:

Nginx

Nginx是一个高性能的HTTP和反向代理服务器。Nginx一方面可以做反向代理,另外一方面可以做静态资源服务器,接口使用Lua动态语言可以完成灵活的定制功能。

Nginx 在启动后,会有一个 Master 进程和多个 Worker 进程,Master 进程和 Worker 进程之间是通过进程间通信进行交互的,如图所示。Worker 工作进程的阻塞点是在像 select()、epoll_wait() 等这样的 I/O 多路复用函数调用处,以等待发生数据可读 / 写事件。Nginx 采用了异步非阻塞的方式来处理请求,也就是说,Nginx 是可以同时处理成千上万个请求的。

Zuul

Zuul 是 Netflix 开源的一个API网关组件,它可以和 Eureka、Ribbon、Hystrix 等组件配合使用。社区活跃,融合于 SpringCloud 完整生态,是构建微服务体系前置网关服务的最佳选型之一。

Zuul 的核心是一系列的过滤器,这些过滤器可以完成以下功能:

Zuul 目前有两个大的版本:Zuul1 和 Zuul2

Zuul1 是基于 Servlet 框架构建,如图所示,采用的是阻塞和多线程方式,即一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。

Netflix 发布的 Zuul2 有重大的更新,它运行在异步和无阻塞框架上,每个 CPU 核一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。

Spring Cloud GetWay

Spring Cloud Gateway 是Spring Cloud的一个全新的API网关项目,目的是为了替换掉Zuul1,它基于Spring5.0 + SpringBoot2.0 + WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官⽅测试,Spring Cloud GateWay是Zuul的1.6倍,旨在为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。

Spring Cloud Gateway可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,实现路由转发、负载均衡、熔断、鉴权、路径重写、⽇志监控等,并且Gateway还内置了限流过滤器,实现了限流的功能。

Kong

Kong是一款基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,由Mashape公司开源的API Gateway项目。Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的,能提供易于使用的RESTful API来操作和配置API管理系统,所以它可以水平扩展多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对大批量的网络请求。

Kong主要有三个组件:

Kong采用插件机制进行功能定制,插件集(可以是0或N个)在API请求响应循环的生命周期中被执行。插件使用Lua编写,目前已有几个基础功能:HTTP基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API请求限流、请求转发以及Nginx监控。

Kong网关具有以下的特性:

Traefik

Træfɪk 是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 来自动化、动态的应用它的配置文件设置。

重要特性:

关于Traefik的更多内容,可以查看官网:https://traefik.cn/

API网关对比

上面是网关对比截图,偷个懒,大家主要关注Kong、Traefik和Zuul即可:

下面是其它网友的思考结论,可供参考:

基于Traefik自研的微服务网关

这个是我司自研的微服务网关,基于Traefik进行开发,下面从技术选型、网关框架、网关后台、协议转换进行讲解,绝对干货!

技术栈选型

网关框架

整个网关框架分为3块:

网关后台

主要由3大模块组成:

一个应用只能绑定一个服务,但是可以绑定多个插件。 通过后台完成网关配置后,将这些配置信息生成Config文件,发布到ETCD中,Config文件需要遵循严格的数据格式,比如Traefix配置需要遵循官方的文件配置格式,才能被Traefik识别。

协议转换模块

hal-proxy模块是整个微服务网关最复杂,也是技术含量最高的模块,所以给大家详细讲解一下。

问题引入

在讲这个模块前,我们先看下面几个问题:

实现原理

我们还是先看一下hal-proxy内部有哪些模块,首先是Resolver模块,这个模块的是什么作用呢?这里我简单介绍一下,目前公司内部通过服务获取到机器列表的方式有多种,比如MIS平台、服务树等,也就是有的是通过平台配置的,有的是直接挂在服务树下,无论哪种方式,我们都通过服务名,通过一定的方式,找到该服务下面所有的主机。

所以Resolver模块的作用,其实就是通过服务名,找到该服务下的所有机器的IP和服务端口,然后持久化到内存中,并定时更新。

协议模块就是支持不同的协议转换,每个协议类型的转换,都需要单独实现,这些协议转换,无非就是先通过机器IP和端口初始化Client,然后再将数据进行转换后,直接发送到下游的机器。

最后就是连接池,之前我们其实也用到go自带的pool来做,但是当对pool数据进行更新时,需要加锁,所以性能一直起不来,后来改成了环形队列,然后对数据的操作全部通过原子操作方式,就实现了无锁操作,大大提高的并发性能。 环形队列的代码,也给你安排上,可以直接看这篇文章 [Go语言核心手册-10.原子操作] 。

实现逻辑

这个是hal-proxy的逻辑实现图,画了2天,包含所有核心对象的交互方式,这里就不去细讲,能掌握多少,靠大家自己领悟,如果有任何疑问(或者看不清图片),可以关注我公众号,加我微信沟通。

尽信书则不如无书,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8