Willson Chen

Stay Hungry, Stay Foolish.

API 网关

API网关

  • 微服务架构中,API网关是一种架构模式,用于将所有服务的API聚合起来,提供统一的服务入口。
  • 可以集中化处理路由、负载均衡、认证鉴权、协议转换等功能。

功能解析

路由

  • 定义:根据匹配规则,将客户端请求导向正确的后端服务。
  • 作用:请求分解和转发,实现负载均衡、容错等。
  • 实现:
    • 路由规则如URL、HTTP方法、请求头等。
    • 请求转发,支持重试、熔断、限流等。

负载均衡

  • 定义:将请求分发到多个后端实例上,实现负载等分担。
  • 作用:提高系统吞吐。
  • 实现:负载均衡算法如加权轮询、一致性哈希、最小连接数等。

反向代理

  • 定义:接收外部请求转发给内部服务器。
  • 区别于正向代理,正向代理是客户端请求的代理,反向代理是服务器响应的代理。
  • 作用:提高安全性,节约IP资源,支持通过缓存加快访问速度。
  • 实现:利用网关的路由和负载均衡实现反向代理。

重试

  • 定义:对失败的请求进行自动重试。
  • 作用:在网络不稳定或后端服务偶发故障时,提高请求成功率。
  • 实现:配置重试策略,如固定时间间隔重试,指数退避重试等。

熔断

  • 定义:当后端服务出现故障或响应慢时,中断连接,避免出现长时间等待。
  • 作用:提高系统稳定性,避免雪崩效应。
  • 实现:
    • 统计故障率,在时间滑动窗口内统计请求成功次数、失败次数、超时次数。
    • 故障率超过阈值时熔断。
    • 熔断状态下不转发,一定时间后开放部分请求尝试恢复。

限流

  • 定义:限制单位时间内客户端对服务的请求次数。
  • 作用:防止过载,控制请求的公平性和优先级,防止恶意调用。

实现:

  • 固定窗口限流(计数器限流):
    • 在固定时长的时间窗口内限制请求数,出现请求+1,窗口结束归零,超过拒绝访问。
    • 优点实现简单。
    • 缺点限流不够平滑,窗口边界可能出现两倍流量。
  • 滑动窗口限流:
    • 在固定窗口限流基础上改进,每来一个请求就推后时间窗口。
    • 解决了窗口边界问题,但仍然不够平滑。
  • 漏桶限流:
    • 请求到来进漏桶,系统固定速率从漏桶出水,超出容量则限流。
    • 优点平滑,缺点无法动态调整速率。
  • 令牌桶限流:
    • 请求到来时移除令牌,可变速率生成令牌。
    • 平滑性好,支持增加突发流量。

协议转换

  • 定义:处理HTTP、HTTPS和RPC协议的转换。
  • 作用:提高安全性、兼容性、不同系统之间的互操作性。
  • 实现:识别协议,通过转换器实现协议转换。

认证鉴权

  • 定义:认证是识别用户身份,鉴权是判断用户是否有权限访问资源。
  • 作用:保护系统的数据和资源,防止未经授权的访问。
  • 实现:
    • 基于身份认证,通过用户名密码登陆方式
    • OAuth2.0,跳转到第三方登录然后包含授权码跳转回来,服务端再根据授权码获取token、refresh_token及用户信息。
    • OIDC,OpenID Connect,完全兼容OAuth2.0,多了ID Token提供用户身份信息等。

灰度发布

  • 定义:将用户流量从旧版本逐步迁移到新版本的策略。
  • 作用:降低发布风险,用于新版本测试。
  • 实现:选择目标用户及流量比例,设置路由及负载均衡策略,监控及日志记录,反馈循环。
  • 发布策略:
    • 滚动发布:对应用的部分服务进行滚动发布,直到全部发布。没有流量控制,较难排查新版本引入的问题。
    • 蓝绿发布:同时两套集群,对硬件要求是平时两倍,容易排查问题,稳定保险。
    • 灰度发布/金丝雀发布:识别少量用户,引流到新版本,验证通过再放量。
    • A/B 测试:同时运行多个版本服务,关注实际效果再选出最好版本,不属于发布策略。

