QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

GitLab 技术选型为何如此不同:坚持用过气 Web 框架十多年、坚决不用微服务

  • 2022-07-07
  • 本文字数:2760 字

    阅读完需:约 9 分钟

GitLab技术选型为何如此不同:坚持用过气Web框架十多年、坚决不用微服务

关于过气网红编程语言 Ruby,我们此前曾发过一篇文章去回顾其大受追捧的过往,并讨论了它每况愈下的生存状态。不过人气并不能直接说明语言质量差,一方面 Ruby on Rails(用 Ruby 写的开源 Web 应用程序框架)仍是实现原型设计演示的好方法,能帮助开发者在几天之内更稳妥地构建起最小可行性产品,另一方面,市场对于 Rails 和 Ruby 开发者还是存在刚性需求。


近期,GitLab 就发布了一篇文章阐述它们坚持使用 Ruby on Rails 的原因。全球有许多流行网站都是基于 Rails 构建的,尽管今天 Rails 有日落西山之势,但技术选型还得图个“合适”。从 GitLab 的角度看,他们本身没有复杂的运行体系,也不需要用微服务,在这样的情况下,Ruby on Rails 对他们而言反而是最佳选择。

Ruby on Rails 胜在哪


2004 年 7 月,Rails 的创始人 David Heinemeier Hansson 从 37signals 公司的项目管理工具 Basecamp 分离出 Ruby on Rails,并且以开源方式发布。


David 曾在一个采访中回顾他创造 Ruby on Rails 的心路历程,其中最大的影响来自他使用 PHP 与 Java 的深度经验。一方面,他不喜欢 Java 那种冗长、僵化、导致 Java Web 框架既复杂又难以使用的设计方式,但他赞赏 Java 良好的结构完整性。另一方面,他喜欢 PHP 易于上手的友好特性,但也发现 PHP 过于混乱,难以提供顺畅的项目开发轨道。



当时的情况就是,必须在两种都不够好的方案中做选择:要么是易于上手却混乱不堪,要么是结构良好却难以使用。这种困境不禁让人联想起服务器级操作系统(例如稳定却难以使用的 Unix)和客户端操作系统(例如简便易懂却经常崩溃的 Windows 和 MacOS)间的经典难题。


当初人人都觉得现实就是这样残酷,只能陷入二选一的艰难抉择。但后来 NeXT 在 Unix 的坚实基础之上却开发出一套漂亮、易用且流畅的 GUI。如今,“服务器级”Unix 不仅能够运行起漂亮的 GUI 桌面,甚至还能搭载在大部分手机、智能手表当中。


所以事实证明,易用性和稳定性之间并不是非此即彼的关系。Web 框架中的易用性和混乱性也是如此——明明是两条并行的车道,为啥非得纠缠在一起?



所以,David 看到的一个理想的平衡点是:既平易近人、又结构良好的 Web 框架。凭借其扎实、支持元编程的 Samlltalk 特性,再加上良好的 Unix 集成效果,Ruby 证明了自己完全可以在配合 Rails 之后成为那个正确答案。



回到 GitLab 本身,当联合创始人 Dmitriy Zaporozhets 在决定开发自己的版本控制服务器软件的时候,他其实也是 PHP 开发背景,但他没有坚持自己熟悉的方法,而是选择了 Rails。


对此,Sid Sijbrandij(GitLab 联合创始人 &现任 CEO)表示了肯定:Dmitry 的判断是有先见之明(或许也有偶然性),但不管怎么说,GitLab 也因此发展得不错。这里的部分原因可归功于 Rails 在良好架构与平易近人之间找到了平衡。

“我们不需要微服务”


在 1971 年发表的文章《关于将系统分解为模块时,所应遵循的标准》中,David L. Parnas 将模块化系统的优势总结如下:


  • 有望“缩短开发时间,因为各独立小组可以在每个模块上工作,彼此之间几乎不需要沟通。”

  • 有望“对单一模块做出重大变更或改进,且不影响其他模块。”

  • 有望每次只学习系统中的一个模块。


Fred Brooks 在后来的《人月神话》中也强调了减少沟通需求的重要意义,认为额外的沟通开销正是“在项目后期再增加人手,反而会进一步拖慢项目进度”的主要原因之一。


