跳到主要内容

精益分析中的良好指标

· 阅读需 3 分钟

每位有抱负的企业家都应该时刻警惕构建没人想要的东西这一致命陷阱。这就是为什么正确的分析变得如此必要。书籍《精益分析》为初创企业创始人提供了良好的指标,以帮助他们在未知中导航并评估他们的成功。

朝着正确方向的数据驱动

数据对商业至关重要。企业家需要数据来说服他人相信他们的想法是可行的。有时,企业家倾向于高估他们的成功,但数据不会说谎。数据帮助创始人保持对现实的清醒认识。然而,个人对追求何种数据的判断也很重要。不要仅仅成为数字的奴隶。

什么是良好的指标?

为了保持数据驱动,您需要找到一些能够提供有意义数据的指标。良好的指标具有三个特征:

  • 可比较:良好的指标可以与不同的时间段、消费者群体等进行比较
  • 易懂:良好的指标简单易懂
  • 比率:比率有效且可比较

精益分析框架的五个不同阶段

精益分析框架建议初创企业将经历五个阶段:

  • 同理心 — 识别人们的需求 / 确定您的细分市场
  • 粘性 — 找出如何用产品满足需求
  • 病毒传播 — 添加吸引人的功能
  • 收入 — 企业开始增长并产生收入
  • 扩展 — 扩展或进入新市场

专注于一个指标

为了取得成功,创始人必须专注于一个最关键的指标。了解最重要的指标可以防止您在数据的海洋中迷失方向。

最佳指标是什么?

一般来说,没有最佳指标。在不同的行业中,最佳指标各不相同。对于电子商务公司来说,最重要的指标是每位客户的收入。然而,对于媒体网站来说,最佳指标是点击率。

从 Uber 裁员谈到:造轮子,要还是不要?

· 阅读需 6 分钟

Uber 在 2014 至 2018 年间造了不少的轮子,比如服务发现的 Hyperbahn, 任务队列 Cherami, 基于 MySQL 的 NoSQL Schemaless, 资源调度器 Peloton, 服务部署平台 uDeploy 等等。如今 Uber 裁员甚至裁到了工程团队上,股价低于15年的估值,到底造这些轮子是功是过?创业公司应该招人造轮子还是应该拿来主义?

管理是个金字塔,花花轿子人抬人,人是靠人顶上去的,任何管理者的政治素养第一课就是把手下的人招的多多的。招大量的工程师在 VC 投钱的公司来讲也是一个有意思的指标,因为投资者不懂技术,而认为人头数多的公司自然发展的更好。

所以很多人都有为自己多招人的动机,而如何衡量这个动机的正当性呢?这个对于机械性的工作,比如在工厂,是比较简单的,因为产出是直接可衡量的;而脑力工作则不好说,尤其是写代码这种事情。比尔盖茨说,靠代码行数来衡量开发进度,就像是凭重量来衡量飞机制造的进度。我甚至听说,谷歌有专门的组来计算每个组对于公司的贡献程度。

管理者喜欢招人,工程师喜欢造轮子。一方面,创造者天生享受创造的乐趣;另一方面,工程师可能会有要不得的 ego 觉得,如果用别人的技术,岂不是显得我的技术不行。管理者提供“想要什么”,工程师提供“想做什么”,做出来的东西是这两种力量产生的结果。

比如,老牌零售公司请了来自硅谷的新 CTO,新 CTO 招大量 Engineer 做项目,并坚称一旦找到了好的人才,就能够带来有用的项目。他还想要把一些内部软件打包卖服务,尽管这些服务还是跑在一个大型主机上。CTO 还真信这一套。这里的关键问题是,做这些事情到底有没有 ROI (投资回报)?

如果 ROI 没法预先知道,那么如何有效地平衡按需招人和浪费资源呢?答案是注重“打造用于概念验证的原型产品 (POCs)”。用最小的投入来试水,管用就多招人,不管用就不招人。

