有什么网站可以免费做图,网站建设专业吗,图片制作app,得物网上商城小熊学Java#xff1a;https://www.javaxiaobear.cn/#xff0c;文末有免费资源
本文我们来学习微服务的架构设计 主要包括如下内容。 单体系统的困难#xff1a;编译部署困难、数据库连接耗尽、服务复用困难、新增业务困难。 微服务框架#xff1a;Dubbo 和 Spring Clou…小熊学Javahttps://www.javaxiaobear.cn/文末有免费资源
本文我们来学习微服务的架构设计 主要包括如下内容。 单体系统的困难编译部署困难、数据库连接耗尽、服务复用困难、新增业务困难。 微服务框架Dubbo 和 Spring Cloud微服务的架构策略。 微服务模式事件溯源、查询与命令职责分离 CQRS、断路器、超时。 微服务最佳实践。
单体系统的困难
在微服务出现之前互联网应用系统主要是单体系统也就是说一个网站的整个系统由一个应用构成。如果是 Java就打包成一个 war 包一个 war 包包含整个应用系统系统更新的时候即使只是更新其中极小的一部分也要重新打包整个 war 包发布整个系统。
这样的单体系统面临的挑战主要是什么呢
编译、部署困难
随着网站的业务不断发展系统会变得越来越庞大最后变成一个巨无霸的系统。 在我曾经工作过的公司单个应用可能有几个 G 大这对于网站开发工程师来说开发编译和部署都是非常困难的。在开发的过程中即使只改了庞大系统中的一行代码也必须把完整的网站系统重新打包才能做测试。这会经历漫长的编译过程出去抽一支烟回来一看在编译又去喝了一杯水回来还在编译再去趟厕所回来还在编译。好不容易编译结束了如果某个配置项错误导致编译失败又得重来一次浪费大半天的时间。这样的单体系统对于开发部署和测试都是非常困难的。代码分支管理困难
因为单体应用非常庞大所以代码模块也是由多个团队共同维护的。但最后还是要编译成一个单体应用统一发布。这就要求把各个团队的代码 merge 在一起这个过程很容易发生代码冲突。而 merge 的时候又是网站要进行发布的时候发布过程本来就复杂再加上代码 merge 带来的问题各种情况纠缠在一起极易出错。所以在单体应用时代每一次网站发布都需要搞到深更半夜。
数据库连接耗尽
对于一个巨型的应用而言。因为有大量的用户进行访问所以必须把应用部署到大规模的服务器集群上。然后每个应用都需要与数据库建立连接大量的应用服务器连接到数据库会对数据库的连接产生巨大的压力某些情况下甚至会耗尽数据库的连接。
新增业务困难
巨无霸单体应用的另一个挑战是新增业务困难。因为所有的业务都耦合在一个单一的大系统里通常随着时间的发展这个系统会变得非常的复杂里面的各种结构也非常乱想要维护这样一个系统是非常困难和复杂的。很多工程师入职公司半年都还不能熟悉业务因为业务太过庞大和复杂经常会出各种错误。所以就会出现这种现象熟悉系统的老员们工忙得要死加班加点干活不熟悉系统的新员工们一帮忙就出乱跟着加班加点干活。整个公司热火朝天地干活但最后还是常常出故障新的功能迟迟不能上线。
发布困难
因为一个 war 包包含了所有的代码进行新版本发布的时候发布代码跟自己的开发的代码一点关系没有但是因为 war 包包含了自己的代码为了以防万一也不得不跟着发布值班。结果真正更新代码功能的只有几个人而整个部门都要跟着加班。常常出现到了深夜有代码更新的同事汗流浃背进行代码冲突处理和修复发布 bug没有代码更新的同事陪着聊天、打瞌睡、打游戏这种情况。
微服务架构
解决上述问题的主要手段是将一个单体的巨无霸系统根据模块以及复用的粒度进行拆分拆分成多个可以独立部署的分布式服务。应用通过远程访问调用的方式使用这些服务构成一个系统。但是由于它的核心服务是在其他的服务器上分布部署的本身的业务逻辑可以变得比较简单这样就把一个巨无霸系统单体应用拆成了若干个可复用的服务利用较少的逻辑代码就可以组成一个应用系统。
SOA 架构
这样的设计思路其实并不是在互联网时代才出现的。在早期的时候就有人提出了 SOA 面向服务的体系架构。如下图所示在面向服务的体系架构里面服务的提供者向注册中心注册自己的服务而服务的使用者向注册中心去发现服务。发现服务以后根据服务注册中心提供的访问接口和访问路径对服务发起请求由服务的提供者完成请求返回结果给调用者。现在的微服务或者分布式服务其实也是 SOA 架构的一种实现。但是在早期的 SOA 架构实践中服务的注册与服务的调用都非常复杂服务调用效率也比较低。 微服务架构
后来在互联网时代的微服务中人们简化了 SOA 架构中的调用规范和服务规范形成了我们现在所熟悉的分布式微服务架构。
如下图所谓的微服务架构就是将一个单体的巨无霸系统拆分成一组可复用的服务基于这些服务构成的应用系统。图中左边是早期的单体应用系统架构里面的各个模块互相调用、耦合所有的系统和模块打包在一起最后组成一个庞大的巨无霸系统。右边是微服务架构根据服务的粒度和可复用的级别对服务进行拆分以独立部署服务的方式对外提供服务调用。而应用系统也按照用途和场景的不同依赖这些可复用的服务进行逻辑组合构建成自己的业务系统。 通过这样一种方式系统变得比较简单复用级别也比较高同时也解决了前面提出的单体巨无霸的几个重要问题。因为每一个服务或是应用系统代码都比较简单所以编译和部署、开发和测试都比较简单和快速。而且这些服务都是独立维护和部署的它的代码分支也是独立的不会和其他的代码分支一起进行管理减少了代码冲突的可能性。发布的时候也是每个服务独立发布只要做好服务的版本控制和接口兼容应用系统不需要跟随服务一起更新发布。
在微服务体系中连接数据库的是具体的服务应用系统不需要自己去连接数据库只需要调用组合服务对服务进行编排。所以对数据库的连接也相对比以前更少一些。最主要的是当需要开发新业务的时候使用这种方式不需要对原有的单体系统进行各种重构和代码修改只需要开发一个新的业务系统组合调用现有的微服务就可以组合出来一个新的产品功能可以快速开发新产品。
Dubbo
目前一些典型的微服务框架本身的架构是如何设计的
先看 Dubbo 架构。Dubbo 是阿里开源的比较早也比较有影响力的一个分布式微服务框架。如下图所示在 Dubbo 架构中最核心的模块有 3 个部分一个是服务的提供者一个是服务的消费者还有一个是服务的注册中心。 服务的提供者顾名思义就是微服务的具体提供者通过微服务容器对外提供服务。而服务的消费者就是应用系统或是其他的微服务。
应用系统通过组合多个微服务构成自己的业务逻辑实现自己的产品功能。具体过程是服务的提供者程序在 Dubbo 的服务容器中启动服务管理容器向服务注册中心进行注册声明服务提供者所要提供的接口参数和规范并且注册自己所在服务器的 IP 地址和端口如下图所示。
而服务的消费者如果想要调用某个服务只需依赖服务提供者的接口进行编程。而服务接口通过 Dubbo 框架的代理访问机制调用 Dubbo 的服务框架客户端服务框架客户端会根据服务接口声明去注册中心查找对应的服务提供者启动在哪些服务器上并且将这个服务器列表返回给客户端。客户端根据某种负载均衡策略选择某一个服务器通过远程通讯模块发送具体的服务调用请求。
服务调用请求通过 Dubbo 底层自己的远程通讯模块也就是 RPC 调用方式将请求发送到服务的提供者服务器服务提供者服务器收到请求以后将该请求发送给服务提供者程序完成服务的执行并将服务执行处理结果通过远程调用通讯模块 RPC 返回给服务消费者客户端服务消费者客户端将结果返回给服务调用程序从而完成远程服务的调用获得服务处理的结果。
Dubbo 使用 Java 进行开发并且通过服务接口的方式对消费者提供服务所以它的服务调用方式比较简单可以透明地进行远程微服务调用。服务消费者程序可以无感知地进行远程微服务调用对开发者相对比较友好。
Spring Cloud
另一种目前比较热门的微服务框架是 Spring Cloud。Spring Cloud 微服务框架组件跟 Dubbo 类似也是由服务的消费者、服务的提供者和注册中心组成。如下图所示Spring cloud 的服务提供者通过 Spring Boot 启动然后向服务注册中心 Eureka Server 进行注册而服务的消费者通过一个 Zuul 网关访问 Eureka Server 进行服务的发现获得自己想要调用的远程服务对应的服务地址。获得地址以后通过 HTTP 的方式向远程的服务提供者发起调用请求。服务提供者完成服务处理后将处理结果通过 HTTP 返回。从而实现了远程的微服务调用。 Spring Cloud 还包含了一组服务调用监控组件主要是 Hystrix通过 Hystrix 可以监控服务调用还在此基础上实现了熔断、降级、超时管理等一系列高可用策略。
微服务架构策略
对微服务架构而言技术现在其实比较成熟。使用什么样的技术去实现一个微服务本身并没有太多的困难。构建一个微服务架构最困难的还是服务治理也就是业务划分。策略要点如图所示。 一个微服务包含的功能有哪些服务的边界是什么服务之间的依赖关系如何这些关键的问题决定了服务的复用程度维护的难易程度开发的便利程度。所以设计微服务架构的时候首先要关注的是业务业务要先行理顺业务模块之间的边界和依赖做好服务治理和调用依赖管理。
微服务技术是微服务架构的手段而不是目的。微服务最主要的目的还是实现服务治理——如何划分和管理服务。首先要有独立的功能模块然后才有分布式的服务。也就是说在软件设计的时候软件功能模块之间的依赖关系就要清晰、合理、规范、便于维护、便于扩展便于实现新的功能。服务之间的依赖关系要清晰、参数要简单、耦合关系要少。设计好这样的模块化结构以后将这些设计好的模块拆分成独立的微服务进行部署和调用就可以构建一个良好的微服务系统。如果模块本身就是混乱的、耦合严重的、边界不清晰的、关系复杂的那么把它们拆分成独立的微服务进行部署只会使事情变得更加复杂。
所以进行微服务架构设计之初就要先做好业务模块的设计和规划。同时对于那些业务耦合比较严重、逻辑复杂多变的系统进行微服务重构的时候也要特别谨慎。如果做不好模块的划分和耦合管理。那么宁可晚一点进行微服务架构重构也不要仓促上马以免最后带来巨大的损失。要使用微服务架构的时候一定要搞清楚实施微服务的目的究竟是什么是为了业务复用是为了开发边界清晰是为了分布式集群提升性能还是仅仅想要使用微服务目的一定要清楚。
跟其他技术不同微服务具有强业务属性业务如果本身结构混乱目标不清晰仓促使用微服务可能会使整个系统变得更加复杂和难以控制。所以在使用微服务前最重要的是要先明确自己的需求我们到底想用微服务达到什么样的目的需求清晰了再去考虑具体的方案和技术。这也是使用大多数技术的时候应有的方法和思路。
如下图所示最重要的是需求。在日常工作中我们要根据需求去考虑具体的价值再根据价值构建我们的设计原则根据原则寻找最佳实践最后根据实践去选择最合适的工具。按这样的方式去选择技术做架构设计才是比较成熟和高效的。如果相反先找到一个工具然后用工具硬往上套需求只会导致技术也没用好业务也没做好所有人都疲惫不堪事情变得一团糟最后还可能反过来怪技术没用。 微服务的使用模式
下面来看可供参考的几种微服务的使用模式。
事件溯源
第一是事件溯源因为微服务的调用过程会比较复杂调用链路可能会比较长。如果某个微服务调用出错如何进行管理和监控使用事件溯源这种模式是一种解决办法。
所谓的事件溯源是指将用户的请求处理过程每一次的状态变化都记录到事件日志中并按照时间序列进行持久化的存储也就是说把所有的变更操作都按日志的方式按时间化序列进行记录。
使用事件溯源的好处有如下两点。
可以精确地复现用户的状态变化。
用户执行了哪些操作使它成为现在这样一种状况然后通过事件溯源的方式追溯以往的操作和动作从而进行复核和审计。当用户投诉的时候当状态不一致的时候可以通过事件溯源中的日志进行审计和查找。
可以有效监控用户的状态变化并在此基础上实现分布式的事务。
我们传统的事务使用数据库事务进行实现可以将多个数据库操作统一提交或者统一回滚保持数据的一致性但是在分布式状况下对数据的操作是分布在多个独立部署的服务进行处理。这个时候就无法使用数据库的事务进行管理。
那么如何在这种情况下实行分布式系统的事务
事件溯源是一种办法。因为事件溯源将所有的数据变更都按日志的方式记录起来所以如果日志不完整我们就知道事务不完整可以对事务进行重组或者补偿操作从而使数据变得一致。
命令与查询职责隔离CQRS
这种模式在服务接口层面将查询操作也就是读操作和命令操作也就是写操作隔离开来在服务层实现读写分离。
使用 CQRS 模式主要的好处是可以有更清晰的领域模型根据操作的方式不同使用不同的领域模型。还可以分别进行读写优化从而实现更好的性能。
我们知道在读操作中主要使用的优化方式是缓存操作。那么我们可以将接口层面的查询操作即读操作尽量多地通过缓存来返回。而写操作也就是命令操作主要的性能优化方式是使用消息队列。那么我们可以将数据的更新操作尽量通过消息队列通过异步化的方式进行处理以改善性能。
因为使用 CQRS 查询和命令分离的方式我们可以在接口层面上使用不同的优化手段。查询操作不会修改数据库那么所有来自于查询接口的服务可以统一连接到只读数据库中防止误操作破坏数据可以更好地保护数据同时使用 CQRS还可以更好地实现刚才的事件溯源机制。因为查询操作是无须进行事件溯源的所有的事件溯源都可以统一设置在命令服务接口上。
断路器
使用微服务的时候你还需要关注一个事情服务的不可用。
当某个服务实例出现故障的时候它的响应延迟或者失败率增加的时候继续调用这个服务实例会导致请求者阻塞。请求阻塞以后会导致资源消耗增加最后可能会导致请求者也失败和崩溃进而出现服务的级联崩溃也就是服务请求者的请求者也失败最后会导致整个系统全部失败即雪崩现象。
在这种情况下可以使用断路器对故障服务进行隔离。断路器有三种状态关闭、打开、半开。当服务出现故障的时候通过断路器阻断对故障服务实例的调用避免它的故障扩散开来。在 Spring Cloud 中可以使用 Hystrix 实现断路器。
超时
还有一件需要关注的事情是微服务调用的超时机制如何设置。
如果使用统一的超时设置那么当下游调用者超时的时候上游调用者一定也已经超时了因为服务调用是阻塞的。所以下游调用的超时一定会反应在上游调用者上。因此在设置超时的时候要设置上游调用者的超时时间大于下游调用者的超时时间之和相同的超时设置是没有意义的如下图所示。 总结回顾
首先之所以要使用微服务是因为传统的单体巨无霸系统带来的挑战和困难包括编译和部署的困难、连接的困难、打包代码冲突的困难以及复用的困难、新增业务的困难。
而具体的微服务框架基本上都是由三个核心部分组成的服务的提供者、服务的调用者和服务的注册中心。服务的提供者向注册中心注册自己的服务而服务的调用者通过注册中心发现服务并进行远程调用。
另外很多微服务架构中还包括一个监控者的角色通过监控者进行服务的管理和流量的控制。
使用微服务最重要的是做好业务的模块化设计模块之间要低耦合高聚合模块之间的依赖关系要清晰简单。只有这样的模块化设计才能够构建出良好的微服务架构。如果系统本身就是一团遭强行将它们拆分在不同的微服务里只会使系统变得更加混乱。
使用微服务的时候有几个重要的使用模式需要关注一个是事件溯源一个是命令与查询隔离还有一个是断路器以及关于超时如何进行设置。
福利资源 海量数据高并发场景构建GoES8企业级搜索微服务https://www.aliyundrive.com/s/ib2BeM5W3Du