SpringCloud基本使用

312 阅读14分钟

Spring Cloud

初识 Spring Cloud

微服务架构

image.png

image.png

微服务架构 "微服务”一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到 martinfowler.com/articles/mi…

  • 微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间一般通过 HTTP 的 RESTfuL API 进行通信协作。
  • 被拆分成的每一个小型服务都围绕着系统中的某一项或些耦合度较高的业务功能进行构建,并且每个服务都维护着白身的数据存储、业务开发自动化测试案例以及独立部署机制。
  • 由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。

走进 Spring Cloud

Spring Cloud 是一系列框架的有序集合。

  • Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来。
  • 通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
  • 它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、 断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
  • Spring Cloud项目官方网址:spring.io/projects/sp…
  • Spring Cloud 版本命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如:最早的Release版本:Angel,第二个Release版本:Brixton,然后是Camden、Dalston、Edgware,Finchley,Greenwich,Hoxton。目前最新的是Hoxton版本。

image.png

Spring Cloud 与 Dubbo 对比

image.png

  • Spring Cloud 与 Dubbo 都是实现微服务有效的工具。
  • Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件。
  • Dubbo 使用 RPC 通讯协议,Spring Cloud 使用 RESTful 完成通信,Dubbo 效率略高于 Spring Cloud。

小结

  • 微服务就是将项目的各个模块拆分为可独立运行、部署、测试的架构设计风格。
  • Spring 公司将其他公司中微服务架构常用的组件整合起来,并使用 SpringBoot 简化其开发、配置。称为 Spring Cloud
  • Spring Cloud 与 Dubbo都是实现微服务有效的工具。Dubbo 性能更好,而 Spring Cloud 功能更全面。

SpringCloud技术栈

开发分布式系统可能具有挑战性,复杂性已从应用程序层转移到网络层,并要求服务之间进行更多的交互。将代码设为“cloud-native”就需要解决12-factor,例如外部配置,服务无状态,日志记录以及连接到备份服务之类的问题,Spring Cloud项目套件包含使您的应用程序在云中运行所需的许多服务。

12-factor(云原生应用程序的12要素):

image.png

SpringCloud架构:

image.png

SpringCloud技术栈

image.png SpringCloud技术栈非常丰富,这也是SpringCloud为什么在微服务领域中如此受欢迎的原因之一,技术栈如上图,在服务注册与配置、服务调用、微服务网关、消息组件、链路追踪、配置中心、安全控制、将极限流等诸多方面技术栈都比较完善,而且阿里巴巴也出了一套SpringCloud Alibaba版本,主要集成了Alibaba中主流的技术栈。

SpringCloud经典技术介绍

微服务项目近几年非常火爆,推出来的相关技术解决方案热度也非常活跃,但SpringCloud技术栈中也有一部分技术组件在逐步被淘汰或者闭源,但都有更优秀的技术方案替代。在不久的将来,那些闭源或者将被淘汰的技术有很大概率将不在项目中使用,所以我们学习的时候可以直接学习更优秀的替代技术方案。

Eureka闭源:

image.png 上面英文大概意思是:Eureka 2.0 的开源工作已经停止,依赖于开源库里面的 Eureka 2.x 分支构建的项目或者相关代码,风险自负。

Eureka在微服务项目中主要承担服务注册与发现工作,可以替代的技术方案比较多,而且很多方案都比Eureka优秀,比如Consul、Nacos等。

Hystrix停止更新:

image.png Hystrix在项目中主要做服务熔断、降级,但官方宣布将不在开发,目前处于维护状态,但官方表示 1.5.18 版本的 Hystrix 已经足够稳定,可以满足 Netflix 现有应用的需求。

关于Hystrix可替代的产品也比较多,比如官方推荐的resilience4j,resilience4j是一个轻量级熔断框架,但resilience4j目前在国内使用频率还不高,功能也不够强,我们更推荐使用功能更加强悍的SpringCloud Alibaba Sentinel。

Zuul过时:

Zuul是一个微服务网关技术,但Zuul1.x使用的是阻塞式的API,不支持长连接,没有提供异步,高并发场景下性能低。SpringCloud官网推出了全新的微服务网关技术SpringCloud Gateway,比Zuul性能更强悍、功能更丰富、且支持异步等多种特性。

SpringCloud Config实用性差:

SpringCloud Config主要用于管理项目的配置文件,每次要使用SpringCloud Config的时候,总得经过一波操作和配置的折腾,才可以使用SpringCloud Config实现配置管理,而且单独使用无法支持配置实时刷新,在项目中用起来,真比较头疼的。

当前有很多技术可以取代SpringCloud Config,比如携程的Apollo、SpringCloud Alibaba Nacos,功能都比SpringCloud Config强,并且支持实时刷新配置。

SpringCloud Bus实用性差:

SpringCloud Bus是服务消息总线,主要实现通知多个服务执行某个任务,一般和SpringCloud Config一起使用。这个功能其实不太使用,因为很多任务组件基本都具备消息通知功能,比如Nacos、Apollo都能实现所有服务订阅执行相关操作。

