我一直对API很着迷。事实上,API、分布式系统和网络服务是我学习代码的原因。当我开始我的第一份工作时,作为一个初级的前端开发人员,与后端API互动对我来说并不陌生。我一直很喜欢解耦的客户-服务器架构。当我在2017年开始自谋职业并开始为客户做顾问时,我更多地是面对微服务架构。这让我对整个服务的解耦有了新的认识。
当我在客户的项目上工作时,我也用网站和副业来扩展我的在线组合。其中一个副业项目是一个以课程形式销售自行出版的电子书的平台,这是我在获得自雇的同时开始的。它不仅仅是销售,因为它还提供优惠券代码和合作伙伴计划等功能。
那么,我的网络应用与微服务有什么关系?由于我总是被解耦我的API所吸引,我作为一个单独的开发者也走上了这条道路。事实证明,这对一个人来说是太多了。谁会想到这一点呢;-)因此,我不再使用微服务,这并不意味着拥有多个团队的公司应该停止使用它们。
免责声明:我在这里并不声称自己是微服务专家。我只是在做实验。作为我的副业项目的单独开发者,我没有把微服务方案推得太远,这意味着我没有超过5个微服务就放弃了这种方法,我没有使用K8S或任何其他这些更复杂的技术栈。我把我所有的项目,无论是网站、网络应用程序还是API,都托管在DigitalOcean。
让我们从好的部分开始,以坏的部分结束:
-
软件工匠精神(+):我喜欢建造东西。超越只有两个实体(前端和后端)的解耦客户-服务器架构是我一直想探索的事情。这是一个挑战,每当你开始一个副业时,不仅仅是为了从中获得收入来源,它应该是为了学习而存在的。所以我问自己。是否有可能将我的网络应用程序的用户认证、支付处理和优惠券代码视为解耦的微服务?
-
解耦(+):除了学习之外,所有关于API的设计也让我着迷。是否有可能将我的支付API与我的课程API解耦,而它们又不知道彼此的具体领域?毕竟,一旦支付成功,它需要通知课程域在数据库中创建课程。在一个普通的单体后端应用程序中,很容易忽视这种明确的关注点分离,因为一个服务(模块)可以很容易地爬到另一个服务中,而没有适当的依赖性注入。然而,如果这样的服务变成了一个只有REST或GraphQL API的微服务,你就不得不避免这些错误的做法。
-
可重用性(+):除了一个项目的服务解耦之外,我想知道是否有可能将我的支付API或认证API重用到我的其他副业项目中。毕竟,为每个项目从头开始开发这些东西实在是太累人了。事实证明这是可能的,但有一个巨大的注意事项(见抽象和心理开销)。
-
抽象(-):如果一个微服务应该为了可重用性而被重新利用,我们必须在对待微服务时考虑到某种程度的抽象性,因为它不再处理一个特定的情况了。例如,如果认证微服务应该被重新利用,API和服务必须区分用户认证的项目。虽然这种抽象允许我们避免实现多个认证API,而这些API的作用基本上都是一样的,但它给认证API增加了另一层复杂性,对于一个单独的开发者来说,维护起来会更加困难。
-
功能爬行(-):开始时,支付API和课程API必须一起工作,这并不是太困难。但在一个不断增长的应用程序中,这并没有结束。最终,更多的功能和更多的API会进入你的微服务组成。一旦我开始使用优惠券API,功能爬升开始变得更加明显,因为它不再只是支付API和课程API之间的单向通信。优惠券API必须被用于前端应用程序以验证优惠券代码,同时也被支付API用于处理购买课程时的折扣价格。
-
精神上的开销(-):考虑到所有这些抽象和功能爬升,作为一个单独的开发者,要推理所有的微服务变得太困难了。微服务的解耦变成了一种负资产。毕竟,在一个单体应用中推理所有这些事情更容易,在那里所有的东西都更接近,尽管它只是在精神上感觉彼此更接近,而且没有任何东西被抽象为某种可重用的情景。
-
代码(-):所有的代码不是在一个单体应用中,而是现在分布在几个微服务中。当与多个团队合作开发一个应用程序时,这可能是一个很大的好处,因为团队可以选择性地声明他们领域的某些所有权,然而,作为一个单独的开发者,经历这些是不可持续的。一切都感觉太遥远了,如果不管理另一个外部依赖(例如库),在一个微服务中重复使用另一个微服务中的一般代码是不可行的。
-
稳健性(-):从理论上讲,拥有解耦的微服务对于每个单独的服务的隔离测试目的和稳健性来说听起来很不错。然而,单独工作,并将其扩展到多个微服务,对我来说并没有使它变得更加健壮。相比之下,管理所有这些单独的代码库和它们的API感觉很脆弱。不仅因为它们是松散耦合的,而且还因为API不是类型化的。在一个单体后端应用中,我至少可以确保在使用类型化语言时,所有服务与服务之间的通信都能正常进行。
-
多故障点(-):如果不对微服务使用更复杂的技术栈,随着时间的推移,服务的组成导致了多个故障点。例如,当有一个单体应用部署时,你会立即知道事情发生的时间。然而,当有多个微服务部署时,你必须确保在事情发生时,每个服务都能得到适当的通知。当你在没有任何错误的情况下浏览应用程序的其他部分时,一个离线支付API并不明显。然而,在这里,我想拥有适当的基础设施设置的资源会有巨大的帮助。
-
基础设施管理(-):作为一个副业项目的单独开发者,管理所有的基础设施实在是太多了。我用一个专门的DigitalOcean实例来管理我所有的API,但要保证一切都按预期进行并不容易。在扩大规模时,所有的CI和CD都需要正常工作,所有的代码都需要处于最新阶段,而且任何部署的服务都不应该有缺陷(见多处故障点)。
正如你所看到的,我作为一个单独的开发者的经验与我合作的拥有多个团队的公司有很大的不同,他们能够用大量的资源来管理他们的微服务组成。如果我有世界上所有的时间,我将继续使用微服务。然而,作为一个单独的开发者,我坚持使用一个单体的应用程序,这为我提供了更多的优势。