首页 > 解决方案 > 在服务器端输出上禁用 gRPC 负载平衡

问题描述

我的 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 条消息,等等。

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

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

标签: load-balancinggrpcgrpc-java

解决方案


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

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


推荐阅读