SpringCloud项目场景

image.png 微服务技术目前已经在很多国内外大厂中都在广泛使用,那么在项目中该如何使用微服务技术呢?我们以滴滴快车业务未来,来讲解一下微服务技术结合业务应用讲解一下。

image.png 打车业务如上图:

  1. 打车的时候会选择车型,选择车型我们调用过程是:Gateway->Driver(加载司机列表)
  2. 选择车型后确认打车,相当于要下单了,调用过程是:Gateway->Order(下单)->Driver(司机状态更改)
  3. 打车结束后,用户进入支付,调用过程是:Gateway->Pay(支付)->Driver(更新司机状态)->Order(更新订单状态)

Spring Cloud 服务治理

Eureka

image.png

  • Eureka 是 Netflix 公司开源的一个服务注册与发现的组件 。
  • Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被 Spring Cloud 社区整合为Spring-Cloud-Netflix 模块。
  • Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。

Eureka – 相关配置及特性

eureka 一共有4部分 配置

  • server : eureka 的服务端配置
    • enable-self-preservation: #是否开启自我保护机制,默认true
    • eviction-interval-timer-in-ms: #清理间隔(单位毫秒,默认是60*1000)
  • client : eureka 的客户端配置
    • service-url.defaultZone:# eureka服务端地址,将来客户端使用该地址和eureka进行通信
    • register-with-eureka: # 是否将自己的路径 注册到eureka上。
    • fetch-registry: # 是否需要从eureka中抓取数据。
  • instance : eureka 的实例配置
    • hostname: localhost # 主机名
    • prefer-ip-address: # 是否将自己的ip注册到eureka中,默认false 注册 主机名
    • ip-address: # 设置当前实例ip
    • instance-id: # 修改instance-id显示
    • lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
    • lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务
    • lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
    • lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务
  • dashboard : eureka 的web控制台配置
    • enabled: true # 是否启用eureka web控制台
    • path: / # 设置eureka web控制台默认访问路径

server示例

eureka:
  instance:
    hostname: localhost # 主机名
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要
  server:
    enable-self-preservation: false # 关闭自我保护机制
    eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔

client示例

eureka:
  instance:
    hostname: localhost # 主机名
    prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名
    ip-address: 127.0.0.1 # 设置当前实例的ip
    instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # 设置web控制台显示的 实例id
    lease-renewal-interval-in-seconds: 3 # 每隔3 秒发一次心跳包
    lease-expiration-duration-in-seconds: 9 # 如果9秒没有发心跳包,服务器呀,你把我干掉吧~
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

HA配置

server:
  port: 8762

spring:
  application:
    name: eureka-server-ha
    
eureka:
  instance:
    hostname: eureka-server2 #主机名
  client:
    service-url:
      defaultZone: http://eureka-server1:8761/eureka #互相注册
    register-with-eureka: true #是否需要将自己的路径注册到eureka上,eureka server不需要,eureka client需要
    fetch-registry: true #是否需要从eureka中拉取路径,eureka server不需要,eureka client需要
  server:
    enable-self-preservation: false # 关闭自我保护机制
    eviction-interval-timer-in-ms: 3000 # 检查服务的间隔时间 默认60s
  dashboard:
    enabled: true # 是否穷eureka web控制台
    path: / # 设置eureka web控制台默认访问路径

Consul

  • Consul 是由 HashiCorp 基于 Go 语言开发的,支持多数据中心,分布式高可用的服务发布和注册服务软件。
  • 用于实现分布式系统的服务发现与配置。
  • 使用起来也较 为简单。具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署 。
  • 官网地址: www.consul.io

Nacos

  • Nacos(Dynamic Naming and Configuration Service) 是阿里巴巴2018年7月开源的项目。
  • 它专注于服务发现和配置管理领域 致力于帮助您发现、配置和管理微服务。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理。
  • 一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。
  • 官网:nacos.io/
  • 下载地址: github.com/alibaba/nac…

Ribbon 客户端负载均衡

Ribbon 概述

  • Ribbon是 Netflix 提供的一个基于HTTP和TCP的客户端负载均衡工具。
  • Ribbon主要有两个功能:
    • 简化远程调用
    • 负载均衡

image.png 服务端负载均衡

  • 负载均衡算法在服务端
  • 由负载均衡器维护服务地址列表

image.png 客户端负载均衡

  • 负载均衡算法在客户端
  • 客户端维护服务地址列表

Ribbon 远程调用

Ribbon 可以与 简化 RestTemplate 的远程调用

  • 在声明restTemplate的Bean时候,添加一个注解:@LoadBalanced
  • 在使用restTemplate发起请求时,需要定义url时,host:port可以替换为 服务提供方的 应用名称

Ribbon 负载均衡

image.png

Ribbon 负责均衡策略:

  • 随机 :RandomRule
  • 轮询 :RoundRobinRule
  • 最小并发:BestAvailableRule
  • 过滤:AvailabilityFilteringRule
  • 响应时间:WeightedResponseTimeRule
  • 轮询重试:RetryRule
  • 性能可用性:ZoneAvoidanceRule

