monolithic vs microservice

微服务( Microservice )是最近几年出现在架构领域的新的术语,无数的人根据自己的理解去解读微服务,一时间它成了秒杀单体应用(Monolithic )、解决任何问题的灵丹妙药。

微服务真的是终极解决方案?单体应用真的没必要?什么时候适合单体应用?什么时候需要拆分服务?一个大的分布式系统如何从简单的单体应用成长为复杂的分布式微服务?本文将尝试回答这些问题。

用 1 个程序实现所有的功能,这是一个单体(Monolithic )应用。运行程序,所有的功能都属于同一个进程,它们之间的调用属于进程内通信。这就保证功能模块之间的同步通信,调用速度快。单体应用可能存在的问题包括:
一个进程集成了所有的功能,意味着它需要更多的系统资源。是否存在能够提供这些资源的主机?用户是否能够或者愿意负担这样的主机?
修改或者升级任何功能模块,必须先停止运行整个应用,导致应用暂时不可用。

把所有的功能划分为 n 个部分,分别用 1 个程序实现,这就是一个多体应用。多体应用既可以部署在单机上,也可以部署在多机上。

分布式应用的不同进程需要相互配合和协调,才能够完成指定的任务。这就要求在承认异步的前提下,提供可靠的故障检测机制、可靠的点对点通信和群组通信、可靠的数据一致性(核心点之一是定义逻辑顺序)等。这正是分布式系统研究的核心内容。

再看微服务( Microservice )的概念。首先,「微」意味着要拆分所有的功能,且分得相对较小,再实现为对应的程序;其次,「服务」意味着这个程序有多个(种)消费者,这些消费者的编程语言、框架和支撑系统不尽相同。这就要求提供标准化的命名和发现机制、访问协议和交换数据格式。像现在流行的一种实现方式,是以 RESTful 风格 API 形式提供微服务,用 DNS 作为服务命名和发现机制, HTTP(S) 作为访问协议, JSON 作为数据格式。

对于一个分布式系统,在设计架构时,我们需要考虑下列问题:

  • 要不要拆分功能,拆分的粒度多大?

  • 拆分后的不同组件,是部署在单机上还是多机上?

  • 其中的一些组件,需要为多个(种)消费者提供服务吗?

  • 各个服务间如何通信?

  • 一个服务挂掉如何保证其他依赖此服务的服务的可用性?

  • 分布式事务如何保证?

对于初创公司,要以实现业务功能为先,此时,由于人力、财力都较少,所以适合单体应用,快速开发、部署。

后面随着业务的发展,人员的增加,开发、运维人员的完整,系统也逐渐发展变大,一些公共的功能可以拆分出去作为独立的服务,交由专门团队维护,这样做,一是提高复用,避免重复造轮子;二是,减少依赖;

再然后,业务继续发展,人员继续增加,此时我们的系统已经相当庞大了。需要将一些核心功能拆分,将大系统拆分为多个微服务,分开部署。提高开发效率。但这样不可避免的增加了运维的成本;

基本上,大的互联网系统都是按照上面的路子演化而来。君不见,淘宝最初也只是一个php写的bbs。

一个大型的分布式系统,最核心是做好下面四点:

  • 大规模分布式缓存系统。单靠数据库当然不可能,几台redis、mongo啥的也不够,需要上百台内存存储。并做好可靠的故障转移,冷然数据处理。

  • 高效可靠的队列系统:亿级pv意味随时有大量数据从用户端产生,并且有一套复杂的后端系统,任意数据提交都需要考虑对这些分布式存储、服务的影响。高效可靠的队列服务必不可少。

  • 细粒度的数据服务系统:用户数据读写、统一id生成、图片视频的写入读取、核心业务对象(例如电商商品订单)的读写都需要独立服务化与子系统化,并能与其它系统实现高效方便的rpc通讯。

  • 强大的线上监控、部署系统。能应对突发故障、流量。