rayeaster 最近的时间轴更新
rayeaster

rayeaster

V2EX 第 74493 号会员,加入于 2014-09-19 22:00:26 +08:00
今日活跃度排名 4811
rayeaster 最近回复了
5 小时 23 分钟前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
第 2 章第 2 节 选择技术栈

两天的时间不能浪费一分一秒。MVP 已经定义了我们将要做的“事情”, 也就是我们的数字版滑板。现在还需要找到“如何”完成它的工具,我们有哪些选择呢?

在软件行业,你选择的一系列工具被称作“技术栈”。就好比是盖房子。首先你得决定采用什么主建材。是用砖块,木材还是钢材?采用何种地基?需要哪些建筑工具?这些选择将决定造房子需要花多长时间,造好的房子有多坚固,以及以后想增加一个房间是否容易。

对于一个周末的黑客松项目来说,只有一个最重要的因素决定着类似的选择:构建的速度。我们暂时不需要考虑那些高大上的可扩展架构,或者最先进最时髦的技术栈。我们需要的是能在最短时间内帮助我们从零打造出可用产品的技术栈。

这意味着我们需要一个熟悉的,可靠的,能帮我们完成很多“脏活”的工具箱。

深入技术细节:编程语言和框架

这是我们第一个也是最重要技术选择:选哪个编程语言以及何种编程框架?

为什么选择 Python ?

编程语言就是你往计算机下达任务的指令“词汇表”。我们选择 Python 是因为它赖以成名的简洁语法。代码读上去就像是普通的英文。当你跟时间比赛时,最好不要在调试工具上浪费时间,比如试图搞明白某个复杂的编码机制或者漏写了一个分号。Python 代码写起来毫无障碍,让我们可以专注在 MVP 问题本身。而且 Python 社区相当活跃,每一种需要的功能都可以找到现成的库来调用。

为什么选择 Djanjo:开箱即用的框架

编程语言仅仅是”词汇表”。好的框架就是完整的指令手册。框架提供了合理的编码结构,顶层设计,以及一系列预先构建好的组件,这些都可以让你无需从零起步。

还是以盖房子为例。你当然可以自己去砍树,自己去加工板材,甚至自己打磨钉子。或者,你也可以购买一个预制的房屋套装,包含所有的墙壁和门窗。你只需要把它们组装起来,然后根据个人喜好做些微调。

这就是 Django 的价值。它是构建互联网应用的预制盖房套装。它的设计哲学就是著名的开箱即用( Batteries-Included )。这意味着你直接立马可以上手开始构建。对于我们需要在 48 小时内完成的 MVP 而言,Django 的两项功能绝对是大杀器:

Django 管理员后台:这是 Django 的杀手锏。只需要几行代码,Django 就可以生成一个完整的安全的并且看上去非常专业的管理员后台。这主要提供给我们作为创始团队登录用以查看全部业务数据。 当有新用户创建一个网店,我们就会在管理后台收到通知。我们可以查看相关商品名录,帮助修改错误的输入(仅在必要时)或者排查用户在使用过程中碰到的其它问题。但如果从零开始,弄出这样一个管理员后台可能需要花费一天的时间。Django 不花我们一分钱,只需要 15 分钟就可以准备好。这个管理员后台就是我们的任务指挥中心。
ORM (对象关系映射器):这个听上去好像有点复杂,但其实很简单。如果要从数据库读取数据,一般来说你得通过编写 SQL 语句完成。就是类似 SELECT * FROM products WHERE store_id=123;这样。SQL 很强大,但也容易出错,且跟我们主要采用的 Python 代码风格迥异。Django 的 ORM 模块就扮演了翻译的角色。它允许我们用 Python 代码跟数据库打交道。上述 SQL 指令在 Django 中可以改写成:Product.objects.filter(store_id=123)。这让代码不仅易于编写和阅读,也能够避免很多比如 SQL 注入的安全隐患。采用自带 ORM 的 Django 框架让我们的代码更简洁,开发速度也更快。

深入技术细节:我们考虑过的其它语言和框架

