searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

服务网格全局限流原理

2024-06-07 09:49:58
31
0

业务背景

什么是限流?限流主要作用是限制流量,防止因系统过载而崩溃。istio限流有两大类,一个是本地限流,另一个是全局限流。

限流按生效位置分可分为virtualhost级别的限流和route级别的限流;按协议分可分为http的限流和tcp的限流;按服务位置分可分为mesh内部限流和对外部请求的限流。

本地限流是在envoy内部(针对Pod)提供一种令牌桶限速的功能,全局限流需要访问外部限流服务(官方实现:envoyproxy/ratelimit)。

 

技术背景

全局限流架构

ratelimit 架构包含两部分,一部分是 Envoy 中 ratelimit filter,一部分是 ratelimit gRPC 服务。每次请求前会调用外部限流服务(传递domain和descriptor)决定是否对流量进行限制。

 

ratelimit filter 

其中,Envoy 中 ratelimit filter 又包含:配置 ratelimit service和启用 action filter。一个示例如下:

    patch:
        operation: INSERT_BEFORE
        # Adds the Envoy Rate Limit Filter in HTTP filter chain.
        value:
          name: envoy.filters.http.ratelimit
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
            # domain can be anything! Match it to the ratelimter service config
            domain: productpage-ratelimit
            # 如果调用限速服务发生错误或限速服务返回了一个错误,并且 failure_mode_deny 设置为 true,则返回 500 状态码
            failure_mode_deny: true
            timeout: 10s
            rate_limit_service:
              # 配置grpc外部限流服务
              grpc_service:
                envoy_grpc:
                  # ratelimit.bookinfo.svc.cluster.local要对应ratelimit服务的host:
                  # <service>.<namespace>.svc.cluster.local
                  cluster_name: outbound|8081||ratelimit.bookinfo.svc.cluster.local
                  authority: ratelimit.bookinfo.svc.cluster.local
              transport_api_version: V3
configPatches:
    - applyTo: VIRTUAL_HOST
      match:
        context: GATEWAY
        routeConfiguration:
          vhost:
            # 给80端口的虚拟主机配置一个rate_limits 动作
            name: "*:80"
            route:
              action: ANY
      patch:
        operation: MERGE
        # Applies the rate limit rules.
        value:
          rate_limits:
            - actions: # any actions in here
              - request_headers:  # ("<descriptor_key>", "<header_value_queried_from_header>")
                  header_name: ":path"
                  # descriptor_key用于选择在configmap里配置的key
                  descriptor_key: "PATH"

action支持:

{
  "source_cluster": "{...}",源集群动作
  "destination_cluster": "{...}",目标集群动作
  "request_headers": "{...}",请求头动作
  "remote_address": "{...}",远程地址动作
  "generic_key": "{...}",通用key动作
  "header_value_match": "{...}",头匹配动作
  "dynamic_metadata": "{...}",动态元数据动作
  "metadata": "{...}",元数据动作
  "extension": "{...}",扩展动作
  "masked_remote_address": "{...}",ip地址mask动作
  "query_parameter_value_match": "{...}",查询参数动作
}

ratelimit service 

Envoy对ratelimit service的client和server的规定请见ratelimit  service v3

RateLimitServiceClient 的定义如下:

// RateLimitServiceClient is the client API for RateLimitService service.
//
type RateLimitServiceClient interface {
	// Determine whether rate limiting should take place.
	ShouldRateLimit(ctx context.Context, in *RateLimitRequest, opts ...grpc.CallOption) (*RateLimitResponse, error)
}

ratelimit service client 定义了 ShouldRateLimit 方法,而该方法将调用 ratelimit service server 的 ShouldRateLimit 方法:

