单人互联网公司背后的枯燥技术

2020-05-16 06:01:33

[UPDATED@DEC,2019年]我发现这篇老博文最近在黑客新闻和Reddit上被分享和讨论了很多。我想澄清几件事:

这篇帖子现在不是很新。技术堆栈不断发展…。而且在过去两年的全职工作中变得有点复杂。最初,Listen Notes在2017年1月的3个DigitalOcean水滴上运行(约30美元/月)。“无聊”并不意味着“简单”或“使用非常陈旧、非常企业级的技术堆栈”。“无聊”在这里的意思是我只使用我熟悉的技术堆栈,这样我就可以快速启动项目&更多地专注于业务方面。

我只花了10%~20%的时间在工程上(可能接近10%),现在 - 80%的工程时间用于迭代现有的特性/基础设施/内部工具,而20%用于试验新事物。我的大部分时间都花在与他人交谈、回复电子邮件(占我时间的30%~40%)和思考(!)上,这被工程师们认为不是“真正的工作”:)我通常每天在办公室呆4~8个小时,但我用苹果手机工作(例如,回复电子邮件、Slake…的聊天操作)。当我不在办公室的时候,多想想“听笔记”。

我必须向那些对这篇文章感到冒犯的人道歉,因为我没有赞扬你最喜欢的技术,或者我没有写出你同意的东西,或者我没有回答你在这篇文章中提出的所有问题, - 公平地说,我无法预测你在写这篇文章时可能会有什么问题!要让每个人都开心是不可能的:(。

这篇博客文章是向你展示为一种非常具体的在线业务类型做工程的单向方法。这不是唯一的办法。这肯定不是最好的办法。我希望这篇博文能为科技界提供一个有用的数据点。您可以从黑客新闻或独立黑客网站找到更多数据点:)。

Listen Notes是一个播客搜索引擎和数据库。Listen Notes背后的技术实际上非常非常无聊。没有AI,没有深度学习,没有区块链。(《任何必须说我在用AI的男人都不是在用真AI》:)。

读完这篇文章后,你应该能够复制我为Listen Notes构建的东西,或者轻松地做一些类似的事情。你不需要雇很多工程师。记住,当Instagram融资5750万美元并被脸书以10亿美元收购时,他们只有13名员工, - 并不是所有人都是工程师。Instagram的故事发生在2012年初。现在是2019年,用一个小小的工程团队 - ,即使是一个人,也比以往任何时候都更有可能建造一些有意义的东西。

ListenNotes.com是一个为播客听众提供服务的网站。它提供了一个搜索引擎,一个播客数据库,可以稍后收听播放列表,收听剪辑,允许你剪切任何播客节目的一段,以及收听警报,当互联网上的新播客中提到指定的关键字时,它会通知你。

播客搜索&;Directory API适用于开发人员。我们需要跟踪API使用情况,从付费用户那里获得资金,做客户支持,等等。

我在AWS上运行所有东西。有20台生产服务器(截至2019年5月5日):

Production-API服务于API流量。我们运行两个版本的API(截至2019年5月4日),即v1api(旧版本)和v2api(新版本)。

生产工人运行离线处理任务,以使播客数据库始终保持最新,并提供一些神奇的东西(例如,搜索结果排名、剧集/播客推荐…)。。

Production-lb是负载平衡器。为方便起见,我还在此服务器上运行Redis&;RabbitMQ。我知道这并不理想。但我不是一个完美的人:)。

Production-Pangu服务器是一种类似于生产的服务器,我有时会运行一次性脚本并测试更改。盘古是什么意思?

这些服务器中的大多数都可以水平扩展。这就是为什么我把它们命名为生产型1,生产型2…。在舰队中增加一批以生产为主的飞机和一批以生产为主的飞机可能是非常容易的。

整个后端都是用Django/Python3编写的。选择的操作系统是Ubuntu。

