马蜂窝如何利用 APISIX 网关实现微服务架构升级

news2024/11/25 19:38:57

作者:董红帅,马蜂窝微服务体系建设以及基础服务能力建设专家。

马蜂窝作为旅行社交平台,是数据驱动的新型旅行电商。基于十余年的内容积累,马蜂窝通过 AI 技术与大数据算法,将个性化旅行信息与来自全球各地的旅游产品供应商实现连接,为用户提供与众不同的旅行体验。

随着业务的发展,马蜂窝架构也在跟随技术步伐进行更迭,开始基于 Kubernetes 进行更多的延展。在这个技术背景下,需要针对云服务开启新一轮的架构更新,比如:微服务场景建设新的蜂效平台及周边设施来支持迭代和流量泳道的能力,在多 Kubernetes 集群场景引入 Karmada 实现多集群管理,在微服务网关领域将 Istio + Envoy 的架构替换为 Apache APISIX 与 Envoy 共存的微服务网关模式。

微服务 1.0 模式现状

目前马蜂窝内部的微服务架构经历了两次迭代,本文中将针对原有架构的第一次调整定义为 1.0 版本。在进行微服务 1.0 架构的搭建之前,我们从发布系统能力、Kubernetes 容器、服务发现和微服务网关等角度进行了一些考量与目标对齐。比如 Kubernetes 的广泛应用,需要开始考虑基于容器做多语言支持,在 CI/CD 环节实现全面容器化,并支持多 Kubernetes 集群等。

在进行第一次迭代之前,内部架构的微服务网关使用的是 NGINX Ingress,但它其实是存在问题的。比如配置变更基于 NGINX reload,会造成业务有损;同时在应用范围内仅支持单 Kubernetes 集群,场景受限;内置资源过于简单,大量匹配规则依赖 Annotations,配置繁杂不友好,尤其是对外部服务发现能力支持很弱。

因此在进行微服务 1.0 迭代落地的过程中,为了满足一些业务需求,我们进行了如下动作(选取部分操作列举):

  • 在 Kubernetes 容器内,基于 macvlan 改造容器网络,IDC 机房网络与云厂商网络互通(容器互通的通信基础);借助网关或容器直连实现服务互访,不再使用 Kubernetes Service。
  • 基于 Kubernetes 容器场景部署;基于 Consul 物理机虚拟机部署。
  • 增加统一服务发现能力,基于 Kubernetes、Consul 建设统一的发现中心 — Atlas;同时基于 Atlas 扩展微服务网关、Java 生态、监控体系等。
  • 在微服务网关的选择上,基于 Istio + Envoy 架构进行构建。对 Istio 中 Pilot 进行二次开发,对接 Atlas 发现中心,由于 Atlas 数据来源于多套 Kubernetes 和 Consul,进而将实例发现与 Kubernetes 集群解耦,间接做到网关对接多 Kubernetes 集群的能力,实现整个网关动态感知识别的变化。

蜂效 1.0 微服务网关架构

痛点梳理

在微服务 1.0 的这套架构中,实践下来还是存在一些痛点。

首先是在发布系统能力方面,微服务 1.0 中的发布系统,仅仅是一个发布系统,无法有效融合项目需求的管理(发布也是度量的一环);同时这套发布系统基于 PHP 构建,无法很好地支持自动化滚动部署、多版本滚动部署容量变更等较为复杂的部署场景;当多人对同一个项目开发,或一个需求关联多个项目时,缺少机制让流量在同一个迭代中自动串联(流量泳道)。同时对多 Kubernetes 集群管理并不方便,当 Kubernetes 下线时需要业务侧参与,给业务线带来了时间成本等。

其次就是微服务网关架构层面。前文也提到了 1.0 架构下网关是基于 Istio+Envoy 对 Pilot 做了二次开发,主要是对接 Atlas 发现中心。随着业务的应用数量越来越多,访问规则也越来越多,这就导致我们线上的网关生效延迟也越来越高。在流量巅峰状态下,大概有 15 秒左右的延迟。这个延迟主要来自于 CRD 资源,几乎全都在相同的 namespace 下,同时上下线时会触发全量更新导致延迟较高。

