为了账号安全,请及时绑定邮箱和手机立即绑定
慕课专栏

目录

索引目录

架构思维成长之微服务

原价 ¥ 68.00

立即订阅
02 微服务架构的规划
更新时间:2020-04-13 11:42:19
人只有献身于社会,才能找出那短暂而有风险的生命的意义。

——爱因斯坦

1、前言

本节主要跟大家聊聊如何去规划一个项目的架构,平时工作当中,很多同学接触到的项目都是现成的,由专门人员搭建好之后,自己在其基础上进行开发,自己也从来没想过为什么是这样的架构,这样的架构有什么缺点,有没有更好的方案等等,就只管编写自己的代码。时间长了,感觉写代码真的很简单,一旦你真感觉写代码很简单的时候,其实是在提醒你要学习了,否则很容易就会进入舒适区。有时候,你看似很简单的问题,但是真要自己动手去搭建一遍,发现遇到的问题很多。

首先,我们梳理一个项目的完整开发流程大概是什么样的?

阶段 1: 需求的规划、原型图的设计;这部分工作一般是产品和美工完成的,主要目的是把虚拟的东西变成一个感观可见的东西。

阶段 2: 需求分析设计阶段,主要是把需求文档的文字梳理成各个模型,包括架构图设计、流程图设计等。这个环节非常的重要,如果跳过该环节直接进入代码实战,则往往事倍功半。

阶段 3: 代码实战,就是撸代码阶段

阶段 4: 功能测试,大家都是熟悉的。包括:接口联调、测试环境测试、灰度测试

阶段 5: 项目上线

上面的流程大家应该都不陌生,作为开发人员,我们比较熟悉的应该是阶段2阶段3;我们的本节的重点就是阶段2 需求的分析和设计。其实在这个阶段,开发人员通过画项目的架构图、各个业务的详细流程图,很多难点都会在流程图上体现出来,再针对难点做技术方案的选型等;这个步骤做好之后,那么代码阶段就会非常的简单,只需要按照标准去实现即可。

思考:规划系统架构需要考虑哪些问题呢?

①架构模式

  • 一般根据项目的预估并发量、项目的规模来选择合适的架构,通常分为单体架构、垂直架构、SOA 架构、微服务架构。

②技术选型

  • 技术选型通常分为基础的开发框架(比如:ssm、SpringBoot+MyBatis 等)、分布式架构本身所引起的技术难点(比如:服务治理、网关、配置中心等等)、具体业务场景选择什么样的解决方案(这个实战部分会深入分析)。
  • 同种类型的框架如何选择,比如:消息队列的主流框架有 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等,我们应该选择哪款框架。
  • 必须熟悉分布式架构常见的问题及解决方案,比如:服务治理问题、自动化部署、系统的稳定性(容错、限流)、分布式事务、分布式锁等等。

③部署架构

  • 根据预估流量、接口压测,来选择具体的部署架构方案,是选择做单节点部署还是集群部署,是传统的部署还是容器化部署。

2、项目架构的规划

2.1、架构模式

了解一下单体模式:
图片描述

无论开发的时候,分多少个子项目,上线的时候,只打成一个包进行部署的项目就是单体项目。

单体项目模式 1:

platform							(项目名称)
	|-- src/main/java
    |  |-- com.micro.utils			(工具包)
	|  |-- com.micro.modules
	|  |-- com.micro.modules.user	(用户模块)
	|  |  |-- UserController.java
	|  |  |-- UserService.java
	|  |  |-- UserServiceImpl.java
	|  |  |-- UserDao.java
	|  |-- com.micro.modules.order	(订单模块)
	|  |  |-- OrderController.java
	|  |  |-- OrderService.java
	|  |  |-- OrderServiceImpl.java
	|  |  |-- OrderDao.java
	|  |-- com.micro.modeules.goods	(商品模块)
	|  |  |-- GoodsController.java
	|  |  |-- GoodsService.java
	|  |  |-- GoodsServiceImpl.java
	|  |  |-- GoodsDao.java
  • 描述:通过包名来区分不同的模块
  • 优点:项目架构简单
  • 缺点:①所有的模块代码严重耦合一起,代码非常的臃肿;②技术受限,不可以灵活的选择合适的开发语言;③整体运行性能较低

