SpringCloud学习笔记
SpringCloud学习笔记
1.Spring Cloud Eureka简介
注册发现中心
Eureka来源于古希腊词汇,意为“发现了”。在软件领域,Eureka是Netflix在线影片公司开源的一个服务注册与发现的 组件,和其他Netflix公司的服务组件(例如负载均衡、熔断器、网关等)一起,被Spring Cloud社区整合为 Spring Cloud Netflix模块。
Eureka是Netflix贡献给Spring Cloud的一个框架!Netflix给Spring Cloud贡献了很多框架,后面我们会学习到!
2.Spring Cloud Eureka和Zookeeper的区别
2.1什么是CAP原则(面试)
在分布式 微服务里面CAP定理
问:为什么zookeeper不适合做注册中心?
CAP原则又称CAP定理,指的是在一个分布式系统中,
一致性(Consistency):三个机器中数据中一致的
可用性(Availability):当有一个节点挂掉了整个集群可以继续对外提供服务
分区容错性(Partition tolerance) (这个特性是不可避免的):由于机房或者分区等原因会导致各个机器中的数据短暂不一致
CAP原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
CP、AP
zk遵循CP原则
eureka注重AP高可用
eureka默认端口号为8761
@EnableEurekaServer注解:开启eureka的注册中心的功能(在SpringBoot启动函数上面添加)
DS replicas:集群相关信息
Indtances currently registered with Eureka:当前在eureka里面注册哪些实例 真实的例子 具体的东西 class new Object
Status:实例 的状态和ID
SpringCloud中的常用配置
集群的深入理解
如果是主从模式 主机该怎么选择?
如果是主从模式 数据是怎么同步的?
分布式数据一致性协议: Paxos raft
Eureka概念的理解
服务的注册
当项目启动时(eureka的客户端——,就会向eureka-server发送自己的元数据(原始数据)(运行的ip,端口port,健康的状态监控等,因为使用的是http/Restful请求风格),eureka-server会在自己内部保留这些元数据(内存中)。(有一个服务列表)(restful风格,以http动词的请求方式,完成对url资源的操作)
服务的续约
项目启动成功了,除了向eureka-server注册自己成功,还会定时的向eureka-server汇报自己,心跳,表示自己还活着。(修改一个时间)
服务的下线(主动下线)
当项目关闭时,会给eureka-server报告,说明自己要下机了。
服务的剔除(被动下线,主动剔除)
当项目超过了指定时间没有向eureka-server汇报自己,那么eureka0server就会认为此节点死掉了,会把它剔除掉,也不会放流量和请求到此节点 了。
Eureka运作原理的特点
Eureka-server对外提供的是restful风格的服务
以http动词的形式对url资源进行操作 get、post、put、delete
http服务+特定的请求方式url地址
只要利用这些restful我们就能对项目实现注册和发现
只不过,eureka已经帮我们使用java语言写了client,让我们的项目只要依赖client就能实现注册和发现!
只要你会发起Http请求,那你就有可能自己实现服务的注册和发现。不管你是什么语言!
Eureka的yml配置文件:
1 | server: |
yml使用技巧:
比如defaulZone里面
1
2 #如果EUREKA_SERVER_URL能获取到值就采用这个,否则就使用“:”后面的默认设定
defaultZone: ${EUREKA_SERVER_URL:http://localhost:8761}
Spring Cloud Ribbon
Ribbon概述
Spring Cloud Ribbon 是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用。轮询hash权重…
简单的说Ribbon就是netfix公司的一个开源项目,主要功能是提供客户端负载均衡算法和服务 调用。Ribbon客户端组件提供了一套完善的配置项,比如连接超时,重试等。
在Spring Cloud构建的微服务系统中,Ribbon作为服务 消费者的 负载均衡器,有两种使用方式,一种是和RestTemplate相结合,另一种是和OpenFeign相结合。OpenFeign已经默认集成了Ribbon,关于OpenFeign的内容将会在下一章进行详细讲解。Ribbon有很多子模块,但很多模块没有用于生产环境!
1 | ribbon: |
负载均衡
负载均衡,英文名称为Load Balance(LB)http:// lb://(负载均衡协议),其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如Web服务器、企业核心应用服务器和 其它主要任务服务器等,从而协同完成工作任务。
负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
@LoadBalanced注解(如果加了Eureka组件就户需要单独导入Ribbon了,Eureka自带)
使用这个注解加在RestTemplate();那么RestTemplate的 操作都会由ribbon来 操作
1
2
3
4
5
public RestTemplate restTemplate(){
return new RestTemplate();
}
1
2
3
4
5
6
7
8 思考ribbon是这么将http://provider/hello 路径请求成功的
http://127.0.0.1:8080/hello
1.拦截这个请求
2.截取主机名称
3.借助eureka来做服务发现list<>
4.通过负载均衡算法 拿到一个服务ip port
5.reConstructURL
6.发起请求只要你给restTemplate加了ribbon的注解 项目中这个对象发起的请求 都会走ribbon的代理
如果你想使用原生的restTemplate 就需要重新创建一个对象
按什么顺序启动服务好
最好先启动服务,再启动注册中心,然后再启动客户端(consumer)
因为consumer会每隔一段时间拉取注册中心的服务列表,而注册中心一下不会更列表,如果先启动consumer那么就会一开始拉取不到后面的服务(因为服务未开启注册中心的列表中没有任何服务)
Feign(里面默认自带了Ribbon!!!不用导)
Feign是申明性(注解)Web服务客户端。它使编写Web服务客户端更加容易。要使用Feign,请创建一个接口并对其进行注解。它具有可插入注解支持,包括Feign注解和JAX-RS注解。Feign还致辞可插拔编码器和解码器。Spring Cloud添加了对SpringMVC注解的支持,并支持使用HttpMessageConverters,SpringWeb中默认使用的注解。SpringCloud集成了Ribbon和Eureka以及SpringCloud LoadBalancer,以在使用Feign时提供负载平衡的http客户端。
Feign是一个远程调用的组件(接口,注解)http调用的
Feign集成了Ribbon Ribbon里面集成了eureka
Feign中yml配置
1
2
3
4 # feign只是帮你封装了远程调用的功能 底层还是ribbon 所以我们需要去修改ribbon的时间
ribbon:
ReadTimeout: 3000 # 给3s超时时间
ConnectTimeout: 3000 # 链接服务的超时时间
Feign调用参数处理(开发重点)
说在前面
Feign传参确保消费者和提供者的参数列表一致 包括返回值 方法签名要一致
1.通过URL传参数,GET请求,参数列表使用@PathVariable(“”)
2.如果GET请求 ,每个继承参数必须加@RequestParam(“”)
3.如果是POST请求,而且是对象集合等参数,必须加@RequestBody或者@RequestParam
Feign日志打印
在SpringBoot启动中添加打印日志输出Bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//开启feign的客户端功能 才可以帮助我们发起调用
public class Study41Application {
public static void main(String[] args) {
SpringApplication.run(Study41Application.class, args);
}
/**
* 打印feign日志信息 级别
* @return
*/
public Logger.Level level(){
return Logger.Level.FULL;
}
}在yaml文件中配置:
1
2
3
4
5
6 logging:
level:
com.study4_1.study4_1.feign.UserOrderFeign: debug #我需要打印这个接口下面的日志
Spring Cloud Hystrix
什么叫服务雪崩:
在一个分布式的系统中如果A服务请求B服务B可能要调用C服务,这个过程叫做链式调用
ABC是三个不同的Tomcat。
1.用户去请求A服务,A的tomcat会分配一个线程支持用户的访问
A发现需要完成用户的操作,需要去调用B
2.A去请求B,B的tomcat也会分配一个线程支持A的访问。B发现需要完成A的操作需要调用C。
3.B去调用C,但是C宕机了,B并不知道还是一如既往的去访问C。导致A和B的线程都没有回收,此时有大量请求进入A服务或者B服务。AB会报错503 Service Unavailable。
在分布式的链路中只要有一个服务宕机那么就可能导致一整个服务链瘫痪
服务雪崩的核心本质是什么?
线程没有及时回收
熔断,熔断!
直接return,业务是不能完成。但是可以缓解服务器压力
1.调整等待时间这样可以缓解压力,但是很有局限性不灵活,有的服务可能需要多的时间去执行
2.在上游服务中直到下一个服务的状态如果是ok的 就正常访问,如果是宕机了,那么就return。这样就可以缓解服务雪崩。
我们可以容忍服务挂掉,我们需要做对应的调整,我们可以设置一个被选方案(备胎)
熔断器,也叫断路器!(正常情况下 断路器是关的 只有出了问题才打开)用来保护微服务不雪崩的方法。思想和我们上面画的拦截器一样。
Hystrix是Netfix公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性。微博 弹性云扩容 Docker K8s
Hystrix快速入门
设置拦截器:
如何开启Hystrix:
2.0版本前只要导入Hystrix然后在yml用如下配置就行
1
2
3 feign:
hystrix:
enabled: true但是超过2.0后此yaml配置改为了:
1
2
3 feign:
circuitbreaker:
enabled: true然后注意在SpringBoot启动类中加入:
1 启动注解
Hystrix常用yaml配置:
1 | hystrix: |
hystrix本质是代理的feign的请求才能完成熔断的效果
链路追踪的由来
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同生产最后的请求结果,每一个请求都会开成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引导起整个请求最后的失败。(不建议微服务中链路调用超过3次)
分布式链路调用的监控
sleuth+zipkin(zipkin就是一个可视化的监控控制台)
Zipkin是Twitter的一个开源项目,允许开发者收集Twitter各个服务上的监控数据,并提供查询接口。
该系统让开发者可通过一个Web前端轻松的收集和分析数据,例如用户每次请求服务的处理时间等 可方便的监测系统中存在的瓶颈
Zipkin(可视化平台)
SpringCloud从F版以后已经不需要自己构建Zipkon server了,只需要调用jar包即可
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkon-server/
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkon-server/2.12.9/
Sleuth快速入门
eureka-server
consumer-user-service
provider-order-service
1.添加依赖
consumer-user-service和provider-order-service都要加
1 | <dependency> |
2.修改配置文件
consumer-user-service和provider-order-service都要该配置文件
1 | spring: |
Admin监控
导包之后记得在SpringBoot启动上面加上注解:
1 |
|
监控端需要加入的依赖:
1
2
3
4 <dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
监控端如果想监控自己实际详细内容yml配置
1
2
3
4
5 management:
endpoints:
web:
exposure:
include: '*' #暴露所有的监控端点(就是暴露Admin的所有详细的内容),如果一个服务需要被将空 那么就要将自身的一些情况(一些信息接口)暴露出去
被监控端需要加入actuator依赖(不加的监控端点显示离线监控,但是能知道端点存活):
1
2
3
4
5 <!-- 暴露自身检查端点 endpoints-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
想要被监控端展示实际详细内容yml配置:
1
2
3
4
5 management:
endpoints:
web:
exposure:
include: '*' #暴露所有的监控端点(就是暴露Admin的所有详细的内容),如果一个服务需要被将空 那么就要将自身的一些情况(一些信息接口)暴露出去
Spring Cloud Gateway(网关)
先说什么是海关?
你出国或者回国都得经过海关才能进出自己的国家否则不准,网关也是这个意思。
网关可以承担的作用:
1.路由转发
2.安全控制 保护每个服务 不需要将每个服务暴露出去
3.负载均衡
什么是网关
网关是微服务最边缘的服务,直接暴露给用户,用来做用户和微服务的桥梁
1.没有网关:客户端直接访问我们的微服务,会需要在客户端配置很多的ip:port,如果user-servie并发比较大,则无法完成负载均衡
2.有网关:客户访问网关,网关来访问微服务,(网关可以和注册中心整合,通过服务名称找到目标的ip:port)这样只需要使用服务名称即可访问微服务,可以实现负载均衡 ,可以实现token拦截,权限验证,限流等操作
你们项目里面 用的什么网关? gateway(SpringCloud官方网关) zuul
他是Spring Cloud官方提供的用来取代zuul(netflix)的新一代网关组件
(zuul:1.0,,2.0,zuul的本质,一组过滤器,根据自定义的过滤器,根据自定义的过滤器顺序来执行,本质就是web组件 web三大组件(监听器 过滤器 servlet) 拦截 springmvc)
Zuul1.0 使用的是BIO(Blocking IO) tomcat7.0以前都是BIO性能一般
Zuul12.0 性能好NIO
AIO 异步非阻塞io a+nio = aio = async + no blocking io
Gateway的核心是过滤器,按照先后执行顺序来执行过滤操作 order 0 1 2
web三大组件
servlet
listener
filter过滤器(啥都拦截 )
interceptor 拦截器 他是springmvc的,主要拦截进入controller的请求的
总结:Gateway的核心逻辑也就是 路由转发+执行过滤器链
Spring Cloud Gateway三大核心概念
Route(路由)(重点 和 eureka结合做动态路由)
路由信息的组成:
由一个ID、一个目的URL、一组断言工厂、一组Filter组成、
如果路由断言为真,说明请求URL和配置路由匹配。
Predicate(断言)(就是一个返回bool的表达式)
Java8中的断言函数。lambda四大接口 供给型,消费型,函数型,断言型
Spring Cloud Gateway 中的断言函数输入类型是Spring5.0框架中的SererWebExchange。Spring Cloud Gateway的断言函数允许开发者去定义匹配来自于Http Request中的任何信息比如请求头 和参数。
Filter(过滤)(重点)
一个标准的Spring WebFilter。 web三大组件(servler listener filter)mvc interceptor
Spring Cloud Gateway 中的Filter分为两种类型的Filter,分别是Gareway Filter和Global Filter。过滤器Filter将会对请求和相应进行修改处理。
一个是针对某一个路由的filter 对某一个接口做限流
一个是针对全局filter token ip黑名单
Gateway快速入门
1.不用选择SpringWeb,Gareway用的自带的Netty!!!!(只要加入gareway依赖就行,其他都不用加)!!!!!!
配置网关只要在application.yml或者properties里面设置就行
Gateway网关yml配置文件方式配置路由
1 | cloud: |
Gateway网关代码方式配置路由
1 |
|
yml配置文件方式与java代码配置方式不冲突,两者可以一起用
如果你的uri后面给了一个访问地址 和匹配地址相同 那么就不会再拼接
动态路由
动态路由需要结合注册发现中心(Eureka)
动态路由先要在Gateway中使用EurekaClient拉取EurekaServer的服务注册表,然后以后访问就可以使用http://…/[服务名称]/url确切拼接路径名
1 | cloud: |
第二种动态路由写法方式(推荐这种,这种不需要在访问路径加服务名称就可以直接访问)
1 | cloud: |
Predicate 断言工厂的使用【了解】
在gateway启动时会去加载一些路由断言工厂(判断一句话是否正确 一个boolean表达式)
断言是给某一个路由来设定的,比如:
1 | cloud: |
能够添加断言条件的有这些
比如:
默认不能作用在动态路由上
Filter过滤器工厂(重点)
概述
gateway里面的过滤器和Servlet里面的过滤器,功能差不多,路由过滤器可以用于修改进入Http请求的返回Http响应
分类
按生命周期分两种
pre 在业务逻辑之前
post 在业务逻辑之后
按种类分也是两种
GatewayFilter 需要配置某个路由,才能过滤。如果需要使用全局路由,需要配置Default Filters。
可以记录接口的访问次数,限流操作
GlobalFilter 全局过滤器,不需要配置路由,系统初始化作用到所有路由上
全局过滤器 统计请求次数 限流 token的校验 ip黑名单拦截 跨域本质(filter)
144 开头的电话 限制一些ip的访问
GlobalFilter过滤器使用:
1 |
|
IP地址访问过滤器实例:
1 | /** |
因为Http是无状态的,所以如果要分布式微服务则需要建立token。
用户登录token注册例子:
1 |
|
一般放在请求头里面 一般key Authorization value bearer token
Token拦截(Token保存在Redis里面):
1 | public class TokenCheckFilter implements GlobalFilter, Ordered { |
关于限流,面试不会直接问,而是间接来问 问 不卖超
比如:如果在抢购过程中,用户量请求非常大,怎么确保商品不会卖超
Redis单线程(IO为什么快,因为我们现在的处理器是多核心数的,redis底层使用的是IO的多路复用)
一般人只会在意商品卖超,而忘记了限流的重要性
Mq(限流,削峰,异步,解耦合)
Mq+Redis+分布式锁
Spring Cloud Alibaba
项目介绍
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必须组件,方便开发者通过Spring Cloud编程模型轻松使用这些组件来开发分布式应用服务。
依托Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将Spring Cloud应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
组件
Nacos
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos致力于发现、配置和管理微服务。Nacos提供了一组简单易用的特征集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台、Nacos是构建以“服务”为中心的现代应用架构(例如微服务范式、云原生 范式)的服务基础设施。
Nacos的核心概念
服务(Service)
服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos支持主流的服务生态,如Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。
服务注册中心(Service Registry)
服务注册中心,它是服务实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查API来验证它是否能够处理请求。
服务元数据(Service Metadata)
服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据
服务提供方(Service Provider)
是指提供可复用和可调用服务的应用方
服务消费方(Service Consumer)
是指会发起对某个服务调用的应用方
配置(Configuration)—配置文件中心
在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在、目的是让静态的系统工件或者交付物(如WAR,JAR包等)更好地和实际的物理运行环境进行适配、配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。
配置管理(Configuretion Management)
在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。
名字服务(Naming Service)
提供分布式系统中所有对象(Object)、实体(Entity)的“名称”到关联的元数据之间的映射管理服务,例如ServiceName -> Endpoints Info,Distributed Lock Name -> Lock Owner/Status Info,DNS Domain Name -> IP List服务发现和DNS就是名字服务的2大场景。
配置服务(Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
NacosServer的安装和启动
NacosServer相对于EurekaServer,只不过EurekaServer使我们自己搭建的一个项目,而NacosServer是别人已经提供好了。
安装:
先在官网下载好Nacos,Nacos是一个jar包,直接启动即可。然后就是配置好里面的配置文件,现在conf文件里面修改properties内的数据库连接这些:
Nacos默认为集群配置,如果是想设置成单个若没有改启动模式为单个那么会报错,修改的地方直接在start文件里面改就行:
Java编写配置:
首先要导入Nacos的依赖,Spring官方可能没有依赖的直接选择项,可以切换依赖来源网站为:http://www.start.alibaba.com
然后进行Nacos依赖选择:
Nacos的基本yml配置:
1 | server: |
namespace是最重要的,这个用来区分项目项,group可以详细对项目下进行分组
Nacos整合Gateway网关
Gateway要依赖SpringCloud,所以一定要确认SpringCloud和SpringBoot和SpringCloudAlibaba之间的版本关系!!!!!!
这里使用方法是差不多的,首先加上合适的依赖后:
yml相关的配置文件:
1 | server: |
然后就是启动类加上网关开启的配置:
1 |
|
完成~。
常用Nacos中yaml文件配置代码:
Nacos配置文件中心
配置文件中心作用
如果生成环境修改了配置文件项目学需要下架重新打包,重新发布。
方便管理,以及配置文件中心修改后可以及时更新而且项目本源不用重启(类似于热部署更新),爽!!!
只要配置文件修改了对应的服务就可以动态感知到不需要重启
配置文件中心配置方式
Nacos端
需要先在Nacos端创建好配置文件的组:
Data id:对应的存储id
Group:对应的组别
Java端:
1 | server: |
这里如果bootstrap无效,可能是你SpringBoot与SpringBootCloud Alibaba的版本对应有问题。
SpringBoot的2.4版本后strap与原本的SpringBoot分离了,所以需要重新加入一个依赖
1 | <dependency> |
然后就是Java内容的引用:
@RefreshScope注解的作用是让这个类里面的所有Value注解都能随着配置文件中心的属性而变化。
配置文件的读取方式(重点)
Nacos配置中心通过namespace、dataId和group来唯一确定一条配置。
-
Namespace:即命名空间。默认的命名空间为public,我们可以在Nacos控制台中新建命名空间;
-
dataId:即配置文件名称
-
Group:即配置分组,默认为DEFAULT_GROUP,可以通过其中:dataId是最关键的配置字段:格式如下:
${prefix} - ${spring.profiles.active}
${file-extension}
说明:
-
prefix默认为spring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来配置;
-
spring.profiles.active即为当前环境对应的profile。注意,当spring.profiles.active为空时,对应的连接符-也将不存在,dataId的拼接格式变成${prefix}.${file-extension};
-
file-extension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置
这就是上面我们为什么能获得到配置的原因了。
注意:在写dataId的时候一定要添加文件类型后缀
Eg:nacos-config-dev.yml
多配置文件读取:
1 | server: |
公共配置文件配置:
1 | server: |
Nacos常用配置:
两端的配置文件写什么内容
本地的bootstrap.yml(应用名称,配置文件中心(注册中心地址),读取的配置文件名称信息)
远端的配置文件(端口,数据源,redis,mq,mybatis,Swagger…)
为了方便去动态刷新和修改
项目结构
单体结构:
分布式聚合项目:
分布式聚合项目优化方案1:
其中将原本的mapper、service、web整合成了core或者enter。
模块清晰,轻耦合
分布式聚合项目优化方案2:
之间的依赖关系明显比方案一少,清晰。
分布式微服务父项目配置案例
1 |
|