SCL和你聊聊--微服务
引子
现实中笔者曾经见到过近百个应用最终的数据存储只有一个数据库的奇葩设计,整个项目大部分的业务逻辑是落在数据库的存储过程中,业务代码基本都是CURD。咨询这个架构的参与者,为何这么设计时,答曰“便于后期业务量上来后的部署拆分”。到笔者看到时这个项目的整体qps还没有过百;
看到这个例子,相信很多开发者内心都在想这又是一个 “为了微服务而微服务” 的项目,那么接下来笔者将和大家一起聊聊微服务。
什么是微服务
微服务由Martin Fowler和James Lewis 在2014年提出,微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。
亚马逊认为微服务主要有一下四个特性:
1、粒度小,且专注于一件事;
2、独立的进程(java的tomcat,nodejs等);
3、轻量级通信机制,通常是HTTP/REST(接口);
4、松耦合,可独立部署(这点是微服务与单体服务的核心区别);
为什么是微服务
我们知道,这些年来随着设备和新技术的发展,软件的架构模式发生了很大的变化。软件架构模式大体来说经历了从单机、集中式到分布式微服务架构三个阶段的演进。随着分布式技术的快速兴起,我们已经进入到了微服务架构时代。
我们先来分析一下软件架构模式演进的三个阶段。
第一阶段是单机架构:采用面向过程的设计方法,系统包括客户端 UI 层和数据库两层,采用 C/S 架构模式,整个系统围绕数据库驱动设计和开发,并且总是从设计数据库和字段开始。
第二阶段是集中式架构:采用面向对象的设计方法,系统包括业务接入层、业务逻辑层和数据库层,采用经典的三层架构,也有部分应用采用传统的 SOA 架构。这种架构容易使系统变得臃肿,可扩展性和弹性伸缩性差。
第三阶段是分布式微服务架构:随着微服务架构理念的提出,集中式架构正向分布式微服务架构演进。微服务架构可以很好地实现应用之间的解耦,解决单体应用扩展性和弹性伸缩能力不足的问题。
我们知道,在单机和集中式架构时代,系统分析、设计和开发往往是独立、分阶段割裂进行的。
比如,在系统建设过程中,我们经常会看到这样的情形:A 负责提出需求,B 负责需求分析,C 负责系统设计,D 负责代码实现,这样的流程很长,经手的人也很多,很容易导致信息丢失。最后,就很容易导致需求、设计与代码实现的不一致,往往到了软件上线后,我们才发现很多功能并不是自己想要的,或者做出来的功能跟自己提出的需求偏差太大。
而且在单机和集中式架构这两种模式下,软件无法快速响应需求和业务的迅速变化,最终错失发展良机。此时,分布式微服务的出现就有点恰逢其时的意思了。
怎么实现微服务?
随着微服务的火热,大家都开始在拆分应用,那么什么时候拆分?怎样拆分?拆分的边界在哪里?大家的疑惑就变得越来越多,那么接下来笔者将聊聊自己的观点。
什么时候拆分?
微服务的复杂性高
对于单体架构来讲,我们只需要维护好这一个项目就可以了,对于微服务架构来讲,项目是由多个微服务构成的,每个模块出现问题都会造成整个项目运行出现异常,问题排查往往不容易,我们无法一步一步通过debug的方式来跟踪,这就对运维提出了很高的要求;
微服务的技术要求高
对于微服务架构来说,分布式(RPC、MQ、缓存、数据库等)是必用的技术,由于分布式本身的复杂性,导致微服务架构也变得复杂起来,对技术、运维等人员的技术要求高。
综上,在公司的业务量还比较小的时候,单体应用的开发成本和维护成本都比较低,这个时候就没必要去做微服务的拆分了。同时在业务量比较小的时候,公司的技术应该更加关注业务,实现业务的快速适应,沉淀业务知识,先将业务做起来。
怎样拆分?
微服务的拆分并不是单纯的涉及应用拆分,同时也要关注数据的分离。通过对业务模块的拆分,将关注点分离,实现业务领域的协同,同时避免相同功能的重复建设。遵循“高内聚、低耦合”的原则实现不同服务的业务划分。
拆分步骤:
1、业务职责划分。根据什么维度来进行应用的职责划分。业务职责的划分是微服务拆分的重点,笔者之后会根据DDD(领域驱动设计)的理念来进行介绍。
2、技术准备。需要你的团队具备RPC(分布式服务)、MQ(分布式消息)、分布式数据库、缓存、分布式调度、分布式搜索等相关的技术。笔者之后会对此一一介绍。
回到文章开头提到的例子,我们能够发现以下几个问题:
1.拆分的时机不对。在业务量很小的情况下没必要拆分,近百个应用的开发和运维是不小的成本。
2.拆分的方式不对。虽然有近百个应用,但是共用一个数据库,这样的架构设计在笔者看来依然是单体应用。因为最终压力会汇集到数据库上,只要数据库一挂所有服务全挂。服务的拆分应该是应用和数据库一起拆分的,数据存储和应用服务共同构成了服务。应用拆分目的之一就是提高应用的横向扩展能力,通过增加机器能够达到服务能力的整体提高。数据库服务能力的提高只能通过增加硬件配置来提高。
3.拆分的粒度不对。应用根据接口进行拆分,将一个web接口从RPC服务到web接口进行拆分,这样的拆分是没有意义的,根据二八原理,大部分的接口最终是没有被使用的,同时根据业务的变化,相同的接口在不同的业务时期访问量是不同的。应该根据领域进行拆分,这样能够保证相同的业务领域的功能职责单一,资源耗损比较平均。
关注源代码清单,技术人的学习清单
下一篇: 情景linux的实例详解