单体项目模式 2:

platform
	|-- platform-user	(用户工程)
	|-- platform-order	(订单工程)
	|-- platform-goods	(商品工程)
  • 描述:开发过程中把一个大的项目拆分多个子项目;但是最后是打包成一个项目来进行部署
  • 优点:相比上面的模式,项目做了拆分,可以实现代码的重复性利用
  • 缺点:①还是技术受限,所有工程必须遵守统一技术规范,否则无法整合;②整体运行性能较低

了解一下分布式(微服务)模式:
图片描述

  • 描述:把一张完整项目拆分多个独立运行的服务,可以是每个服务独立自己的数据库、也可以共用一个数据库。
  • 优点:①每个服务的功能单一;②运行速度快;③开发和迭代周期短;④技术选型比较灵活
  • 缺点:①服务数量较多;②部署复杂度提高;③会引起很多的其他问题(下面详细分析)

大型项目都会选择微服务的架构模式,架构模式是,前后端分离 + 后端微服务架构,具体如下:

图片描述

  • 相信很多老程序员都接触过 jsp 这玩意,它是一种模板引擎技术,前后端分离之前,基本上都是使用它来开发的页面。jsp 虽然内置了好多的标签,开发起来也比较方便。但是分工责任问题,让前端和后端开发人员合作起来相对比较麻烦。前端开发好 html 页面丢给后端整合成 jsp,这中间出现各种样式问题、兼容性问题等等。因此前后端分离让项目开发起来效率更加高,毕竟专业的人做专业的事。

思考:微服务架构会存在哪些问题呢?

1)稳定性问题

服务网稳定性问题,主要来自于以下几个方面。

①高并发访问、或者突发流量、恶意攻击等;

  • 可以采用限流、容错、防恶意攻击的方式保护服务,比如:前端加验证码、IP 控制、网关限流、消息队列限流、服务限流。

②由于服务的数量很多、关系复杂,其中一个服务出问题,就可能导致雪崩效应。

  • 为了防止服务之间的雪崩效应,最常见解决方案就是,服务容错及降低,主要是当调用的服务出问题时,返回默认值。

③分布式事务问题,这个是服务拆分必然引起的问题。

  • 原来单体项目模式,则所有操作属于同一个事务,数据一致性得到了保证,但是微服务模式下,则不在同一个事务下了,需要解决分布式事务的问题。

④为了更好的保护我们的服务,我们需要在所有服务前面加上一层网关,它的核心功能是请求转发、认证、鉴权、限流。

⑤接口调用幂等性问题,比如:接口消费方超时时间是 2s,但是此时接口提供方出现卡顿了,处理花了 5s,此时消费方会发起接口重试,就会导致重复执行。

⑥网络延迟、连接假死等引起远程通讯问题

2)通讯问题

服务之间通讯,如果使用传统的 HttpClient、WebService 肯定是满足不了的,因为服务之间互相通讯,复杂度更加的高,比如:集群模式需要动态新增节点、负载均衡、服务容错等,一般得集成服务治理框架(Dubbo 等)。

3)部署问题

服务数量很多,并且服务器数量也很多的情况下,手工部署效率会非常的低,一般都是自动化部署和自动化扩容;然而项目部署肯定需要修改项目的配置信息,因此需要依赖一个叫配置中心的中间件。

4)错误定位问题

日志文件散落在各个服务器,如何快速定位异常信息呢?如果依靠手工去每台服务中查看日志信息,则效率非常的慢。因此需要集成日志采集、存储、分析框架,比如:ELK 技术栈。除此之外,为了提高效率,建议做以下两个小操作。

  • 最好自定义异常类,这样可以更加快速的定位异常地方。

  • 很难筛出指定请求的全部相关日志,以及下游服务调用对应的日志,因此建议使用一个 traceId 跟踪请求的全部路径。

5)链路追踪问题

