1,微服务架构是什么
很多做微服务的程序猿都很避讳SOA架构,谈起微服务必然和单体应用进行对比,好像不如此微服务架构就不高大上,不足以与有荣焉。
然而,从单体分层应用到分布式架构,再到面向服务的架构,直到微服务架构,都是在前者的基础上为解决面临的问题而一步步发展而来,甚至于在解决问题的同时,也总是引入新的问题(比如技术复杂度越来越高),只有在有效解决引入问题后,新的架构风格才能体现其价值。
单体分层应用 到 分布式架构:
当单体分层应用模块之间耦合严重,不能针对行扩展集群的问题越来越不能忍受后,产生了分布式架构,分布式架构降低了每个单体应用的复杂度、可以灵活不是升级和横向扩展集群,但是引入了问题:进程间通讯。当时主要是采用EJB框架或者其他RPC组件,以解决进程通讯问题。同时引入了分布式事务等问题和各种解决方案。
分布式架构可以理解为:多个单体分层架构系统,以进程通讯技术整合到一起的一种架构风格。
分布式架构到SOA架构:
随着分布式架构风格构建的系统,进程通讯使用的RPC封装相关问题、接口描述稳定性、异构系统问题等导致使用技术复杂度高和难以维护的问题越来越突出的时候,为解决问题,就出现了SOA架构风格,就像是编程引入的面向接口编程,要求所有分布式中的单个系统都定义和发布明确的服务接口,并采用webservice技术等解决异构系统之间的交互。同时,SOA架构引入了服务治理的难点,当dubbo等框架逐渐成熟,有效解决各种问题后,SOA架构才算真正体现价值。(但事实上,webservice性能问题等原因,dubbo依然采用RPC,做进程通许,在这一块儿,复杂度依然不可避免。)
SOA架构也有直接称为:面向服务的分布式架构。
SOA架构 到 微服务架构:
SOA架构是一种复杂度很高的架构模式,一般大型的、用户量非常大的产品采用,这种环境下的产品面对复杂多变的需求,产品的快速迭代,需要更小、更灵活以及更高的自治的小应用来应对,每个小应用根据自身的业务需求等确定技术选型,相互之间通讯抛弃复杂度高的重方法(RPC),以更好的快速响应市场变化。
所以简单来说:微服务架构就是:一种粒度更小,更轻量级、去中心化的、服务间通讯采用轻量级通讯机制(通常是restful API)的SOA架构。
从SOA架构到微服务架构,从技术上其实没有跨度,可以理解为:微服务是一种方法,指导更好的实现SOA架构。
不要认为SOA就必须采用ESB,ESB只是实现SOA的一种技术,微服务建议不采用ESB这种中心化的富贵论坛管理实现SOA。
微服务的核心思想就是:以更轻、更小的粒度来纵向拆分应用,各个小应用能够独立选择技术、发展、部署
2,微服务设计原则和实现
1,高内聚、低耦合
分布式架构纵向拆分系统时,不管如何强调高内聚、低耦合,都不为过。微服务的架构更是如此,因为大的系统,被拆分很多互相协作的小应用,这会导致服务之间的交互量会大大增大,如果不能高内聚、低耦合,对服务的管理、监控就会提出巨大的挑战。如果牵一发而动全身,那么维护变得比单体应用的复杂度更高,得不偿失。
如何纵向拆分,获得高内聚、低耦合的分布式应用?
围绕业务进行建模,按照业务的领域模型进行分析;按照界定上下文,划分业务领域;界定上下文之内的各种模型是稳定的,并且内聚的。在一个业务的界定上下文下,内部的各种模型之间交互,完成该上下文的业务逻辑。各业界定上下文之间的输入输出,其实就是拆分后各个小应用之间基本的服务需求。各个小系统按照界定上下文涉及的业务内聚,同时只有各个输入输出之间依赖,没有业务上的复杂耦合。
领域驱动设计的基本概念和内容,参见:DDD简要描述
2,只发布有价值的服务
微服务架构拆分出来的小应用可以具有技术、部署等独立和灵活性,但是绝不是意味着小应用就可以为所欲为。
在小应用的服务设计时,要有清晰的系统意思:整个分布式系统中的所有小应用+使用软件产品的组织和人,一起协同运作才是一个系统。单独的小应用本身需要和其他应用协作才能产生价值。
小应用应该向外暴露且只暴露有价值的服务。
应用暴露的服务是否有价值,从下面考虑:
1,服务是服务于业务场景的,一个不会被使用的服务是没有价值的。可以提前定义服务,但是,是依赖于对业务的分析和发展的预期,而不是:“未来可能有应用会用到”。不管你多喜欢这个服务,都不应该因为小应用团队自身的喜好而给其他协作团队带来不必要麻烦。
2,服务的价值依赖于业务场景价值实现来体现,尽量优先实现和发布价值高的服务。
(如何判断需求的价值、优先级?从产品立项,产品在组织的整体运营目标中就是具有其核心价值的,是从组织整体的运营目标中拆分出来的,是承担了服务整体运营的任务的,这就是产品的基本原则来源。产品原则确定什么最重要,是对团队信仰和价值观的总结,用来指导对US价值、优先级的衡量。)
3,服务接口稳定
服务接口是对相关协作应用团队的承诺,其他团队使用信息是完全基于接口说明的,如果接口多变,会导致协作工作量剧增。
如何使服务稳定:
1,良好的领域分析,对业务流和数据交互掌握清晰,并对潜在的业务变化有一定的预测,并清楚哪些变化点可能影响到服务,有一定的前瞻性设计;(并不推荐过于强调可能的变化点)
2,尽量采用异步方式进行小应用间的交互,通过消息发布、订阅机制,让订阅者决定实现方式,减少应用间的服务依赖。(当然,消息也需要进行良好的设计和定义)
4,严格区分公共模型和内部模型
应用内部实现不应该暴露给不需要的应用,内部模型反应了内部业务信息,不应该混用公共模型和内部模型。公共模型是稳定的需要交互的信息,公共模型可以在交互的系统间复用,但是内部模型是不稳定的,应用团队可以根据需要随时进行重构。
如何分离:
对外暴露服务的出参、入参、消息体等都应该抽取出来定义到jar包中作为公共模型,该部分jar包可以被需要交互的应用引用。该包中的内容应该是相对稳定的,随着暴露服务的增加,会有增加,但是不应该轻易变化。
3,服务化技术栈
微服务条目(落地技术)
服务开发(springboot、spring等)
服务配置与管理(Archaius等)
服务注册与发现(Eureka、Consul、Zookeeper等)
服务调用(Rest、RPC、gRPC)
服务熔断器(Hystrix、Envoy等)
负载均衡(Ribbon、Nginx等)
服务接口调用(客户端调用服务的简化工具;Feign等)
服务配置中心管理(SpringCloudConfig等)
服务路由(API网关;Zuul等)
服务监控(Zabbix、Nagios、Metrics、Spectator等)
全链路追踪(Zipkin、Brave、Dapper等)
服务部署(Docker、OpenStack等)
消息队列(RabbitMQ、Kafka、ActiveMQ等)
事件消息总线(SpringCloud Bus)
总结
微服务架构实践并不容易,不可能强大无匹还简单无比。虽然有很多现有框架对微服务在技术上都能有很好的支撑(比较而言:spring cloud应该是对SOA架构各方面支撑最全面的框架)。但是必须意识到微服务不是一蹴而就的,也不是一劳永逸的。做好技术和环境准备,再一步步实践,必要的调整以期逐渐完善。