首先介绍一下系统架构演变

 

1.1 系统架构演变

随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。
系统架构大体经历了下面几个过程: 单体应用架构—>垂直应用架构—>分布
式架构—>SOA架构—>微服务架构,当然还有悄然兴起的Service Mesh(服务网格化)。
接下来我们就来了解一下每种系统架构是什么样子的, 以及各有什么优缺点。

1.1.1 单体应用架构

web项目,然后部署到一台tomcat服务器上

优点:

  • 项目架构简单,小型项目的话, 开发成本低
  • 项目部署在一个节点上, 维护方便

缺点:

  • 全部功能集成在一个工程中,对于大型项目来讲不易开发和维护
  • 项目模块之间紧密耦合,单点容错率低
  • 无法针对不同模块进行针对性优化和水平扩展

1.1.2 垂直应用架构

所谓的垂直应用架构,就是将原来的一个应用拆成互不相干的几个应用,以提升效率。

这样拆分完毕之后,一旦某个应用用户访问量变大,只需要增加对应应用节点就可以了,而无需增加其他节点。

优点:

  • 系统拆分实现了流量分担,解决了并发问题,而且可以针对不同模块进行优化和水扩展
  • 一个系统的问题不会影响到其他系统,提高容错率

缺点:

  • 系统之间相互独立, 无法进行相互调用
  • 系统之间相互独立, 会有重复的开发任务

1.1.3 分布式架构

分布式系统架构,它把工程拆分成表现层和服务层两个部分,服务层中包含业务逻辑。表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。


优点:
抽取公共的功能为服务层,提高代码复用性
缺点:
系统间耦合度变高,调用关系错综复杂,难以维护

1.1.4 SOA架构

增加一个调度中心对集群进行实时管理。此时,用于资源调度和治理中心(SOA Service Oriented
Architecture,面向服务的架构)是关键。

优点:

  • 使用注册中心解决了服务间调用关系的自动调节

缺点:

  • 服务间会有依赖关系,一旦某个环节出错会影响较大( 服务雪崩 )
  • 服务关心复杂,运维、测试部署困难

1.1.5 微服务架构

微服务架构在某种程度上是面向服务的架构SOA继续发展的下一步,它更加强调服务的"彻底拆分"。

优点:

  • 服务原子化拆分,独立打包、部署和升级,保证每个微服务清晰的任务划分,利于扩展
  • 微服务之间采用Restful等轻量级http协议相互调用

缺点:

  • 分布式系统开发的技术成本高(容错、分布式事务等)

1.2 微服务架构介绍

微服务架构, 简单的说就是将单体应用进一步拆分,拆分成更小的服务,每个服务都是一个可以独立运行的项目。

1.2.1 微服务架构的常见问题

一旦采用微服务系统架构,就势必会遇到这样几个问题:

  • 这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])
  • 这么多小服务,他们之间如何通讯?(restful rpc)
  • 这么多小服务,客户端怎么访问他们?(网关)
  • 这么多小服务,一旦出现问题了,应该如何自处理?(容错)
  • 这么多小服务,一旦出现问题了,应该如何排错? (链路追踪)

对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一
问题提供了相应的组件来解决它们。

在这里插入图片描述

常见的微服务组件及发展趋势

1.2.2 微服务架构的常见概念

1.2.2.1 服务治理

服务治理就是进行服务的自动化管理,其核心是服务的自动注册与发现。

服务注册:服务实例将自身服务信息注册到注册中心。


服务发现:服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。

服务剔除:服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到。

 

1.2.2.2 服务调用

在微服务架构中,通常存在多个服务之间的远程调用的需求。目前主流的远程调用技术有基于
HTTP的RESTful接口以及基于TCP的RPC协议。

  • (Representational State Transfer)
    这是一种HTTP调用的格式,更标准,更通用,无论哪种语言都支持http协议
  • RPC(Remote Promote Call)

一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC框架的主要目标就是让远程服务调用更简单、透明。RPC框架负责屏蔽底层的传输方式、序列化方式和通信细节。开发人员在使
用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。

区别与联系

比较项RESTfulRPC
通讯协议HTTP一般使用TCP
性能略低较高
灵活度
应用微服务架构SOA架构

1.2.2.3 服务网关

