03.大型高并发微服务系统设计

大型高并发微服务系统设计

首先复习一下典型互联网分布式系统架构图

03.大型高并发微服务系统设计_第1张图片

通过上面的图片我们能够看出微服务具体应用在哪里

看起来好像与我们日常开发的项目有所不同,为什么这么复杂?

一、分布式架构的演变

《淘宝技术这十年》:任何网站的发展都不是一蹴而就的。它在发展过程中会遇到各种各样的问题和业务带来的压力。正是这些问题和压力推动着技术的进步和发展,而技术的发展反过来又会促进业务的更大提升。如今淘宝网的流量排名已是全球前15名、国内前3名,其系统服务器也从一台发展到万台以上。

好的架构是进化来的,不是设计来的。好的功能也是进化来的,不是设计来的

1、单体架构

单体架构是最简单的软件架构,常用于传统的应用软件开发以及传统 Web 应用。传统 Web 应用,一般是将所有功能模块都打包(jar、war)在一个 Web 容器(JBoss、Tomcat)中部署、运行。随着业务复杂度增加、技术团队规模扩大,在一个单体应用中维护代码,会降低开发效率,即使是处理一个小需求,也需要将所有机器上的应用全部部署一遍,增加了运维的复杂度。

03.大型高并发微服务系统设计_第2张图片

2、SOA架构

当某一天使用单体架构发现很难推进需求的开发、以及日积月累的技术债时,很多企业会开始做单体服务的拆分,拆分的方式一般有水平拆分和垂直拆分。垂直拆分是把一个应用拆成松耦合的多个独立的应用,让应用可以独立部署,有独立的团队进行维护;水平拆分是把一些通用的,会被很多上层服务调用的模块独立拆分出去,形成一个共享的基础服务,这样拆分可以对一些性能瓶颈的应用进行单独的优化和运维管理,也在一定程度上防止了垂直拆分的重复造轮子。

SOA 也叫面向服务的架构,从单体服务到 SOA 的演进,需要结合水平拆分及垂直拆分。SOA 强调用统一的协议进行服务间的通信,服务间运行在彼此独立的硬件平台但是需通过统一的协议接口相互协作,也即将应用系统服务化。

举个例子

在一个电子厂流水线上,我们会看到每个人只负责产品中单独的一个工序(比如安装主板),而不是每个人都做一个单独的产品(手机)

03.大型高并发微服务系统设计_第3张图片

3、微服务架构

微服务(Microservices Architecture)是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

03.大型高并发微服务系统设计_第4张图片

微服务也是面向服务开发的一种。不过和SOA有些区别

松耦合:每个微服务内部都可以使用 DDD(领域驱动设计)的思想进行设计领域模型,服务间尽量减少同步的调用,多使用消息的方式让服务间的领域事件来进行解耦。

轻量级协议:Dubbo 是 SOA 的开源的标准实现之一,类似的还有像 gRPC、Thrift 等RPC协议。微服务更倾向于使用 Restful 风格的 API,轻量级的协议可以很好地支持跨语言开发的服务,可能有的微服务用 Java 语言实现,有的用 Go 语言,有的用 C++,但所有的语言都可以支持 Http 协议通信,所有的开发人员都能理解 Restful 风格 API 的含义。

高度自治和持续集成:从底层的角度来说,SOA 更加倾向于基于虚拟机(VM ware)或者服务器的部署,每个应用都部署在不同的机器上,一般持续集成工具更多是由运维团队写一些 Shell 脚本以及提供基于共同协议(比如 Dubbo 管理页面)的开发部署页面。微服务可以很好得和容器技术结合,容器技术比微服务出现得晚,但是容器技术的出现让微服务的实施更加简便,目前 Docker 已经成为很多微服务实践的基础容器。因为容器的特色,所以一台机器上可以部署几十个、几百个不同的微服务。如果某个微服务流量压力比其他微服务大,可以在不增加机器的情况下,在一台机器上多分配一些该微服务的容器实例。同时,因为 Docker 的容器编排社区日渐成熟,类似 Mesos、Kubernetes 及 Docker 官方提供的 Swarm 都可以作为持续集成部署的技术选择。

其实从架构的演进的角度来看,架构的演进都是朝着越来越轻量级、越来越灵活的应用方向发展,甚至到近两年日渐成熟起来的和Service Mesh(服务网格)、 Serverless(无服务)架构。从单体服务到分层的服务,再到面向服务、再到微服务甚至无服务,对于架构的挑战是越来越大。

4、分布式

微服务和SOA架构都属于典型的分布式架构,区别不过是微服务架构的部署颗粒度比分布式小了很多。

5、微服务的优点

  • 每个微服务都很小,这样能聚焦一个指定的业务功能或业务需求。

  • 微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成。

  • 微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。

  • 微服务能使用不同的语言开发。

  • 微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。

  • 微服务允许你利用融合最新技术。

  • 微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。

6、微服务的缺点

  • 系统复杂度提高
    • 例如,据 Adrian Cockcroft 了解到, Hailo 拥有 160 个不同的服务,Netflix 拥有的服务超过 600 个。
    • 如果出现错误定位错误困难
  • 系统响应速度变慢
    • 服务与服务需要通过远程调用而不是直接调用本地方法
  • 部署难度提高
    • 以前我们只需要部署一个项目,现在需要部署少则十几个多则成百上千的服务。
  • 服务间的发现
    • 当一个服务调用另一个服务时如何发现
  • 服务的治理