如果 ROI 能够预先知道,那么答案就是一个简单的算术题。比如 HipChat 每个人每月收 $5, 然后 Uber 有 6 万全职员工和合同工,那么一个月的服务需要花 30 万,而招一个工程师去拿开源的 Mattermost 来魔改的话,每个月只需要付 3 万。那么"自己造轮子"省钱能省到大概是原来的五分之一到十分之一。

也有造了很多轮子,同时又发展得特别好的公司,在其中强力的管理和工程文化起到了很重要的作用,他们推崇简单至上和技术责任感。如果外部现成的轮子功能专一、方案成熟,他们会拿来即用;如果外部现成的轮子什么都做、复杂不可控,他们会自己造轮子。我记得当初 Uber 没有第一时间采用 Cassandra 的一个重大原因就是公司里面没有 Apache Cassandra 的内部人士,技术不可控。

简单至上四字箴言与注重细节并不冲突。比如你可以先选择昂贵笨重的来自微软、SAP 甚至甲骨文的 ERP,然后在跟你业务结合紧密不得不做特殊处理的地方,自己写一些服务,但是要保证服务短小精悍易于维护。而那些新一代的创业公司做 ERP 的时候不注重细节,连最重要的“审计”功能,比如会计里面的复式记账,都做不好,是他们失败的重要原因。

查尔斯·汉迪:第二曲线

· 阅读需 2 分钟

当你知道你应该去哪里时,去那里已经太晚;如果你总是坚持原来的道路,你将错过通往未来的路。

查尔斯·汉迪用他去达维酒吧的路做了一个类比。在距离达维酒吧还有半英里时,向右转并上山。然而,当他意识到自己走错了路时,他已经到达了达维酒吧。

增长曲线通常呈“S”形,我们称之为S曲线或 sigmoid 曲线。为了保持整体增长率高,你必须在投资时间和资源之前发展你的第二条S曲线,以免为时已晚。

英特尔的CPU、Netflix的视频流、任天堂的游戏、微软的云计算都是推动第二曲线业务的优秀例子。

如何找到并抓住第二曲线需要远见和执行力。你必须输入更多信息并不断整理,以识别最佳机会。然后,一旦识别出机会,你需要一个可靠的团队来打这场战斗,并弄清楚它是否真的有效。

让你成功的因素可能不会让你再次成功。增长总是有一个限制。第二曲线理论帮助我们反思为什么以及如何拥抱变化,过上更繁荣的生活。

查尔斯·汉迪: 第二曲线

· 阅读需 2 分钟

当你知道该往哪走的时候,往往已经太迟了;如果你总是坚持最初的道路,你会错失通向未来的道路。

查尔斯·汉迪是通过"戴维酒吧"类比的:在通往"戴维酒吧"的路上,距离它还有半英里的时候向右转上山。然而,当他意识到走错路的时候,他已经到了"戴维酒吧"。

增长曲线通常是 S 形的,我们称之为 S 曲线。为了让增长率能够一直高涨,你必须在还来得及的时候,投入时间和资源,发展出第二条 S 曲线。

英特尔的 CPU,奈飞的视频流,任天堂的游戏,微软的云,都是这种第二曲线驱动的业务的绝佳例子。

怎样才能发现和把握第二曲线呢?你得输入更多信息,辨别好坏,甄别机会。然后一旦机会出现,有一个强有力的团队打硬仗,才能回答是否真的找到了第二曲线。

过去让你成功的原因也许不会让你在将来再次成功,增长总是有极限。第二曲线理论帮助我们反思为什么以及如何拥抱变化过更好的人生。

增长失败的十大原因

· 阅读需 4 分钟

Facebook 的增长 VP Alex Schultz 曾经跟 Mark Zuckerberg 讨论为什么他们会成功。答案不是因为他们绝顶聪明,也不是因为他们经验丰富,而是因为他们非常努力,执行力超强。与执行力比起来,增长反而是可有可无的。因为道理大家都懂,差别就是人有没有快速执行。