服务之间互相依赖,方法之间调用,可能是层层调用,复杂度很高,导致系统上线之后,为如何定位异常、性能监控等带来难题,因此我们需要使用这方面的开源中间件来监控,比如:Zipkin 等。

通过上面分析微服务存在的问题和解决方案,我来大致描绘一下微服务的架构图,具体如下:
图片描述

架构图分析说明

  • ①绿色部分需要做限流,可以使用 RateLimiter 框架,也可以使用阿里 Sentinel 框架
  • ②红色部分容错,表示的是服务之间的接口调用(rpc 远程调用),需要容错机制,否则其中一个服务出问题了,可能引起一片服务产生问题,也就是常说的雪崩效应
  • ③红色部分日志采集,一般采用埋点的方式进行日志采集,也就是说提供一个 jar 给服务集成,底层采用 Aop 的模式进行收集信息,这个后面实战部分会详细讲解
  • ④配置中心,目的是把经常变动的配置信息由项目抽离到配置中心,方便后期在线修改,常见框架有 Nacos、Apollo
  • ⑤注册中心,目的是做服务地址管理,一般是跟 rpc 框架结合使用,例如:Dubbo

2.2、技术选型

上面我们了解完整个微服务的架构图了,这里我们主要讲解微服务涉及的技术栈及相应的解决方案是什么。

目前主流的微服务技术方案,主要是 SpringCloudNetflix 和 SpringCloudAlibaba 两个派系,SpringCloudNetflix 的话,它会有针对每个场景都有具体的解决方案。这里主要讲解以阿里系为主的解决方案说明。

序号 解决方案 落地技术
1 服务网关 Nginx,注意的是 Zuul 和 Gateway 不适合 Dubbo,它依赖 Eureka
2 限流框架 Sentinel
3 容错框架 Sentinel
4 配置中心 Nacos
5 分布式事务 seata
6 服务治理 Dubbo+Zookeeper
7 链路追踪 Zipkin
8 接口幂等性 可以全局 ID 手工实现
9 日志管理 一般使用 ELK 技术栈,进行日志的采集、存储、分析、展示

以上只是最基本的微服务技术栈,还有一些常见业务场景的解决方案,具体如下:

序号 业务点 技术
2 分布式文件系统 FastDFS、HDFS
2 分布式锁 Zookeeper、Redis
3 消息队列 ActiveMQ、RabbitMQ、RocketMQ、Kafka
4 全文检索引擎 Solr、ElasticSearch
5 分布式缓存 Redis
9 过期监听 Redis 过期监听、延迟队列
10 消息推送 WebSocket、Netty

2.3、部署架构

一般情况下,高并发的系统部署架构都会采用分布式集群部署,主要核心是解决以下方面的问题

  • ①提高系统性能,一般需要使用多层负载均衡的方式解决流量分散,负载均衡的含义,其实就是把用户的请求,根据某种算法均摊到不同的服务器身上,减轻单台服务器的压力,是提高系统性能的常见手段。
  • ②节点容灾,也称为服务高可用,例如:只有一个 Nginx 对外提供服务,如果该 Nginx 挂掉之后,则整个项目无法对外提供正常服务,因此需要做节点高可用。特殊说明,负载均衡其实也是解决高可用其中一种方式;可以使用 Keepalived 来实现节点高可用,可以参考部署篇,里面有这部分的详细讲解。
  • ③服务器灾备,服务器是会宕机的,服务器宕机之后,里面的所有服务都失效了,一般使用 docker-swarm、k8s 去做灾备。
  • ④数据备份,数据安全是非常重要的,很多小公司做备份,使用人工备份或者定时备份,其实这是不够安全的,比如说:机房发生火灾,那么数据将全部丢失,因此需要做一个异地备份(双机房备份),参考后面 MySQL 主从章节。