而在早期的使用过程中,Envoy 在数据全量推送过程中还会出现链接中断的状况,造成 503 问题的产生。除此之外,Envoy 还存在使用内存持续增长导致 OOM 的情况,当网关出现问题时,对 Envoy 和 Pilot 进行排错的成本较高。当使用一些高阶配置时,需要借助 Envoy Filter 实现,其上手门槛较高,对于想简单实现熔断、限流、Auth 鉴权等功能而言,成本较高。

除此之外,两个社区(Istio 和 Envoy)的发展速度很快,这也导致我们的架构比较难跟进上游社区的发展。

基于 APISIX 的微服务 2.0 模式

新平台与新架构

面对 1.0 架构下存在的痛点与问题,内部对于这套微服务架构进行了再次迭代,来到了 2.0 时代。2.0 架构场景下,我们新增了一套发布平台——蜂效平台。

蜂效平台重点突出了以下能力:

  • 融合了需求管理,支持了迭代部署能力,使得发布系统可以增益度量。
  • 将容器部署和机器部署(物理机部署)在产品能力上进行了统一。
  • 增强了精细化的流量管理能力、回滚能力(回滚策略:批次、实例数、间隔等)
  • 与 Java 生态融合共建,支持了流量泳道能力,环境流量隔离。
  • 网关基于 APISIX 进行重构,解决 Envoy OOM 及规则生效延迟较高的同时,通过 APISIX 产品化能力降低了问题排错成本,降低了扩展和配置网关的上手门槛。

在蜂效平台产品侧中,我们将需求管理与迭代部署关联结合,并且为了支持了多种迭代流水线模式。在流量管理方面,我们借助 Atlas Instance 模型中的 env 属性以及扩展属性,实现了流量泳道能力。基于流量泳道模型,在上层产品侧构建迭代流量环境调用链路隔离。

规划蜂效 2.0

在周边生态建设方面,Java SDK 侧做到了应用在迭代环境中可以实现隔离的链路调用,网关侧也进行了类似的操作。只是网关侧作为整个流量的入口,我们是通过 Cookie 的规则,也就 Cookie 的方式进行配置的。基线环境的流量只能到达基线环境的版本中,迭代环境的流量就会转发到迭代的版本上去。

v1 与 v2 版本的流量分配

同时在部署层的 Kubernetes 多集群管理层面,我们则借助 Karmada 实现了一个多 Kubernetes 集群的管理。在整个架构中(如下图所示),底层的能力主要是由 Kubernetes 多集群和流量网关 Envoy 与 APISIX、发现中心 Atlas、日志服务与监控服务等组成。

而蜂效平台在整个架构中主要是进行配置管理、构建部署、扩缩容和上下线等等,同时包含任务流的模块。最上方则是应用市场的一些能力,比如迭代能力和插件能力等。

蜂效平台 2.0 架构图

整体来说,我们基于应用中心和服务打造出了 2.0 新架构。这套新架构在 Kubernetes 集群发生变更时,可通过 PropagationPolicy、OveridePolicy 等策略,实现 Deployment 等在 Kubernetes 集群级别的资源分发,减少集群变更时业务参与的成本,减轻了业务研发侧的一些压力。

网关选型

在 2.0 模式的架构中,流量网关我们提到了两个网关产品,即 Envoy 与 APISIX。Envoy 作为之前 1.0 版本的选择,我们并没有完全放弃,在 2.0 中我们也因为一些需求和产品期望,开始考虑新的网关产品进行替代,比如:

  • 访问规则变化时,网关的生效速度需要控制在毫秒级(生效慢,会导致网关生效速度不一,在使用了 CDN 场景下可能导致业务资源长时间 404)。
  • 可在现有场景中,完全替换 Istio+Envoy 架构;同时支持 HTTP、gRPC,并兼容现有路由策略。
  • 需要降低问题的排查成本,最好有产品化支持(如 Dashboard)。
  • 产品足够稳定,社区活跃,功能强(对限流等场景支持)。
  • 不需要二次开发即可支持公司现有架构的替换。
  • 在替换 Istio+Envoy 架构过程中,需要保持双架构可用(Istio、Envoy 与新网关并存),如果新架构有问题可快速回退至原来方案。