执行是一件很难的事情,增长执行失败有十大原因。

  1. 没有从注重留存开始。没有留存的增长就像是麦田的火环,总会被烧完。增长没有留存就没有 PMF。达到PMF的标志是 cohort analysis 的留存率曲线最后是平的。

  2. 认为产品就是一切。基于这个错误的观念,==人们会错误地倾向于“做更多”的产品,而不是把现有的产品“做更好”。而增长是一个“做更好”的过程。== builder 喜欢造新东西,但是你作为领导要确保他们能够至少一部分地为结果负责。

  3. 想要找到银弹。好的产品是花时间花精力在细节上打磨出来的,不是变戏法变出来的。好点子是点子多的副产品,你没法控制找到好点子的结果,但是你构建一个能够让更多好点子冒出来的流程。

  4. 不够专注。见人就砍,而不是先砍死一个再砍一个。怎样突破这里的门槛效应?记住两点1)大多数的公司的主要规模来自于单一渠道2)规模化就那几种方法,选一个。

  5. 数据不够,分析不够。这里的难点是很难量化数据分析的产出,所以你要坚信这件事情是非常有价值的,它能够让你做正确的选择。

  6. 实验不够,远远不够。Hubspot 半年跑了上千个实验。

  7. 不问为什么。一个实验结束效果不好就换下一个,没有问为什么。

  8. 有了成效不加注 (double down)。如果你发现某个渠道效果非常好,还没有用到尽头,要继续投入。Zynga 发现一个游戏中的虚拟礼物非常挣钱病毒营销效果非常好,就立马把这个功能加到所有游戏中。

  9. 资源投入不够。增长需要专门的组来做。

  10. 没法拥抱变化。公司的增长通常会经历三个阶段:Traction, transition, growth 一个阶段的原因不会帮助你在下一个阶段成功。

服务一亿美元生意的四合增长模型

· 阅读需 3 分钟

问题:对于 Hubspot 的 freemium 和流程全自动 (touchless) 的软件生意,如何在 VC-backed 的情况下用最少的时间获得最高的增长?

解决方案:四合模型,造就公司成长有四个相关元素:产品、市场、渠道、模式。作者认为这四个因素是联动的,必须要相互配合。

PMF:产品与市场要匹配。世界上有两种公司:顺风公司和逆风公司,区别是 PMF。所谓找到了 PMF,就是指你的产品有一群人随着时间迁移反复使用,反复使用产生的利润足够支撑你继续增长;就是指你的产品有粘住的用户,使得你的留存率曲线虽然随着时间掉下来,但是最后趋势还是平的。

PCF:产品与渠道要匹配。产品本身的属性决定用什么渠道推广好。简单普世的产品对应大众便宜的渠道,复杂晦涩的产品对应领域特殊的渠道。

CMF: 获客与商业模式要匹配。在ARPU ↔ CAC光谱上,高 ARPU 对应高 CVC;低 ARPU 对应低 CVC。怕的是, ARPU 设的太高低 CAC 的用户用不起,ARPU 设的太低挣不到足够的钱支撑高 CAC。

MMF:商业模式和市场要匹配。我们的目标是 ARPU × 市场上的所有消费者 × 你能够拿下的消费者的比例 >= 一亿美元,那么如果这个式子算出来不对,那么要相应地改变你的商业模式扩大你的收费,或者面向跟多更广的用户群体。

使用这个增长模型有几个要注意的点:

  1. 使用的前提是目标 VC-backed 的一亿美元生意
  2. 你如果想要改变一个元素,就得相应地调整其他地方
  3. 元素本身也在不断变化
  4. 一次最好不要改变太多的元素,你不熟悉相关领域的知识,可能会处理不了

设计以人为本的国际化(i18n) 工程方案

· 阅读需 14 分钟

需求分析

