但是,终极我们决定放弃 PHP 拥抱 Go,下面我将阐明为什么这么做,并分享一些在我们的微做事架构中数据库干系的想法。
微做事和 PHP:观点性错配
我们熟习的措辞是 PHP,它支撑了我们现有的运用程序,有两个模糊的论据可以支持我们连续这么做下去:
我们熟习 PHP,它开拓很快题。为什么要放弃对我们有用的东西?

市情上有很多 PHP 开拓职员。 选择 PHP 让我们更随意马虎扩充团队。
这听起来非常合理,但是当我们清楚 PHP 真的不是我们的精确选择时,我们很快就放弃了这些想法。
我们正在迁移到微做事架构,由于我们希望我们的高流量架构根本举动步伐(200 万日活用户)可更好扩展。从长远来看,随着我们向 1000 万(还会更多)日活用户迈进,而且每天和每小时都能随之改变(译者注:指扩容和缩容):随着全体国家在安歇或者白天,我们的根本举动步伐该当随之弹性伸缩到相应的规模。
PHP 不适宜我们的紧张缘故原由:
1、PHP 具有较高启动开销
PHP 曾经被设计成(或长成)为运行短命令的脚本,因此持久并不是这个措辞适宜支持的特性。这意味着对付每个要求,数据库连接和类都必须重新被实例化,这增加了不必要的延迟开销。
当然熟习这方面读者都知道,有办理方案,例如通过 PHP-FPM 或 Apache 的连接池或 C 绑定等方法,可以支持与 Redis 的持久连接。
但是,由于我们追求高性能,这些依赖使我们对选择 PHP 作为得当的工具存在疑虑。
2、容器化 PHP 是一个雷区
PHP 须要 Nginx 和 PHP-FPM(或类似工具)来实现进程和连接池管理等功能。这意味着对付每个支配的微做事,PHP-FPM 和 Nginx 也必须一起运行。这摧残浪费蹂躏了资源,也降落了扩展的效率。
还有优化配置的问题。优化单 PHP 实例已经很头大了,由于须要理解和配置 PHP,PHP-FPM 和 Nginx 这一堆组合,我们无法想象终极在弹性的 Kubernetes 环境中配置多个 PHP 栈的痛楚环境,您完备不知道在同一台机器上运行了哪些做事。
微做事器的繁芜性在架构中:您正在处理一个由大略做事组成并且相互之间浸染的繁芜系统。既然我们已经致力于这个架构,那么由于措辞而增加更多长期开销和观点上的缺点便是得不偿失落的。
招聘又如何呢?我们创造它对我们的情形是无效的。像微做事一样,我们认为开拓职员该当是措辞无关的。我们甘心聘请一位聪明的开拓职员学习一门新措辞来完成事情,而不是利用一位坚持自己干事办法的措辞专家。在这个意义上,移除 PHP 实际上让我们得到了真正自由。
向 Go 迈进
我们偏爱的两个紧张措辞是 Node.js 和 Golang。我们做了一些研究,并决定了转向 Go 而非 Node。
为什么是 Go?
性能。二进制文件的办法启动一个长期运行的守护进程,意味着每个要乞降持续连接的启动本钱很低。Go(包括 Goroutine )天生就为网络及多核环境设计,使其在处理大量并发要求方面超快和高效。
Go 可以编译成小巧且可移植的二进制文件。这使它非常适宜在 Docker 容器中利用。支配我们的 Go 容器只需几秒钟,由于它们的体积小(大多只有 4 - 5MB),并且由于静态链接的缘故原由,在容器内不须要 OS 或运行时依赖。作为参考,当利用 Node alpine 镜像时,我们的前端容器大约须要 55MB。
Go 是类型严格的。这使代码中的内部通信更为可靠。它也有助于在编译构建期间捕获问题,而不是在运行期间。
Go 有非常好的工具链。虽然工具是很多措辞的问题,但 Google 决定从一开始就办理这个问题,供应了大量常用的工具,作为措辞安装包的一部分。
当然我们也同时考虑到了 Go 的这些缺陷:
Go 不附带依赖管理工具。官方团队正致力于此,当官方工具发布的时候,很可能非常好用。现在,您可以检讨您的 vendors,或者利用 Glide 等工具。
更多代码。这是 Go 的优雅和大略的反面。
然而,我们选择接管这一点:利用 Go 确实须要一些努力,但它会产出高质量代码。
这不是说我们把 Go 用到所有地方。对付做事器端渲染,我们选择 Node,由于它许可我们在前端和后端之间共享逻辑。我们也利用Java来办理特定的问题,由于 Java 已经存在了很永劫光,并且有大量类库。
我们希望利用每个场景最适宜的工具,也便是说,对付大多数情形,Go 将是我们的首选工具。
Big Gopher (Gyga8K)
评估 NoSQL当我们开始用 Go 编写我们的第一个做事时,我们同时也同时思考数据库的问题。我们习气利用 MySQL,它过去事情良好,但它每每也是性能瓶颈。
在我们的传统技能栈中,我们还大量利用了 Redis 进行缓存,这对付性能来说非常棒,由于它有效地减少了数据库 join 查询的访问压力。
因此当我们开始在新技能栈中进行数据库选型时,评估 NoSQL 就很有必要,可以看看我们是否可以完备避免这些 join 查询。
我们评估了两个数据库:
MongoDB- 我们很好奇去理解一个文档型数据库是否可以用来存储游戏中大量元数据。当然麻烦的是,我们必须在 Google Cloud 中利用,根据社区的说法,这样根本不能很好地扩展。我们只管即便避免繁芜的 DevOps 事情,因此 MongoDB 出局。
Cassandra- 它是一个已知的可以扩展的数据库,并被一些大型高访问量平台 Netflix 和 Reddit 利用。我们喜好的特性是:它的速率非常快,并支持线性扩展。不过,我们创造管理太繁芜了。
如果您确切知道如何查询您的数据,Cassandra 非常适宜。对付具有大量数据的剖析做事来说,情形可能如此,但是在敏捷的产品设计开拓环境中,随着产品的发展,用户适应性变革,Cassandra 虽然强大,但是对付我们这样的小团队来说难于掌握。
连续与 SQL 共舞
我们逐渐走近微型做事的观点,更加坚信构建小型的独立做事的想法,这些做事完成特界说务,并且在须要时可以轻松升级或被改换。
因此我们还是坚持利用 MySQL 作为我们的默认数据库。我们利用了 MySQL 很多年,知道如何设计高性能的数据库模式。虽然它不支持原生的线性伸缩,但现在也不是一个大的问题:由于微做事架构的模块化特性,运用程序负载分布在许多机器的不同微做事上。并且每个微做事器都可以访问自己的 32 核数据库机器和几个只读从库,这种办法还可以连续前行很长的路。
我们非常高兴,现在我们现在还没有过度工程化。如果有一个做事须要 Cassandra 或其他数据库,那么我们也可以轻松迁移该做事。
那么为什么选择 MySQL?现在紧张是由于它可以很方便在 Google Cloud 上进行管理,在 DevOps 方面我们是务实的。
我们也考虑考试测验 Postgres,由于它开放源码,还有一个强大的社区,并且显然已经运行了很多年。因此,取决于 Google Cloud 未来的 Alpha 版本,我们也可能会考试测验 Postgres。
作者补充:
Reddit 上不少网友指出,我们对 PHP 启动本钱有误解。虽然我们的不雅观点仍旧站得住脚,但为了准确起见,我们已经清理了这一段。
其余感谢 Casper van Wezel 对本文所做贡献。 有问题请留言,英文好的读者可以点击阅读原文跟原作者互动。