func (c *rateLimitServiceClient) ShouldRateLimit(ctx context.Context, in *RateLimitRequest, opts ...grpc.CallOption) (*RateLimitResponse, error) {
	out := new(RateLimitResponse)
	err := c.cc.Invoke(ctx, "/envoy.service.ratelimit.v3.RateLimitService/ShouldRateLimit", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

RateLimitServiceServer 的定义如下:

// RateLimitServiceServer is the server API for RateLimitService service.
type RateLimitServiceServer interface {
	// Determine whether rate limiting should take place.
	ShouldRateLimit(context.Context, *RateLimitRequest) (*RateLimitResponse, error)
}

RateLimitServiceServer 注册函数如下:

func RegisterRateLimitServiceServer(s *grpc.Server, srv RateLimitServiceServer) {
	s.RegisterService(&_RateLimitService_serviceDesc, srv)
}

 

官方限流服务

 

envoyproxy/ratelimit 是一个官方提供的Go/gRPC 服务,旨在为各种应用程序提供通用速率限制方案。应用程序根据 domain 和一组 descriptor 向 ratelimit 服务请求限速决定(限速或不限速)。

ratelimit 服务读取配置内容(监听磁盘目录),根据配置文件内容组成一个 cacheKey,并且通过该 cacheKey 访问 Redis 缓存,最后返回一个限速决定到调用方,支持每秒、每分、每小时或者每天限速

0条评论
0 / 1000
x****n
4文章数
1粉丝数
x****n
4 文章 | 1 粉丝
原创

服务网格全局限流原理

2024-06-07 09:49:58
31
0

业务背景

什么是限流?限流主要作用是限制流量,防止因系统过载而崩溃。istio限流有两大类,一个是本地限流,另一个是全局限流。

限流按生效位置分可分为virtualhost级别的限流和route级别的限流;按协议分可分为http的限流和tcp的限流;按服务位置分可分为mesh内部限流和对外部请求的限流。

本地限流是在envoy内部(针对Pod)提供一种令牌桶限速的功能,全局限流需要访问外部限流服务(官方实现:envoyproxy/ratelimit)。

 

技术背景

全局限流架构

ratelimit 架构包含两部分,一部分是 Envoy 中 ratelimit filter,一部分是 ratelimit gRPC 服务。每次请求前会调用外部限流服务(传递domain和descriptor)决定是否对流量进行限制。

 

ratelimit filter 

其中,Envoy 中 ratelimit filter 又包含:配置 ratelimit service和启用 action filter。一个示例如下:

    patch:
        operation: INSERT_BEFORE
        # Adds the Envoy Rate Limit Filter in HTTP filter chain.
        value:
          name: envoy.filters.http.ratelimit
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
            # domain can be anything! Match it to the ratelimter service config
            domain: productpage-ratelimit
            # 如果调用限速服务发生错误或限速服务返回了一个错误,并且 failure_mode_deny 设置为 true,则返回 500 状态码
            failure_mode_deny: true
            timeout: 10s
            rate_limit_service:
              # 配置grpc外部限流服务
              grpc_service:
                envoy_grpc:
                  # ratelimit.bookinfo.svc.cluster.local要对应ratelimit服务的host:
                  # <service>.<namespace>.svc.cluster.local
                  cluster_name: outbound|8081||ratelimit.bookinfo.svc.cluster.local
                  authority: ratelimit.bookinfo.svc.cluster.local
              transport_api_version: V3
configPatches:
    - applyTo: VIRTUAL_HOST
      match:
        context: GATEWAY
        routeConfiguration:
          vhost:
            # 给80端口的虚拟主机配置一个rate_limits 动作
            name: "*:80"
            route:
              action: ANY
      patch:
        operation: MERGE
        # Applies the rate limit rules.
        value:
          rate_limits:
            - actions: # any actions in here
              - request_headers:  # ("<descriptor_key>", "<header_value_queried_from_header>")
                  header_name: ":path"
                  # descriptor_key用于选择在configmap里配置的key
                  descriptor_key: "PATH"

action支持:

{
  "source_cluster": "{...}",源集群动作
  "destination_cluster": "{...}",目标集群动作
  "request_headers": "{...}",请求头动作
  "remote_address": "{...}",远程地址动作
  "generic_key": "{...}",通用key动作
  "header_value_match": "{...}",头匹配动作
  "dynamic_metadata": "{...}",动态元数据动作
  "metadata": "{...}",元数据动作
  "extension": "{...}",扩展动作
  "masked_remote_address": "{...}",ip地址mask动作
  "query_parameter_value_match": "{...}",查询参数动作
}

ratelimit service 

Envoy对ratelimit service的client和server的规定请见ratelimit  service v3

RateLimitServiceClient 的定义如下:

// RateLimitServiceClient is the client API for RateLimitService service.
//
type RateLimitServiceClient interface {
	// Determine whether rate limiting should take place.
	ShouldRateLimit(ctx context.Context, in *RateLimitRequest, opts ...grpc.CallOption) (*RateLimitResponse, error)
}

ratelimit service client 定义了 ShouldRateLimit 方法,而该方法将调用 ratelimit service server 的 ShouldRateLimit 方法:

func (c *rateLimitServiceClient) ShouldRateLimit(ctx context.Context, in *RateLimitRequest, opts ...grpc.CallOption) (*RateLimitResponse, error) {
	out := new(RateLimitResponse)
	err := c.cc.Invoke(ctx, "/envoy.service.ratelimit.v3.RateLimitService/ShouldRateLimit", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

RateLimitServiceServer 的定义如下:

// RateLimitServiceServer is the server API for RateLimitService service.
type RateLimitServiceServer interface {
	// Determine whether rate limiting should take place.
	ShouldRateLimit(context.Context, *RateLimitRequest) (*RateLimitResponse, error)
}

RateLimitServiceServer 注册函数如下:

func RegisterRateLimitServiceServer(s *grpc.Server, srv RateLimitServiceServer) {
	s.RegisterService(&_RateLimitService_serviceDesc, srv)
}

 

官方限流服务

 

envoyproxy/ratelimit 是一个官方提供的Go/gRPC 服务,旨在为各种应用程序提供通用速率限制方案。应用程序根据 domain 和一组 descriptor 向 ratelimit 服务请求限速决定(限速或不限速)。

ratelimit 服务读取配置内容(监听磁盘目录),根据配置文件内容组成一个 cacheKey,并且通过该 cacheKey 访问 Redis 缓存,最后返回一个限速决定到调用方,支持每秒、每分、每小时或者每天限速

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
0