Django 当然不是唯一的选择。技术层面看,总有很多不同的方法可以达到同一个目的。关键是要根据任务性质和特点选择最合适的工具。

Node.js 以及 Express 框架:这也是一个非常流行的组合。Node.js 允许使用 JavaScript 语言编写服务端代码,而 JavaScript 通常是运行在客户端浏览器中。这对于很多全栈型创业团队非常友好。Express 框架则非常灵活,也遵循极简设计的原则。所以对于我们而言,这反而是它的不足。与其说 Express 是一个预制的盖房套装,不如说更像是一盒子高质量的乐高积木。它提供了很多很底层的功能,但是需要自行组装更高阶的模块。由于我们只有 48 小时,所以这样的自由度不是我们所需,我们需要的是 Django 开箱即用的丰富组件和编码结构。
Ruby on Rails:这可能是一个更接近 Django 的备选。Rails 与 Django 的设计哲学高度相似。它同样推崇“约定优先于配置”的理念,意味着它内置的很多合理决策能加速软件开发的过程。实话说,Rails 也的确是个不错的选择。最终选择 Django 可能更多是基于我个人的喜好和熟悉程度。因为我过去更多使用过 Python 和 Django ,所以在时间紧迫的情况下,押注最熟悉的工具总没错。
深入技术细节:数据库选型

有了合适的编程框架,我们需要决定在哪持久化保存我们的业务数据,比如店铺名称,商品明细,价格等等。我们需要一个数据库。如果说编程框架是盖房套装,那数据库无疑就是房子的地基。必须得稳定,可靠并且易于查找数据。

为什么选择关系型数据库?

我们决定使用一款关系型数据库( Relational Database )。原因很简单:我们的数据将保存在数据库的表( Table )中,就像一张巨型且功能强大的 Excel 表格。店铺信息存储在店铺表中,产品信息存储在产品表中。更关键的是,可以在这些表之间建立关系( Relationship ),比如每一款产品肯定属于某一个店铺。

这样的关系结构对于电商业务是完美的选择。数据间有了明确的联系和规则。肯定没人想看到一个不属于任何店铺的产品信息,或者一个没有顾客信息的订单。关系型数据库会强制约束数据之间的关系结构,保证数据始终一致,不多也不少。

为什么选择 PostgreSQL ?

在众多的关系型数据库中(比如 MySQL ,微软的 SQL Server 等等),我们最终选择了 PostgreSQL (常被简称为 Postgres )。

原因呢?其实对于 MVP 而言,Postgres 及其主要竞争对手 MySQL 都是不错的选择。但我们出于以下几点更倾向于 Postgres 。Postgres 在开发社区中的口碑相当不错,令人称赞地健壮,可靠并且符合通用的技术标准规范。绝对是开发中可以放心使用的主力选择。更重要的是,我知道 Postgres 有一些后面我们可能能用上的高级功能。比如其中一个功能是订阅通知机制( LISTEN/NOTIFY ),这将是我们在第 8 章提到的实时缓存系统背后的秘密武器。对于我们要完成的 MVP ,这个特性还用不上,但即使暂时用不到全部功能,从一开始就选择一个功能强大的地基,在将来无疑也是会受益颇多。

综上,我们的盖房图纸已经就绪。技术栈选择如下:

编程语言:Python
编程框架:Django
数据库:PostgreSQL
万事俱备,可以开工了。现在需要开始浇筑地基,准备建造承重墙了。换句话说,我们需要开始准备服务器了。
20 小时 26 分钟前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
第 2 章: WhatsApp 应用里的 PDF 难题 (故事起源)

第 1 节 主意和滑板

每家创业公司都是解决某个问题而诞生。我们的公司( Dukkan )起步则源自一个粗糙的 PDF 文档以及全国(印度)因疫情封禁导致的混乱。

