Envoy已在服务网格和代理世界中获得了很多欢迎。这是一项了不起的技术,但有时有些难以理解。我一直在玩的一件事是使用Envoy来执行速率限制。幸运的是,限速是Envoy的头等公民。然而,阅读率限制的文档有很多概念,这就可能导致我们很难运行一个demo。经过探索,我对Envoy的限速理念和概念做一些总结。 Envoy允许我们同时配置TCP和HTTP速率限制过滤器,但在本文中我们将重点介绍HTTP。
Rate Limit Service
在查看这一切在Envoy中的工作方式时,我们注意到的第一件事是Envoy希望您定义速率限制服务。这是因为Envoy本身没有机制来确定是否应让请求通过或限制请求。这是有道理的,因为有时这需要代理可能不应该是所有者的信息。很酷的事情是,Envoy希望从限速服务中获得的接口已被详细记录。由于这是一个gRPC API(与Envoy的其他控制平面和数据平面API一样),因此可以很容易地从响应该模式的服务开始。为了使事情变得更好,Lyft最近发布了响应该接口的服务版本:https://github.com/lyft/ratel...
要使用Envoy的配置文件配置此服务,我们需要执行以下操作:
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: my_rate_limit_service
timeout: 0.25s
但是要使我们的限速服务正常工作,我们需要一些信息。该信息与gRPC请求一起发送,我们可以在这里查看:https://github.com/envoyproxy...
率限制请求有三个字段:
-
domain
让envoy告诉我们的限速请求,我们系统中的哪些设备正在要求这些限速。这对于避免可能因domain而异的键冲突很有用。 -
hits_addend
是envoy为该请求指定额外费用的一种方式,例如,更昂贵的路线。我很好奇为什么要在请求中,而不是让服务来决定,但这仍然很有趣。 - 最后,
descriptors
是速率限制请求的关键。它是一组描述此请求上下文的键值对。它们可以帮助我们的限速服务计算密钥,识别参与者等。
Descriptors
当我第一次阅读gRPC接口时,这一切对我来说很有意义。但马上产生一个疑问,我不清楚如何配置descriptors。我的目标是能够根据用户的HTTP_AUTHORIZATION
标头对限制用户进行评分,很难看到如何发送带有标头值的描述符值。这是一个运行时值,可能会随每个请求而变化,因此将其作为静态配置没有任何意义。 这是速率限制操作起作用的地方。
Actions
到目前为止,我们涉及的内容是我们的限速服务的一部分,以便让我们做出正确的决定。但是,我们仍然不知道Envoy如何填充这些数据,甚至不知道我们如何发送感兴趣的数据。在envoy中配置的路由可以选择定义RateLimit配置,定义动作。动作是构建descriptor的一种方法:通过配置动作,我们使Envoy知道我们希望它如何使用几个不同的选项来构建要发送到速率限制服务的descriptor列表。
例如,如果我们想对请求的Authorization标头实现速率限制,则可以指示envoy通过以下操作构建此类descriptor:
rate_limit:
actions:
- request_headers:
header_name: HTTP_AUTHORIZATION
descriptor_key: auth_token
现在,在进行此配置的情况下,速率限制服务将收到以下descriptor列表:
[
"key": "auth_token",
"value": "1ae59f456ff7ec1185c03b781f955a4e"
]
这是我们的限速服务将做出决定的地方。基于该descriptor集(此示例中只有1个),我们可以查找密钥,使用某种速率限制算法(令牌桶,滑动窗口等)对密钥进行速率限制,然后将决策发送回envoy。注意,可以定义多个动作,在此进行解释。
这里更复杂的是发送多个descriptor时。descriptor条目是分层的,这意味着条目可以建立在其他条目之上。
速率限制请求的主要消息。速率限制服务被设计为完全通用的,因为它可以在任意层次的键/值对上运行。加载的配置将解析请求并找到最具体的限制。此外,RateLimitRequest可以包含多个“descriptor”以进行限制。当提供多个descriptor时,服务器将限制它们的全部,如果其中任何一个超出限制,则返回OVER_LIMIT响应。如果需要,这将启用更复杂的应用程序级别速率限制方案。
如您所见,Envoy中的速率限制非常通用且强大。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。