如果问硅谷的公司跟中国最大的不同是什么,我想答案很可能正如吴军所言,硅谷公司的产品大多面向全球市场。陈志武说的好,创造财富能力有三个衡量维度:深度,即生产力,同样的时间提供更好产品或服务的能力;长度,即利用金融杠杆,跨越时间和空间交换价值的能力;广度,即市场大小,开创跨越地域的市场或者新行业的能力。而国际化,也就是产品和服务在语言和文化上的本地化,正是跨国公司征战全球市场的战略要地。

Internationalization 因为字母 i 后面跟了 18 个字母然后以 n 结尾,所以被称为 18n,我们这次设计的 i18n 工程方案主要是解决网站和移动 App 开发过程中的如下问题:

  1. 语言
  2. 时间与时区
  3. 数字与货币

构架设计

语言

逻辑和细节

语言的本质是把消息交付给受众的媒介,不同的语言就是不同的媒介,不同的媒介面向不同的受众。比如,我们要对用户显示文字:“你好,小丽!”,显示的过程就是查一下语言表,根据用户的语言,和当前需要的插值,比如姓名,显示相应的消息:

Message CodesLocalesTranslations
home.helloenHello, ${username}!
home.hellozh-CN你好, ${username}!
home.helloIW!${username}, שלום

不同语言在细节上略有不同,比如一个物品的单数和复数的形式;比如第三人称,在称呼上男性和女性的区别。

这些都是简单的查表无法应对的问题,需要更复杂的逻辑处理。在代码中你可以无脑地使用条件语句去处理这些特例。此外有一些国际化的框架会发明 DSL (domain specific language) 来专门应对这种情况。以 The project fluent 为例:

还有一个新手容易忽略的问题是行文的方向。中文和英文等常用语言是从左至右的,但是还有一些语言,是从右往左的,比如希伯来文和阿拉伯文。

行文方向的不同不仅仅会影响到文字本身,还会影响到输入的方式。中国人如果从右至左输入会觉得非常的奇怪;而我的一位犹太同事就觉得英文和犹太文混着输入轻而易举。

还有一种情况就是布局。整个 UI 的布局、视觉元素比如箭头的方向。都可能会根据语言的方向的不同而发生变化。你的 HTML 需要设置好相应的 dir 属性

如何确定用户的地域?

你可能会问,我们如何知道用户当前的语言设置呢?如果是浏览器的话。在用户请求网页的时候,会有一个 header Accept-Language 标注接受的语言。这些设置来自于用户的系统语言,以及浏览器的设置。移动 App 情况下,通常都会有获取 locale 变量或者常量的 API。还有一种方式是根据用户的IP 或者 GPS 信息知道用户的位置,然后显示相应的语言。如果是跨国公司,用户在注册的时候,通常会标注出用户注册时候的语言习惯、地理区域。

如果用户想要改换语言,网站的做法各有千秋,移动 App 会有相对固定的 API。网页有这样几种方法:

  1. 设置 locale cookie
  2. 使用不同的子域名
  3. 使用专有域名。 Pinterest 有一篇文专门讲他们如何用本地化的域名。 研究表明使用本地域名后缀的点击率会更高。
  4. 使用不同的路径
  5. 使用 query params。这个做法虽然能用,但是对 SEO 不友好。

新手在做网站的时候容易忘记在 HTML 上标注 lang 标签。

翻译管理系统

当你注意到如上种种细节。小心翼翼的实现了文字语言的显示之后。你会发现,翻译库的建立和管理,也是一个麻烦的过程。

通常开发者并不会有多语言的功底。这时候就需要引入外部的翻译官或者是别人已经建立好的翻译库。而这里的难点在于,翻译官往往并不是技术人员。如果让他们直接改代码、或者直接跟开发人员沟通,会极大的增加翻译的成成本。所以在硅谷的公司,这种提供给翻译官使用的翻译管理系统 (translation management system),往往是有一个团队专门来做,或者直接采购现有的方案,比如说,闭源收费的 lokalise.co ,或者是开源的 Mozilla Pontoon。翻译管理系统可以统一管理翻译库、项目、审核、任务分配。