那是 2020 年。整个世界仿佛按下了一个巨大的暂停键。印度曾经熙熙攘攘充斥着喇叭声(车辆)和各种小商贩的喧闹街头彻底陷入了沉寂。日常生活的熟悉节奏被打乱了。对于数以百万计的小企业主而言,比如社区便利店的店主大叔,街坊里蔬菜档口的卖菜老板,售卖手作印度传统纱丽的老阿姨,这绝对是一场浩劫。他们的店铺关门,他们的顾客只能呆在家里,他们的生计正在慢慢消失。

唯一的出路是互联网,或者更具体一点,是 WhatsApp 这款移动应用。它变成了新的交易市场,新的店铺甚至新的特价柜台。但是这个新市场乱糟糟的,也不够高效,还常令人感到万分沮丧。

这就是我的联合创始人苏米特登场的时刻。他并不是想要打造一家多么高大上的大公司,他只是想帮助他的一个邻居杂货铺能够不至于关门大吉。在亲眼目睹了那家杂货铺通过 WhatsApp 进行了多次有些凌乱的对话最终完成了所有交易流程之后,他被这样的场景深深吸引,但又感到深深震惊。

因为整个交易过程在低效方面堪称登峰造极:


步骤 1:建立商品名录。店主需要给每一位潜在的顾客发送一个很多页的 PDF 文档。但是这个 PDF 文档多半是通过微软的 Word 应用制作出来的,并且格式混乱,分辨率很低,甚至充斥着各种错误。产品名称乱七八糟,价格也模糊不清,更无法进行搜索。比如,如果想知道这个商家有没有你最爱的那个牌子的饼干,你得不停滚动鼠标从长达五页的粗糙图片中试图找到答案。


步骤 2:顾客下单。在经过长时间仔细定睛搜寻想要买的商品之后,顾客不得不通过逐字逐句输入长长一串订单的信息,而这显然极易出错。比如:“一包 Maggi 牌面条,两公斤面粉,半公斤糖,然后再来一包那个蓝色的乐事。。。”

步骤 3:商家确认订单。店家通常同时在处理数十个类似的与不同顾客的对话,需要逐一对顾客输入的订单文字信息进行确认。“不好意思,女士,蓝色的乐事没货了,但是我们有绿色包装的。”于是新一轮的商品挑选和订单信息又得再来一遍。

步骤 4:支付货款。好不容易等到订单信息终于确定,店家就会把自己的 UPI (印度的统一支付平台)账号或者类似的二维码发送给顾客。顾客就可以用自己手机的谷歌支付( GPay )或者是 PhonePe 应用完成支付,最重要的是,会同时把支付成功的截图作为凭证一起发给商家。可想而知,店家的手机相册堪称一个支付凭证截图的坟场,根本没有办法从数千张图片中高效地找到某个顾客为某个订单支付的款项。

这完全是一场噩梦。无非是印度人从疫情的绝望中想出来的一个临时数字解决方案( jugaad )


于是有天晚上我的手机响了。是苏米特打来的。我通过手机能感受到他当时炸裂的激情。因为他当时不仅仅是普通的聊天,而显然是处于灵感迸发的亢奋。

“苏巴什,我跟你说,有件事太疯狂了。”他开门见山,甚至连日常的招呼寒暄都省掉了。“我刚亲眼目睹了某个大叔通过 WhatsApp 开店卖货的过程,简直不忍直视。有时候把订单搞忘了,有时候有把顾客的支付搞混了,整个流程到处出错。我们得做点什么。”

他绘声绘色地对我描述了上述提到的令人头疼的几个步骤,也提到了 PDF 和截图满屏飞的混乱场景。

“我们得给这些商家做个什么东西让他们做生意更容易。” 他的声音开始变得严肃起来,“就是一个手机应用,可以让商家上传商品名录,顾客可以直接下单,这样大家就都很轻松,就是给商家准备的线上店铺。”

一个名字呼之欲出:Dukaan ,为“商店”之意。

苏米特说的没错。问题不是市面上缺少足够的技术解决这样的难题,而是没有足够简单高效的解决方案。这些卖家其实并不需要诸如亚马逊或者 Shopify 这样复杂的大型电商系统。他们既没有时间也没有技术搞明白那些。他们需要一个就像使用 WhatsApp 那般简单的电商专属解决方案。

