Aeraki系列:如何設(shè)置本地限流規(guī)則
Aeraki 可以幫助你在服務(wù)網(wǎng)格中管理任何七層協(xié)議。目前 Aeraki 已經(jīng)支持了 Dubbo、Thrit、Redis 等開源協(xié)議。你還可以使用 Aeraki 的 MetaProtocol 協(xié)議擴(kuò)展框架來管理私有協(xié)議的七層流量。
本系列教程將介紹如何通過 Aeraki 來在服務(wù)網(wǎng)格中為 Dubbo、Thrift 等協(xié)議的服務(wù)提供七層流量路由、本地限流、全局限流,以及如何基于 Aeraki Protocol 快速開發(fā)一個(gè)自定義協(xié)議,并在 Istio 服務(wù)網(wǎng)格中對采用自定義協(xié)議的服務(wù)進(jìn)行管理。
本篇教程介紹如何利用 Areaki 提供的 MetaRouter CRD 資源對基于 MetaProtocol 開發(fā)的應(yīng)用協(xié)議設(shè)置本地限流規(guī)則。
安裝示例程序
如果你還沒有安裝示例程序,請參照 快速開始(https://www.aeraki.net/zh/docs/v1.0/quickstart/) 安裝 Aeraki,Istio 及示例程序。
安裝完成后,可以看到集群中增加了下面兩個(gè) NS,兩個(gè) NS 中分別安裝了基于 MetaProtocol 實(shí)現(xiàn)的 Dubbo 和 Thrift 協(xié)議的示例程序。你可以選用任何一個(gè)程序進(jìn)行測試。
- ➜ ~ kubectl get ns|grep meta
- meta-dubbo Active 16m
- meta-thrift Active 16m
Aeraki 的限流規(guī)則設(shè)計(jì)直觀而靈活,既支持對一個(gè)服務(wù)的所有入向請求進(jìn)行限流,也支持按照不同的條件對一個(gè)服務(wù)器的請求進(jìn)行細(xì)粒度的限流控制。
對服務(wù)的所有入向請求進(jìn)行限流
- kubectl apply -f- <<EOF
- apiVersion: metaprotocol.aeraki.io/v1alpha1
- kind: MetaRouter
- metadata:
- name: test-metaprotocol-thrift-route
- namespace: meta-thrift
- spec:
- hosts:
- - thrift-sample-server.meta-thrift.svc.cluster.local
- localRateLimit:
- tokenBucket:
- fillInterval: 60s
- maxTokens: 2
- tokensPerFill: 2
- EOF
備注:因?yàn)楸镜叵蘖魇窃谝粋€(gè)服務(wù)實(shí)例上進(jìn)行處理的,因此當(dāng)服務(wù)有多個(gè)實(shí)例,實(shí)際的限流效果為限流數(shù)量乘以實(shí)例數(shù)量。
使用 aerakictl 命令來查看客戶端的應(yīng)用日志,可以看到客戶端每分鐘只能成功執(zhí)行 4 次請求(有兩個(gè)服務(wù)實(shí)例,每個(gè)服務(wù)實(shí)例限流為每分鐘 2 次):
- ➜ ~ aerakictl_app_log client meta-thrift -f --tail 10
- Hello Aeraki, response from thrift-sample-server-v1-5c8476684-842l6/172.17.0.40
- Hello Aeraki, response from thrift-sample-server-v2-6d5bcc885-hpx7n/172.17.0.41
- Hello Aeraki, response from thrift-sample-server-v1-5c8476684-842l6/172.17.0.40
- Hello Aeraki, response from thrift-sample-server-v2-6d5bcc885-hpx7n/172.17.0.41
- org.apache.thrift.TApplicationException: meta protocol local rate limit: request '5' has been rate limited
- at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:79)
- at org.aeraki.HelloService$Client.recv_sayHello(HelloService.java:61)
- at org.aeraki.HelloService$Client.sayHello(HelloService.java:48)
- at org.aeraki.HelloClient.main(HelloClient.java:44)
- Connected to thrift-sample-server
- org.apache.thrift.TApplicationException: meta protocol local rate limit: request '1' has been rate limited
- ...
按條件對服務(wù)的入向請求進(jìn)限流
Aeraki 支持按照條件為服務(wù)設(shè)置多個(gè)限流規(guī)則,以滿足細(xì)粒度的限流要求。例如按照用戶或者對接口對請求進(jìn)行分組,并對每個(gè)分組設(shè)置不同的限流規(guī)則。
分組限流的匹配條件和路由匹配條件相同,任何可以從請求數(shù)據(jù)包中提取出來的屬性都可以用于限流規(guī)則的匹配條件。
例如下面的規(guī)則為 sayHello 和 ping 兩個(gè)接口分別設(shè)置了不同的限流條件:
- apiVersion: metaprotocol.aeraki.io/v1alpha1
- kind: MetaRouter
- metadata:
- name: test-metaprotocol-thrift-route
- namespace: meta-thrift
- spec:
- hosts:
- - thrift-sample-server.meta-thrift.svc.cluster.local
- localRateLimit:
- conditions:
- - match:
- attributes:
- method:
- exact: sayHello
- tokenBucket:
- fillInterval: 60s
- maxTokens: 10
- tokensPerFill: 10
- - match:
- attributes:
- method:
- exact: ping
- tokenBucket:
- fillInterval: 60s
- maxTokens: 100
- tokensPerFill: 100
同時(shí)設(shè)置按服務(wù)和按條件的限流規(guī)則
可以同時(shí)設(shè)置服務(wù)粒度的限流規(guī)則和按照條件的限流規(guī)則,這適用于需要對一個(gè)服務(wù)的所有請求設(shè)置一個(gè)整體的限流規(guī)則,同時(shí)又需要對某一組或者幾組請求設(shè)置例外的情況。
例如下面的限流規(guī)則為服務(wù)設(shè)置了一個(gè) 1000 條/分鐘的整體限流規(guī)則,同時(shí)單獨(dú)為 ping 接口設(shè)置了 100 條/分鐘的限流條件。
- apiVersion: metaprotocol.aeraki.io/v1alpha1
- kind: MetaRouter
- metadata:
- name: test-metaprotocol-thrift-route
- namespace: meta-thrift
- spec:
- hosts:
- - thrift-sample-server.meta-thrift.svc.cluster.local
- localRateLimit:
- tokenBucket:
- fillInterval: 60s
- maxTokens: 1000
- tokensPerFill: 1000
- conditions:
- - match:
- attributes:
- method:
- exact: ping
- tokenBucket:
- fillInterval: 60s
- maxTokens: 100
- tokensPerFill: 100
理解原理
Aeraki 向 Sidecar Proxy 下發(fā)的配置中為服務(wù)對應(yīng)的 Listener 設(shè)置了 MetaProtocol Proxy,配置中設(shè)置了 local rate limit filter。
Aeraki 會將 MetaRouter 中配置的限流規(guī)則翻譯為local rate limit filter 的限流配置,通過 Aeraki 下發(fā)給 MetaProtocol Proxy。
可以通過下面的命令查看服務(wù)的 sidecar proxy 的配置:
- aerakictl_sidecar_config server-v1 meta-thrift |fx
其中 Thrift 服務(wù)的 Inbound Listener 中的 MetaProtocol Proxy 配置如下所示:
- {
- "name": "envoy.filters.network.meta_protocol_proxy",
- "typed_config": {
- "@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
- "type_url": "type.googleapis.com/aeraki.meta_protocol_proxy.v1alpha.MetaProtocolProxy",
- "value": {
- "stat_prefix": "inbound|9090||",
- "application_protocol": "thrift",
- "route_config": {
- "name": "inbound|9090||",
- "routes": [
- {
- "route": {
- "cluster": "inbound|9090||"
- }
- }
- ]
- },
- "codec": {
- "name": "aeraki.meta_protocol.codec.thrift"
- },
- "meta_protocol_filters": [
- {
- "name": "aeraki.meta_protocol.filters.local_ratelimit",
- "config": {
- "@type": "type.googleapis.com/aeraki.meta_protocol_proxy.filters.local_ratelimit.v1alpha.LocalRateLimit",
- "stat_prefix": "thrift-sample-server.meta-thrift.svc.cluster.local",
- "token_bucket": {
- "max_tokens": 2,
- "tokens_per_fill": 2,
- "fill_interval": "60s"
- }
- }
- },
- {
- "name": "aeraki.meta_protocol.filters.router"
- }
- ]
- }
- }
- }