在调研了一些关键网关产品的模型之后,我们最终将方案锁定在了 Apache APISIX。APISIX 的架构也分为控制面和数据面,同时还附带 Dashboard 产品。在功能使用上,APISIX 提供了丰富的插件,比如限流、熔断、日志安全和监控等等。我们可以通过 APISIX 的 Admin API 提供的接口,去完整操作 APISIX 的所有能力,比如 Upstream、Consumer 还有各种插件等。对我们而言,APISIX 还有一个特别有优势的点,就是 APISIX 在升级时,能够做到对低版本的 API 进行统一的兼容。

APISIX 架构

除此之外,我们认为 APISIX 还有以下几个优势:

  • APISIX 基于 Openresty 的性能很好,相比 Envoy 来说,性能损耗很少。在经过我们测试之后,在 QPS 的表现上,APISIX 损耗 3%,而 Envoy 损耗 16%;在时延表现上,APISIX 平均转发耗时 2ms,而 Envoy 耗时 7ms。数据的体现,已经展示了 APISIX 在性能上的卓越优势。
  • APISIX 还附有 Dashboard 支持,对于路由匹配异常等场景可快速判断是否为规则配置错误。
  • 作为开源产品,APISIX 的社区更为活跃。在产品的功能上,在限流、鉴权、监控等方面相比 Envoy 成本更低,支持性更好。
  • APISIX 相比 Envoy 内存占用很低,但在配置的动态变更上相比 Envoy 要弱(Envoy 几乎大部分配置可动态下发),但也足够满足需求。

因此,在调研与测试之后,我们在微服务 2.0 的架构下增添了 Apache APISIX 作为流量网关加入。由于网关是整个微服务流量的核心,如果从一套旧架构切换到一套新的架构,其实成本是比较高的。所以我们希望微服务的网关规则变化能够对新旧两套网关(Envoy 与 APISIX)同时生效,也就是一套配置可以适用于两种架构,因此我们在 2.0 架构中,针对这些变动做了一些调整。

落地方案与实践问题

首先考虑到成本问题,对原本的 Istio 架构保持不变,并未进行改造。同时在网关架构中,引入了新开发的关键组件—— istio-apisix-translator

istio-apisix-translator 主要是去对接 Atlas 发现中心以及 Istio 的 CRD 数据。作为数据同步服务,实时将 VirtualService、DestinationRule 等规则变化转换为 APISIX 路由规则,将 Atlas Instance 数据实时转换为 APISIX Upstream 规则等。简单来说,就是通过这样一个服务组件,实现了对 Atlas 以及 Istio CRD 的数据支持。

借助这种架构,我们就实现了对两种网关的完整支持,如下图所示。

蜂效 2.0 微服务网关架构

网关架构的核心部分则是图中最下方的 APISIX,上层的 istio-apisix-translator 则充当类似 Istio 架构中的 Pilot 角色,将 Instance 与 CR 数据整合后,借由 APISIX Admin API 推送至 APISIX 中,实例则是对接到内部业务的 Atlas 发现中心。因此,无论是访问规则发生变化还是 Atlas 的数据源发生变化,都可以将这份数据变化转换成 APISIX 的数据推到 APISIX 中。目前全链路都是基于 Watch 机制保证数据变化的实时处理,因此在实际应用场景下,基本可以达到数据变化的毫秒级生效。

当然,在使用 APISIX 的过程中,我们也遇到了几处问题。但均已解决并将结果同步给了社区进行反馈。

第一个问题就是在 APISIX 使用证书对接 etcd 时,如果 APISIX 节点较多,可能会导致 APISIX Admin API 接口响应非常慢。这个问题的原因是因为目前 etcd 存在一个关于 HTTP/2 的 BUG。如果通过 HTTPS 操作 etcd(HTTP 不受影响),HTTP/2 的连接数上限为 Golang 默认的 250 个。而 APISIX 的控制面和 Istio 架构的控制面有区别,APISIX 节点是直连 etcd,当 APISIX 数据面节点数较多时,一旦所有 APISIX 节点与 etcd 连接数超过这个上限,则 APISIX 的接口响应会非常的慢。

为了解决这个问题,我们也在 etcd 和 APISIX 的社区均进行了反馈,后续也通过升级版本(etcd 3.4 升级到 3.4.20 及以上,etcd 3.5 升级到 3.5.5 及以上)解决了这个问题。同时我们也已将这个结果同步到了 APISIX 社区官网 Q&A 文档中,方便后续用户遇到同样问题时,可以有所参考。