随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个
服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:

  • 客户端需要调用不同的url地址,增加难度
  • 在一定的场景下,存在跨域请求的问题
  • 每个微服务都需要进行单独的身份认证

针对这些问题,API网关顺势而生。

API网关直面意思是将所有API调用统一接入到API网关层,由网关层统一接入和输出。一个网关的
基本功能有:统一接入安全防护协议适配流量管控长短链接支持容错能力。有了网关之后,
各个API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问题。

 

1.2.2.4 服务容错

在微服务当中,一个请求经常会涉及到调用几个服务,如果其中某个服务不可用,没有做服务容错的话,极有可能会造成一连串的服务不可用,这就是雪崩效应。

我们没法预防雪崩效应的发生,只能尽可能去做好容错。服务容错的三个核心思想是:

  • 不被外界环境影响

  • 不被上游请求压垮

  • 不被下游响应拖垮

1.2.2.5 链路追踪

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。
互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。
因此,就需要对一次请求涉及的多个服务链路进行日志记录,性能监控即链路追踪

 

1.2.3 微服务架构的常见解决方案

1.2.3.1 ServiceComb

Apache ServiceComb,前身是华为云的微服务引擎 CSE (Cloud Service Engine) 云服务,是全球
首个Apache微服务顶级项目。它提供了一站式的微服务开源解决方案,致力于帮助企业、用户和开发
者将企业应用轻松微服务化上云,并实现对微服务应用的高效运维管理。

1.2.3.2 SpringCloud

 

  • Spring Cloud是一系列框架的集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

  • Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理

  • 最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