统一对外接口

  • 定义:将对外的接口统一到API网关上,统一接口标准、安全标准等。
  • 作用:方便外部调用,提高安全性,便于监控维护。
  • 实现:通过路由控制、协议转换、认证鉴权将内部接口标准化暴露到外部。接口文档可以借助swagger。

健康检查

  • 定义:通过主动或被动方式检查上游服务等状态,以确保能代理到正常的服务。
  • 作用:提高系统可靠性,保证服务可用性。
  • 实现:
    • 主动检查:独立线程使用探针,如HTTP GET向上游服务并行发起多个请求,检查状态码和响应时间。
    • 被动检查:没有额外探针,依靠业务调用上游服务到情况来判断,无法提前感知健康状态。

版本控制

  • 定义:管理接口变更和版本更迭,为接口定义不同版本,控制访问权限和使用范围。
  • 作用:解决API到兼容性问题,允许多版本共存。
  • 实现:为接口定义版本号如v1.0,通过路由规则控制访问策略。

接口mock

  • 定义:模拟实际接口响应的功能。
  • 作用:不需要等待接口开发完成即可提前测试和验证,缩短开发周期。
  • 实现:定义接口请求和响应数据,配置路由规则。

数据缓存

  • 定义:将后端服务的返回数据存储在磁盘或内存里,下次直接返回。
  • 作用:减轻后端服务压力,提高性能和可靠性。
  • 实现:设置缓存存储方式和缓存策略,通常需要结合后端服务http头缓存控制来实现。

日志

  • 定义:记录API请求和响应的相关信息。
  • 作用:方便对API请求对跟踪和分析。
  • 实现:
    • 日志内容包括URL、HTTP方法、请求头部、请求体、响应状态码、响应头、响应体,还可以记录用户ID、IP、时间戳等。
    • 通常需配置日志的内容、格式、存储方式。
    • 常见工具平台如ELK结合filebeat。

监控

  • 定义:对不同粒度(环境、接口、密钥)下的多个指标(请求数、响应时间、成功率等)等监控。
  • 作用:确保可用性,方便流量管理与优化。
  • 实现:
    • 日志记录、收集监控指标报警提醒。
    • 如提供metrics接口给prometheus,可视化工具如grafana

全链路追踪

  • 定义:跟踪从客户端到API网关到目标微服务之间的全过程。
  • 作用:提高可观测性,便于排查全链路中的问题及瓶颈。
  • 实现:
    • 在API网关处生成traceId,来源于GUID或请求头的x-request-id
    • 在服务调用中层层传递,如通过上下文信息传递。
    • 通过zipkin等平台收集存储分析和展示。
    • 相关标准有OpenTracing、OpenTelemetry等。

数据聚合

  • 定义:对多个后端服务的数据进行聚合及标准化提供给前端。
  • 作用:减少开发工作量。
  • 坏处:使网关变复杂,通常不建议使用。主流网关如apisix不支持该功能。

API网关设计重点

  • 高性能
    • 采用非阻塞IO确保支持高并发(linux的epoll)
    • Java下如Netty实现NIO框架。
  • 高可用
    • 采用集群部署,避免单点故障
    • 对各种内外部不确定因素都有应对方案,如突发流量、下游接口不可用,配置中心故障等。
  • 高扩展
    • 支持热插拔,支持动态配置

API网关选型

apisix

  • 基于Nginx和Lua的API网关,支持动态配置。
  • 特点:
    • 支持OpenResty,基于Nginx和Lua,性能高。
    • 支持动态配置,支持热插拔,支持多种插件。
    • 支持多种协议,如HTTP、gRPC、Dubbo、Kafka等。
    • 支持多种路由规则,如按域名、按路径、按Header等。
    • 支持多种负载均衡策略,如轮询、随机、一致性Hash等。
    • 支持多种插件,如限流、熔断、重试、日志、监控等。
    • 支持多种认证方式,如JWT、OAuth2等。
    • 支持多种后端服务,如HTTP、gRPC、Dubbo等。