微服务架构的规划 向右看齐 2023-07-25 14:09 6阅读 0赞 # 微服务架构的规划 # ![format_png][] 人只有献身于社会,才能找出那短暂而有风险的生命的意义。 ——爱因斯坦 ## 1、前言 ## 本节主要跟大家聊聊如何去规划一个项目的架构,平时工作当中,很多同学接触到的项目都是现成的,由专门人员搭建好之后,自己在其基础上进行开发,自己也从来没想过为什么是这样的架构,这样的架构有什么缺点,有没有更好的方案等等,就只管编写自己的代码。时间长了,感觉写代码真的很简单,一旦你真感觉写代码很简单的时候,其实是在提醒你要学习了,否则很容易就会进入舒适区。有时候,你看似很简单的问题,但是真要自己动手去搭建一遍,发现遇到的问题很多。 > 首先,我们梳理一个项目的完整开发流程大概是什么样的? **阶段 1:** 需求的规划、原型图的设计;这部分工作一般是产品和美工完成的,主要目的是把虚拟的东西变成一个感观可见的东西。 **阶段 2:** 需求分析设计阶段,主要是把需求文档的文字梳理成各个模型,包括架构图设计、流程图设计等。这个环节非常的重要,如果跳过该环节直接进入代码实战,则往往事倍功半。 **阶段 3:** 代码实战,就是撸代码阶段 **阶段 4:** 功能测试,大家都是熟悉的。包括:接口联调、测试环境测试、灰度测试 **阶段 5:** 项目上线 上面的流程大家应该都不陌生,作为开发人员,我们比较熟悉的应该是`阶段2` 和`阶段3`;我们的本节的重点就是`阶段2` 需求的分析和设计。其实在这个阶段,开发人员通过画项目的架构图、各个业务的详细流程图,很多难点都会在流程图上体现出来,再针对难点做技术方案的选型等;这个步骤做好之后,那么代码阶段就会非常的简单,只需要按照标准去实现即可。 # # ## 思考:规划系统架构需要考虑哪些问题呢? ## ①架构模式 * 一般根据项目的预估并发量、项目的规模来选择合适的架构,通常分为单体架构、垂直架构、SOA 架构、微服务架构。 ②技术选型 * 技术选型通常分为基础的开发框架(比如:ssm、SpringBoot+MyBatis 等)、分布式架构本身所引起的技术难点(比如:服务治理、网关、配置中心等等)、具体业务场景选择什么样的解决方案(这个实战部分会深入分析)。 * 同种类型的框架如何选择,比如:消息队列的主流框架有 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等,我们应该选择哪款框架。 * 必须熟悉分布式架构常见的问题及解决方案,比如:服务治理问题、自动化部署、系统的稳定性(容错、限流)、分布式事务、分布式锁等等。 ③部署架构 * 根据预估流量、接口压测,来选择具体的部署架构方案,是选择做单节点部署还是集群部署,是传统的部署还是容器化部署。 ## 2、项目架构的规划 ## ### 2.1、架构模式 ### 了解一下单体模式: ![图片描述][format_png 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 (商品工程) * 描述:开发过程中把一个大的项目拆分多个子项目;但是最后是打包成一个项目来进行部署 * 优点:相比上面的模式,项目做了拆分,可以实现代码的重复性利用 * 缺点:①还是技术受限,所有工程必须遵守统一技术规范,否则无法整合;②整体运行性能较低 了解一下分布式(微服务)模式: ![图片描述][format_png 2] * 描述:把一张完整项目拆分多个独立运行的服务,可以是每个服务独立自己的数据库、也可以共用一个数据库。 * 优点:①每个服务的功能单一;②运行速度快;③开发和迭代周期短;④技术选型比较灵活 * 缺点:①服务数量较多;②部署复杂度提高;③会引起很多的其他问题(下面详细分析) > 大型项目都会选择微服务的架构模式,架构模式是,前后端分离 + 后端微服务架构,具体如下: ![图片描述][format_png 3] * 相信很多老程序员都接触过 jsp 这玩意,它是一种模板引擎技术,前后端分离之前,基本上都是使用它来开发的页面。jsp 虽然内置了好多的标签,开发起来也比较方便。但是分工责任问题,让前端和后端开发人员合作起来相对比较麻烦。前端开发好 html 页面丢给后端整合成 jsp,这中间出现各种样式问题、兼容性问题等等。因此前后端分离让项目开发起来效率更加高,毕竟专业的人做专业的事。 ## 思考:微服务架构会存在哪些问题呢? ## **1)稳定性问题** 服务网稳定性问题,主要来自于以下几个方面。 ①高并发访问、或者突发流量、恶意攻击等; * 可以采用限流、容错、防恶意攻击的方式保护服务,比如:前端加验证码、IP 控制、网关限流、消息队列限流、服务限流。 ②由于服务的数量很多、关系复杂,其中一个服务出问题,就可能导致雪崩效应。 * 为了防止服务之间的雪崩效应,最常见解决方案就是,服务容错及降低,主要是当调用的服务出问题时,返回默认值。 ③分布式事务问题,这个是服务拆分必然引起的问题。 * 原来单体项目模式,则所有操作属于同一个事务,数据一致性得到了保证,但是微服务模式下,则不在同一个事务下了,需要解决分布式事务的问题。 ④为了更好的保护我们的服务,我们需要在所有服务前面加上一层网关,它的核心功能是请求转发、认证、鉴权、限流。 ⑤接口调用幂等性问题,比如:接口消费方超时时间是 2s,但是此时接口提供方出现卡顿了,处理花了 5s,此时消费方会发起接口重试,就会导致重复执行。 ⑥网络延迟、连接假死等引起远程通讯问题 **2)通讯问题** 服务之间通讯,如果使用传统的 HttpClient、WebService 肯定是满足不了的,因为服务之间互相通讯,复杂度更加的高,比如:集群模式需要动态新增节点、负载均衡、服务容错等,一般得集成服务治理框架(Dubbo 等)。 **3)部署问题** 服务数量很多,并且服务器数量也很多的情况下,手工部署效率会非常的低,一般都是自动化部署和自动化扩容;然而项目部署肯定需要修改项目的配置信息,因此需要依赖一个叫配置中心的中间件。 **4)错误定位问题** 日志文件散落在各个服务器,如何快速定位异常信息呢?如果依靠手工去每台服务中查看日志信息,则效率非常的慢。因此需要集成日志采集、存储、分析框架,比如:ELK 技术栈。除此之外,为了提高效率,建议做以下两个小操作。 * 最好自定义异常类,这样可以更加快速的定位异常地方。 * 很难筛出指定请求的全部相关日志,以及下游服务调用对应的日志,因此建议使用一个 traceId 跟踪请求的全部路径。 **5)链路追踪问题** 服务之间互相依赖,方法之间调用,可能是层层调用,复杂度很高,导致系统上线之后,为如何定位异常、性能监控等带来难题,因此我们需要使用这方面的开源中间件来监控,比如:Zipkin 等。 通过上面分析微服务存在的问题和解决方案,我来大致描绘一下微服务的架构图,具体如下: ![图片描述][format_png 4] 架构图分析说明 * ①绿色部分需要做限流,可以使用 RateLimiter 框架,也可以使用阿里 Sentinel 框架 * ②红色部分`容错`,表示的是服务之间的接口调用(rpc 远程调用),需要容错机制,否则其中一个服务出问题了,可能引起一片服务产生问题,也就是常说的雪崩效应 * ③红色部分`日志采集`,一般采用埋点的方式进行日志采集,也就是说提供一个 jar 给服务集成,底层采用 Aop 的模式进行收集信息,这个后面实战部分会详细讲解 * ④配置中心,目的是把经常变动的配置信息由项目抽离到配置中心,方便后期在线修改,常见框架有 Nacos、Apollo * ⑤注册中心,目的是做服务地址管理,一般是跟 rpc 框架结合使用,例如:Dubbo ## 2.2、技术选型 ## 上面我们了解完整个微服务的架构图了,这里我们主要讲解微服务涉及的技术栈及相应的解决方案是什么。 目前主流的微服务技术方案,主要是 SpringCloudNetflix 和 SpringCloudAlibaba 两个派系,SpringCloudNetflix 的话,它会有针对每个场景都有具体的解决方案。这里主要讲解以阿里系为主的解决方案说明。 <table> <thead> <tr> <th>序号</th> <th>解决方案</th> <th>落地技术</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>服务网关</td> <td>Nginx,注意的是 Zuul 和 Gateway 不适合 Dubbo,它依赖 Eureka</td> </tr> <tr> <td>2</td> <td>限流框架</td> <td>Sentinel</td> </tr> <tr> <td>3</td> <td>容错框架</td> <td>Sentinel</td> </tr> <tr> <td>4</td> <td>配置中心</td> <td>Nacos</td> </tr> <tr> <td>5</td> <td>分布式事务</td> <td>seata</td> </tr> <tr> <td>6</td> <td>服务治理</td> <td>Dubbo+Zookeeper</td> </tr> <tr> <td>7</td> <td>链路追踪</td> <td>Zipkin</td> </tr> <tr> <td>8</td> <td>接口幂等性</td> <td>可以全局 ID 手工实现</td> </tr> <tr> <td>9</td> <td>日志管理</td> <td>一般使用 ELK 技术栈,进行日志的采集、存储、分析、展示</td> </tr> </tbody> </table> 以上只是最基本的微服务技术栈,还有一些常见业务场景的解决方案,具体如下: <table> <thead> <tr> <th>序号</th> <th>业务点</th> <th>技术</th> </tr> </thead> <tbody> <tr> <td>2</td> <td>分布式文件系统</td> <td>FastDFS、HDFS</td> </tr> <tr> <td>2</td> <td>分布式锁</td> <td>Zookeeper、Redis</td> </tr> <tr> <td>3</td> <td>消息队列</td> <td>ActiveMQ、RabbitMQ、RocketMQ、Kafka</td> </tr> <tr> <td>4</td> <td>全文检索引擎</td> <td>Solr、ElasticSearch</td> </tr> <tr> <td>5</td> <td>分布式缓存</td> <td>Redis</td> </tr> <tr> <td>9</td> <td>过期监听</td> <td>Redis 过期监听、延迟队列</td> </tr> <tr> <td>10</td> <td>消息推送</td> <td>WebSocket、Netty</td> </tr> </tbody> </table> ## 2.3、部署架构 ## 一般情况下,高并发的系统部署架构都会采用分布式集群部署,主要核心是解决以下方面的问题 * ①提高系统性能,一般需要使用多层负载均衡的方式解决流量分散,负载均衡的含义,其实就是把用户的请求,根据某种算法均摊到不同的服务器身上,减轻单台服务器的压力,是提高系统性能的常见手段。 * ②节点容灾,也称为服务高可用,例如:只有一个 Nginx 对外提供服务,如果该 Nginx 挂掉之后,则整个项目无法对外提供正常服务,因此需要做节点高可用。特殊说明,负载均衡其实也是解决高可用其中一种方式;可以使用 Keepalived 来实现节点高可用,可以参考部署篇,里面有这部分的详细讲解。 * ③服务器灾备,服务器是会宕机的,服务器宕机之后,里面的所有服务都失效了,一般使用 docker-swarm、k8s 去做灾备。 * ④数据备份,数据安全是非常重要的,很多小公司做备份,使用人工备份或者定时备份,其实这是不够安全的,比如说:机房发生火灾,那么数据将全部丢失,因此需要做一个异地备份(双机房备份),参考后面 MySQL 主从章节。 负载均衡部署架构图: ![图片描述][format_png 5] * ①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:垂直架构** ![图片描述][format_png 6] * 描述:网盘系统和后台管理系统都是独立的工程,操作同一份数据库; * 缺点:如果有相同的接口,则重复在两个工程里面实现;所有功能都在单体项目里面实现了。 **方案 2:微服务架构 1** ![图片描述][format_png 7] * 描述:把 controller 工程和 service 工程独立,远程调用接口 * 优点:共用同一个接口工程,controller 工程变的很薄 * 缺点:Controller 工程拆分粒度比较粗 **方案 3:微服务架构 2** ![图片描述][format_png 8] * 描述:把 controller 工程和 service 工程独立,并且 controller 根据客户端类型再细分,远程调用接口 * 优点:拆分粒度更细,controller 工程变的更薄 * 缺点:工程数量比较多 **方案 4:微服务架构 3** ![图片描述][format_png 9] * 描述:controller 根据客户端类型拆分,Service 也拆分成主要业务和非主要业务并通过 MQ 解耦,总体拆分粒度比较细 * 优点:拆分粒度更细,整体性能更高 * 缺点:工程数量比较多 > 总结:关于工程拆分粒度的总结 > > ①controller 拆分,一般根据根据业务来拆分(比如:订单、商品);或者客户端类型来拆分 > > ②service 拆分,一般根据业务来拆分(比如:订单服务、商品服务);或者根据主要业务和辅助业务拆分(主要目的是提高主要业务的处理速度,快速响应用户) 总结,其实项目的架构不一定是一步就到位的,我们按照项目的规模、按照项目的并发量来进行选择。以上四种模式就是架构的一个逐步升级的过程,根据实际情况来选择合适的架构。 > 思考:比如,一个网站的首页应该怎么规划呢?网站首页的功能非常的多,涉及的服务非常的多。 > > **方案 1:** ![图片描述][format_png 10] * 描述:整个网站只对应一个 Controller 工程,由 controller 工程再具体调用不同的服务; * 优点:只有一个 Controller,相对简单 * 缺点:如果 Controller 挂了则整个网站就访问不了了(当然可以做集群);无法很好解耦,比如说:秒杀压力很大,则所有模块都会受秒杀模块的影响;如果系统升级的时候,所有模块都受影响。 **方案 2:** ![图片描述][format_png 11] * 描述:网站的不同模块对应不同的 Controller 工程, * 优点:这样压力也均摊到不同 Controller 上,每个 Controller 工程的后期迭代升级、项目部署都互不干扰。适合更加大型的项目 * 缺点:架构变的更加庞大了和复杂了。 ## 4、小结 ## 本节主要介绍微服务架构的模式,微服务面临的问题及它的技术解决方案,微服务总体架构图,以及通过案例来分析微服务架构图。 [format_png]: /images/20230528/4705a4255bd5492096ba0a28b9552c0d.png [format_png 1]: /images/20230528/bdf7dec4cc194000b85221f2643d71a2.png [format_png 2]: /images/20230528/5c6898a342d047e48cbe1b97b0dff7cd.png [format_png 3]: /images/20230528/3be9c801422e4c41a4715513a9d09075.png [format_png 4]: /images/20230528/f8e84ffd925f4411acac1c7fc4215d18.png [format_png 5]: /images/20230528/7acb1c7a077d4eb2b831c2d1b010963b.png [format_png 6]: /images/20230528/6b08667fd174423ea53f312ab5a6ee08.png [format_png 7]: /images/20230528/2ba5fe27c7d046fe9eaa0ae8466171df.png [format_png 8]: /images/20230528/17af3d546b0147aea2ce39af53604b3e.png [format_png 9]: /images/20230528/8980cd99fc2e42559d25d333e2062476.png [format_png 10]: /images/20230528/80248e566a2243238502610af6974ece.png [format_png 11]: /images/20230528/73290fb492cd423da1ec722f4b34a816.png
相关 【微服务】微服务架构设计 文章目录 背景 一、流量入口Nginx 二、网关 三、业务组件 四、服务注册中心 五、缓存和分布式锁 六、数据持久层 七、 亦凉/ 2023年10月12日 18:07/ 0 赞/ 144 阅读
相关 微服务架构 — 微服务框架 目录 文章目录 目录 微服务框架 第一代微服务框架 Spring Cloud Dubbo 下一代微服务框架 — S 迈不过友情╰/ 2023年10月05日 04:47/ 0 赞/ 103 阅读
相关 微服务架构的规划 微服务架构的规划 ![format_png][] 人只有献身于社会,才能找出那短暂而有风险的生命的意义。 ——爱因斯坦 1、前言 本节主要跟 向右看齐/ 2023年07月25日 14:09/ 0 赞/ 7 阅读
相关 架构:微服务架构 系统架构设计描述了在应用系统的内部,如何根据业务、技术、组织、灵活性、可扩展性以及可维护性等多种因素,将应用系统划分成不同的部分,并使这些部分彼此之间相互分工、相互协作,从而为 古城微笑少年丶/ 2023年07月10日 08:59/ 0 赞/ 82 阅读
相关 微服务架构 Microservices a definition of this new architectural term The term "Microservice Arc 忘是亡心i/ 2022年07月13日 06:08/ 0 赞/ 601 阅读
相关 微服务架构 微服务架构 微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事,从技术 £神魔★判官ぃ/ 2022年04月25日 07:06/ 0 赞/ 332 阅读
相关 微服务架构 [微服务架构核心20讲][20] -------------------- 01 | 微服务定义 微服务是一种架构风格 大中台,小前台 > 定义一 一 港控/mmm°/ 2022年04月24日 04:08/ 0 赞/ 469 阅读
相关 微服务与微服务架构 什么是微服务? > 微服务的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事,从技术角度看就是 偏执的太偏执、/ 2021年12月17日 05:59/ 0 赞/ 659 阅读
相关 微服务架构 一、先了解一下什么是单体应用 就是一个应用程序包含了所有模块功能,各模块同时部署。当然这种应用模式比较容易部署、测试,但随着项目的加大,单体模式就会变得越来越臃肿,维护的成 古城微笑少年丶/ 2021年09月23日 07:40/ 0 赞/ 654 阅读
还没有评论,来说两句吧...