宝塔自助建站源码,做心理咨询的网站,企业网站建设费入什么科目,Django 个人博客网站开发单体架构图参考网络#xff1a; 1. 什么是单体应用 单体应用就是将应用程序的所有功能都打包成一个独立的单元#xff0c;最终以一个WAR包或JAR包存在#xff0c;没有外部的任何依赖#xff0c;里面包含DAO、Service、UI等所有的逻辑。 优点#xff1a; #xff11; 1. 什么是单体应用 单体应用就是将应用程序的所有功能都打包成一个独立的单元最终以一个WAR包或JAR包存在没有外部的任何依赖里面包含DAO、Service、UI等所有的逻辑。 优点 便于开发只需要借助的开发,调试功能即可。 易于测试只需要通过单元测试或浏览器即可完成测试。 易于部署打包成单一可执行jar包执行jar包即可完成部署。 可是这种简单的单元有很大的局限性。应用随着业务需求迭代功能的追加扩展最终成为一个庞然大物变得更加复杂逻辑耦合很严重难以理解。团队开发人员职责不清部署困难回归测试成本巨大交付率大大降低总结下来单体应用有以下大缺点: .复杂性高 代码难以理解 部署困难 应用越来越大 测试越来越难 在业务规模和团队规模发展到一定阶段这些不足表现的更加明显。单体架构的不足表现在复杂性上maven模块增多多个模块耦合在一起代码结构混乱很难理解整个代码逻辑容易导致代码质量低复杂性进一步增加同时代码复用度降低不清楚某段代码的修改后的影响范围。 代码难以被修改和重构 不理解代码当然也写不出高内聚低耦合的代码代码质量持续下降复杂性进一步增加然后耦合度越来越高代码牵一而动全身代码就很难修改和重构了。 团队职责不清楚 高度耦合的单体工程使得逻辑边界模糊不清新的业务需求开发任务无法有效分配到人团队人员职责不清楚沟通成本增加。
交付效率低 构建和部署耗时长难以定位问题开发效率低。代码比较庞大编译时间就会很长开发调试将大部分时间花在重新编译上代码量的增加又很难定位导致开发效率进一步降低在代码合并过程中很容易造成代码冲突又花不少时间解决代码冲突这些都可以导致开发效率降低。还有就是当我们开发一个新的功能或者修复一个代码的变更影响是很难预估的每次发布之前都要进行全部功能的回归测试部署耗时长影响范围广风险大发布频次低也会造成产品不能及时呈现给用户甚至被对手赶超。 伸缩性(scalable)差 单体应用只能按整体横向扩展无法分模块垂直扩展。密集型模块和密集模块无法独立升级和扩容。业务模块对资源的需求是不一样的比如图片压缩加解密这些 都是cpu资源密集的应该升级CPU而IO密集型的模块比如日志收集服务IO操作比较多需要更大的内存使用比如SSD性能更好的磁盘。 可靠性差 一个bug有可能引起整个应用的崩溃。比如一个不重要的部分的内存泄露就会导致所有应用实例一个个宕机掉 阻碍技术创新 受技术栈限制团队成员使用同一框架和语言。升级和变革技术框架困难。
2. 什么是微服务 2.1 微服务的定义
微服务架构图参考网络 微服务架构是将单体应用拆分为多个高内聚低耦合的小型服务每个服务运行在独立的进程可由不同的团队开发和维护服务间采用轻量通信机制独立自动部署可以采用不同的语言及存储。 单体架构整个团队为何开发一个大工程和一个单库在微服务架构中用户请求经过API Gateway被路由到下游服务服务之间以轻量级通信协议进行通信服务通过注册中心发现彼此每个服务都有专门的开发维护团队每个服务都可以有自己独立的数据库服务独立开发部署上线。
微服务的优点 易于开发与维护微服务相对较小易于理解启动时间短开发效率高。 独立部署一个服务的修改不需要协调其他服务 伸缩性强可以横向和纵向扩展 与组织结构匹配更好的将架构和组织匹配每个团队独立负责某些服务。 技术异构性使用最适合该服务的技术降低尝试新技术的成本。 说完优点那么微服务有什么挑战呢 2.2 微服务的挑战 服务拆分 拆分原则领域模型限定上下文单一职责组织结构康威定律。 现实中没有一个具体明确的方法可以将拆分一步到位而是遵守一定的规则。服务拆分的同时还要考虑到数据库也要独立(如果需要)当每个服务服务直接读写数据库中同一张表时对这些表做任何改动都需要协调这些相关服务的部署。共享的数据存储很容易不经意间造成耦合。每个服务需要有自己的私有数据。这一点违背了服务相互独立这一原则。比如订单表被订单服务和商品服务所共享商品服务单独做统计并不知道自己一天多少商品被卖出不知道哪些数据由本服务产生的就无法进行技术产品规划对表结构的修改也要通知多个服务这是所不能容忍的。每个服务需要自己的数据库但这些数据库可共置在一台共享的数据服务器上数据库私有的重点在于不应让服务知道其他服务底层数据库的存在。可用一台共享数据服务器先开始开发以后如果数据量和并发量变大服务器可以进行隔离。服务器隔离后只要更改配置即可将不同服务的数据库隔离起来。确定服务边界也是一个难题需要对自己的产品和业务有足够的了解才能确定最自然的服务边界确定服务边界坚持的原则是要高内聚弱耦合弱耦合就是一个服务与其他服务的任何通信都应通过公开暴露的接口API、事件等实现这些接口需要妥善设计以隐藏内部细节。这样我们的服务之间保持独立在未来我们可以轻松重构高内聚力就是密切相关的多个功能应尽量包含在同一个服务中这样可将服务之间的干扰降至最低。 数据一致性 在单体架构中我们通过数据库事务完成的操作放在分布式微服务架构下无法完成了因为实例被部署不同服务器上比如订单服务进行下单操作下单操作和扣减库存应该放在同一个事务中。在微服务架构下下单操作和扣库存操作被分布在不同服务器上就需要进行分布式事务操作而分布式事务具有延迟较高、nosql数据库不支持等缺点。 这些缺点导致分布式事务无法应用到微服务中在微服务场景下我们通常使用最终一致性来代替强 一致性 可靠性事件模式 补偿模式-sagas模式 服务通信 通信技术方案: RPC vs REST vs 异步消息 RPC、REST API、异步消息异步消息我们可以借助一些消息队列框架来实现比如kafka、rrabbitMQ那现在我们说下rpc和使用http协议的类似REST API之间 如何选择TTP的好处是方便调试、跨语言、门槛低、广泛接受同样缺点是协议文档不好维护协议较为繁琐性能较TCP要差是http协议的不足。 Rpc通信通常基于Tcp常用的技术选型是thrift、grpc、dubbo像thrift、grpc需要定义idl文件通过idl文件来生成java代码通过rpc的好处是IDE友好有代码提示协议维护在代码中传参和响应结果都通过代码可以知道。但同时也有缺点比如很多rpc方案不知道跨语言所支持的语言有限需要定义和维护idl文件且有一定的学习成本另外rpc不容易方便的调试和测试。 服务注册和发现 在服务实例变化不定的环境中用硬编码指定IP地址的方式是行不通的需要通过某种发现机制让服务能相互查找。这就需要我们将我们的服务信息注册到一个分布式存储中这些服务信息就叫做服务注册表服务注册表可以作为信息的权威来源。其中包含有关可用服务的信息以及服务网络位置比如ip、端口号这些信息。那借助什么组件进行实现呢一般有EurekazookeeperNocas除此之外我们还可以借助etcdconsulredis这些。 负载均衡 有了注册发现功能客户端通过服务注册表发现实例清单并决定要连接哪个实例在客户端做负载均衡基于客户端做负载均衡相比服务端负载均衡有诸多好处首先节省了硬件均衡设备减少了运维成本其次可以实现多种负载均衡策略比如响应感知的负载均衡策略。 4.服务网关 API Gateway 我们的微服务如果和终端用户通信势必要考虑到身份认证安全防御等方面如果每个微服务都与终端用户打交道那么这些方面代码需要拷贝多份植入到每个微服务业务代码中。造成了业务代码和身份认证代码的耦合降低了代码的复用性。这就需要在网络边界实现一个服务网关(这里的网络边界可以认为是内网和外网之间的边界)将身份认证安全防御流量控制这些功能放到服务网关中向业务服务屏蔽网络边界服务的细节使得业务服务专注于业务逻辑的开发维护和测试。 为前端服务的后端(Backends For Forntends) 服务网关可以根据终端产品形态来划分比如公共API,桌面客户端移动客户端分别对应一个服务网关而服务网关可以是API Gateway只输出api或者是为前端服务的后端这里的为前端服务的后端比如将来自多个服务的数据聚合到一起返回给前端。
身份认证、路由服务、限流防刷、日志统计
高可观察 健康检测、集中监控 每个服务和使用的组件都有提供健康检测机制使得我们可以及时发现异常的节点然后做出判断和调整将所有的监控指标进行聚合输出可视化图表和界面帮助我们快速直观发现问题。 日志聚合及检索 比如在电商app我们发现无法进行下单操作在分布式架构下日志散落在多个服务多个服务器中我们不知道错误日志打在哪台服务器上如果每台服务器去登陆去看是极其低效的。这要求我们做到日志格式标准化并通过一些手段聚合到一起进行检索查询。同时可跨越所有服务、特定的某个服务或服务的某个实例搜索日志将日志发送至集中化日志系统所用的代码可包含在共享库中或通过代码脚手架提供。 分布式追踪 在微服务架构场景中一个客户端发起的请求要经过多个服务的调用最终聚合数据结构返回给客户端但我们不知道这个请求不知道经过哪些服务调用哪个服务出现了问题每个服务的输入输出是什么这给我们定位问题带来了困扰除此以外如果一个请求耗时较长我们不知道到底哪个服务耗时最长好有针对性的性能优化。随着架构的演进我们在架构设计规划时需要知道 服务之间的依赖关系这有需要什么技术来实现呢这就是我们要介绍的分布式追踪分布式追踪借助关联id在请求源头创建这个关联id并且在服务间进行透传最终将关联id等信息聚合到一起进行查询分析。
可靠性 在讲单体的过程中我们讲到一个业务模块的内存泄露会导致整个进程退出。在微服务场景下如果一个服务出现内存泄露是不会影响 没有依赖关系的服务的。但是却可以因为该异常服务的僵死或不可用造成上游服务线程hang住进而产生级联效应故障进一步向上游传播。 流量控制超时控制 可靠性技术通过流量的控制和超时控制保证服务消费者不被下游服务拖慢及时对业务线程循环复用。 舱壁隔离熔断机制 熔断是指服务调用出错次数在一定时间达到一定数量自动关闭对该服务的调用开关改为返回错误或者将请求转交给降级方法降低资源耗尽的风险当服务不可用时作为服务消费者应该对接口方法编写一个降级方法。 服务降级, 幂等重试 由于服务间通信是通过网络传输的网络异常和网络分区故障 就会经常出现我们遇到这种情况可以进行调用重试重试时要注意两点一个是接口必须是幂等的无论运行一次或多次最终结果必须相同。幂等性保证了重试不会产生负面影响。在重试过程时休眠时间应该是指数增长的否则会产生惊群效应比如故障后的服务恢复上线后如果有大量其他服务正在同一个重试窗口内重试此时很容易给系统造成巨大压力。 提炼代码脚手架 除了开发业务逻辑我们还需要搭建一套微服务工程可用框架这样是是为了加快团队工作效率微服务解决方案保持统一增强代码复用性统一进行优化微服务要解决的问题非常多所以抽取服务代码模板是有必要的它包括服务注册发现、服务通信、监控、日志、异常处理等等。 从单体迁移到微服务 1、何时迁移微服务 讲了这么多微服务的好处我们是不是可以从此抛弃单体架构一切项目直接投向微服务的怀抱了呢? Martin Fowler在《MicroservicePremium》一文说 “don’t even consider microservices unless you have a system that’s too complex to manage as a monolith”翻译过来就是如果你的系统不到足够复杂的程度不要考虑使用微服务。 当业务不复杂团队规模不大的时候单块架构比微服务架构具有更高的生产率productivity。因为建立微服务架构需要额外的开销来支持和管理微服务从而降低生产率但是随着业务复杂性的增加和团队规模的扩大单块架构比微服务架构的生产率下降更趋明显。 当复杂性达到一个临界点微服务架构的生产率会优于单块架构因为微服务的松散耦合自治特性减缓了生产率的下降趋势。 所以我们在做项目时一定要根据自己的团队和业务复杂性来判断何时应用微服务。 以我的经验给大家的建议时一个全新项目在1-3团队时可以先拆分成一个API 网关和一个集合所有业务的后端服务API网关关注鉴权和路由、处理部分失败后端服务要划分好业务模块项目初期由于流量不多可以不必添加流量控制和断路器等组件。
同时即使向微服务架构迁移之后拆分的粒度也要由粗到细演进式发展一定要根据自己的业务规模复杂性和团队规模来定。
如何迁移到微服务上来 一个策略是不要大规模big bang重写代码只有当你承担重建一套全新基于微服务的应用时候可以采用重写这种方法。重写代码听起来很不错但实际上充满了风险最终可能会失败就如Martin Fowler所说“the only thing a Big Bang rewrite guarantees is a Big Bang!”相反应该采取逐步迁移单体式应用的策略通过逐步生成微服务新应用与旧的单体式应用集成随着时间推移单体式应用在整个架构中比例逐渐下降直到消失或者成为微服务架构一部分。这个策略有点像在高速路上限速到70迈对车做维护尽管有挑战但是比起重写的风险小很多。 Martin Fowler将这种现代化策略成为绞杀应用名字来源于雨林中的绞杀藤strangler vine也叫绞杀榕(strangler fig)。绞杀藤为了爬到森林顶端都要缠绕着大叔生长一段时间后树死了留下树形藤。这种应用也使用同一种模式围绕着传统应用开发了新型微服务应用传统应用会渐渐退出舞台。 SOA VS 微服务 SOA和微服务的对比是一个老生常谈的话题我认为两者最大的不同是提出时所处的技术背景和环境。 SOA的出现其实是为了解决历史问题企业在信息化的过程中会有各种各样互相隔离的系统需要有一种机制将他们整合起来所以才会有ESB的出现。同样的也成了SOA初期的服务是很大的概念通常指定的一个可以独立运作的系统。 微服务没有历史包袱服务的尺寸通常不会太大。从服务粒度来讲SOA更像是单体的简单组合而微服务是粒度更细小的服务其次数据拆分SOA倾向于共享数据库微服务一个服务对应一个数据库。
3. 为什么采用Spring Cloud Alibaba
Spring Cloud Alibaba架构图参考网络 3.1 Spring Cloud Alibaba 真实应用场景 大型复杂的系统例如大型电商系统原因业务复杂高并发系统例如大型门户秒杀系统原因去中心化能够承载更高的负载压力并且提供个一款很好用的容错组件Sentinel可以进一步提升应用可用性、容错性需求不明确且变更很快的系统例如创业公司业务系统原因修改模块方便 3.2 Spring Cloud Alibaba 和 Spring Cloud 有什么区别和联系呢 Spring Cloud Alibaba 是 Spring Cloud的子项目Spring Cloud Alibaba 是 Spring Cloud的子项目 Spring Cloud 第一代状态Spring Cloud Alibaba状态Eureka2.0孵化失败Nacos Discovery性能强劲感知更快Ribbon进去维护状态预计2020年1月停止维护新的标准已形成spring-clound-loadbalancer,但暂无参考实现。Spring Clound Hoxton 才会孵化出替代品Hystrix/Hystrix Dashboard/Turbine进入维护状态预计2020年1月停止维护Sentinel可视化配置上手更简单Zuul进入维护状态预计2020年1月停止维护Spring Cloud Gateway性能是Zuul的1.6倍Spring Clound Config搭建复杂约定多设计繁重没有洁面难维护难以上手Nacos Config搭建简单有可视化界面配置管理更高效学习曲线低
总体来将 Spring Cloud Alibaba 组件性能更强良好的可视化界面搭建简单学习曲线低文档丰富并且是中文
3.3 Spring Clound Alibaba 的重要组件
服务发现 Nacos实现负载均衡 Ribbon声明式HTTP客户端-Feign服务发现原理负载均衡的常见模式剖析如何使用FeignNacos Server/ClientRestTemplate整合RibbonFeign配置自定义高可用Nacos搭建Ribbon配置自定义如何扩展Feign0如何扩展 Ribbon0
服务容错 Sentinel消息驱动 RocketMQAPI网关 Gateway服务容错原理Spring Clound Stream整合GatewaySentinel实现异步消息推送与消费三大核心Sentinel Dashboard聚合微服务请求Sentinel 核心原理分
用户认证与授权配置管理 Nacos调用链监控Sleuth认证授权的常见方案配置如何管理调用链监控原理剖析改造Gateway配置动态刷新Sleuth使用扩展Feigh Dashboard配置管理的最佳实践Ziplin使用