负载均衡部署架构图:
图片描述

  • ①OSPF (开放式最短链路优先) 是一个内部网关协议 (Interior Gateway Protocol, 简称 IGP)。OSPF 通过路由器之间通告网络接口的状态来建立链路状态数据库,生成最短路径树,OSPF 会自动计算路由接口上的 Cost 值,但也可以通过手工指定该接口的 Cost 值,手工指定的优先于自动计算的值。

    OSPF 计算的 Cost,同样是和接口带宽成反比,带宽越高,Cost 值越小。到达目标相同 Cost 值的路

    径,可以执行负载均衡,最多 6 条链路同时执行负载均衡。

  • ②LVS 负载,Lvs 是第四层负载(tcp/ip 协议)

  • ③Nginx 负载,Nginx 主要是用于搭建 Tomcat 负载均衡集群,它是第七层负载(http 协议)

  • 如果有条件,也可以使用 F5 负载,成本比较高

3、案例分析

通过上面的分析,相信大家对微服务也有了一个了解了,这里主要是以网盘系统为案例讲解如何规划它的架构。

首先大概了解网盘系统的核心功能(可以登录系统查看)。网盘主要分为三个核心部分:网盘后台、个人文件的管理、以及对接应用系统;它的客户端类型分为好多种(比如:网页版、h5 版本、app 版本等)。那么我们如何架构网盘的项目架构呢?

方案 1:垂直架构
图片描述

  • 描述:网盘系统和后台管理系统都是独立的工程,操作同一份数据库;
  • 缺点:如果有相同的接口,则重复在两个工程里面实现;所有功能都在单体项目里面实现了。

方案 2:微服务架构 1
图片描述

  • 描述:把 controller 工程和 service 工程独立,远程调用接口
  • 优点:共用同一个接口工程,controller 工程变的很薄
  • 缺点:Controller 工程拆分粒度比较粗

方案 3:微服务架构 2
图片描述

  • 描述:把 controller 工程和 service 工程独立,并且 controller 根据客户端类型再细分,远程调用接口
  • 优点:拆分粒度更细,controller 工程变的更薄
  • 缺点:工程数量比较多

方案 4:微服务架构 3
图片描述

  • 描述:controller 根据客户端类型拆分,Service 也拆分成主要业务和非主要业务并通过 MQ 解耦,总体拆分粒度比较细
  • 优点:拆分粒度更细,整体性能更高
  • 缺点:工程数量比较多

总结:关于工程拆分粒度的总结

①controller 拆分,一般根据根据业务来拆分(比如:订单、商品);或者客户端类型来拆分

②service 拆分,一般根据业务来拆分(比如:订单服务、商品服务);或者根据主要业务和辅助业务拆分(主要目的是提高主要业务的处理速度,快速响应用户)

总结,其实项目的架构不一定是一步就到位的,我们按照项目的规模、按照项目的并发量来进行选择。以上四种模式就是架构的一个逐步升级的过程,根据实际情况来选择合适的架构。

思考:比如,一个网站的首页应该怎么规划呢?网站首页的功能非常的多,涉及的服务非常的多。

方案 1:
图片描述

  • 描述:整个网站只对应一个 Controller 工程,由 controller 工程再具体调用不同的服务;
  • 优点:只有一个 Controller,相对简单
  • 缺点:如果 Controller 挂了则整个网站就访问不了了(当然可以做集群);无法很好解耦,比如说:秒杀压力很大,则所有模块都会受秒杀模块的影响;如果系统升级的时候,所有模块都受影响。

方案 2:
图片描述

  • 描述:网站的不同模块对应不同的 Controller 工程,
  • 优点:这样压力也均摊到不同 Controller 上,每个 Controller 工程的后期迭代升级、项目部署都互不干扰。适合更加大型的项目
  • 缺点:架构变的更加庞大了和复杂了。

4、小结

本节主要介绍微服务架构的模式,微服务面临的问题及它的技术解决方案,微服务总体架构图,以及通过案例来分析微服务架构图。

}
立即订阅 ¥ 68.00

你正在阅读课程试读内容,订阅后解锁课程全部内容

千学不如一看,千看不如一练

手机
阅读

扫一扫 手机阅读

架构思维成长之微服务
立即订阅 ¥ 68.00

举报

0/150
提交
取消