Uber工程团队宣布将uForwarder这一基于推送机制的Apache Kafka消费者代理工具开源发布。该工具旨在提升分布式微服务环境中高吞吐量事件流处理的可扩展性、效率以及运营管控能力。uForwarder作为Kafka与消费者服务之间的中间层,用基于gRPC的推送接口取代了传统的直接消费者客户端实现方式。这一系统的设计目的是简化消费者服务的逻辑处理、集中管理消息偏移量、隔离不同的工作负载,并为事件队列提供内置的延迟处理功能。
开发uForwarder的初衷源于Uber内部的Kafka部署环境——该环境需要支持超过1,000个下游消费者服务,每天要处理数万亿条消息以及数PB级别的数据。在如此大规模的应用场景下,标准的Kafka消费者组存在诸多局限性,比如分区管理复杂、不同服务之间语言支持不一致,以及运营开销较高。直接使用消费者客户端会导致每个服务都必须自行实现偏移量处理、重试机制和延迟控制功能,从而增加系统出现头部阻塞现象的可能性,也会降低资源利用效率。
高级消费者代理架构图(来源:Uber官方博客文章)
之前开发的内部消费者代理工具存在四个主要问题:当消息因数据量限制或服务实例异常而无法成功传递时,顺序处理分区的机制会导致系统停滞,从而引发头部阻塞现象;部署数千台代理服务器来为消费者服务提供支持是一种效率低下的方案,因为硬件资源会被不均匀地消耗掉;许多消费者服务还会自行实现复杂的延迟处理逻辑,进一步增加了系统的复杂性;在生产环境与非生产环境之间,或在不同地区之间隔离工作负载时,要么需要为每个主题创建额外的副本,要么就需要采用复杂的负载均衡配置。
uForwarder通过引入基于上下文的路由机制,有效提升了工作负载的隔离能力及消息传递的准确性。Kafka消息头会携带路由相关元数据,这些信息会在后续的gRPC调用中被传递下去,从而使得基础设施层面能够做出相应的决策,而无需应用程序进行额外的过滤操作。负载均衡器会根据地区、租户或环境等因素,仅将事件发送给对应的消费者实例,这样既能避免不必要的网络流量,也能简化消费者的逻辑处理流程。
具有上下文感知能力的路由功能(来源:Uber博客文章)
乱序提交跟踪机制通过防止分区阻塞来强化偏移量管理。该机制能够独立监控提交的进展,并根据预设的阈值检测出出现问题的偏移量。当遇到问题时,相关消息会被重定向到死信队列中;同时,提交指针会继续向前移动,从而避免出现头部阻塞的情况,确保各个分区之间的吞吐量保持稳定。
消费者自动均衡器会持续监测各个工作节点的CPU使用率、内存压力以及吞吐量情况。根据实时收集到的数据,它会重新分配分区以平衡负载。在流量突然增加时,该机制能够迅速扩展资源规模,从而减少延迟;而在流量下降时,则会逐渐缩减资源占用,防止系统出现不稳定现象,进而提升整体资源利用率和性能稳定性。
DelayProcessManager实现了对分区级别的暂停与恢复控制功能,这使得系统能够更精细地处理背压问题。当某些依赖项无法获取或受到速率限制时,只有被阻塞的分区会被暂存起来,而其他分区则可以继续正常运行。这样一来,既能保证吞吐量不受影响,又能减少整个系统的整体延迟,同时还能简化服务内部的延迟处理流程。
消费者代理工作线程中的延迟处理机制(来源:Uber博客文章)
Uber表示,uForwarder已经成为其内部使用的主要Kafka消费者工具,而现在它也已经作为一个开源项目在GitHub上发布了。这种架构能够提高工作负载的隔离性,减少消费者的延迟现象,并更高效地利用硬件资源,同时还能简化微服务中的消费者逻辑。开发团队正在扩大队列的容量,并通过将偏移量回放到最新位置来解决延迟问题;同时还会使用额外的消费者线程来处理那些被延迟的数据。此外,原生Protobuf支持也被添加进来,以便各种服务能够直接接收结构化消息。