第二个问题就是在使用 APISIX 的过程中会遇到性能抖动的问题。

首先是会出现 499 响应抖动,这个问题主要出现在连续两次以上过快的 post 请求(也不止 post)的场景下。这种情况是 NGINX 认定为不安全的连接,则主动断开了客户端的连接。为了处理这个问题,只需将 proxy_ignore_client_abort 的配置调整为 on 即可。

除此之外,当 APISIX Admin API 接口请求密集时,也会出现 APISIX 数据面少部分响应超时的状况。这个主要是因为 istio-apisix-translator 在重启时,会将 Atlas、Istio CR 数据聚合,全量同步至 APISIX 中,大量请求引发 APISIX 数据变更,APISIX 数据面密集的同步变更导致小部分响应超时。为此,我们引入协程池和令牌桶限流,减少 APISIX 数据密集变更的场景来应对此问题。

总结与发展

马蜂窝当前是基于 Kubernetes 容器部署以及基于 Consul 的机器部署场景,自建 Atlas 服务发现中心,同时,在 Java 生态、微服务网关,微服务体系的流量泳道,以及监控体系做对接和适配。

在微服务网关前期,是基于 Istio 1.5.10 对 Pilot 二次开发,也在网关侧支持非容器部署场景。目前阶段则是保持了 Istio+Envoy 架构与 APISIX 架构同时支持,通过引入外部服务组件,让 APISIX 也复用 Istio CRD 资源。

从网关发展视角来看,未来我们也会跟随网关的一些趋势。比如现在很多产品都开始支持 Gateway API,像 APISIX Ingress、Traefik、Contour 等;同时网关的动态化配置也是未来非常明显的趋势,对于运维或者基础研发的同学来说,在后续考虑网关架构的选型和迭代时,也可以更多关注网关动态配置的方面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Water Pamola通过恶意订单对电商发起攻击

自2019年以来,趋势科技的研究人员一直在追踪一个被称为“Water Pamola”的攻击活动。该活动最初通过带有恶意附件的垃圾邮件攻击了日本、澳大利亚和欧洲国家的电子商务在线商店。 但是,自2020年初以来,研究人员注意到Water Pamola的活动发生…

(二十三)Collecttion集合

目录 前言: ①Collecttion集合的体系结构 ②Collecttion集合的遍历方式 方式一:迭代器 方式二:foreach/增强for循环 方式三:Lambda表达式 ③常见数据结构 前言: Collection: 是所有集合的顶级接口,里面规定了集合操作元素的相关功能方法集合与数组一样,用于存储一组…

使用Sa-token实现单点登录

使用Sa-token实现单点登录单点登录需求为何选择Sa-Token简单使用sa-token接口如何保持登录态使用拦截器实现鉴权聊聊Sa-Token的理解聊聊遇到的一些问题单点登录需求 其实一直想写一个单点登录系统,现在的现状是公司内部有非常多项目的,然后每个项目一套登…

数据分析面试题--数理知识点1

目录标题1,python统计一段话每个单词出现的次数2,SQL中如何利用replace函数统计给定重复字段在字符串中的出现频率?3,常见的统计分析方法有哪些?拿到数据如何分析4,参数估计和假设检验的联系和区别5&#x…

网络实验之OSPF路由协议(一)

一、OSPF路由协议简介 开放式最短路径优先(Open Shortest Path First,OSPF)路由协议是用于网际协议(IP)网络的链路状态路由协议。该协议使用链路状态路由算法的内部网关协议(IGP),在…

NIO笔记

一. NIO 基础 non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 st…

SAP ABAP 代码修改自动比较对象版本一致

第一步,找到SE38/SE37代码修改的出口 SMOD中查找 第二步,实施增强 CMOD中添加增强并激活,如下图 第三步,添加代码 如上图两个双击添加并修改代码 ZXSEUU08中与 ZXSEUU01代码一致,如下 *&----------------------…

【年度总结】我的2022年-职业生涯大转折

【年度总结】我的2022年-职业生涯大转折2022总结大厂的苦与乐找工作的焦虑再起启航2023展望持续刷题持续学习捡起博客在漩涡中疯狂挣扎的一年 2022总结 大厂的苦与乐 上半年主要在搞中台,需要对接的其他团队比较多,每天都在对接需求、优化需求。同时还…

