【问题标题】:Vert.x: How to process event sequences in whole worker thread poolVert.x:如何处理整个工作线程池中的事件序列
【发布时间】:2020-09-15 00:31:18
【问题描述】:

我的问题是:

如果我在事件循环线程中收到多个事件序列,我如何处理每个序列阻塞和有序但不同的序列由整个工作线程池处理。

用例:

我在 vert.x 中有一个 gRPC 客户端,它有 4 个事件循环和 20 个工作线程。我在 10 个线程中开始远程调用。

  • 每次调用都会收到 2 个事件 StreamObserver.onNextStreamObserver.onCompleted
  • 在每个此类事件中,我都希望以这样的方式开始阻塞任务,即 gRPC 调用 onNextonClose 是有序的,而对于不同的 gRPC 调用,事件在 不同的工作线程。

目标是将调用执行分配给尽可能多的工作线程,但要对单个调用的事件进行排序。

  • 如果我使用 executeBlocking 和有序 true - 它们将在每个事件线程的工作线程中执行。
  • 如果 false - 处理 onNextonClose 将没有顺序。

【问题讨论】:

    标签: vert.x


    【解决方案1】:

    我认为这对 Kafka 来说是一个很好的用例。

    您可以继续使用工作池,每个线程创建和侦听 kafka 的消费者。除了工作池,您还可以在同一个 java 进程甚至多个 jvm 实例(甚至容器,为什么不 :p )中实例化多个 Verticle。我更喜欢第二种方法来处理事件驱动和分布式架构中的动态可伸缩性(我在this answer 中写了更多详细信息)。

    无论哪种方式,所有消费者都需要以相同的group.id 实例化才能成为同一消费者组的一部分。这样kafka就可以将topic的partition分配给每个group的成员(单个partition不能被两个成员同时读取)。

    最后,为了能够创建“事件序列”,您只需要在 kafka 主题中使用定义您的序列的分布键生成事件(使用相同分布键生成的两条消息将存储在同一个分区并将被组的同一消费者读取)。

    【讨论】:

    • 我有一个简单的用例——在事件循环之外以半有序的方式处理 gRPC 调用(客户端和服务器之间的轻量级通信)。在他们之间放一个卡夫卡对我来说似乎有点矫枉过正。而且这个问题更笼统 - 如何有效地使用 vert.x 工作池(没有任何外部)/何时完全排序或缺少排序都不合适。
    • @AvgustinMarinov 在这种情况下,我认为您将不得不重新发明轮子,例如广播事件并检查您的听众是否可以处理该事件,因为它是来自新序列的事件或者来自同一个监听器启动的序列(例如,使用数据库或分布式缓存让所有监听器都知道序列的归属)。在这种情况下,也许您会认为 redis 不会那么矫枉过正?
    • 我宁愿考虑“以某种方式”获取一组不同的 Vert/x 上下文(绑定到每个工作线程)的可能性,将这样一个上下文(即它的工作线程)分配给每个序列并执行每个序列在其上下文中排序。因此,我将有效地获得每个序列的顺序处理(它在一个有序的工作线程中处理)并充分使用工作线程池 - 通过使用使用所有工作线程的所有上下文。当前的问题是我不知道(或 Vert.x 不允许)如何获取这样的上下文集 - n 个上下文绑定到 n 个工作线程
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多