我们的系统引入了API网关,用了一个月之后,发现了不少问题。本文记录了使用网关过程中遇到的各种坑,包括性能问题、配置复杂、调试困难、安全风险、监控不足等。每个问题都有具体的现象、原因分析和解决方案。如果你在考虑引入API网关,或者正在使用网关,希望这篇文章能帮你提前避坑。
一、为什么引入网关
先说说我们为什么引入API网关。
我们的系统是微服务架构,有十几个服务。之前前端直接调用各个微服务,带来了很多问题:前端要维护多个服务的地址,跨域问题麻烦,每个服务都要自己做鉴权和限流,接口协议不统一。
为了解决这些问题,我们决定引入API网关。网关作为系统的统一入口,负责路由转发、鉴权、限流、日志、协议转换等功能。这样前端只需要和网关交互,后端的服务也可以专注于业务逻辑。
我们选了一款开源的API网关,功能比较丰富,社区也比较活跃。部署上线之后,刚开始用着还不错,路由转发、鉴权、限流这些基本功能都正常。
但是用了一个月之后,各种问题开始暴露出来。有些是网关本身的问题,有些是我们使用不当的问题,还有一些是架构层面的问题。下面详细说说。
二、问题1:性能瓶颈
第一个问题是性能瓶颈。
现象
上线初期,流量不大,网关的性能还可以。但是随着业务增长,QPS上来之后,网关的延迟明显增加。尤其是在高峰期,网关的P99延迟达到了几百毫秒,而后端服务的延迟只有几十毫秒。也就是说,大部分延迟都消耗在了网关上。
而且网关的CPU使用率很高,经常达到80%以上,内存也涨得很快。有一次流量突增,网关直接OOM了,导致整个系统不可用。
原因分析
经过分析,我们发现性能瓶颈主要来自几个方面:
- 插件太多:我们在网关上配置了很多插件,鉴权、限流、日志、监控、转换、缓存等,每个请求都要经过十几个插件的处理,每个插件都有开销。
- 同步阻塞:这款网关的部分插件是同步阻塞的,比如调用远程鉴权服务的时候,会阻塞请求线程,导致线程被占满。
- 配置热更新:网关支持配置热更新,但是每次更新配置都会重新加载所有路由和插件,期间会有短暂的卡顿。
- 日志打印过多:我们为了调试,开了很详细的日志,每个请求都打印大量日志,IO开销很大。
解决方案
针对这些问题,我们做了以下优化:
- 精简插件:去掉了不必要的插件,只保留核心功能。一些非核心的功能移到了后端服务处理。
- 本地缓存:把鉴权信息、路由配置等缓存在网关本地,减少远程调用。
- 异步处理:把日志、监控等非核心操作改成异步处理,不阻塞请求线程。
- 调整日志级别:生产环境只打印必要的日志,详细日志只在调试时开启。
- 水平扩展:网关是无状态的,可以水平扩展。我们增加了网关实例,用负载均衡分摊流量。
优化之后,网关的延迟降下来了,CPU使用率也正常了。
三、问题2:配置复杂且容易出错
第二个问题是配置太复杂,而且容易出错。
现象
网关的配置项非常多,路由、插件、限流规则、鉴权策略等,每一项都有很多参数。我们的系统有十几个服务,每个服务有十几个接口,配置下来有几百条规则。
这些配置都是用YAML或者JSON写的,没有图形化界面(或者图形化界面不好用)。配置多了之后,管理起来非常混乱,经常出现配置错误。
有一次,一个同事修改限流规则的时候,把一个接口的限流阈值改错了,导致那个接口被大量限流,用户投诉很多。还有一次,路由配置写错了,把A服务的请求转发到了B服务,导致数据错乱。
原因分析
- 配置格式不友好:YAML格式对缩进敏感,很容易因为缩进错误导致配置失效。
- 缺少校验:网关的配置校验不够严格,很多错误要到运行时才发现。
- 没有版本管理:配置直接在线上修改,没有版本控制,出错了不好回滚。
- 配置分散:有的配置在配置文件里,有的在数据库里,有的在管理界面上,分散在多个地方。
解决方案
- 引入配置中心:把网关配置统一放到配置中心管理,支持版本控制和回滚。
- 增加配置校验:在配置发布前做校验,检查格式、引用、冲突等问题。
- 编写配置模板:为常见的场景编写配置模板,减少手写配置的错误。
- 灰度发布:配置变更先在灰度环境验证,确认没问题再全量发布。
- 配置审查:重要的配置变更需要两人审查,避免单人操作失误。
四、问题3:调试困难
第三个问题是调试困难。
现象
网关出问题的时候,排查起来非常麻烦。一个请求经过网关,要经过路由匹配、鉴权、限流、转发、响应处理等多个环节,任何一个环节出问题都可能导致请求失败。
但是网关的日志不够详细,出了问题不知道是哪个环节出的错。而且网关和后端服务的日志是分开的,要把一个请求在网关和后端的日志串联起来,需要手动查,非常耗时。
有一次,一个用户反馈某个接口偶发失败。我们查了网关日志,发现请求转发了;查了后端日志,发现请求没收到。中间到底发生了什么,查了半天才发现是网关的超时设置太短,后端还没处理完,网关就超时断开了。
原因分析
- 日志不完整:网关的日志只记录了部分信息,缺少请求的完整链路。
- 缺少链路追踪:网关没有集成链路追踪,无法和后端服务的日志串联。
- 调试模式不友好:网关的调试模式需要改配置、重启,不能动态开启。
- 错误信息不明确:网关返回的错误信息太笼统,不知道具体是哪里出的问题。
解决方案
- 集成链路追踪:在网关上集成了链路追踪(比如SkyWalking、Jaeger),每个请求生成唯一的traceId,贯穿网关和后端服务。
- 增强日志:在日志中增加请求ID、路由信息、插件执行情况、耗时等详细信息。
- 动态调试:支持动态开启某个请求或者某个接口的详细日志,不需要重启网关。
- 完善错误信息:网关返回的错误信息中包含具体的错误原因和建议,方便排查。
五、问题4:安全风险
第四个问题是安全风险。
现象
网关作为系统的统一入口,是攻击的重点目标。上线之后,我们遇到了几次安全问题。
有一次,有人通过网关的一个配置漏洞,绕过了鉴权,直接访问了后端的内部接口。还有一次,网关被大量恶意请求攻击,导致正常用户的请求被限流。
另外,网关本身也有一些安全漏洞,比如某些版本有已知的CVE漏洞,如果不及时升级,可能被利用。
原因分析
- 鉴权配置不严谨:有些接口的鉴权规则配置有误,导致可以被绕过。
- 缺少WAF功能:网关本身没有Web应用防火墙的功能,不能有效防御SQL注入、XSS等攻击。
- 限流粒度不够:限流是基于IP或者接口的,不能有效识别和拦截恶意请求。
- 版本升级不及时:网关的版本更新不及时,已知的安全漏洞没有修复。
解决方案
- 安全审计:定期审计网关的安全配置,检查鉴权规则、路由配置、限流策略等。
- 接入WAF:在网关前面加了一层WAF,防御常见的Web攻击。
- 增强限流:增加了基于用户、设备、行为的更精细的限流策略。
- 及时升级:关注网关的安全公告,及时升级到安全版本。
- 最小权限:网关的管理后台设置严格的权限控制,避免未授权访问。
六、问题5:监控和告警不足
第五个问题是监控和告警不足。
现象
刚上线的时候,网关的监控很简单,只有CPU、内存、QPS这些基础指标。有一次网关的某个插件出了问题,导致大量请求失败,但是我们没有及时收到告警,等用户反馈了才知道。
还有一次,网关的磁盘满了,因为日志没有轮转,把磁盘占满了,导致网关无法写入日志,请求全部失败。
原因分析
- 监控指标不全:只监控了系统指标,没有监控业务指标(比如错误率、延迟、插件执行情况)。
- 告警阈值不合理:有些指标没有设置告警,有些告警阈值设置得太宽松。
- 缺少日志监控:没有监控日志的大小和错误日志的数量。
- 没有链路监控:不能从整体上监控请求的链路状态。
解决方案
- 完善监控指标:增加了错误率、延迟分布、插件耗时、路由命中率等业务指标。
- 合理设置告警:为每个关键指标设置了合理的告警阈值,并且分级告警。
- 日志监控:监控日志文件的大小和增长速度,自动轮转和清理旧日志。
- 链路监控:通过链路追踪系统,监控整个请求链路的健康状态。
- 大盘展示:做了一个网关监控大盘,实时展示网关的运行状态,一目了然。
七、问题6:服务依赖和耦合
第六个问题是服务依赖和耦合。
现象
网关本来应该是薄的,只做转发和通用功能。但是用着用着,越来越多的业务逻辑被加到了网关上。
比如,我们在网关上做了用户信息的组装、接口参数的转换、甚至一些业务规则的判断。这样网关就变得越来越重,和业务服务的耦合越来越深。
有一次,后端服务改了一个接口的参数格式,因为网关里有对应的转换逻辑,也要跟着改。而且网关的发布流程比后端服务复杂,导致一个简单的参数变更,要等网关发布才能生效。
原因分析
- 图方便:有些功能在网关上做比较方便,就直接加在网关上了,没有考虑长期维护。
- 职责不清:网关和后端服务的职责边界没有明确,导致功能越界。
- 缺少规范:没有制定网关的使用规范,什么功能该放在网关,什么功能该放在后端,没有明确的规定。
解决方案
- 明确职责:制定了网关使用规范,明确网关只做通用的、与业务无关的功能(路由、鉴权、限流、日志等),业务逻辑一律放在后端服务。
- 清理网关:把网关上的业务逻辑逐步迁移到后端服务,让网关回归"薄"的本质。
- 代码审查:网关的变更需要严格审查,防止业务逻辑被加进来。
- 独立发布:网关和后端服务独立发布,互不影响。
八、总结和建议
用了一个月网关,踩了不少坑,也总结了一些经验。
网关的价值
虽然有这么多问题,但是网关的价值还是很大的。它统一了系统入口,简化了前端调用,集中处理了鉴权、限流、日志等通用功能,让后端服务更专注于业务。这些好处是实实在在的。
使用建议
如果你在考虑引入API网关,这里有一些建议:
- 选型要谨慎:根据自己的需求选择合适的网关,不要盲目追求功能多。性能、稳定性、社区活跃度都是重要的考量因素。
- 从简单开始:刚开始不要配置太多插件和功能,先把核心的路由和鉴权跑通,再逐步增加功能。
- 做好监控:上线之前就要把监控和告警做好,不要等出了问题才补。
- 保持网关薄:不要把业务逻辑加到网关上,网关只做通用功能。
- 配置管理:用配置中心管理网关配置,做好版本控制和审查。
- 性能测试:上线前做充分的性能测试,找到网关的性能瓶颈和极限。
- 安全第一:网关是系统的入口,安全非常重要,做好鉴权、限流、WAF等安全防护。
什么情况下不需要网关
不是所有系统都需要网关。如果你的系统只有一两个服务,或者流量很小,直接用Nginx做反向代理就够了,不需要引入重量级的API网关。网关本身也有运维成本和性能开销,要根据实际情况来决定。
九、写在最后
API网关是微服务架构中的重要组件,用好了能大大提升系统的可维护性和安全性。但是网关不是银弹,它也有自己的问题和局限性。
我们用了一个月,踩了不少坑,但是也通过不断优化,让网关稳定地运行了下来。这些问题和解决方案,希望能给正在使用或者准备使用网关的同学一些参考。
技术选型没有最好的,只有最合适的。在引入任何新技术之前,都要充分评估它的优缺点,以及自己团队的维护能力。不要因为别人都在用就跟风,也不要因为有坑就完全否定。
最后用一句话结束本文:"网关是入口,也是瓶颈。用好了是利器,用不好是累赘。"愿每一个团队都能根据自己的实际情况,做出最合适的架构选择。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录