Python NumPy 创建数组(ndarray)

前言NumPy(Numerical Python的缩写)是一个开源的Python科学计算库。使用NumPy,就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能。本文主要介绍使用Python NumPy 创建…

鉴源论坛 · 观辙丨基于机器学习的汽车CAN总线异常检测方法

作者 | 张渊策 上海控安可信软件创新研究院研发工程师 来源 | 鉴源实验室 目前机器学习是研究车辆网络入侵检测技术的热门方向,通过引入机器学习算法来识别车载总线上的网络报文,可实现对车辆已知/未知威胁的入侵检测。这种基于机器学习的异常检测技术普…

chrono_duration(一)

文章目录chrono简介std::chrono::durationduratio基本介绍基本概念使用引入std::ratio 参数深入特化的duratio改造之前的代码静态成员函数 count原型例子构造函数支持加减乘除运算编译细节支持比较运算符查询范围类型转换例子引入修改seconds的范围浮点类型系统特化的duratio自…

os模块的使用方法详解

os模块os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;即os模块提供了非常丰富的方法用来处理文件和目录。使用的时候需要导入该模块:import os常用方法如下:方法名作用os.remove(‘path/filename’)删除文件os.re…

Unidbg模拟执行某段子so实操教程(一) 先把框架搭起来

一、目标 最近又开始研究Unidbg了,费了好大劲,没有跑起来。今天就先找个软柿子捏捏看。 今天的目标是 之前研究的 某段子App签名计算方法(一) 某段子App版本 5.5.10 二、步骤 先搭起框架来 在 /unidbg/unidbg-android/src/test/java/ 下面新建一个 …

K8S 三种探针ReadinessProbe、LivenessProbe和StartupProbe 之探索

一、事件背景因为k8s中采用大量的异步机制,以及多种对象关系设计上的解耦,当应用实例数增加/删除、或者应用版本发生变化触发滚动升级时,系统并不能保证应用相关的service、ingress配置总是及时能完成刷新。在一些情况下,往往只是…

Python爬虫之Scrapy框架系列(4)——项目实战【某瓣Top250电影更多信息的获取】

前言: 上篇文章使用Scrapy框架简单爬取并下载了某瓣Top250首页的排名前25个电影的电影名。 太寒酸了,这篇文章咱就来仔细搞一搞,搞到更加详细的信息!!! 目录:1.分析2.使用scrapy shell提取电影详…

进程信号--Linux

文章目录信号?kill -l 指令查看所有信号信号的工作流程信号产生1.通过终端按键产生信号2.通过系统调用接口产生信号3.通过软件产生信号4.硬件异常产生信号信号接收信号处理总结信号? 进程间的通信我们了解到有管道通信,有共享内存的通信。这…

flowable编译

git clone -b flowable-release-6.7.2 https://github.com/flowable/flowable-engine.git下载之后File-Open,打开工程,modules是核心代码模块 找到flowable-root.xml按下altf12 ,启动Terminal终端输入命令:mvn clean package -Ds…

《Buildozer打包实战指南》第三节 安装Buildozer打包所需的依赖文件

目录 3.1 安装依赖软件包 3.2 安装Cython 3.3 设置环境变量 3.4 安装p4a、Android SDK、NDK以及其他编译文件 Buidozer这个打包库下载安装完毕之后,我们还需要下载一些打包安卓apk所需要的依赖文件。 3.1 安装依赖软件包 首先输入以下命令更新Ubuntu上的软件包…

使众人行:如何带领一群人把事做成?

你好,我是雷蓓蓓,一名程序员出身的项目经理,曾任网易杭研项目管理部总监。 我所带领的网易杭研项目管理部,从2011年成立以来,就一直在互联网项目管理领域深耕,为网易云音乐、网易严选、云计算、智慧企业等…

智慧社区管理系统改造方案

伴随着城市发展的持续加速,许多在建智慧社区和老旧小区智能化改造都在有规划的展开着。如今许多老旧小区在展开设备升级,许多小区智能安防设备、物业管理服务系统软件、社区综合服务平台及其监控器设备等都会展开智能化改造。但是,很多人对老…