Sid Sijbrandij 认为,模块化虽然受到高度追捧,但也往往神秘莫测。因此,设计师们只能从当今世界上规模最大的软件系统中汲取灵感——万维网。考虑到万维网的基本特性,它只能选择模块化构建方式。


使用独立的进程组织本地软件系统,再使用 REST 架构风格将各微服务组合起来,这样确实有助于通过操作系统强制划定模块边界。虽然这是种行之有效的严格模块化实现方式,但对应的成本也相当沉重。


Sid Sijbrandij 进一步说道,目前分布式系统也面临着类似的实现挑战与高昂成本,人们迟迟找不到在分布式计算中保障性能与可靠性的有效方法。


“简而言之,为了保证性能与可靠性,我们只能把原本以纳秒为衡量单位、且永不失败的函数调用,替换成以毫秒甚至秒为衡量单位、而且随时可能失败的网络调用。而且我们经常需要在几乎没有工具支持的情况下,跨多项服务开展跟踪,于是故障诊断变得更加困难。只有相当成熟的 DevOps 组织才能成功运行起微服务架构。总之,请大家明确一点——我们不是谷歌,我们可能搞不定那么复杂的大规模运行体系。”


而且即使是真能管理起来,还有另一个问题要注意:**架构本身的复杂度,是不是已经超出了问题本身的原始复杂度。**微服务并不能降低复杂性,所以想象中的模块化改进最终带来的很可能只是一团永远理不清头绪的乱麻。

模块化单体架构

凭借着良好架构加平易近人、再加高效操作,Rails 帮助 GitLab 开发出了模块化单体架构。模块化单体与分布式架构完全相反:它强调程序应该具有良好的结构、架构以及更高的模块化水平,其中每个进程都能稳定运行且尽可能保持简单。


Sid Sijbrandij 表示,虽然将 GitLab 构建成单体最符合项目预期,但对于具体结构取舍也绝不能太过教条。总之,架构要为需求服务,而非需求为架构服务。


虽然 Rails 确实能帮助 GitLab 有效达成目标,但它也有一些缺点,特别是在性能方面。所幸的是,GitLab 大多数代码库中只有极小一部分需要重视性能。“所以我们用 Go 自己编写了 gitaly 守护进程以处理实际 git 操作,并使用 PostgreSQL 处理非 repo 持久性数据。”Sid Sijbrandij 坦言道。


Sid Sijbrandij 表示,模块化单体架构把 GitLab 的“核心开放”(Open Core)商业模式从理论真正转化为现实。尽管 Rails 本身并不能实现这一点,这是那些出色的贡献者和工程师们完成的,但 Rails 还是为这些成功奠定了基础。


开源运动的“圣经”《大教堂与集市》里提到,为了发挥开源的真正优势,贡献者必须能够随时访问源代码。另一方面,为了在接收各种贡献的同时保持架构完整性,就需要在开放组件和封闭组件之间划开定清晰的分界线、保证代码结构良好。


如此一来,有些人可能会想问,GitLab 为什么不开发一套合适的插件接口呢?或者干脆建立基于微服务的服务接口?对于这类问题,Sid Sijbrandij 的回答是坚决的:没必要。因为这些方法不仅会在部署和集成层面,显著提升源代码轻微改动的实现难度,同时也会带来过于严格的架构实施约束。“谁能预测出未来一切可能的扩展点?根本不可能,我们也压根不打算给自己找这个麻烦。”


“凭借着这些无聊的模块化单体,用户及其他第三方开发商一样能为核心产品做出贡献、并帮助社区积累起巨大的影响力,同时保持着无与伦比的创新速度与可扩展性。”或许在 GitLab 看来,有时候,平平淡淡才是真。


参考链接:


https://about.gitlab.com/blog/2022/07/06/why-were-sticking-with-ruby-on-rails/


https://corecursive.com/045-david-heinemeier-hansson-software-contrarian/

2022-07-07 15:106503

评论 5 条评论

发布
用户头像
够用的设计哲学永远也不过时~适合自己的架构才是最好的架构~
2022-07-11 14:11
回复
用户头像
积重难返 + 够用
2022-07-11 08:49
回复
用户头像
唯一优点就是功能确实比较完善了. 如果Ruby可以站在性能的金字塔上部,如C++; 或者一直是主流语言,如Java,也可以。 结果呢,既是小众语言,生态很差,性能也次,资源占用还高;如果是个商业产品也忍了。 开源出一堆垃圾,真不知道怎么这么好意思
2022-07-09 19:07
回复
Gitlab代码我读过,非常清晰,也很容易修改(毕竟开源),随便改一下就能满足自己的奇怪需求,实在是比研究啥插件系统方便太多了。
2022-07-18 00:51
回复
用户头像
或许在 GitLab 看来,有时候,平平淡淡才是真。
2022-07-08 08:55
回复
没有更多了
发现更多内容