7、那么如何选择系统的架构呢?

因地制宜、对症下药。

单体架构模式 只适用于简单、轻量级的应用程序,如果您使用它来构建复杂应用,您最终会陷入痛苦的境地。

微服务架构模式是复杂、持续发展应用的一个更好的选择。尽管它存在着缺点和实现挑战。

二、大型高并发微服务系统设计

1、需求提出

假设要你设计一个初期并发量大概为4000qps的电商系统,并且由于运营团队很给力,还有可能在短期内并发量快速扩张,你该如何设计?

2、思考

在面对高并发场景,单体架构是玩不转的,一定要上分布式,那么现在最主流的就是微服务架构了。那么我们要结合着具体的模块采用不同的策略。

电商系统中常见的模块有:用户模块、购物车模块、搜索模块、首页模块、商品模块、订单模块、秒杀模块…。

这么多的模块他们各自有什么特点呢?

如:秒杀模块的qps一定高于用户模块

因此要根据响应的模块采用不同数量级的集群数量,集群无论是机房还是云服务器,都是要花钱的所以要慎重。这也是架构师的价值所在。

3、需求分析

这里我们不需要设计一个大而全的系统。这里我们以订单系统为例。下单流程大致如下:

03.大型高并发微服务系统设计_第5张图片

大致的流程分析过后,如若要我们自己着手实现订单服务该怎么做?

4、服务的拆分——DDD领域驱动设计

既然是微服务就必然涉及到服务的拆分,具体如何拆分,我们要采用DDD领域驱动设计模型。

按照我们上述图中去拆分服务也是可以的但是,太不专业

4.1、软件开发和DDD区别

一般软件设计或者说软件开发分两种:瀑布式,敏捷式。

  • 瀑布式:一般是项目经理经过大量的业务分析后,会基于现有需求整理出一个基本模型,再将结果传递给开发人员,这就是开发人员的需求文档,他们只需要照此开发便是。这种模式下,是很难频繁的从用户那里得到反馈,因此在前期分析时就已经默认了这个业务模型是正确的,那么结果可想而之,数月甚至数年后交付的时候,必然和客户的预期差距较大。
  • 敏捷式:在此基础上进行了改进,它也需要大量的分析,范围会设计到更精细的业务模块,它是小步迭代,周期性交付,那么获取客户的反馈也就比较频繁和及时。可敏捷也不能够将业务中的方方面面都考虑到,并且敏捷是拥抱变化的,大量的需求或者业务模型变更必将带来不小的维护成本,同时,对人的要求也必然会更高。

DDD则不同:它像是更小粒度的迭代设计,它的最小单元是领域模型(Domain Model),所谓领域模型就是能够精确反映领域中某一知识元素的载体,这种知识的获取需要通过与领域专家(Domain Expert)进行频繁的沟通才能将专业知识转化为领域模型。领域模型无关技术,具有高度的业务抽象性,它能够精确的描述领域中的知识体系;同时它也是独立的,我们还需要学会如何让它具有表达性,让模型彼此之间建立关系,形成完整的领域架构。通常我们可以用象形图或一种通用的语言(Ubiquitous Language)去描述它们之间的关系。在此之上,我们就可以进行领域中的代码设计(Domain Code Design)。如果将软件设计比做是造一座房子,那么领域代码设计就好比是贴壁纸。前者已经将房子的蓝图框架规划好,而后者只是一个小部分的设计:如果墙纸贴错了,我们可以重来,可如果房子结构设计错了,那可就悲剧了。

4.2、模型驱动设计

03.大型高并发微服务系统设计_第6张图片

参考DDD的设计,DDD官方架构草图,总体架构分为四层:

  • Infrastructure(基础实施层)
  • Domain(领域层)
  • Application(应用层)
  • Interfaces(表示层,也叫用户界面层或是接口层)

4.3、微服务结合 DDD

不过对于领域设计而言,代码层其实不是最重要,最重要的是如何去划分领域,划分好边界。

而对于微服务而言,非常适合从业务上去划分各个 Modules,划分好各个业务板块,微服务 + DDD,个人觉得首先从微服务的角度考虑去划分大的业务模块,每个微服务都应该是一个可以独立部署,各司其职的模块。

简单的说,在微服务实际的开发中,结合 DDD 的思想去划分所有属于自己的领域。

第一点是使用通用的语言(UML图)建立所有的聚合,实体,值对象。

第二点也就是最关键的“建模”:

  • 划分“战略建模”,从一种宏观的角度去审核整个项目,划分出“界限上下文”,形成具有上帝视角的“上下文映射图”。
  • 还有一个建模是“战术建模”,在我们的“战略建模”划分出来的“界限上下文”中进行“聚合”,“实体”,“值对象”,并按照模块分组。

现在我们的首要任务先确定好系统中的核心领域是什么?

作为一个电商系统首要的一定是销售领域

03.大型高并发微服务系统设计_第7张图片

因此我们现将微服务拆分为5个领域

  • 销售域
  • 商品域
  • 订单域
  • 用户域
  • 支付域

5、微服务系统开发

接下来需求分析结束后我们可以着手开发微服务系统了。

但在开发微服务系统之前我们要先对微服务框架选型

你可能感兴趣的:(Java专栏,微服务,java,高并发,架构)