最近调研了一些支持Microservices的框架系统,发现大致有两类:一种是致力于支持互联网领域的微服务框架系统,比较出名的是Netflix开源的一系列微服务项目;另一种是致力于将传统的企业级软件(monolithic system)改造成跑在支持微服务的系统上。这两类系统有一个很大的不同, 那就是企业级软件通常能跑在一台机器上,所以如果把它们移植到微服务系统上,这类微服务系统自身要能跑在一台机器上,并且每个服务的足印要很小,才能和传统的企业级软件的足印相似。举个例子,如果一个企业软件原来是跑在Tomcat server上,并且通过Spring Rest暴露出很多的服务,但是业务逻辑都是耦合在一起的。现在我们如果想改造它跑在微服务系统上,这个系统最小也可以跑在一个机器上。而互联网领域的微服务框架系统就没有这个限制,它的每个模块都可以部署在一个独立的机器上。我们这里要讨论如何为传统的企业级软件选取一个相应的微服务系统,从而进一步改造它。
我们一般需要什么样的微服务系统呢?Akka的作者最近写了一篇"Reactive Microservices Architecture"的文章,对这种系统的几个特征进行了详细的介绍。我比较赞同的观点包括:
- 每个微服务应该只做一件事,并且把它做好。因此微服务不一定是微小的。
- 微服务管理的状态是文档。
- 每个微服务是独立的,自我管理的。
- 系统要支持异步通信。
- 微服务位置是可变的,但总是可寻址的。
- 系统要负责每个微服务都需要的功能,比如安全管理。
对于一个比较复杂的企业软件,当我们把它们改造成基于微服务的软件之前,我们希望下面的微服务框架系统还能有更强的一些能力,包括:
- 将微服务暴露成Rest服务
- 基于任务的工作流
- 内置的异步通信,和基于之上的并发操作
- 提供至少一种状态管理系统
- 状态的多版本维护,以便于对历史的查询
- 支持微服务的高可用性,复制,可扩展性
- 状态监测和统计
当带着这些问题去搜索可用的开源微服务系统,我发现了一个很不错的开源项目Xenon (https://github.com/vmware/xenon/wiki)。License是Apache License Version 2.0, 非常友好的开源License。经过一些时间的研究,我发现这个系统设计的很简练,轻巧,同时提供了很多强大的功能,上面列出的很多需求Xenon都能满足。下面让我们看看Xenon是如何满足这些需求的。
Xenon的框架平台主要是基于Java的,使用Netty(NIO)作为支持异步网络请求的基础。它是一个分布式的结构, 每个机器(可以是物理机或者虚机)可以跑一个或者多个服务主机,一个服务主机在Xenon中称为一个节点。每个节点可以运行几千个微服务实例,因为每个服务实例的足印很小,只有大约360字节。多个节点可以形成一个节点组,然后通过组可以支持服务的高可用,复制和扩展。通过这个结构,我们可以看出最基本的部署方式是在机器上启动一个服务主机,然后将传统的企业软件转变成多个微服务部署在服务主机上。启动一个服务主机很简单,只需要运行 java -jar xenon-host/target/xenon-host-*-with-dependencies.jar。
Xenon提供的Example Service Tutorial (https://github.com/vmware/xenon/wiki/Example-Service-Tutorial)很容易上手,可以帮助我们很快的理解如何在服务主机上创建一个微服务实例,和系统提供的一系列功能。例如这个教程会演示如何通过POST请求创建一个有状态的服务,并将状态对应到一个文档存储到后端的Lucene上。每次的文档更新都有对应的版本。对于不熟悉Lucene的开发人员,可以将文档管理系统替换为其他的系统。我们可以通过每个服务暴露的状态服务(stats),来查询服务状态,也可以通过默认的UI来快速熟悉Xenon的可视化服务监控模块。
虽然Xenon目前的版本是0.8.0,但是我们会发现它已经支持很多实际项目上会用到的功能,例如基于任务的工作流,丰富的异步并发操作,精心设计过的支持高可用,复制的框架。我想可能有两个原因。第一是这个项目的主导者Geoge在这个领域有很深厚的技术积累,在开发这个项目之前,他在Google和F5有多年的分布式控制系统的研发经验,目前是VMware技术级别的最高层:Fellow。第二是这个项目已经被用到VMware另外一个开源分布式项目Photon Controller的服务搭建上,所以有很多实际的需求被反馈到Xenon中并予以支持。
从使用者的角度,Xenon提供详尽的文档来帮助用户理解系统功能。例如基于任务的工作流,我们可以参考https://github.com/vmware/xenon/wiki/Task-Service-Tutorial。相信开发过基于Rest服务的人都不会陌生任务,也就是那些不能立即返回的操作,我们都可以将它们当做任务,然后用户可以查询任务状态,或者订阅任务状态改变,而不用阻塞在这个操作上。丰富的异步并发操作,也是Xenon很吸引人的一个地方,它提供了多种并发组合操作,例如一个服务可以并行发出多个请求到多个服务上,当这些服务请求都完成时,这个服务更新自己的状态。也可以通过发布者-订阅者模式异步通知。当然为了支持常用的工作流,多个服务的顺序调用在Xenon中也是可以的。
最后,我们再简单的讨论一下服务的安全访问和可寻址。Xenon目前只提供了基本的基于本地用户名和密码认证的方式,我们在实际工作中需要扩充来支持自定义的认证方式。可寻址在Xenon中就是将服务的URI地址存到Lucene中,然后发出查询任务到Lucene中,返回符合条件的所有服务。
Xenon的文档也简单讨论了如何设计微服务,可以参考https://github.com/vmware/xenon/wiki/service-design-patterns。对于喜欢研究Xenon背后实现细节的同学,Xenon也提供了详细的文档介绍,例如我们可以参考https://github.com/vmware/xenon/wiki/Leader-Election-And-Replication-Design来学习Xenon基于组的分布式系统所用到的协议。