高效打造跨平台桌面应用:Electron加载服务器端JS

快乐非自愿限量之名

跨平台 Electron

Nexpose 6.6.270 发布下载,新增功能概览

sysin

漏洞扫描 Nexpose

inBuilder低代码平台新特性推荐-第二十四期

inBuilder低代码平台

低代码 表单设计

一文搞定WeakHashMap

不在线第一只蜗牛

Java

基于LangChain手工测试用例转App自动化测试生成工具

霍格沃兹测试开发学社

万界星空科技饮料行业生产管理MES系统解决方案

万界星空科技

工业互联网 mes 万界星空科技 饮料行业 食品饮料

openGemini 发布人才培养计划,与顶尖的数据库专家并肩成长

华为云开发者联盟

#开源

【IoTDB 线上小课 07】多类写入接口,快速易懂的“说明书”!

Apache IoTDB

Cloud Kernel SIG 月度动态:ANCK 新增多家厂商硬件新特性支持

OpenAnolis小助手

开源 操作系统 龙蜥社区 龙蜥sig

从源码角度,深度解读 MySQL 优化器的 GROUP BY 优化策略

华为云开发者联盟

数据库

阿里巴巴拍立淘API返回值:商家优化商品信息的参考

技术冰糖葫芦

API Gateway API 接口 API 测试 pinduoduo API

2024新动态:低代码开发占领新常态市场

EquatorCoco

低代码

支持 128TB 超大存储,GaussDB (for MySQL) 如何轻松应对海量数据挑战

华为云开发者联盟

数据库

基于LangChain手工测试用例转App自动化测试生成工具

测吧(北京)科技有限公司

测试

面试官:GROUP BY和DISTINCT有什么区别?

王磊

探索大模型和 Multi-Agent 在运维领域的实践

华为云开发者联盟

AIGC

解决 AI 算法开发和存储难题,华为云 DTSE 助力文华云技术架构升级

华为云开发者联盟

繁星·数智思享会:以流程为中心的数字化转型战役已打响

望繁信科技

数字化转型 流程管理 流程挖掘 流程资产 流程智能

专访阿里云:AI 时代服务器操作系统洗牌在即,生态合作重构未来

OpenAnolis小助手

开源 AI 操作系统 龙蜥社区 龙蜥操作系统大会

二维码固定资产管理系统,中小微企业的合适之选

软件大师兄

低代码 无代码 无代码平台 草料二维码

一文详解低代码开发如何成为学校低成本数字化转型的新引擎

快乐非自愿限量之名

低代码 数字化

在 React 中模拟输入

yuanyxh

前端 js react context

商家运营优化:基于京东API返回值的商品管理策略

技术冰糖葫芦

API Gateway API 接口 API 测试 pinduoduo API

Vue3.5中解构props,让父子组件通信更加丝滑

快乐非自愿限量之名

Vue 前端

中国信通院可信人工智能基础平台(AI Infra)第八批评估工作正式启动

中国信通院AI Infra工作组

低代码开发:助力制造业数字化高质量发展

不在线第一只蜗牛

低代码

豆包MarsCode IDE 搭建 VitePress 博客并使用 GitHub 部署

豆包MarsCode

人工智能 程序员 AI 开发者 计算机

恭喜!龙蜥赛题队获得 2024 大学生操作系统能力大赛 OS 功能挑战赛道三等奖

OpenAnolis小助手

开源 操作系统 龙蜥社区

CDN加速是什么?CDN加速的原理是什么?

Ogcloud

CDN 网络加速 CDN加速 CDN技术 CDN网络加速

个人GPU云服务器是什么

Ogcloud

gpu 云主机 云服务器 GPU云服务器 云服务器租用

Java SE 23 新增特性

EquatorCoco

Java Python

GitLab技术选型为何如此不同:坚持用过气Web框架十多年、坚决不用微服务_文化 & 方法_Sid Sijbrandij_InfoQ精选文章