网关系统 分析

本文通过分析他司的网关系统来帮助自己建立网关系统,虽然是重复劳动没啥创新, 但是自研产品对系统有更好的控制,并且提升自身的技术能力。

  • 公司A分享的网关系统,图如下:

我们一步一步逐步分析每个步骤的作用, 以及应该如何设计与开发。

  • 用户的请求首先经过slb,先说明下slb:

slb的全称server load balancer,是将访问流量根据转发策略分发到后端多台real server(rs)的设备,常用的有4层和7层均衡负载。四层slb在传输层进行解析,通过替换目标ip地址和端口实现流量的转发;7层slb在应用层进行解析, 可以根据url等信息进行转发,常见的如openrestry等。欲详细了解的点击这里

不过这不是网关的范畴,接下来看网关。从图中我们知道网关架构中有3个核心点,内核(过滤链)、配置中心、监控中心。


网关内核(过滤链)

请求在访问rs的服务之前经过一个过滤链,如springcloud gateway就提供了一组过滤链提供请求的pre/post处理;

  • 防刷

设置全局过滤器,可以通过对请求速度进行控制,对于异常ip加入黑名单。可以根据请求的ip进行限流,常用的限流算法有漏斗算法和令牌算法

对于被流控限制的请求,可以进行日志打点,打点事件可以记录为 logEvent({"eventType":"requestLimit", "eventName":"ip request to fast", "ip":${ip}})。后续使用同一日志时间解析任务分析,单个ip拦截次数过多,对于异常的ip进行上报,可以手动或者自动加入黑名单。

  • 黑名单

黑名单持久化存储(文件或者db,不建议用redis,redis存在失效策略,可能会导致黑名单失效),网关初始化时加载到java set中。

  • 时间校验

该过滤器应该是指系统功能在某个时间段不开放,此类一般不是全局的,而是针对某一个或者某一模块的功能进行控制,因此需要针对进行进行对应配置。如果是采用springcloud gateway可以参考相关配置

  • 验签

1、 对于open api场景:

存在不需要鉴权的可以直接访问,对于需要鉴权的,需要为使用者分配账号。权限设置可以如此进行。在配置中心配置开发者账号以及公私钥,私钥和开发者账号分配给开发者,开发者每次请求对请求体进行数字签名,网关根据请求中的开发者账号拿到系统内的公钥进行签名验证,验证通过则通过。公私钥生成策略见下文配置中心-开发者账号配置

2、对于内部应用场景:

可以考虑将用户id信息使用jwt加密,并且配合失效刷新等策略,实现访问的验签

  • 限流

此问题和防刷类似 , 这里就不做赘述

  • 用户鉴权

1、 对于openapi场景,每个客户可访问的api需要经过严格的控制:

我们在用户验签后,已经拿到用户id,通过对用户id的权限进行控制实现不同级别的api控制,如:

user_id access_level
1 1
api_path access_level
/list/goods 1

如果用户的access_level >= api对应的access_level则通过

  • 报文转换

请求的报文转换:例如用户使用开发者账号访问,网关处理后,需要将对应业务系统的userid设置到请求头中,需要进行请求体报文转换

响应的报文转换:例如修改响应状态码,需要用到响应报文转换

  • 网关插件

可以自定义其他过滤器,加入到过滤链中

  • 泛化调用

对api实例进行抽象,通过代理实现任何类型的api访问;

  • 报文组装(跟报文转换类似)

配置中心

  • 防刷流控:高频率使用配置,通过应用变量配置,如:

如果令牌算法,访问速度replenishRate=10,容量burstCapacity=20

  • 告警策略:低频率使用配置,通过db配置或者文件配置,网关在使用时进行缓存,如:

一个告警事件(来自于对日志打点的分析)包含:事件类型+请求的数据, 请求的数据可以是ip或者其他从请求中解析出来的特征值,如:

流控事件:配置类似于下图,有升级事件的配置,会进行告警统计,例如如果1个小时内某个ip出现request_limit告警次数超过5次, 则生成升级事件,会邮件通知关注人

事件类型 级别 动作 升级事件 升级阀值 关注人
requet_limit 初级 系统提醒 达到升级阀值,邮件提醒 5次/h a

熔断事件:事件 circuitBreak 发生后,在监控系统中进行初级提醒,由于是区间影响,如果使用屏幕展示的话,会是在事件关闭前的一段区间进行展示。如果再升级阀值达到后,熔断器依然没有关闭,则升级事件、,进行邮件提醒。

事件类型 级别 动作 升级事件 升级阀值 关注人
circuitBreak 初级 系统提醒 达到升级阀值,邮件提醒 5m a

异常次数、熔断次数、失败次数也可以设置告警策略, 周期内超过一定次数就进行告警。

  • 开发者账号配置:

开发者id可以根据snowflake算法生成,公私钥使用rsa算法生成,结合sha256withrsa进行签名与验证

  • 熔断配置

系统在访问量大过大、服务请求超时或者服务请求失败率超过阈值的时候,开启熔断开关,对新的请求进行熔断或者降级处理。 在分布式系统中有很多解决方案, spring全家桶中提供的hystrix 是个很好的参考,如果是使用springcloud gateway 可以直接使用该组件进行配置。

可以看下hystrix的工作图

在系统发生熔断事件时,进行日志打点,打点事件可以记录为 logEvent({"eventType":"circuitBreak", "eventName":"circuitBreaker open", “api”:${api}, "status":"open", "message":"request time out"),同样熔断恢复时需要进行熔断关闭时也进行日志打点,告警由统一日志分析任务进行处理。

  • 缓存配置

配置中心提供缓存清理功能,实现配置及时生效。缓存主要由以下几类:

配置缓存:告警策略等配置;

数据缓存:使用者账号信息、api信息、服务实例缓存等;

  • 错误码管理

错误采用:模块+api_id+业务错误码,形如:001:1:100001


监控中心

  • 调用量统计

在网关内核——过滤链中加入一个过滤器实现调用量、异常熔断、降级的统计;如采用springcloud gateway可以使用GatewayMetricsFilter全局过滤器实现指标数据的统计,结合actuator,通过/actuator/metrics/gateway.requests实现请求数据的监控

这里需要注意一点, 如果开启actuator,需要注意结合鉴权,防止内部请求暴露于外网

  • 日志打点

对于一些重要的系统事件,可以使用日志进行记录,将事件类型的日志单独记录到一个日志文件,格式可以是:

${time}  ${event_type}  ${event 体 json 格式}

为后续的系统告警提供数据

  • 异常次数
  • 熔断次数
  • 降级次数
发布了22 篇原创文章 · 获赞 1 · 访问量 531

猜你喜欢

转载自blog.csdn.net/weixin_37512224/article/details/102566138