在服务器端输出上禁用 gRPC 负载平衡

Posted

技术标签:

【中文标题】在服务器端输出上禁用 gRPC 负载平衡【英文标题】:Disabling gRPC load balancing on server side output 【发布时间】:2020-02-06 09:35:54 【问题描述】:

我的 gRPC 通信遇到问题。担心的是我需要保持事件的顺序。事件通过多个流发送,但仅来自一个线程。我需要在客户端保持该顺序,以使我的状态保持一致。

为了进行测试,我在 stream1 和 stream2 上交替发送消息(1 上的消息,2 上的消息,1 上的消息,等等)。

我可以通过修改执行器来禁用客户端的线程部分:

.withExecutor(new SerialExecutor(new DirectExecutor()));

class DirectExecutor implements Executor

  public void execute(Runnable r)
  
     r.run();
  


private class SerialExecutor implements Executor

  final Queue<Runnable> tasks = new ArrayDeque<>();
  final Executor executor;
  Runnable active;

  SerialExecutor(Executor executor)
  
     this.executor = executor;
  

  public synchronized void execute(Runnable r)
  
     tasks.add(() -> 
        try
        
           r.run();
         finally
        
           scheduleNext();
        
     );
     if (active == null)
     
        scheduleNext();
     
  

  protected synchronized void scheduleNext()
  
     if ((active = tasks.poll()) != null)
     
        executor.execute(active);
     
  

现在加载一点我的系统并再次检查后,我仍然遇到问题。我在 stream1 上随机收到 5 条消息,然后在 stream2 上收到 2 条消息,然后在 stream1 上收到 1 条消息,然后在 stream2 上收到 3 条消息,等等。

我的问题是:如何控制服务器以避免这种输出负载平衡?

在客户端我使用执行器修复了它,但我觉得它只用于接收。

【问题讨论】:

【参考方案1】:

http2 层不保证流间顺序。您最好的选择是客户端生成一个序列号,因此您可以在服务器端按顺序处理它。或使用单个流(可能不是一个选项)。

顺便说一句,负载平衡有特殊的含义。您的问题与负载平衡无关。

【讨论】:

以上是关于在服务器端输出上禁用 gRPC 负载平衡的主要内容,如果未能解决你的问题,请参考以下文章

GKE 上的 GRPC 负载平衡(在 L7、HTTP/2 + TLS 上)

初识gRPC

gRPC初体验

为 App Engine 负载平衡器创建后端服务

gRPC 发布 v1.32.0

如何在超过 2 台服务器的主动/被动模式下进行 tcp 负载平衡?