这样一来,开发的流程就会变成,首先设计师根据不同的语言和文化习惯,在设计的时候标志出需要注意的地方,比如这个按钮虽然在英文里很短,但是在俄文里面会非常长,要注意不要溢出。然后,开发者开发团队根据设计的需求实现具体的代码逻辑,并在翻译管理系统中提供消息码、上下文的背景、以及一个开发者熟悉的语言写成的例子。再然后,翻译官团队在管理系统中填上各种语言的翻译。最后,开发团队把翻译库拉回代码库中,发布到产品中。

其中,上下文的背景是容易被忽视而且不容易做好的地方。这个需要翻译的消息在UI界面的什么地方?用作什么用途,如果消息过短的话,还应该进一步的解释这个消息是什么意思。那么翻译官有了这个背景知识之后,就能够更加精准地加上其他语言的翻译。如果翻译官对想要表达的信息。无法透彻的理解。他们还需要拥有一个提供反馈的渠道,能够找到产品的设计和开发者询问问题。

这么多的语言和文字,通常都不是由一个翻译官来解决的,这通常需要很多个国家语言身份的人一起来为这个翻译库添砖加瓦。整个过程耗时耗力,所以翻译官通常是有专门的团队来负责的,比如外包给 smartling。

现在我们已经有了代码逻辑和翻译库。接下来的问题是:如何把翻译库的内容搬到产品中?

具体可以有很多不同的实现方式,最直接的就是,静态的做法,每次更新的时候。交一个 diff,然后在 merge 到代码当中。这样在构建的时候,就会有就已经有了相关的翻译资料在代码里面。

还有一种做法是动态地做。一方面,可以去远程的翻译库“拉取”内容,这种情况在网站流量大的时候,可能会有性能问题。但是好处是,翻译永远是最新的。另一方面,想要做优化的话,可以采取“推送”的方式,每次翻译库有新改动,触发一个 webhook 来把内容推到服务器上。

在我看来,维护翻译会比添加翻译更加的繁琐。我曾经看到一些很大的项目,因为更新翻译之后没能够及时的删除老的翻译,导致翻译库过于的庞大,整个项目变得乱七八糟。这个时候如果有一个好的工具,能够保证数据的一致性。会对清洁的代码,有非常大的帮助。

阿里巴巴的 Kiwi 国际化全流程解决方案就做了 linter 和 VS Code 插件来帮助你检查和抽取代码中的翻译。

时间和时区

谈完了语言,接下来是时间和时区问题。因为是全球化的公司,所以说有很多数据是来自于全球、显示给全球的用户的。举个例子。国际航班在设置开始时间结束时间的时候如何保证这个时间在全局是一致的,并且在不同的时区会相应的显示。这非常的重要。同样的情况还应用于一切跟时间有关的事件,比如预定酒店、预定餐馆、安排会议。

首先时间有这样几种典型的表现形式。

  1. 自然语言,比如 07:23:01, 星期一 28, 十月 2019 CST AM/PM
  2. Unix timestamp (Int 类型),比如 1572218668
  3. Datetime. 注意 MySQL 存datetime 的时候会根据服务器时区转化成 UTC 然后存起来,读取的时候再转换回来。但是呢,服务器时区一般都是设置成 UTC 的。这种情况就是,存储不带时区,默认 UTC。
  4. ISO Date,比如 2019-10-27T23:24:28+00:00,这是带时区信息的。

我对这些形式没有大的偏好,你如果有相关经验,欢迎留言讨论。

具体在显示的时候。有两个可能出现的转化,一个是,从服务器存储的时区转化成当地时区显示的形式;另外一个是,语言上会由机器代码转换成自然语言。后一步流行的做法是使用强大的处理时间和日期的库,比如 moment.jsdayjs

数字与货币

不同国家区域对于数值的显示,其实是天差地别的。数值中间的逗号和点,在不同的国家,有不同的含义。

