微服务分布式架构

文章目录

第一章 微服务简介

1.1 从单体架构到微服务架构的演进

1.1.1 单体架构

什么是单体架构,就拿大家平常做的课设来说那就是一个单体架构,最经典的就是学生成绩管理系统之类的了,项目结构图大体如下:
微服务分布式架构
整个系统的架构非常简单,使用Spring+SpringMVC+Mybatis构建一个基础工程、MySQL数据库作为持久化存储,在这个工程中创建不同的Service实现项目中不同的业务场景,如线路、线路分类、用户等。最后把项目构建成一个war包部署在Tomcat容器上即可使用,这时我们之前经常采用的架构。通常来说,如果一个war包或者jar包里面包含一个应用的所有功能,则我们称这种架构为单体架构。很多传统互联网公司或者创业型公司早期基本都会采用这样的架构,因为这样的架构足够简单,能够快速开发和上线。而且对于项目初期用户量不大的情况,这样的架构足以支撑业务的正常运行。

1.1.2 集群和垂直化

以商城系统为例。随着业务的发展,产品被越来越多的人使用,那么对于整个技术架构来说,可能会面临以下挑战:
● 用户量越来越大,网络访问量不断增大,导致后端服务器的负载越来越高。
● 用户量大了,产品需要满足不同用户的需求来留住用户,使得业务场景越来越多并且越来越复杂。
● 当服务器的负载越来越高的时候,如果不进行任何处理,用户在网站上操作的响应会越来越慢,甚至出现无法访问的情况,对于非常注重用户体验的互联网产品来说,这是无法容忍的。
● 业务的场景越多越复杂,意味着war包中的代码量会持续上升,并且各个业务代码之间的耦合度也会越来越高,后期的代码维护和版本发布涉及的测试和上线,也会很困那。举个最简单的例子,当你需要在库存模块里面添加一个方法时,带来的影响是需要把整个系统重新测试和部署,而当一个war包有几GB的大小时,部署的过程也是相当痛苦的。
因此,我们可以从两个方面进行优化:

  1. 通过横向增加服务器,把单台机器变成多台机器的集群。
  2. 按照业务的垂直领域进行拆分,减少业务的耦合度,以及降低单个war包带来的伸缩性困难问题。

1.2 微服务简介

简单来说就是把一组应用中所涉及的业务经营模块化管理,客户端可以无障碍的请求到各个服务模块,模块与模块之间也可以进行相互通讯(rpc HTTP),各个业务可以自行组装成不同模块,使得各服务器可以得到最有效率的运用。
彻底的解耦,一个微服务提供单个业务功能,能自行单独开启或销毁,拥有自己独立的数据库。

1.3 微服务框架

所以,为了能向上述所说的那样,现在市面上提供了一系列的解决方案,比如Spring Cloud,应该具备一些什么功能呢?微服务框架的功能主要体现在以下几个方面。
● 注册中心:服务提供者和消费者,能够从注册中心注册和得到服务信息。
● 配置中心:在微服务架构中设计服务较多需要对于配置文件统一管理。
● 服务链路追踪:对于服务之间的负载调用,要能通过链路追踪,得到具体参与者,调用链路出现问题能够快速定位。
● 负载均衡:服务调用服务会采用一定的负载均衡策略,来保证服务的高可用。
● 服务容错:通过熔断、降级服务容错策略,对系统进行有效的保护,降级是在服务或依赖的服务异常时,返回保底数据,熔断是指依赖服务多次失效,则熔断器打开,不再尝试调用,直接返回降级信息。熔断后,定期探测依赖服务可用性,若恢复则恢复调用。
● 服务网关:用户请求过载时进行限流、排队、过载保护、黑白名单、异常用户过滤拦截等都可以通过服务网关实现。
● 服务发布与回滚:蓝绿部署、灰度、AB Test等发布策略,可快速回滚应用。
● 服务动态伸缩、容器化:根据服务负载情况,可快速手动或自动进行节点增加和减少。

微服务分布式架构

第二章 服务的注册和发现Eureka

注册中心:服务提供者和消费者,能够从注册中心注册和得到服务信息。

分为eureka-server和eureka-client,能把各个eureka-client注册的信息展示到eureka-Server界面中,便于管控。

第三章 客户端服务间的通讯RestTemplate、LoadBalancer、openFeign

3.2 RestTemplate

RestTemplate是Spring Resources中一个访问第三方RESTful API接口的网络请求框架。RestTemplate的设计原则和其他的Spring Template(例如JdbcTemplate)类似,都是为了执行复杂任务提供了一个具有默认行为的简单方法。
RestTemplate是用来消费REST服务的,所以RestTemplate的主要方法都与REST的HTTP协议的一些方法紧密相连,例如HEAD、GET、POST、PUT、DELETE、OPTIONS等方法,这些方法在RestTemplate类对应的方法为headForHeaders(),getForObject()、postForObject()、put()、delet()等。

3.3 LoadBalancer