那通电话点燃了星星之火。但如果不付诸行动,再好的点子也是空想。得投入精力用心打造,才能把点子变成现实。而在创业赛道,想做成点什么事情也必须“兵贵神速”。所以我们没有花费 6 个月的时间去慢慢打磨出一款完美产品的资格。我们必须得在短暂的几天时间里就知道是否值得依循这个点子继续做下去。

这就引出了对于任何跃跃欲试的创业者或技术宅最重要的一个概念:最小可行产品( MVP ,Minimum Viable Product )

深入理解:最小可行产品( MVP )

MVP 这个词在技术领域经常被谈起。很多人认为 MVP 就是打造一个最终产品的早期版本,可能错误比较多,功能比较少。不过这个想法是错误的。

因为 MVP 不是打造一个产品,而是做一场试验。

MVP 的最终目标并不是赚钱或者收获百万用户。MVP 最主要的目标是学习。它是为了以最小的开销验证最重要的预期假设而设计的一款具有严肃科学性质的工具。对于我们而言,这个预期假设是:“如果我们为那些小企业主打造一款超简单的开网店工具,他们会愿意使用嘛?”

为了验证这个假设,我们并不需要一款完美无缺的产品。我们只需要找到一个能回答上述问题的最简方案。这就是 MVP 的哲学出发点。

可以设想这个场景:比如你的目标是解决“出行”的问题,那你不需要从制造一辆汽车开始。造车那可太麻烦了,需要引擎,轮子,座椅,底盘,电力系统等等。这需要耗费太长时间。而等到你造好汽车,那时候你才悲催的发现你的顾客其实想要的是一辆摩托车。

MVP 的思路是,先整个滑板吧。这就简单多了,但也能解决核心的问题所在:能够把人从 B 点运到 A 点。这足以让你验证核心的预期假设,即人们是否愿意通过某种带有轮子的载具出行?

如果这个假设可以通过滑板得到确认,那就可以利用用户反馈打造下一个产品版本:带扶手的滑板车。然后是自行车,然后是摩托车。最后,才是汽车。每个阶段,你可以不断学习改进并给用户输出他们确实需要的价值产品。

所以对我们的 Dukaan 来说,需要找到属于我们自己的最初滑板。那到底什么才是可以用来测试我们点子的最基本形态呢?我们删除了所有想得到的各种附加功能。不需要支付网关的集成,不需要货运追踪,只提供给商家,没有花里胡哨的皮肤模板,没有销售数据分析。我们最后在最精简的核心诉求上达成共识。


这是我们为 Dukaan 定义的最核心业务流程:

店家创建店铺:只需要一个单页面,用户输入手机号,接收一条短信验证码,然后允许为店铺去个自定义的昵称名字。齐活。店家的网店就生成了。无需邮箱,无需密码,无需各种复杂的表格填写。
添加商品:采用极简的产品录入表单。产品名,价格,再来一个按钮让用户从手机相册选择一张照片作为产品卖家秀就行了。不需要定义产品类别,不需要定义产品规格(比如尺寸,颜色等等),不需要记录库存数量。这些就是建立一个商品名录的最基本所需。
分享店铺链接:店家添加若干商品之后,Dukaan 应用就会自动为这个店铺生成一个独一无二的可分享的链接(比如 mydukaan.io/mystore 这样)。店家可以在 WhatsApp 聊天框里直接使用这个链接分享给客户。
以上就是我们的滑板。

很显然,这根本称不上是一个功能齐备的“平台”,也不是什么“电商解决方案”。不过就是个用兼容手机端的单页面来替换丑陋 PDF 的简单小工具。这是我们想到的用来解决目前 WhatsApp 商家难题的最简单方法。

确定好这个 MVP 之后,我们决定给自己上上难度。不要很长的开发周期,不要繁琐的需求讨论。我们打算只用一周末的时间完成开发并发布上线。

于是,48 小时的两人黑客松正式启动。时间不等人。现在需要做出第一个重大的技术决策:用什么打造我们的 Dukaan 滑板?
3 天前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
第 1 章第 3 节: 我们伟大而危险的大单体应用