SpringCloud提供的全生态的分布式组件支持,netflex系列

  1. 服务注册发现:Eureka(其他选择: Consul,Zookeeper,Nacos,Etcd)
  2. 负载均衡:Robbin(声明式调用:Fegin
  3. 断路器:Hystrix
  4. 网关:Zuul2,Spring Cloud Gateway
  5. 配置中心:Spring Cloud Config
  6. 监控:Spring Boot Admin,Spring Boot Actuator
  7. 链路跟踪:Spring Cloud Sleuth

三、组件介绍

1、Eureka

(1)体系划分

Eureka是SpringCloud官方推荐的服务注册发现组件。Eureka的角色和Dubbo中Zookeeper的角色类似,体系划分如下,

  • 业务上可以分为:服务注册中心、服务提供者、服务消费者
  • 代码逻辑上分为:Eureka Server 和 Eureka Client

(2)结构原理

看图说话,

  • 两台Eureka服务注册中心构成的服务注册中心的主从复制集群;
  • 然后服务提供者向注册中心进行注册、续约、下线服务等;
  • 服务消费者向Eureka注册中心拉去服务列表并维护在本地;
  • 然后服务消费者根据从Eureka服务注册中心获取的服务列表选取一个服务提供者进行消费服务。

(3)Eureka 集群(三节点,两两注册)

从图中可以看出 Eureka Server 集群相互之间通过 Replicate 来同步数据,相互之间不区分主节点和从节点,所有的节点都是平等的。在这种架构中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。

如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点。当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会进行节点间复制,将请求复制到其它 Eureka Server 当前所知的所有节点中。

Eureka Server 集群之间的状态是采用异步方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的(Eureka保证AP,Zookeeper强调CP)。

2、Robbin

(1)客户端的软负载

Robbin是springcloud的LB调用组件,提供客户端的软件负载均衡。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

Robbin 提供的客户端软负载,是SpringCloud微服务的典型特征之一。

(2)负载均衡策略

  • 轮询(RoundRobin),以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
  • 随机(Random),随机选择状态为UP的Server。
  • 加权响应时间(WeightedResponseTime),根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
  • 区域感知轮询(ZoneAvoidanceRule),复合判断server所在区域的性能和server的可用性选择server。

(3)核心组件

Ribbon的核心组件(均为接口类型)有以下几个,

  • ServerList,用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。
  • ServerListFilter,仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。
  • IRule,选择一个最终的服务地址作为LB结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。

Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果。

3、Fegin

Fegin是一个声明式Http端调用,集成了Robbin的负载均衡功能,同时声明式调用更加方便(只需要简单的注解即可)。简单的可以理解为:Spring Cloud Feign 的出现使得Eureka和Ribbon的使用更加简单。

(1)Fegin接口示例

a、启动类 @EnableFeignClients 注解

 
  1. @SpringBootApplication

  2. @EnableEurekaClient

  3. @EnableFeignClients // 启用fegin声明式调用

  4. public class FeginComsumerApplication {

  5.  
  6. public static void main(String[] args) {

  7. SpringApplication.run(FeginComsumerApplication.class, args);

  8. }

  9.  
  10. }

b、声明一个调用的Feign接口,

 
  1. @Service

  2. @FeignClient(name = "name-service")

  3. public interface NameService {

  4.  
  5. @RequestMapping(value = "/getName", method = RequestMethod.GET)

  6. public String getName();

  7.  
  8. }

c、服务端提供接口实现

 
  1. @RequestMapping(value = "/getName", method = RequestMethod.GET)

  2. public String getName(){

  3. return "hello world";

  4. }

d、fegin声明是调用

 
  1. @Autowired

  2. private NameServiceClient feginNameServiceClient;

  3.  
  4. @RequestMapping(value = "/getName", method= RequestMethod.GET)

  5. public String getName(){

  6. return feginNameServiceClient.getName();

  7. }

(2)Fegin 的类加载流程

  • 通过主类上的EnableFeignClients 注解开启FeignClient;
  • 根据Feign 的规则实现接口,并加上FeignClient注解,供调用的地方注入调用;
  • 程序启动后,会扫描所有FeignClient 注解的类,并将这些信息注入到IOC 容器中;
  • 当b中接口被调用时,通过jdk代理,以及反射(Spring处理注解的方式),来生成具体的RequestTemplate
  • RequestTemplate 生成Reqest
  • Request 交给httpclient处理,这里的httpclient 可以是OkHttp,也可以是HttpUrlConnection 或者HttpClient
  • 最后Client被封装到LoadBalanceClient类,这个类结合Ribbon 实现负载均衡。

(3)Fegin的原理

4、Hystrix

Hystrix 是springcloud生态的断路器(隔离、限流、降级),主要是用来预防服务雪崩的现象,剔除掉分布式系统中某些挂掉或请求过慢的服务节点。Hystrix 是一个帮助解决分布式系统中超时处理和容错的类库, 拥有保护系统的能力。

(1)隔离、限流、降级

Hystrix断路器有两种隔离策略:信号量隔离(默认)和线程池隔离

  • 信号量模式从始至终都只有请求线程自身,是同步调用模式,不支持超时调用,不支持直接熔断,由于没有线程的切换,开销非常小。
  • 线程池模式可以支持异步调用,支持超时调用,支持直接熔断,存在线程切换,开销大。

信号量隔离:常用于获取共享资源的场景中,比如计算机连接了两个打印机,那么初始的信号量就是2,被某个进程或线程获取后减1,信号量为0后,需要获取的线程或进程进入资源等待状态。Hystrix的处理有些不同,其不等待,直接返回失败。

线程池隔离:采用的就是jdk的线程池,其默认选用不使用阻塞队列的线程池,例如线程池大小为10,如果某时刻10个线程均被使用,那么新的请求将不会进入等待队列,而是直接返回失败,起到限流的作用。

此外,其还引入了一个断路器机制,当断路器处于打开状态时,直接返回失败或进入降级流程。断路器打开和关闭的触发流程为:当总的请求数达到可阈值HystrixCommandProperties.circuitBreakerRequestVolumeThreshold(),或总的请求失败百分比达到了阈值HystrixCommandProperties.circuitBreakerErrorThresholdPercentage(),这时将断路器的状态由关闭设置为打开。当断路器打开时,所有的请求均被短路,在经过指定休眠时间窗口后,让下一个请求通过(断路器被认为是半开状态)。如果请求失败,断路器进入打开状态,并进入新的休眠窗口;否则进入关闭状态。

(2)Hystrix 的整体处理流程

流程如上图所示,Hystrix框架通过命令模式来实现方法粒度上的服务保障,主要涉及HystrixCommandHystrixObservableCommand类,前者提供同步的execute和异步的queue方法,后者提供立即执行observe和延迟执行toObservable的回调方法。此外,实际项目中通常不会使用Hystrix集成的本地缓存。

5、Spring Cloud Gateway

Spring Cloud Gateway 是springcloud全新推出的第二代微服务网关,用来替代Zuul。gateway实现了服务转发、熔断、限流、权限校验等功能,有测评显示,性能比Zuul要好不少。

(1)相关概念

  • Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
  • Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
  • Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

(2)请求流程

spring cloud gateway处理request请求的流程如下图,

我们先看gateway的构成:一个netty server,一个netty client,Route(包含Predicate和Filter)。在gateway中最重要的应该是Route(Netty Server和Client已经封装好了),它由RouteLocatorBuilder构建,内部包含Predicate和Filter。

流程:即在最前端,启动一个netty server(默认端口为8080)接受请求,然后通过Routes(每个Route由Predicate(等同于HandlerMapping)和Filter(等同于HandlerAdapter))处理后通过Netty Client发给响应的微服务。

(3)yml配置

 
  1. server.port: 8082

  2.  
  3. spring:

  4. application:

  5. name: gateway

  6. cloud:

  7. gateway:

  8. routes:

  9. - id: path_route

  10. uri: http://localhost:8000

  11. order: 0

  12. predicates:

  13. - Path=/foo/**

  14. filters:

  15. - StripPrefix=1

上面给出了一个根据请求路径来匹配目标uri的例子,如果请求的路径为/foo/bar,则目标uri为 http://localhost:8000/bar。如果上面例子中没有加一个StripPrefix=1过滤器,则目标uri 为http://localhost:8000/foo/bar,StripPrefix过滤器是去掉一个路径。

6、Spring Boot Admin

Spring Boot Admin 是springcloud提供的监控组件,用于管理和监控SpringBoot各个微服务。Admin通过注册中心(如Eureka)来监控各个节点的状态。可以结合 Spring Boot Actuator 使用,常用的监控数据有,

  • 显示健康状况
  • 显示详细信息,例如
    • JVM和内存指标
    • micrometer.io指标
    • 数据源指标
    • 缓存指标
  • 查看jvm系统和环境属性

监控 server端需要 @EnableAdminServer 注解,client端只需要配置好yaml文件就好了,admin会通过注册中心获取各个服务节点的状态。

 
  1. management:

  2. endpoints:

  3. web:

  4. exposure:

  5. include: '*'

  6. endpoint:

  7. health:

  8. show-details: ALWAYS

7、Spring Cloud Config

Spring Cloud Config 是springcloud的分布式配置中心组件。

分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件Spring Cloud Config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。

SpringCloudConfig分为服务端(Config Server)和客户端(Config Client),服务端负责将git(svn)中存储的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置, 它需要每个客户端通过POST方法触发各自的/refresh,SpringCloudBus就通过一个轻量级消息代理连接分布式系统的节点。

Config Server用于配置属性的存储,存储的位置可以为Git仓库、SVN仓库、本地文件等,Config Client用于服务属性的读取。

spring cloud config是将配置保存在git/svn上,依赖git每次push后,触发webhook回调,最终触发spring cloud bus(消息总线),然后由消息总线通知相关的应用。

1.2.3.3 SpringCloud Alibaba

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

SpringCloud Alibaba介绍

 

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式 应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接
入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

1.3.1 主要功能

  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修
    改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任
    何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
    同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有
  • Worker(schedulerx-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

组件

Sentinel: 把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳
定性。
Nacos: 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ: 一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠
的消息发布与订阅服务。
Dubbo: Apache Dubbo™ 是一款高性能 Java RPC 框架。
Seata: 阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud ACM: 一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心
产品。
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提
供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和
访问任意类型的数据。
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精
准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速
搭建客户触达通道。

具体技术点(约定>配置>编码)

  • maven:3.6.0


  
 

这样做的好处就是: 如果有多个子项目都引用同一样的依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样想升级或切换到另一个版本时,只需在顶层父容器里更新,而不需要一个一个子项目的修改l;另外如果某个子项目需要另外的一个版本,只需声明version版本 

  • 数据库:MySQL 5.7

  • 持久层: SpingData Jpa

  • 其他: SpringCloud Alibaba 技术栈

  • 安全框架:Spring Security Spring Cloud Oauth2
    	分布式任务调度:elastic-job
    	持久层框架:MyBatis、通用Mapper4、Mybatis_PageHelper
    	数据库连接池
    	日志管理:Logback	前端框架:Vue全家桶以及相关组件
    	三方服务: 邮件服务、阿里云短信服务、七牛云文件服务、钉钉机器人服务、高德地图API

 

Logo

开源、云原生的融合云平台

更多推荐