写点什么

不要以模块化为理由去实施微服务

作者:neverwinter
  • 2023-11-18
    上海
  • 本文字数:1286 字

    阅读完需:约 4 分钟

不止一次听说,采用微服务的原因是为了模块化。这是大错特错的。

有哪些模块化手段?

对于软件来说,模块化永远是正确的,这一点无需质疑。为了实现模块化,方法很多。任何手段只要能够让我们对代码进行封装,隐藏内部细节,就都可作为模块化的手段。

编译期

首先就是编译期完成的,一种静态的模块化方案。对于简单的程序,可以把一个函数当成一个模块,或者把一组函数当成一个模块,比如 C 语言里的 stdio.h,本质上就是一个模块。面向对象的程序语言提供了类和包等语言结构,也可以用来做模块化。现代的程序语言,一般都提供了更高级的结构,像 rust,直接提供 mod 用来做模块化。Java9 之后,提供了 jigsaw 模块化支持。


编译期的手段最可靠,最容易掌握,最容易重构。在开发工具的帮助下,我们更容易搞清楚模块间的关系,更容易调整模块。这种方式几乎没有性能开销。

运行期

除了编译期的解决方案,还有一些运行期的方案。运行期的方案又可以分两种,

进程内

一种是进程内的。比如 C 语言的动态链接库,java 的动态载入 class,OSGI 等。这些方案,都是在一个进程内动态载入程序块。相比于编译期的方案,这种方案更加灵活,要付出的代价就是,模块间不匹配的可能性更高了。一般这种方案中,模块的接口定义还是和编译期一样,是通过语言提供的机制来实现的,所以依旧可以依赖开发工具的帮助。

进程间

另一种,则是进程间的。同一个服务器上多进程,跨网络分布式的多进程等等。服务化,微服务化,都是属于这一类的了。这个时候,模块是一组进程。进程间只能通过数据交换通信,信息需要被序列化和反序列化。这意味着,失去了程序语言编译期的保护。我们已经不能通过 IDE 快速可靠的重构代码,发布变更也变得更加复杂。

模块化技术选型

首选编译期模块化技术。如果需要在运行期动态替换模块,考虑进程内模块技术。任何时候都尽量不要使用进程间模块化技术,尤其是不要用分布式模块化技术。


我们首先要使用成本低廉,不容易出错的编译期模块化技术,来做好模块化。如果这一步都做不好,那么即使你直接上微服务,也不可能做好模块化,只会得到分布式大泥球。


实际上所有可以用来做分布式模块化的技术,它们的设计目的都不是用来解决模块化的,而是解决其它问题。


SOA,本质来源于企业应用本身的复杂性。比如,一个企业的财务系统可能是购买 A 公司的产品,供应链系统是自己研发的,HR 系统是购买 B 公司的产品,那么这些系统天然就是分开的,自然就各自服务化。或者大规模的企业,由于不同的部门,子公司,业务线,处于协作上的目的,遵循康威法则才做的服务化。这么做的初衷,并不是为了模块化。


微服务,它的初衷是为了应对伸缩性的挑战。系统中存在某些功能的伸缩性要求和别的功能不一样,为了节省成本,才去采用微服务。比如,一家公司的业务功能 A 每天在一段时间访问量是其它时段的 1 万倍,而另外的功能 B 每天所有时段的访问量都只有前者的千分之一。这种情况下,这个这家公司需要在 A 功能高峰期,增加大量的服务器,过了高峰期再下线这些服务器。如果 A B 功能在一个进程内,即使 B 没人使用,也会占用一部分的机器资源,这些资源成了一种浪费。因此需要把 A 和 B 分开到不同的服务中。这才是采用微服务的意义。

发布于: 刚刚阅读数: 4
用户头像

neverwinter

关注

还未添加个人签名 2017-10-25 加入

还未添加个人简介

评论

发布
暂无评论
不要以模块化为理由去实施微服务_架构_neverwinter_InfoQ写作社区