如果说服务器就像厨房, 那如何描述我们大厨( CPU )正在使用的菜谱(代码)呢? 在软件行业的术语里,我们称之为服务架构。我们采用的架构非常经典, 是那种几乎每一个初创公司早期都会采用的架构。
是的,我们用的是一个巨大的单体应用( Monolith )。

这个名字听上去像某种远古巨石阵一般巨大,有点唬人。但事实上,它非常简单。单体应用是指你所有的代码逻辑都在一处一起运行。比如我们的用户注册,商品名录,订单管理,商户仪表盘,支付,所有功能都同处在一个 Django ( Python 流行的 web 框架)项目里面。

可以把它想象成一本巨大的百科全书般的食谱。它包含从开胃小食,主食,甜品,以及饮品在内的所有菜谱,很显然这本书会超级厚。

为什么我们要选择从大单体应用起步(为什么它是正确的上手选择!)
我想直截了当地明确这一点:从大单体应用开始构建没有问题。对于初创企业而言,它大部分时候都是最优可行方案。在创业初期,你唯一的目标就是尽快构建并推出产品,越快越好。因为你需要知道你打算推出的产品的确有人愿意买单。
大单体应用天然就是为速度而生:
1. 易于代码开发: 所有逻辑都在一处。无需操心复杂的服务间通信问题。只需要编写一个函数然后调用它就行了。
2. 易于测试: 可以在笔记本电脑上运行整个应用并轻松地联调测试所有功能。
3. 易于部署: 只需把所有代码打包放到服务器上就完工了。
我们构建的大单体应用允许仅靠苏米特和我两个人在 48 小时内就上线了一个可以正常运行的电商平台。如果我们采用更复杂的“微服务”架构(本书后面的章节会详述), 我们现在可能还在为系统设计的细节争论不休。
所以大单体应用就是我们的超能力,给予我们极速试错的机会。但就像所有超能力一样,它也有一个不易察觉的危险副作用。
大单体应用的隐型危险
随着我们的菜谱增加,问题逐步开始显露。

● 变得愈发沉重以致难以使用。 查找某个食谱可能耗时更长。搞清楚为什么甜品部分的一个改动可能影响到开胃餐部分变得几乎不可能。在软件行业的术语里,我们称之为紧耦合。
● 一个小错误可能会毁了整本食谱书。 一个菜谱里面的一个小小的笔误理论上可能导致整本书都难以理解. 类似的,一个小小的代码错误可能会让整个网站都崩掉。
● 雇佣一个各司其职的专业团队变得毫无意义。比如即使你聘请了一个专业的糕点大厨, 它可能仍然需要理解一整本巨无霸食谱书才能开始工作。类似的,大单体应用会让新加入的开发者很难迅速融入以致降低效率。

最重要的是(也是那天晚上导致我们网站崩溃的原因), 大单体应用让你别无选择:如果你仅仅想为食谱书中某一部分(对应软件应用的某个功能)扩容( Scale ),那你只能先把整本书都扩容。


比如我们电商客户的商铺主页面访问量很高 (好比是食谱上的主食部分很受欢迎)。但另一方面我们的销售仪表盘(好比是食谱上的开胃餐部分) 被访问的次数就要少得多。可是由于他们同处于一个大单体应用中,我们的服务器资源得同时提供给所有功能。 处理主食的巨大消耗(厨师/CPU )让其它厨房任务处于资源嗷嗷待哺的状态,最终导致整个系统的崩盘。


我们那运行在小得可怜的服务器上的大单体应用成了一个潜在的完美毁灭风暴:一个软件层面的单点( Single Point of failure )运行在一个硬件层面的单点。 这简直就是一枚时间炸弹,最终在周二凌晨 3 点 14 分被引爆了。


第 1 章的关键知识点总结