怎么说呢,就一个服务调用另一个服务的桥梁,在一个服务调用另一个服务的时候又会遇到,负载过大的问题,所以又有了控制负载均衡的组件LoadBalancer:
负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。一种独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如Nginx。另一种是将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提供者的信息列表,有了信息表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到负载均衡的目的。
默认的负载均衡算法是轮询算法,其他还有随机算法,访问时间加权算法等。

3.4 openFeign

相当于可以实现RestTemplate和loadBalancer的功能,并且可以在得到数据的过程中,自动转换为对应对象,接收到的相当于是被处理过后的json对象。

第四章 微服务容错Resilience4j

4.1微服务容错简介

在高并发访问下,比如天猫双11,流量持续不断的涌入,服务之间的相互调用频率突然增加,引发系统负载过高,这时系统所依赖的服务的稳定性对系统的影响非常大,而且还有很多不确定因素引起雪崩,如网络连接中断,服务宕机等。一般微服务容错组件提供了限流、隔离、降级、熔断等手段,可以有效保护我们的微服务系统。

Resilience4j四大处理方案:

  • 隔离(Builkhead)
    微服务系统A调用B,而B调用C,这时如果C出现故障,则此时调用B的大量线程资源阻塞,慢慢的B的线程数量持续增加直到CPU耗尽到100%,整体微服务不可用,这时就需要对不可用的服务进行隔离
  • 熔断(CircuitBreaker)
    当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
  • 降级
    降级是指当自身服务压力增大时,系统将某些不重要的业务或接口的功能降低,可以只提供部分功能,也可以完全停止所有不重要的功能。比如,下线非核心服务以保证核心服务的稳定、降低实时性、降低数据一致性,降级的思想是丢车保帅。
    举个例子,比如,目前很多人想要下订单,但是我的服务器除了处理下订单业务之外,还有一些其他的服务在运行,比如,搜索、定时任务、支付、商品详情、日志等等服务。然而这些不重要的服务占用了JVM的不少内存和CPU资源,为了应对很多人要下订单的需求,设计了一个动态开关,把这些不重要的服务直接在最外层拒绝掉。这样就有跟多的资源来处理下订单服务(下订单速度更快了)
  • 限流(RateLimiter)
    限流,就是限制最大流量。系统能提供的最大并发有限,同时来的请求又太多,就需要限流,比如商城秒杀业务,瞬时大量请求涌入,服务器服务不过来,就只好排队限流了,就跟去景点排队买票和去银行办理业务排队等号道理相同。

限流的四大算法:

  • 漏桶算法
  • 令牌桶算法
  • 固定时间窗口算法
  • 滑动时间窗口算法

第五章 微服务网关Spring Cloud Gateway

Spring Cloud Gateway简介

Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流

特征

SpringCloud官方,对SpringCloud Gateway 特征介绍如下:
● 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
● 集成 Spring Cloud DiscoveryClient
● Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
● 具备一些网关的高级功能:动态路由、限流、路径重写
● 集成Spring Cloud DiscoveryClient
● 集成熔断器CircuitBreaker
从以上的特征来说,和Zuul的特征差别不大。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。
简单说明一下上文中的三个术语:
(1)Filter(过滤器):
和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对下游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。
(2)Route(路由):
网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
(3)Predicate(断言):
这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。

第六章 Spring Cloud Config配置管理

配置文件想必大家都不陌生。在Spring Boot项目中,默认会提供一个application.properties或者application.yml文件,我们可以把一些全局性的配置或者需要动态维护的配置写入改文件,不如数据库连接,功能开关,限流阈值,服务地址等。为了解决不同环境下服务连接配置等信息的差异,Spring Boot还提供了基于spring.profiles.active={profile}的机制来实现不同的环境的切换。
随着单体架构向微服务架构的演进,各个应用自己独立维护本地配置文件的方式开始显露出它的不足之处。主要有下面几点。
● 配置的动态更新:在实际应用会有动态更新位置的需求,比如修改服务连接地址、限流配置等。在传统模式下,需要手动修改配置文件并且重启应用才能生效,这种方式效率太低,重启也会导致服务暂时不可用。
● 配置多节点维护:在微服务架构中某些核心服务为了保证高性能会部署上百个节点,如果在每个节点中都维护一个配置文件,一旦配置文件中的某个属性需要修改,可想而知,工作量是巨大的。
● 不同部署环境下配置的管理:前面提到通过profile机制来管理不同环境下的配置,这种方式对于日常维护来说也比较繁琐。
统一配置管理就是弥补上述不足的方法,简单说,最近本的方法是把各个应用系统中的某些配置放在一个第三方中间件上进行统一维护。然后,对于统一配置中心上的数据的变更需要推送到相应的服务节点实现动态跟新,所以微服务架构中,配置中心也是一个核心组件,而Spring Cloud Config就是一个配置中心组件,并且可以Git,SVN,本地文件等作为存储。

微服务分布式架构

上一篇:Vue 项目中引入 tinymce 富文本编辑器


下一篇:给春招准备跳槽的小伙伴的一篇文