我使用uWSGI服务于网络流量。我把nginx放在uWSGI进程前面,uWSGI进程也是负载均衡器。

主要的数据存储是 - ,这是我多年的开发和运营经验,PostgreSql经过战斗测试的技术很好,所以我晚上可以睡个好觉。它有多种用途(例如缓存、统计、…)。。不难猜测,某个地方使用了Elasticsearch。是的,我使用Elasticsearch为播客和amp;剧集编制索引,并为搜索查询提供服务,就像大多数乏味的互联网公司一样。

芹菜是用来进行线下加工的。而芹菜击败是为了调度任务,这就像Cron作业,但要好一点。如果将来Listen Notes获得了吸引力,而芹菜和Amp;Beat导致了一些规模问题,我可能会转而使用我为前雇主做的两个项目:ndkale和nndScheduler。

等等,Docker/Kubernetes/Serverless怎么样?没有。随着经验的积累,你知道什么时候不能过度设计。事实上,早在2014年,我就为我的前雇主做过一些Docker的早期工作,这对一家价值10亿美元的中型初创公司来说是件好事,但对于一家只有一个人的小型初创公司来说,这可能是矫枉过正。

网站前端主要是用Reaction+Redux++webpack+搭建的。这是现在相当标准的。在部署到生产中时,JS捆绑包将上传到Amazon S3平台,并通过云前端提供服务。

在ListenNotes.com上,大多数网页一半是服务器端呈现的(Django模板),另一半是客户端呈现的(REACT)。服务器端渲染部分提供网页的样板,客户端渲染部分基本上是交互式Web应用程序。但有几个网页完全是通过服务器端呈现的,因为我懒得让事情变得完美&还有一些潜在的搜索引擎优化(SEO)好东西。

我在ListenNotes.com上使用了一个经过大量修改的Reaction-media-Player版本来构建音频播放器,它在几个地方使用,包括Listen Notes网站、Twitter Embedded Player和第三方网站上的嵌入式Player:

我们为开发者提供简单可靠的播客API接口。构建API类似于构建网站。我将相同的django/python栈用于后端,将ReactJ用于前端(例如,api仪表板、文档…)。。

对于接口,我们需要跟踪用户在当前计费周期内使用了多少个请求,并在一个计费周期结束时收取$。不难想象,Redis在这里被大量使用(:)。

我使用Ansible服务器进行机器配置。基本上,我编写了一堆YAML文件来指定哪种类型的服务器需要有什么配置文件&什么软件。我可以使用所有正确的配置文件和只需按一下按钮即可安装的所有软件启动服务器。以下是这些Ansible YAML文件的目录结构:

我在给东西命名时本可以做得更好。但再说一次,现在对他来说已经足够好了。

我还使用Ansible将代码部署到生产环境中。基本上,我有一个在MacOS上运行的包装器脚本,名为deploy.sh:

listennote repo的版本:head的意思是“只部署最新版本”。如果指定了GIT提交的sha,那么它将部署特定版本的代码 - 这在我需要从糟糕的部署回滚时特别有用。

服务器类型:Web、Worker、API还是全部。我不必一次性部署到所有服务器。有时我会修改Javascript代码,然后我只需要部署到Web上,而不需要接触API或Worker。

部署过程主要由Ansible YAML文件编排,当然,它非常简单:

在我的Macbook Pro上,如果要部署到Web服务器,那么构建Javascript捆绑包并上传到S3。

在目标服务器上,git将listennote repo克隆到一个以时间戳命名的文件夹,签出特定版本,然后pip安装新的Python依赖项(如果有的话)。

在目标服务器上,将symlink切换到上述时间戳命名的文件夹,然后通过superorctl重新启动服务器。

如您所见,我不使用那些花哨的CI工具。只是非常简单的实际有效的事情。

我使用数据采集卡进行监控和报警。我在一个简单的仪表板中有一些高级指标。无论我在这里做什么,都是为了在处理生产服务器时增强我的信心。