(1000.1).toLocaleString("en")
// => "1,000.1"
(1000.1).toLocaleString("de")
// => "1.000,1"
(1000.1).toLocaleString("ru")
// => "1 000,1"

阿拉伯数字并不是在所有区域都通用的,比如 Java 的 String.format 中 1、2、3这种数字在真正的阿拉伯语言里,使用的数字是١、٢、٣

价格方面,同样的货物,在不同的国家地区,是否要显示成当地货币的价值?货币的符号是什么?货币能够精确到哪一位?这些问题统统要先做好准备。

总结

本文提到的国际化工具有,翻译管理系统,开源的 Mozilla Pontoon、闭源收费的 lokalise.co,POEditor.com 等等。代码上的一致性 阿里巴巴 Kiwi 国际化全流程解决方案。UI 显示上的 moment.js, day.js

如同一切软件系统的开发一样,国际化这件事情没有银弹,好的作品都是靠基本功一点一滴磨出来的。

设计负载均衡器或 Dropbox 修补程序

· 阅读需 5 分钟

需求

互联网规模的网络服务处理来自全球的高流量。然而,单个服务器在同一时间只能处理有限数量的请求。因此,通常会有一个服务器集群或大型服务器集群来共同承担流量。问题来了:如何路由这些请求,以便每个主机能够均匀地接收和处理请求?

由于从用户到服务器之间有许多跳数和负载均衡器层,因此这次我们的设计要求是

注意:如果服务 A 依赖于(或消费)服务 B,则 A 是 B 的下游服务,而 B 是 A 的上游服务。

挑战

为什么负载均衡很难?答案是很难收集准确的负载分布统计数据并相应地采取行动。

按请求分配 ≠ 按负载分配

随机和轮询通过请求分配流量。然而,实际负载并不是每个请求 - 有些在 CPU 或线程利用率上很重,而有些则很轻。

为了更准确地评估负载,负载均衡器必须维护每个后端服务器的观察到的活动请求数量、连接数量或请求处理延迟的本地状态。基于这些信息,我们可以使用诸如最少连接、最少时间和随机 N 选择等分配算法:

最少连接:请求被传递给活动连接数最少的服务器。

基于延迟(最少时间):请求被传递给平均响应时间最少和活动连接数最少的服务器,同时考虑服务器的权重。

然而,这两种算法仅在只有一个负载均衡器的情况下效果良好。如果有多个负载均衡器,可能会出现 羊群效应。也就是说,所有负载均衡器都注意到某个服务瞬时更快,然后都向该服务发送请求。

随机 N 选择(在大多数情况下 N=2 / 也称为 二选一的力量):随机选择两个并选择两个中的更好选项,避免选择更差的选项

分布式环境

本地负载均衡器对全局下游和上游状态并不知情,包括

  • 上游服务负载
  • 上游服务可能非常庞大,因此很难选择正确的子集来覆盖负载均衡器
  • 下游服务负载
  • 各种请求的处理时间很难预测

解决方案

有三种选项可以准确收集负载统计数据,然后采取相应的行动:

  • 集中式和动态控制器
  • 分布式但具有共享状态
  • 在响应消息或主动探测中附加服务器端信息

Dropbox Bandaid 团队选择了第三种选项,因为它很好地适应了他们现有的 随机 N 选择 方法。

然而,他们并没有像原始的 随机 N 选择 那样使用本地状态,而是通过响应头使用来自后端服务器的实时全局信息。

服务器利用率:后端服务器配置了最大容量并计算正在进行的请求,然后计算利用率百分比,范围从 0.0 到 1.0。

需要考虑两个问题:

  1. 处理 HTTP 错误:如果服务器快速失败请求,它会吸引更多流量并导致更多失败。
  2. 统计衰减:如果服务器的负载过高,则不会将请求分配到该服务器,因此服务器会被卡住。他们使用反向 sigmoid 曲线的衰减函数来解决此问题。