设置负载均衡策略

  • 编码
  • 配置

image.png

Feign 声明式服务调用

Feign 概述

  • Feign 是一个声明式的 REST 客户端,它用了基于接口的注解方式,很方便实现客户端配置。
  • Feign 最初由 Netflix 公司提供,但不支持SpringMVC注解,后由 SpringCloud 对其封装,支持了SpringMVC注解,让使用者更易于接受。

开启对Feign的支持

  • 在消费端引入 open-feign 依赖
  • 编写Feign调用接口
  • 在启动类 添加 @EnableFeignClients 注解,开启Feign功能
  • 测试调用

Feign接口使用步骤

  • 定义接口
  • 接口上添加注解 @FeignClient,设置value属性为 服务提供者的 应用名称
  • 编写调用接口,接口的声明规则 和 提供方接口保持一致。
  • 注入该接口对象,调用接口方法完成远程调用

Feign 超时设置

• Feign 底层依赖于 Ribbon 实现负载均衡和远程调用。 • Ribbon默认1秒超时。 • 超时配置:

image.png

Feign 日志记录

  • Feign 只能记录 debug 级别的日志信息。

image.png

  • 定义Feign日志级别Bean

image.png

  • 启用该Bean:

image.png

Hystrix 熔断器

Hystrix 概述

image.png

  • Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。
  • 雪崩:一个服务失败,导致整条链路的服务都失败的情形。
  • Hystix 主要功能
    • 隔离
      • 线程池隔离
      • 信号量隔离
    • 降级: 异常,超时
    • 熔断
    • 限流

Hystrix 降级

image.png Hystix 降级:当服务发生异常或调用超时,返回默认数据

服务提供方步骤

  • 在服务提供方,引入 hystrix 依赖
  • 定义降级方法
  • 使用 @HystrixCommand 注解配置降级方法
  • 在启动类上开启Hystrix功能:@EnableCircuitBreaker

服务消费方步骤

  • feign 组件已经集成了 hystrix 组件。
  • 定义feign 调用接口实现类,复写方法,即降级方法
  • 在 @FeignClient 注解中使用 fallback 属性设置降级处理类。
  • 配置开启 feign.hystrix.enabled = true

Hystrix 熔断

image.png

  • Hystrix 熔断机制,用于监控微服务调用情况,当失败的情况达到预定的阈值(5秒失败20次),会打开断路器,拒绝所有请求,直到服务恢复正常为止。
  • circuitBreaker.sleepWindowInMilliseconds:监控时间
  • circuitBreaker.requestVolumeThreshold:失败次数
  • circuitBreaker.errorThresholdPercentage:失败率

Hystrix 熔断监控

image.png

  • Hystrix 提供了 Hystrix-dashboard 功能,用于实时监控微服务运行状态。
  • 但是Hystrix-dashboard只能监控一个微服务。
  • Netflix 还提供了 Turbine ,进行聚合监控。

Gateway 网关

image.png

网关概述

  • 网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
  • 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求。
  • 存在的问题:
    • 客户端多次请求不同的微服务,增加客户端的复杂性
    • 认证复杂,每个服务都要进行认证
    • http请求不同服务次数增加,性能不高
  • 网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等
  • 在目前的网关解决方案里,有Nginx+ Lua、Netflix Zuul 、Spring Cloud Gateway等等

Gateway 网关快速入门

  • 搭建网关模块
  • 引入依赖:starter-gateway
  • 编写启动类
  • 编写配置文件
  • 启动测试

Gateway 网关路由配置

静态路由

动态路由

  • 引入eureka-client配置
  • 修改uri属性:uri: lb://服务名称

微服务名称配置

image.png

Gateway 网关过滤器

image.png

Gateway 支持过滤器功能,对请求或响应进行拦截,完成一些通用操作。

  • Gateway 提供两种过滤器方式:“pre”和“post”
  • pre 过滤器,在转发之前执行,可以做参数校验、权限校验、流量监控、日志输出、协议转换等。
  • post 过滤器,在响应之前执行,可以做响应内容、响应头的修改,日志的输出,流量监控等。
  • Gateway 还提供了两种类型过滤器
    • GatewayFilter:局部过滤器,针对单个路由
    • GlobalFilter :全局过滤器,针对所有路由

局部过滤器

  • GatewayFilter 局部过滤器,是针对单个路由的过滤器。
  • 在Spring Cloud Gateway 组件中提供了大量内置的局部过滤器,对请求和响应做过滤操作。
  • 遵循约定大于配置的思想,只需要在配置文件配置局部过滤器名称,并为其指定对应的值,就可以让其生效。

全局过滤器

image.png

  • GlobalFilter 全局过滤器,不需要在配置文件中配置,系统初始化时加载,并作用在每个路由上。
  • Spring Cloud Gateway 核心的功能也是通过内置的全局过滤器来完成。
  • 自定义全局过滤器步骤:
    • 定义类实现 GlobalFilter 和 Ordered接口
    • 复写方法
    • 完成逻辑处理