最佳实践听起来很棒。为什么我们不想确保我们的软件是最好的呢?这样做比使用每个人都认为最好的做法更好吗?这是我在职业生涯早期非常关心的事情。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--JkMpQS4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.professorbeekums.com/ img/2019/context.jpeg)

我曾在各种情况下工作过:从小公司到大公司、消费品和 B2B 产品、纯软件公司和销售实体产品的公司、新软件到大型成熟系统。这帮助我艰难地了解到,虽然有一些软件实践平均而言是好的,但始终考虑到你正在构建软件的环境是很重要的。

让我们以微服务为例。一群开发人员批评单体系统已成为家常便饭。我肯定参与了这些讨论,过去很少为巨石辩护。让 20 到 30 名开发人员为单个代码库贡献代码是一件相当麻烦的事情,尤其是当有人想要修改“核心”代码或更新库时。相反,让每个团队维护自己的一组微服务可以解决很多问题。

然而,微服务有大量的开发开销。根据定义,每个都将在自己的存储库中。如果您有一个需要修改多个微服务的功能,这会使事情变得复杂。这也使部署变得复杂,因为您必须确保以正确的顺序部署所有内容,并且不会破坏向后兼容性。这在单体应用中不是问题,因为所有代码都是一次性部署的。

微服务还增加了基础设施开销,因为它们都需要自己的监控和备份。有趣的是,您往往还想定期测试它们以确保它们仍然有效。找出所有备份已损坏的最糟糕时间是您真正需要它们的时候。更多的微服务意味着花费更多的时间来做这个测试。

对于一家成长中的公司,微服务也使入职流程复杂化。对于新开发人员来说,一套微服务的设置比单体架构更复杂(除非单体架构真的设置得很差)。这可以通过 Docker 来缓解,但是当添加新的微服务或对现有微服务进行系统更改时,您需要有人维护 Docker 设置的开销。

最后,由少数开发人员组成的单个团队可能会在单体应用中做得最好。对于每个新开发人员,维护单体应用的开销最终将超过微服务的开销,此时应考虑过渡。在此之前构建微服务弊大于利。

另一个例子是将数据捆绑在一起以提高效率。在 SQL 数据库中,我们可以使用 JOIN 查询来做到这一点。在 NoSQL 中,我们可以通过在文档中嵌套更多数据来做到这一点。这通常有很多意义。当您只能进行 1 次查询时,为什么还要对您的数据库进行 2 次或更多查询?以这种方式进行优化可以帮助在中短期内扩展,并且可以更好地提高性能。

不幸的是,从长远来看,这方面的多重挑战开始出现。让我们假设您觉得将单体应用拆分为微服务是个好主意。将大部分数据捆绑在一起会限制您这样做的能力。您最终会遇到一种情况,您必须分析所有数据以找到合适的拆分,然后才发现没有多少可以拆分的内容。为了进行转换,必须重写大量代码以解耦数据。

它还使其难以扩展,至少对于 SQL 而言。 SQL 服务器不以水平扩展而闻名,单个服务器能够做的事情也只有这么多。拥有大量 JOIN 使得很难将表拆分为它们自己的数据库,因为您无法跨多个服务器运行 JOIN 查询。这也使得对数据库进行分片变得很困难,因为您必须确保需要加入的所有数据都在同一个分片上。

话虽如此,确保您的所有数据都是独立的有其自身的问题。除了进行更多查询的性能开销之外,您还必须处理管理所有独立数据源的更多开发开销。

这里没有正确答案。做“最好”的事情取决于您正在构建什么样的软件以及为谁构建它。每种方法都需要权衡取舍。你不能简单地选择一些东西,因为其他人都认为它是最佳实践。必须考虑到您的独特情况。每个设计决策都必须有一个真正的理由,而不仅仅是因为它是如此。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