Lagom is a Swedish word meaning “just the right amount”.
当我们谈论微服务时,大多数人会关注这个“微”字,假设它的含义是服务粒度应该小,那么这个假设成立吗?这是一个错误的问题,我们应该关注的是在把系统分解为微服务时、找到正确的服务边界,这个边界的划分原则是清晰的有界上下文bounded contexts、业务功能business capabilities、以及隔离需求isolation requirements. 服务粒度够不够小是果而不是因,别管这个问题了,专注于设计“Lagom”的微服务吧!“micro”微指的应该是职责的范围而非代码行数,指导原则仍然是Unix哲学的单一职责原则ngle Responsibility Principle (SRP): let it do one thing, and do it well.
牢记微服务的核心价值是弹性或者叫横向扩展、高可用、服务迁移blablabla......what ever,要实现这些价值的必由之路是分布式。BTW如果你不需要这些,那就别用微服务,简单说就是能别用就别用。
微服务的原则是Divide and Conquer分拆与征服:大系统小做,把系统分拆为discrete离散的、isolated互相隔离的子系统。微服务的出现不仅仅是技术原因,类似OO,它们的起因是大规模代码难以驾驭、人力几乎无法驯服,导致“大部分系统只是碰巧能够工作”。第一次改变尝试叫SOA,但是基本失败了,但到2016年,很多制约因素变化了:网络更快了、磁盘更便宜而且快得多了、内存便宜了、多核CPU普及了。
J2EE应用服务器AS支持的都是单体巨兽模型:WebLogic、WebSphere、JBoss、Tomcat(即使它不支持EAR):
AS使用 class loader tricks 管理各个服务jar,对服务做基本/简陋的隔离,对这种经典J2EE的第一次冲击是spring,spring主要是轻量化和解耦改进,而服务隔离和分布式是彻底革命。
时至今日,已经出现了更多、更精细的服务隔离手段即虚拟化virtualization, 包括:Linux Containers (LXC), Docker, and Unikernels. 我们可以开始正儿八经做服务隔离了,因为服务隔离是如此重要,我们表面上看到的是要持续交付、高效运维,这些只是树叶和花朵,君不见它们的树干是弹性系统,而树根是服务隔离。作为javaer值得思考的是如果我只用JVM语系构建系统,那么JVM即可作为一个绝佳的成熟虚机,微服务作为SOA2.0,是一个大口号,它与语言无关,它要做通用规范就需要更底层的虚拟化。微服务就是actor,actor即微服务。
隔离是弹性的前提和基础,它还要求异步通讯:微服务已经互相隔离了,它们之间是异步通讯的,这样才能在时空两方面解耦:
1、Time时间:支持高并发;
2、Space空间:允许分布式和服务迁移,这样才能进一步地消除共享的/可变的状态,然后更进一步滴:最小化互相之间的远程协调coordination, 比如消除分布式事务(这种怪兽级stuff从来就不应该出现),这样才能最小化互相之间的冲突和达成一致的代价,在高并发大规模分布式系统中出现冲突那是要命的,所以:要构建一个顺畅的系统,我们需要的是Share-Nothing Architecture.
隔离天生自带如下好处:
1、失效隔离Failure isolation,也称为舱壁模式:
该模式带来自治自驱,每个微服务对外无依赖,完全自主决策自己的行为和状态。
2、弹性:从失效中恢复的能力,它基于隔离,它要求必须破除同步通讯及其带来的强耦合,微服务要求进程之间要异步通讯、无论这俩进程在一台节点机还是不同节点机、只要是跨进程边界的通讯优先要求用异步消息,以此来解耦对于失效的监管,不同于以往对失效/异常的工作流处理模式,现在对失效的监视和应对使用服务监管 supervision 模式,actor语言Erlang和actor库Akka都实现了监管模式,Akka在本地使用父子监管、远程使用DeathWatch监视(通过"akka.watch.heartbeat.pause"设置心跳暂停。心跳暂停应该要是心跳间隔的倍数。失败阀值可以通过"akka.watch.threshold"配置来设置)。进程边界即微服务之间的有界上下文bounded contexts. 微服务理论基本将一个进程视为一个微服务,对应到Akka中则是在一个节点机上运行的actorContext——JVM进程,只不过actorContext同样是由微服务形式的actor组成,可以说Akka是更彻底的微服务、Akka也是更彻底的OO:每一个actor完全自治自驱、达成自洽self-consistent.
Isolation is a prerequisite for autonomy(自治、人身自由). 我们知道,人群是人的坟墓,人也多嘴也多是讲不清道理的,人的自主性比你想象的脆弱得多,当你身处人群,外界的嘈杂或强力的权威可以轻易摧毁你的独立思想,人们走到一起实际上只会形成一种群体:乌合之众,这是因为你与外界“耦合”过多,当一个人的有限精力都被外界干扰填满,长此以往这会形成可怕的习惯,这种恶习能轻易扼杀你的独立思考能力。
软件亦然,一个对象的状态就像一个人的思想,它们都决定了这个对象/人的下一步行为,外界可以与你交互,但决不允许直接插手读写你的状态,外界的交互首先经过你的自主处理/独立思考,然后完全由你自己做出判断、自主决定自己的状态和下一步的行为。
3、持续交付 Continuous Delivery:服务之间的隔离天生带来持续交付能力,持续交付允许你以一个服务接一个服务的增量形式、安全地部署服务应用、滚动升级甚至回滚;
4、开发改进:每个微服务现在可以独立开发调试了,在单体巨兽应用中这很难。对应idea每个微服务可以作为一个module模块,可以单独启动调试开发打包;
微服务是SOA新瓶装旧酒吗?
“How splendid his Majesty looks in his new clothes, and how well they fit!” everyone cried out. “What a design! What colors! These are indeed royal robes!”
—“The Emperor’s New Clothes” by H.C. Andersen 皇帝的新衣是乌合之众的童话版,而那个说出真话的孩子,是牛顿、是达尔文,孩子引领人类的进步。
是,微服务和SOA的初心是一样的:decoupling, isolation, composition, integration...
也不是,SOA可能是被误解最多的,讲真大部分都是误用而导致的复杂系统,这个系统以Enterprise Service Bus (ESB)为核心,串接起来各个单体应用,对遗留应用没有做重构和分拆,类似巨兽联盟。微服务的微字强调要勇于分解巨兽,如果直接拿过来遗留的单体巨兽应用作为服务单元,它太重了,服务的迁移和恢复一定很壮观...
今天的软件世界和SOA出现的10~15年前大不相同了:多核CPU、云计算、移动设备以及IOT迅速崛起,这意味着:所有的系统都是分布式系统!新的挑战要求新的思考方式:响应式也就是actor模型,最早由 Joe Armstrong and Robert Virding 在Erlang语言中实现,微服务可以说是这几年响应式方法论的最佳实践之一。
在IOT物联网,大量传感器生成的上报数据属于一种日志:append-only不可变的、totally-ordered总体有序的事实数据journal:
从左到右时序递增、数据产生时间从早到晚,可以以最新一条的entry时间戳作为整个数据分片的版本标识,用在分布式环境下可以识别一台节点机上数据的版本。