我将Datadog连接到PagerDuty。如果出现问题,PagerDuty会通过电话和短信向我发送提醒。

我还使用滚动条工具来关注Django代码的运行状况,它会捕捉到意外的异常,并通过电子邮件&;Slake通知我。

我经常使用Slake。是的,这是一个人的公司,所以我不使用SLACK与人交流。我使用Slake监视有趣的应用程序级事件。除了将Datadog和Rollbar与Slake集成之外,我还在Listen Notes后端代码中使用Slack Income WebHooks,每当用户注册或执行一些有趣的操作(例如,添加或删除内容)时都会通知我。这在科技公司是非常普遍的做法。当你阅读一些关于亚马逊或贝宝早期历史的书籍时,你会知道这两家公司都有类似的通知机制:每当用户注册时,办公室里的每个人都会听到“叮当”的声音。

自2017年初推出以来,Listen Notes除了这一次之外,没有任何大的停机(>;5分钟)。在这些业务上,我总是非常细心和务实。网络服务器的配置严重过剩,以防因新闻事件或其他原因而出现巨大的峰值。

我在旧金山的一个名为WeWork的协同工作空间工作。有些人可能会想,为什么不干脆在家工作,或者随便去几家咖啡店。嗯,我很看重生产力,我愿意在生产力上投资。我不相信堆积如山的时间有助于软件开发(或任何类型的知识/创造性工作)。我一天工作超过8小时是很罕见的(对不起,有996人)。我想让每一分钟都有价值。因此,我需要的是一间漂亮而相对昂贵的私人办公室。(&;)我不是为了花更多的时间和省钱而优化,而是为了花更少的时间&;赚钱而优化:)。

我用的是MacBook Pro。我在流浪者+VirtualBox内部运行(几乎)相同的基础设施。我使用与上述相同的一组Ansible YAML文件在Vagant内提供开发环境。

我赞同这种铁板一块的回购理念。所以只有一个Listennote repo,包含DevOps脚本、前端和后端代码。此Listennote回购作为GitHub私有回购托管。我负责主分支机构的所有开发工作。我很少使用功能分支。

我使用PyCharm编写代码并运行开发服务器(Django runserver&;webpack开发服务器)。是的,我知道,这很无聊。毕竟,它不是Visual Studio代码或Atom或任何很酷的IDE。但是PyCharm对我来说很好。我是个老派。

我用很多有用的工具和服务将Listen Notes打造成一种产品和一家公司:

办事员需要为筹款(SAFE)和雇用不是来自Upwork的承包商生成法律文件。

BREX表示,对于充值卡 - ,您可以获得5,000美元的增量AWS积分,该积分可以在WeWork或条纹地图集的AWS积分之上申请。

邦沃伊商务运通卡 - 您可以为豪华酒店和航班赚取万豪邦沃伊积分。这是旅游的最佳信用卡积分:)

如你所见,我们生活在一个开办公司的美好时代。有这么多现成的工具和服务,可以节省我们的时间和金钱,提高我们的生产力。用一个很小的团队(或者只有一个人),使用简单乏味的技术,建立一些对世界有用的东西,这比以往任何时候都更有可能。

随着时间的推移,公司变得越来越小。你不需要雇佣大量的全职员工。您可以雇佣服务(SaaS)和按需承包商来完成任务。

大多数时候,建造和运输东西的最大障碍是想得太多。如果这个,如果那个。孩子,你一点也不重要。每个人都忙于自己的生活。没有人关心你和你建造的东西,直到你证明你值得别人关注。即使你搞砸了最初的产品发布,也很少有人会注意到,他们想大,从小做起,行动迅速。只要你真的解决了问题,使用无聊的技术,开始一些简单(甚至丑陋)的事情是完全可以的。

现在有这么多狂热的货运狂热分子。忽略噪音。保持冷静,继续前进。