结果:请求更加均衡

设计负载均衡器

· 阅读需 5 分钟

需求分析

互联网服务往往要处理来自全世界的流量,但是,一个服务器只能够同时服务有限数量的请求。因此,通常我们会有一个服务器集群来共同处理这些流量。那么问题来了,怎样才能够让这些流量均匀地分布到不同的服务器上呢?

从用户到服务器,会经过很多的节点和不同层级的负载均衡器。具体来讲,我们这次设计的需求是:

  • 设计第7层的负载均衡器,位于数据中心的内部。
  • 利用来自后端实时的负载信息。
  • 服务每秒千万级的流量以及10 TB每秒级别的吞吐量。

补充:如果服务 A 依赖服务 B,那我们称 A 是 B 的下游服务,而 B 是 A 的上游服务。

挑战

为什么负载均衡会很难做?答案是很难收集准确的负载分布数据。

按照数量分布 ≠ 按照负载分布

最简单的做法是根据请求的数量,随机地或者循环地分布流量。然而,实际的负载并不是根据请求的数量来算的,比如有些请求很重很耗CPU,有些请求很轻量级。

为了更加准确地衡量负载,负载均衡器得保持一些本地状态 —— 比如,存当前的请求数、连接数、请求处理的延迟。基于这些状态,我们能够使用相应的负载均衡的算法 —— 最少连接、最少延迟、随机 N 取一。

最少连接:请求会被导向当前连接数最小的服务器。

最少延迟:请求会被导向最少平均反应时长且最少连接数的服务器。还可以给服务器加权重。

随机 N 取一 (N 通常是 2,所以我们也可以称之为二选一的力量):随机的选两个服务器,取两者之中最好的,能够避免最坏的情况。

分布式的环境

在分布式的环境中,本地的负载均衡器难移了解上下游服务完整的状态,包括

  • 上游服务的负载
  • 上游服务可能超级大,因此很难选择一个合适的子集接入负载均衡器
  • 下游服务的负载
  • 不同种类的请求的具体处理时间很难预测

解决方案

有三种方案能够准确地搜集负载的具体情况并相应地处理:

  • 中心化的一个均衡器,根据情况动态地处理
  • 分布式但是各个均衡器之间要共享状态
  • 服务器返回请求的时候捎带上负载信息,或者是均衡器主动询问服务器

Dropbox 在做 Bandai 的时候选择了第三种方案,因为这很好地适应了现行的随机 N 选一的算法。

然而,与原配的随机 N 选一的算法所不同的是,不是使用本地的状态,而是选择服务器实时返回的结果。

服务器使用率:后端服务器设置了最大负载,数当前的连接,然后计算出使用率,范围是从 0.0 到 1.0.

有两个问题需要考虑:

  1. 处理错误: 如果 fail fast ,由于处理得很快,反而会吸引更多的流量产生更多的错误。
  2. 数据要衰减: 如果服务器的负载太高,没有请求会发到那里。因此,使用一个类似于反 S 曲线的衰减函数来保证老数据会被清理掉。

结果: 服务器接收的请求更加的均衡了

并发模型

· 阅读需 1 分钟

  • 单线程 - 回调、承诺、可观察对象和 async/await:原生 JS
  • 线程/多处理,基于锁的并发
    • 保护临界区与性能
  • 通信顺序进程 (CSP)
    • Golang 或 Clojure 的 core.async
    • 进程/线程通过通道传递数据。
  • 演员模型 (AM):Elixir、Erlang、Scala
    • 本质上是异步的,并且具有跨运行时和机器的位置信息透明性 - 如果您有演员的引用 (Akka) 或 PID (Erlang),您可以通过邮箱向其发送消息。
    • 通过将演员组织成监督层次结构来实现强大的容错能力,您可以在其确切的层次结构级别处理故障。
  • 软件事务内存 (STM):Clojure、Haskell
    • 类似于 MVCC 或纯函数:提交 / 中止 / 重试