SpringCloud学习笔记
2023-01-10 14:38:28 26 举报
AI智能生成
登录查看完整内容
SpringCloud学习笔记
作者其他创作
大纲/内容
RPC概念
在传统的RPC远程调用框架中,管理每个服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
什么是服务治理
Eureka采用CS(客户端和服务端)的设计架构,EurekaServer作为服务注册功能的服务器,他是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到EurekaServer 并维持心跳连接,这样系统的维护人员就可以通过EurekaServer来监控系统中各个微服务是否正常运行。在服务注册与发现中有一个注册中心。当服务器启动时,回把当前自己服务的信息 比如 服务地址、通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址。然后再实现本地RPC调用RPC远程调用。 框架设计核心思想在于注册中心,因为使用注册中心管理每个服务与服务之间的依赖关系(服务治理概念)。在任何RPC远程款家中,都会有一个注册中心(存放服务地址相关信息(接口地址))
什么是服务注册
服务注册:将服务信息注册进注册中心服务发现:从注册中心撒谎给你获取服务信息实质:存key服务名 取value调用地址
1.先启动eureka注册中心2.启动服务提供者服务A3.A服务启动后会把自身信息(比如服务地址)以别名方式注册进eureka4.消费者B服务在需要调用接口时,使用服务别名去注册中心获取实际的RPC远程调用地址5.消费者货得调用地址后,底层实际是利用HttpClient技术实现远程调用6.消费者获得服务地址后回缓存在本地jvm内存中,默认每间隔30秒更新一次服务调用地址
Eureka Server提供服务注册服务各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
Eureka Client通过注册中心进行访问是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的使用轮询(round-robin)负载算法的负载均衡器。再应用启动后,将会向EurekaServer发送心跳(默认周期为30秒)。如果Eureka Server在多噶心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点一出(默认90秒)
Eureka包含两个组件:EurekaServer和EurekaClient
Eureka心跳机制与自动保护机制原理分析
Eureka集群:互相注册,相互守望
Eureka
C:Consistency(强一致性)一致性是指更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。(所有节点在同一时间看到的数据是一致的)与ACID的C完全不同A:Availability(可用性) 可用性是指服务一直可用,而且是正常响应时间。(所有的请求都会收到响应)P:Partition tolerance(分区容错性) 分区容错性是指分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
最多只能同时较好的满足两个。CAP 理论的核心是:一个分布式系统不可能同事很好的满足一致性,可用性和分区容错性这三个需求。因此,根据CAP原理将NoSql数据库分成了满足CA原则、满足CP原则和满足AP原则三大类:CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。CP-满足一致性,分区容忍性的系统,通常性能不是特别高。AP-满足可用性,分区容忍性的系统,通常可能对一致性的要求低一些。
CAP理论
子主题
组件名 语言 CAP 服务健康检查 对外暴露接口 SpringCloud集成Eureka Java AP 可配支持 HTTP 已集成Consul Go CP 支持 HTTP/DNS 已集成Zookeeper Java CP 支持 客户端 已集成Nacos AP/CP
何时选择何种模式
不同注册中心的异同点
服务注册中心
OpenFeign
服务调用
Hystrix
服务降级
Zuul
gateway
服务网关
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的Spring Cloud 提供了Config Server来解决这个问题
分布式系统面临的配置问题
Spring CloudConfig为微服务结构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个 中心化的外部配置
是什么
Spring Cloud Config分为服务端和客户端两部分。服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息,配置服务器默认采用git来存储配置信息,这样就有助于对环境配置配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
怎么玩
集中管理配置文件
不同环境不同配置,动态化的配置更新,分环境部署比如 dev/test/prod/beta/release
运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
将配置信息以REST接口的形式暴露
能干嘛
由于Spring CloudConfig默认使用Git来存储配置文件(其他方式比如SVN和本地文件)但是最推荐的还是git ,而且使用的是http/https访问的形式
与GitHub整合配置
官网
概述
用自己的账号在github上新建一个名为Spring Cloud-Config的新Repository
由上一步获得刚新建的git地址
本地硬盘目录上新建git仓库并clone
新建Module模块XXX 它即为Cloud的配置中心模块cloudConfig Center
修改pom文件 <groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId> 新增yml文件 修改主启动类 (注解增加@EnableConfigServer)
127.0.0.1 config-3344.com
Windows下修改hosts文件,增加映射
启动刚搭建的微服务
http://config.3344.com:3344/master/config-dev.yml
测试通过Config微服务是否可以从GitHub上获取配置内容
http://config.com:3344/master/config-dev.yml
http://config.com:3344/master/config-test.yml
http://config.com:3344/master/config-prod.yml
master分支
http://config.com:3344/dev/config-dev.yml
http://config.com:3344/dev/config-test.yml
http://config.com:3344/dev/config-prod.yml
dev分支
/{label}/{application}-{profile}.yml
地址上不标明分支就读取默认分支,默认分支为工程文件里lable声明的分支如果没有配置就默认为master分支
http://config.com:3344/config-prod.yml
如果访问不存在的配置文件,返回值为空
/{application}-{profile}.yml
http://config.com:3344/config/dev/master
http://config.com:3344/config/test/master
http://config.com:3344/config/test/dev
/{application}/{profile}[/{label}]返回值为json串,不是直接配置文件的内容
lable 表示分支(branch)name/application 表示服务名profiles 表示环境(dev/test/prod)
更重要的细节配置
配置读取规则(常用)
Config服务端配置与测试
配置微服务为Config的客户端,需要在pom文件中添加依赖 <groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId>
application.yml 是用户级的资源配置项。bootstrap.yml是系统级的,优先级更高Spring Cloud会创建一个\"Bootstrap Context\",作为Spring应用的'ApplicationContext'的父上下文。初始化的时候,'Bootstrap Context'负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的'Environment'。
'Bootstrap'属性有高优先级,默认情况下,它们不会被本地配置覆盖。'Bootstrap context'和'Application Context'有着不同的约定,所以新增了一个'bootstrap.yml'文件,保证'Bootstrap context'和'Application Context'配置的分离.
font color=\"#ff0000\
说明
内容
bootstrap.yml
正常情况下git上修改配置,服务端可获取最新配置,但是客户端想获得新配置需要自己重启服务或者重新加载
分布式配置的动态刷新问题
Config客户端配置与测试
pom文件引入actuator监控
修改yml,暴露监控端口
@RefreshScope业务类Controller修改
修改客户端配置<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
必须是post请求
curl -X POST \"http://localhost:3355/actuator/refresh\"
需要运维工程师发送Post请求刷新客户端
步骤手动刷新
如果微服务客户端特别多,每个微服务都需要执行一次post请求
可否广播?一次通知,处处生效?
想要大范围的自动刷新
手动刷新的问题
Config客户端之动态刷新
SpringCloud Config 分布式配置中心
nacos
服务配置
分布式自动刷新配置功能
SpringCloud Bus 配合SpringCloud Config使用可以实现配置的动态刷新
对上一讲的加深和扩充,一言以蔽之
Bus支持两种消息代理:RabbitMQ和Kafka
SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。
什么是总线
ConfigClient 实例都监听MQ中同一个topic (默认是SpringCloud Bus)。当一个服务刷新数据的时候,它会把这个消息放入Topic中,这样其他监听同一Topic的服务就能得到通知,然后去更新自身的配置。
基本原理
为何被称为总线
略
Rabbit MQ环境配置
2)利用消息总线出发一个服务端Config Server的/bus/refresh端点,而刷新所有客户端的配置
打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。
破坏了微服务各节点的对等性
有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
图二的架构显然更加适合,图一不适合的原因如下
设计思想
添加对rabbitMQ的支持
<groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId>
pom
rabbitMQ 是和spring同等级
#rabbitmq 相关配置rabbitmq: host: localhost port: 5672 username: guest password: guest
#rabbitmq 相关配置 暴露bus刷新配置的端点 有这种类似监控的 pom文件里必须配置actuatormanagement: endpoints: #暴露bus刷新配置的端点 web: exposure: include: 'bus-refresh'
yml
配置中心服务端添加消息总线支持
<groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
#rabbitmq 相关配置 在spring的下一级?rabbitmq: host: localhost port: 5672 username: guest password: guest
#rabbitmq 相关配置 暴露bus刷新配置的端点 有这种类似监控的 pom文件里必须配置actuatormanagement: #和spring平级 endpoints: #暴露bus刷新配置的端点 web: exposure: include: \"*\"
客户端添加消息总线支持
修改github上的配置文件
发送post请求给配置中心服务端
运维工程师
测试
SpringCloud Bus 动态刷新全局广播
不想全部通知,只想定点通知
指定具体某一个实例生效而不是全部
公式: http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}
/bus/refresh请求不再发送到具体的服务实例上,而是发给configserver并通过destination参数类指定到需要更新配置的服务或实例
简单一句话
案例
通知总结All
SpringCloud Bus 动态刷新定点通知
Spring Cloud Bus消息总线
服务总线
屏蔽底层消息中间件的差异,降低切换成本,统一消息的编程模型
一句话
官方定义 SpringCloudStream 是一个构建消息驱动微服务的框架。
应用程序通过inputs或者outputs来与Spring CloudStream中的binder对象交互。通过我们配置来binding,而SpringCloudStream的binder对象负责与消息中间件交互。所以,我们只需要搞清楚如何与Spring Cloud Stream交互就可以方便使用消息驱动的方式,
通过使用SpringIntegration来连接消息代理中间件以实现消息事件驱动。SpringCloudStream为一些供应商的消息中间件产品提供了个性化的自动配置实现,引用了发布-订阅、消费组、分区的三个核心概念
目前仅支持RabbitMQ 和Kafka
什么是SpringCloudStream
Message
生产者/消费者之间靠消息媒介传递信息内容
消息通道MessageChannel
消息必须走特定的通道
消息通道MessageChannel的子接口SubscribeChannel,由MessageHandler消息处理器所订阅
消息通道里的消息如何被消费呢,谁负责收发处理
标准MQ
在没有绑定器这个概念的情况下,我们的SpringBoot应用要直接与消息中间件进行信息交互的时候由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性。通过定义绑定器作为中间层,完美地实现了应用程序与消息中间件细节之间的隔离。通过向应用程序暴露统一的Channel通道,使得应用程序不需要再考虑各种不同的消息中间件实现。
通过定义绑定器Binder作为中间层,实现了应用程序与消息中间件细节之间的隔离
stream凭什么可以统一底层差异?
INPUT对应于消费者
OUTPUT对应于生产者
在没有绑定器这个概念的情况下,我们的Spring Boot应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性,通过定义绑定器作为中间层,完美地实现了应用程序与消息中间件细节之间的隔离。Stream对消息中间件的进一步封装,可以做到代码层面对中间件无感知,甚至于动态的切换中间件,使得微服务开发的高度解耦,服务可以关注更多自己的业务流程。
Binder
为什么用CloudStream
在rabbit MQ就是Exchange
在Kafka中就是Topic
topic主题进行广播
Stream中的消息通信方式遵循了发布-订阅模式
编码API和常用注解所使用的图片是这张
很方便的中间件,屏蔽差异
通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过Channel对队列进行配置。
Channel
简单的可理解为参照对象是SpringCloudStream自身,从Stream发布消息就是输出,接受消息就是输入。
Source和Sink
SpringCloudStream 标准流程套路
Middleware 中间件,目前只支持RabbitMQ和KafkaBinder Binder是应用于消息中间件之间的封装,目前实行了Kafka和 RabbitMQ的Binder,通过Binder可以很方便的连接中间件,| 可以动态的改变消息类型(对应于Kafka的topic,RabbitMQ的 exchange),这些都可以通过配置文件来实现@Input 注解标识的输入通道,通过该输入通道接收到的消息进入应用程序@Output 注解表时输出通道,发布的消息将通过该通道离开应用程序@StreamListener 监听队列,用于消费者队列的消息接收@EnableBinding 指信道channel和exchange绑定在一起
编码API和常用注解
消息驱动概述
需要RabbitMQ环境
工程中新建三个子模块,一个生产者,两个消费者
案例说明
新建Module
<groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-rabbit</artifactId>
主启动类
业务类
消息驱动之生产者
消息驱动之消费者
新建一个消费者模块
需要RabbitMQ,注册中心服务,一个生产者(8001)两个消费者(8002.8003)
启动
重复消费问题
持久化问题
运行后有两个问题
分组和持久化属性group
如何解决
同一个组内会发生竞争关系,只有其中一个可以消费
生产实际案例
目前是两个消费者同时收到,存在重复消费的问题
故障现象:重复消费导致原因:默认分组group是不同的,组流水号不一样,被认为不同组,可以消费自定义配置分组,自定义配置分为同一个组,解决重复消费问题
消费
微服务应用放置于同一个group中,就能够保证消息只会被其中一个应用消费一次不同的组是可以消费的,同一个组没会发生竞争关系,只有其中一个可以消费
原理
group: A B
8802修改yml
8803修改yml 同上 只差一个分组名称
我们自己配置
结论
8002和8003都变成不同组,group两个不同
8802/8803实现了轮询分组,每次只有一个消费者8001模块的发的消息只能被8802或8803其中一个接收到,这样避免了重复消费
8802/8803都变成相同组,group两个相同
分组
持久化
分组消费与持久化
消息驱动Cloud Stream
服务限流降级:默认支持Servlet,Feigin,RestTemplate,和Rocket MQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics监控
服务注册与发现:适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的支持。
分布式管理配置:支持分布式系统中的外部化部署,配置更改时自动刷新。
消息驱动能力:基于SpringCloudStream为微服务应用构建消息驱动能力
阿里云对象存储:阿里云提供的海量、安全、低成本、高可用的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据
分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于Cron表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有Worker(schedulerx-client)上执行
能做什么
为什么叫 Nacos ---Naming Configuration Service一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台Dynamic Naming and Configuration ServiceNacos 就是注册中心+配置中心的组合 等价于 Eureka +Config+Bus
什么是Nacos
替代Eureka做服务注册中心
替代Config做服务配置中心
下载地址
https://github.com/alibaba/Nacos
官网中文地址
官网地址
地址
各种=
Nacos简介:
本地Java8+Maven环境
从官网下载Nacos
解压安装包直接运行bin目录下的startup.cmd
默认用户名密码都是nacos
命令运行成功后直接访问 http://localhost:8848/nacos
参考文档地址 https://spring-cloud-alibaba-group.github.io/github-pages/2021/en-us/index.html
安装并运行nacos
使用端口9001
新建module
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.4.0</version> <type>pom</type> <scope>import</scope> </dependency>
父pom
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
本模块pom
server.port=8081spring.application.name=nacos-payment-providerspring.cloud.nacos.discovery.server-addr=127.0.0.1:8848management.endpoints.web.exposure.include=*
@SpringBootApplication@EnableDiscoveryClient
仿照9001 建9002
生产者
consumer-nacos-order83
因为nacos-discovery的jar包里整合了ribbon
为什么nacos支持负载均衡
pom
主启动
ApplicationContextBean
OrderNacosController
消费者
nacos作为服务注册中心演示(官方文档都有)
为什么配置两个Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目正常启动。spring boot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application
ConfingClientController
通过SpringCloud原生注解@RefreshScope实现配置自动更新
@RefreshScope
Nacos中的dataid的组成格式及与Spring Boot配置文件中的匹配规则
官网https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
理论
新增配置
${prefix}-${spring.profiles.active}.${file-extension}
公式:
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。 ‘
小总结说明
设置DataId
Nacos界面配置对应
实操
Nacos中的匹配规则
在nacos中添加配置信息
自动刷新测试
nacos作为配置中心-基础配置
问题1:实际开发中,通常一个系统会准备dev开发环境 test测试环境prod生产环境如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?
问题2:一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又会有想应的开发环境、测试环境、预发环境、正式环境....那怎么对这些微服务配置进行管理呢?
多环境多项目管理
问题
Nacos的图形化管理界面
类似Java里面的package名和类名最外面的NameSpace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象
1 是什么
三者情况
三者关系
Namespace+Group+DataID 三者关系?为什么这么设计?
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
新建dev配置DataID
新建test配置DataID
默认空间+默认分组+新建dev和test 两个DataID
通过spring.profile.active属性就能进行多环境下配置文件的读取
DataID方案
Group方案
Namespace方案
三种方案加载配置
Case
nacos作为配置中心-分类配置
nacos作为配置注册中心演示
Nacos 服务注册和配置中心!!!!!!!!
SpringCloudAlibaba
SpringCloud
收藏
收藏
0 条评论
回复 删除
下一页