新手问题 Dropbox Bandaid 微服务反向代理/Sevice Mesh 代理解析

AlexaMa · 2018年03月28日 · 18 次阅读

随着微服务架构以及的广泛普及,很多公司都会使用或者自行开发自己的 API Gateway, 甚至在内部服务也会应用Service Mesh.

不久前,看到了一篇 Dropbox 公司介绍其内部服务代理 Bandaid 的文章: Meet Bandaid, the Dropbox service proxy. 不得不说设计细节一贯独角兽风格,非常有收获,对于改进我们自己设计的 proxy 也有一定参考意义。这里做一个简单的读后笔记。英语好的同学可以直接阅读原文。(插一句,Dropbox 不久前在美股上市了,在中美贸易战中为数不多逆势上涨的股票之一,玩美股的同学可以关注一下。再插一句:股市有风险,投资须谨慎。)

Bandaid 诞生的背景

Bandaid 是有公司内部的反向代理服务演变而来,使用 Golang 实现。反向代理有很多成熟的解决方案,之所以选择自行开发主要有以下几个原因:

  • 更好的与与内部的基础设施集成
  • 可以复用公司内部基础库(更好的与内部代码集成)
  • 减少对外部的依赖,团队可以灵活的按需开发
  • 更适合公司内某些特殊使用场景

上面的大部分因素根我们进行微服务组件开发时候的考量基本一致。这也是我们当初没有使用Go kit 这种工具套装进行架构微服务改造的顾虑,当然,那个时候还没有这些工具链。

Bandaid 的特性

  • 支持多种负载均衡策略 (round-robin, least N random choices, absolute least connection, pinning peer)
  • 支持 https to http
  • 上下游支持 http2
  • 路由改写
  • 缓存请求与响应
  • host 级别的逻辑隔离
  • 配置热加载
  • 服务发现
  • 路由信息统计
  • 支持 gRPC 代理
  • 支持 HTTP/gRPC 健康检查
  • 流量支持按权重分配和金丝雀测试

丰富的负载均衡策略,以及对 HTTP/2 和 gRPC 的支持实例亮点。要知道,nginx 从 1.13.10 才开始支持 gRPC.

另一方面,从支持的特性看,如果要求不是特别多,直接用来作为 Service Mesh 也是相当不错的。而且由于是使用 Go 开发,对于本来就在使用 Go 作为技术栈的团队来说,无论是使用还是二次开发,门槛和学习成本都是很低的。

Bandaid 设计解析

整体架构

请求队列设计

接收的请求按照LIFO 后入先出的方式进行处理。这个设计有点反直觉,但却是合理的:

  • 绝大部分情况下,队列应该是空或者接近空的状态。因此 LIFO 的策略并不会恶化队列最大等待时间。
  • 根据业务类型,可以配置队列的优先级和长度。可以非常方便的实现服务限流、服务降级和熔断器。
  • Bandaid 采用总是接收 TCP 连接,并将连接交由用户态管理的策略。结合 LIFO 有一个很大的好处:

    • 与内核态管理连接比较,如果客户端发送请求后意外关闭了 TCP 连接,Bandaid 是无法马上获取到该错误的,需要等到读取完该请求,然后处理请求后开始写 response 时才会触发错误,发现这个连接其实已经关闭。因此,处理这类请求是在无谓的消耗服务器资源。而采用 LIFO 和用户态管理连接的话,Bandaid 可以根据配置的超时策略,一定程度上 drop 掉这类请求,减少处理这种「dead request」的数量。

Worker 设计

Worker 采取固定大小的工作池设计,一方面可以精确的控制并发数量,另一方面,也避免频繁创建 worker 的开销。不过文中也承认,池的大小在设置的时候需要结合业务考虑清楚,否则可能不能充分利用服务器资源,错误的触发服务降级。

worker 在处理队列中的请求时,支持按照优先和权重处理。因此,可以非常容易的实现金丝雀发布和逻辑上的 upstream 隔离。

负载均衡策略

  • RR, 均匀撒胡椒面。优点是足够简单,缺点是没有考虑不同后端服务实例的数量和接口处理时长差异,会导致大量 Bandaid 服务资源被极少数的慢服务和接口消耗掉。
  • least N random choices: 先随机选择 N 个候选 upstream host, 然后选择连接数最少的 host (认为是当前负载最低的) 作为最终目标 host.

这种方式在在大部分时候可以工作得很好,但对于那种快速失败的小服务会失效。因为这种服务有很大概率被选中,但是并不意味着其当前负载较低。缓解该策略的方式是absolute least connection.

  • absolute least connection: 从全局 host 中选择连接数最少的 host 作为目标 host.

  • pinning peer: 将 worker 与 host 绑定。这种方式可以避免慢服务过量消耗 Bandaid 资源的问题,但是请求调度不够灵活。

总结

从 Bandaid 的设计看,无论是作为 reverse proxy 还是 service mesh 都有不错的潜力。不过 Dropbox 团队当前还没有公开 Bandaid 性能测试数据,代码也还没有开源。因此,猴急的同学可能还需要等一段时间。

Originnaly published on liudanking.com

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册