如何使用Envoy解决此节点亲缘关系

时间:2018-10-01 11:59:33

标签: load-balancing grpc envoyproxy

我提供的gRPC服务不幸的是必须在BeginTransactionCommit API调用之间具有节点亲缘关系。

消费者API调用顺序通常为:

  1. BeginTransaction()返回txnID
  2. DoStuff(txnID, moreParams...)
  3. DoStuff(txnID, moreParams...)
  4. ...
  5. Commit(txnID)

消费者可以是同时调用我的API的多线程进程,因此他们可能在任何时间点使用数百个事务。

如果我使用Envoy代理作为服务入口点,则应将BeginTransaction路由到群集中的任何运行正常的节点,但是必须确保将使用返回的txnID的后续调用路由到同一节点。

在我的情况下,可以在http标头中或在消息的任何部分中传递任何上下文信息。

1 个答案:

答案 0 :(得分:0)

使用Ring Hash平衡器取得了一些进步

在特使代理服务器中(查找“哈希”):

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 80
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: http2
          stat_prefix: ingress_http #just for statistics
          route_config:
            name: local_route
            virtual_hosts:
            - name: samplefront_virtualhost
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/mycompany.sample.v1"
                  grpc: {}
                route:
                  cluster: sampleserver
                  hash_policy:
                    header:
                      header_name: "x-session-hash"
              - match:
                  prefix: "/bbva.sample.admin"
                  grpc: {}
                route:
                  cluster: sampleadmin
          http_filters:
          - name: envoy.router
            config: {}
  clusters:
  - name: sampleserver
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: ring_hash
    http2_protocol_options: {}
    hosts:
    - socket_address:
        address: sampleserver
        port_value: 80 #Connect to the Sidecard Envoy
  - name: sampleadmin
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http2_protocol_options: {}
    hosts:
    - socket_address:
        address: sampleadmin
        port_value: 80 #Connect to the Sidecard Envoy
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001

在我的消费者中,我在BeginTransaction()之前创建了一个随机哈希,并确保每次都在x-session-hash标头中发送一次,直到Commit(txnId)

它可以工作,但是有一些限制:

当我扩展服务,添加更多节点时,某些操作会失败,并显示错误upstream connect error or disconnect/reset before headers。当一个节点丢失时,失败是绝对可以的,但是当添加一个节点时,它们几乎是不能接受的!好消息是两种情况下的负载都会重新平衡。

客户端必须在进行第一个调用(BeginTransaction)之前生成哈希,因此客户端会无意中指示哪个节点将参加此事务的请求。

我将继续调查。