● 你创业历程中第一台服务器肯定会有崩溃的一天。这不是一个会不会崩溃的问题,而是何时崩溃的问题。所以我们的目标应该是如何从崩溃中迅速恢复并从中总结经验, 而不是绞尽脑汁试图去避免崩溃。
● 深入理解架构基础。 在学习复杂架构之前, 彻底搞明白有关服务器运行的原理。 思考这些概念:CPU (大厨的手速), 内存 (操作台面空间), 以及磁盘 (储藏室).
● 掌握基本诊断工具库。如果看不到问题,那也没办法修复问题。学会使用 ssh 和 htop(或 top) 这些命令行工具。这些就是系统管理员的听诊器。
● 从大单体应用开始构建是一个实用选择( feature ),不是错误( bug )。创业初期,速度就是王道。尝试打造完美的早期产品属于用力过度。
● 认识到你的初期技术选择存在保质期。 为你赢得头 1 万个用户的架构很可能没办法帮你拿下接下来的 10 万个用户。为迭代进化做好准备。
3 天前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
第 1 章第 2 节 庖丁解服务器(一个厨师的厨房)

让我们先把这场半夜 3 点的惊慌无措搁在一边。在我们解决问题之前,得先理解问题。所以问题来了:“服务器”到底是啥?


请暂时忽略过于技术的解释。忘记在冰冷机房闪烁的指示灯。在本书剩余部分,我建议你用一个更简单浅显的概念来看待“服务器”:它就是只有一个厨师的餐厅后厨,所以很明显那个厨师会非常忙碌。

这个类比将会是有关服务器架构的最重要基础,其它东西都将在这个类比的基础上构建。

CPU: 厨师的速度

中央处理器 (Central Processing Unit) 就是掌勺的大厨。它是所有处理逻辑的核心大脑。这位厨师把原料 (数据)按照菜谱(代码)制作成一道可口的菜肴(一张网页,一个搜索结果,一笔完成的订单)。


● 更快的 CPU (用千兆赫作为单位, 即 GHz) 意味着你拥有手脚更麻利的厨师。 它可以用更快的速度进行切菜,炒菜和装盘。


● 多核 CPU 就像厨师多了几个机械臂。 比如 4 核 CPU 就像一位能够同时操作切菜,炒菜,煎炸和调味的厨师。它可以在同一时间处理多项任务。

我们那 512MB 的服务器只有一个单核 CPU 。按照这个厨师的类比,就如同我们只有一位独臂大厨但我们却要求他为 1 万人做一顿大餐。




RAM: 厨房的操作台面空间

内存( Random Access Memory )就是厨房的操作台面。这是理解服务器最关键的一步。内存就是厨师可以利用的工作空间。厨师( CPU )会使用内存来保存当前正在被制作的菜肴所需的所有原料以及锅碗瓢盆。

从厨房台面拿取所需非常快速。厨师甚至不需要思考, 想要什么直接伸手去拿就可以了。 更多的内存意味着更大的操作台面。如果拥有很大的操作台面,那厨师可以立马处理很多不同的点餐需求因为所有食材都在它面前的台面上摆放着可供随时取用。

但是如果台面放不下了,那厨师就会有棘手的麻烦。他得放下手头正在处理的活儿, 一头钻进后面的储藏室,从中花时间找到并拿回他所需的食材,还需要从台面上挪走一些东西以便腾出空间。这样一个操作明显会让所有事情都变得更慢。




这就是之前发生在我们服务器上的事情。我们仅有 512MB 的服务器就好比一个只有砧板大小的厨房台面。而我们自己的应用( Dukkan ),我们的数据库以及服务器上的操作系统本身 全都在争夺这一块小小的砧板空间。所以当台面放不下的时候,服务器开始使用 "SWAP"空间—可以看成是储藏室中一个特殊的区域,在临时救急时也可用作台面空间。这肯定是效率极低的方案。厨师不得不花时间来回奔走于储藏室与台面之间,必然耽误了它真正用于烹饪的功夫。


磁盘: 厨房的储藏室

磁盘,无论是传统机械硬盘或者是固态硬盘,都可以看做厨房的储藏室和冰箱,是用来长期存储菜谱(代码),食材(数据)以及厨房用具(操作系统)的地方。

