<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>LB on 涯余的博客</title><link>https://hangyan.github.io/tags/lb/</link><description>Recent content in LB on 涯余的博客</description><generator>Hugo</generator><language>zh</language><managingEditor>hang.yan@hotmail.com (涯余)</managingEditor><webMaster>hang.yan@hotmail.com (涯余)</webMaster><lastBuildDate>Mon, 18 Jan 2021 13:33:12 +0800</lastBuildDate><atom:link href="https://hangyan.github.io/tags/lb/index.xml" rel="self" type="application/rss+xml"/><item><title>LB系列1 - Bandaid</title><link>https://hangyan.github.io/post/2021-lb-1-bandaid/</link><pubDate>Mon, 18 Jan 2021 13:33:12 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2021-lb-1-bandaid/</guid><description>&lt;p&gt;很多大厂的LB都是自研的，而且设计考量都不相同。本文介绍 Dropbox自研的LB，名字叫 Bandaid.参考链接: &lt;a href="https://dropbox.tech/infrastructure/meet-bandaid-the-dropbox-service-proxy"&gt;Meet Bandaid, the Dropbox service proxy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="queue设计"&gt;Queue设计&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://dropbox.tech/cms/content/dam/dropbox/tech-blog/en-us/2018/03/1st.png"&gt;&lt;/p&gt;
&lt;p&gt;Bandaid 处理 Queue 中的 Request 的思路是后近先出(Last in, First out)。当系统负载不高的时候，Queue中的数据其实不多，那么先进后出或者后进先出其实区别不大。如果负载过高，考虑到先进的排队太久，可能很快就timeout了，还不如优先处理后进来的 request.&lt;/p&gt;
&lt;h2 id="user-space的-read-queue"&gt;User Space的 Read Queue&lt;/h2&gt;
&lt;p&gt;Read Requests 会被放到一个用户态的 Queue 中，而不是 kernel 里的 queue中。这样做的原因是， 可以在用户态提前关闭已经被 client close的 request, 而不是等到真正的request经由 kernel, 然后 application 在处理的时候才发现 request 已经 close 了。尤其是 client 一般还带有重试，很容易把 Kernel queue打满。User Space 的 Queue 能够通过处理只把正常的 request 传给后面。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://dropbox.tech/cms/content/dam/dropbox/tech-blog/en-us/2018/03/2nd.png"&gt;&lt;/p&gt;
&lt;h2 id="权重以及-route划分"&gt;权重以及 Route划分&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://dropbox.tech/cms/content/dam/dropbox/tech-blog/en-us/2018/03/4th.png"&gt;&lt;/p&gt;
&lt;p&gt;精细程度可以做到按照 Route 将一个 Service 的重要的 Route 以及不重要的 Route 按权重定向到不同的 Backend上。不同的 Queue 可以有不同的权重，rate limit, 并发度。&lt;/p&gt;</description></item><item><title>Linkerd系列1 - Linkerd2-proxy</title><link>https://hangyan.github.io/post/2020-11-17-linkerd2-proxy/</link><pubDate>Tue, 17 Nov 2020 18:48:42 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2020-11-17-linkerd2-proxy/</guid><description>&lt;p&gt;ServiceMesh这块属于 k8s 的一个大热门，但据我所知，落地的并不是太多。看文章大概理解为 overhead 以及部署都比较重，对一般的企业来讲，要考虑的东西比较多，所以落地难度比较大。有的建议是说，先上 envoy，其他的先搁置，这也是个思路。envoy 轻量级一些，可以先作为一个 proxy 去体验一下 ServiceMesh 架构下的 proxy 设计。然后再逐步看看怎么引入 ServiceMesh.&lt;/p&gt;
&lt;p&gt;另一个方面，Istio vs Linkerd 应该还没完全分出胜负，对于企业的选型来说，仍然是个难点。好处是，我们可以去对比二者在各个功能点上的设计思路差异，然后加深理解。在 ServiceMesh 的组件中，毫无疑问 proxy 是核心组件之一。linkderd 的 linkderd2-proxy 也是一个经过深思熟虑并且设计良好的组件，可以作为切入点研究下 linkderd 的整体设计。&lt;/p&gt;
&lt;h2 id="语言选型"&gt;语言选型&lt;/h2&gt;
&lt;p&gt;envoy 是 C++ 写的，而 linkderd2-proxy 是 Rust. 语言的选型不仅对于实现者来说很重要，对于用户来说也是。想一下 marathon 用的 scala 以及它的失败就知道了。为什么选 Rust, 这跟它最开始的目标有关&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;资源占用低。因为 ServiceMesh 场景下的 proxy, 经常是以 sidecar 方式挂载在业务组件的 Pod 里，所以一定不能有太多的资源占用。&lt;/li&gt;
&lt;li&gt;延迟低。因为要转发所有的请求，不能有太多的 overhead.&lt;/li&gt;
&lt;li&gt;安全。同上，因为要转发所有的请求，如果 proxy 本身有安全漏洞，那就影响太大了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为 linkderd2-proxy 主要的设计思路是简单，只定义为 ServiceMesh 场景，那么上面几个条件几乎都是硬性的，符合上面几个条件的语言基本上就只有 Rust了。因为上面几个条件意味着:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不能有GC. GC会带来 worst case tail latency。Go/Java不符合&lt;/li&gt;
&lt;li&gt;不能太重了。JVM再经过调优也不符合。linkderd2-proxy第一版就是用 Scala 写的，被抛弃了。&lt;/li&gt;
&lt;li&gt;有内存安全保障。C/C++不符合。历史经验表明，很多组件一大半的安全漏洞都是跟内存安全有关的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="自动协议检测及-mtls"&gt;自动协议检测及 mTLS&lt;/h2&gt;
&lt;p&gt;这点跟 envoy 的差别也比较大。envoy 的配置文件上来一看还是挺吓人的，虽然可维护性更好。而linkderd2-proxy的设计思路是尽可能的少配置，基本上能做到插入即用，不需要额外配置什么。&lt;/p&gt;</description></item></channel></rss>