储藏室比操作台面( RAM )显然要大很多,但存取耗时也要慢很多很多. 你肯定不希望你的厨师即使为了拿一点点食盐也得跑去储藏室一趟。 最理想当然是食盐就摆在它的操作台面上。


资源竞争: 厨房里的无序


现在请设想一下我们面对的场景。在一个迷你的厨房里,我们的独臂厨师只有一个砧板大小的操作台面, 然后我们苛求它完成:

● 运行应用程序: 厨师需要看明白菜谱(我们的 Python 代码) 并完成菜肴的烹制。

● 管理数据库: 大厨还得兼任储藏室管理员,不停地把食材(我们的用户数据)分门别类记录好 ,保存好并按食谱准确地取用。

● 处理网络流量: 除了以上, 大厨还需要完成服务生的工作:跑到餐厅前台以最快速度为数千用户点单。

这就是资源竞争。每一项任务都在同一时刻高呼大厨希望优先得到处理。应用程序需要 CPU 来处理运算逻辑,数据库需要把数据写入磁盘,还有刚接收到的用户请求需要内存来暂时记录。所有这些都在竞争同一个有限的资源,所以结果就是完全的死局,无法动弹。

如果想看到厨房里发生的这些无序竞争,你可能需要安装一个监控摄像头。在服务器的世界里,我们的摄像头只是一个简单的命令:htop. 它是命令行工具 top 的优化版本,可以让你犹如现场直播般看到大厨正在忙啥。

虽然可能看上去挺复杂,但你只需要了解以下几点:

● 顶部的 CPU 柱: 如果它显示红色的 100%,那你的大厨就是过载了。


● 内存柱: 如果这个数字满了,说明你的操作台面已经放不下了。


● SWAP 柱: 如果这个数字开始增加,这不是好的信号。说明你的大厨正在尝试使用储藏室作为额外的操作台面。


● 进程列表: 这里展示了大厨正在处理的每一个任务并且能让你看到哪一个占用了最多的资源。

学会读懂这个 htop 的输出只是成为 CTO (要么像我这样误打误撞,要么按部就班)的第一步。从这里开始,我们将进行科学的诊断而不是盲目的瞎猜。对于我个人而言, 那晚半夜 3 点的服务器屏幕尖锐地喊出了一个无可辩驳的事实: 我们的厨房对于我们的抱负而言,实在是太小了,小到足以致命。
3 天前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
第 1 章 凌晨 3 点响起的手机

第一节: 服务器崩了


我的手机突然响了起来,但不是那种普通的来电铃声,而是一种类似尖叫的声音。

那声音伴随着一种特定的手机振动(通常被手机厂商用于提示最高等级的恐慌情绪)。振动的手机在我床边廉价的木桌上发出了剧烈而仿佛暴怒的嗡嗡声。那是一种不光能让你从睡梦中惊醒并且能够让你立马进入高度戒备状态的声音。此刻,时钟上的时间微微透着令人不安的红光:凌晨 3 点 14 分。

其实甚至在我睁开眼之前,我的心就已经开始砰砰直跳。因为一般来说,在这样的午夜时分收到来电只有两个原因:要么是家里人有急事,要么就是公司业务出大事了。手机显示的来电号码确认了后一种情形。一个再熟悉不过的名字闪入我的视线:苏米特( Suumit )。

苏米特.萨( Suumit Shah )是我的至交和公司合伙人,他敏锐的商业头脑对于我这样的码农而言非常重要。他在凌晨 3 点打电话给我那只会有一个原因。公司出大事了。


我迅速在手机上滑动接听,虽然我的声音听上去有些沙哑和疲惫:“咋啦,兄弟?”


“苏巴什( Subhash )! 网站全挂了!” 透过手机麦克风,苏米特的声音听上去就像是一声令人肾上腺素飙升和无比紧张的枪响:“快起来!网站全都不能用了!”


他不用再多说什么。我已经翻身下了床,光脚踩在冰凉的地板上,全身就像被电击一样。我摸索着找到了我的笔记本电脑, 熟悉的苹果标志泛着白光就像黑暗的房间里的一座灯塔。 我此刻思绪万千,一大堆可能出现的服务灾难场景在脑海中无序地飘过:


是被黑客攻击了嘛? DDoS 攻击?难道是哪个外国写脚本的小屁孩闲着无聊来搞垮我们的网站用以取乐?

或者是我们自己的程序员上传了一段有问题的代码?难道是某个多余的分号导致网站完全崩了?

是不是我们的云服务商挂了?如果是这种情况,那我们还能做啥?

“网站页面显示不出来。手机端应用也在报错。全都挂了。完完全全的彻底崩了。”苏米特用紧张并且焦虑的声音继续说着。我甚至能听到他在电话那头来回踱步。

“好的好的,我已经在处理了。哥们淡定。” 我尽量让自己听上去比真实的内心更稳定一点。 一定要保持冷静。 救火第一条原则就是不要火上浇油去添乱。

略带睡意,我用笨拙的手指开始在键盘敲击。我打开终端( terminal )准备登录。这个黑底绿字的界面是通往我们所有线上服务的指令中枢。

ssh [email protected]


我敲下了回车键。光标开始闪烁,继续闪烁,仍在闪烁。

正常来说,登录提示符应该很快就出现。但现在这个情况。。。感觉不妙。非常不妙。这意味着服务器不只是出现问题了,而是像一个已经进入生命倒计时的垂危病人甚至无法从病床下来应门。在等待了很长很长一段时间之后(长到我甚至觉得仿佛比一辈子还要久),登录提示符终于出现了。还好,至少服务器还没有完全挂,但也差不远了。

我开始思考原因:如果服务器响应如此缓慢,那应该不是简单的应用代码问题( bug )。应该是有更深层的问题。可能出在系统层面。就像是服务器本身在苟延残喘。

我输入了我的第一个诊断命令。这是用来检查服务器基本体征的一个简单工具:


htop


屏幕上显示的检查指令输出结果令我脊背发凉。满屏的红色。

每一个进程( process )似乎都处于异常状态。CPU 使用率已经飙升到 100%。结果显示服务器几乎所有内存都已经被占用。甚至连服务器临时救急的 SWAP 存储空间都已经满了。

看上去服务器并不是在苟延残喘。 它其实已经凉透了,而我们只不过目睹了它超负荷状态下的最后几次抽搐(登录和检查指令响应)。


紧接着我马上知道了我们网站彻底歇菜的原因。简单得甚至有些尴尬:显示屏上方清楚地展示着服务器的总内存容量是 512MB 。

五百壹拾贰兆字节。

我的智能手机拥有 8GB 的内存,比这台承载了我们公司所有业务的服务器要大 16 倍。数千家电商客户以及他们数以百万记的商品名录,Dukaan (我们的公司)全部的希望和梦想都运行在这台比我口袋里的手机还要弱的服务器上。

这不是一次复杂的黑客行为或者代码错误。原因很简单:就是服务器不够用了。 就好像我们在一个小小的电话亭举办一场大型的摇滚演唱会,最终电话亭被挤爆了。

盯着屏幕,手机仍响在耳侧,我突然瞬间清醒。像我这样一个不是计算机专业科班出身,没有正儿八经大规模系统扩容经验的人,到底是如何承担起这一切的?

要弄明白这个问题,先得弄懂我们正尝试驯服的这头野兽。也就是需要如庖丁解牛一样深入理解此刻正在作妖的家伙:服务器。
3 天前
回复了 rayeaster 创建的主题 阅读 看到本有趣的书 准备过年的时候读一读
翻译自 Subhash Choudhary 的 Accidental CTO 一书
2025 年 5 月 13 日
回复了 sayyesorno 创建的主题 酷工作 [海外电商] [上海] 招聘资深前端
需要后端 Java 嘛?
需要后端开发嘛
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   1770 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 15ms · UTC 10:57 · PVG 18:57 · LAX 02:57 · JFK 05:57
♥ Do have faith in what you're doing.