接下来我会大家学习非常重要的一个内容,那就是 SpringCloud,接下来的内容会以 最快的速度带大家学习 SpringCloud,因为当你学完之后,你就真的可以算是跨过了 Java 的入门学习,也就是你已经有了 Java 的底子,有了 Java 整个大的知识框架,接 下来就是不断的去填补细节内容了,至于工作,你已经完全可以出去找实习了!
文末提供PDF和Markdown下载!
OK,接下来我们正式开始 SpringCloud 的学习!
快速上手 SpringCloud
SpringCloud 是一套完整的微服务处理框架,基本在微服务领域无人能敌,首先大家 需要明白一个知识点:
SpringCloud依赖于SringBoot,也就是说两者的版本必须符合,某一个版本的SpringCloud必须使用特定的 SpringBoot 版本”
查看版本对应
那该如何查看版本之间的对应关系呢?这里有个官方地址可以看下:
https://start.spring.io/actuator/info
打开之后返回的是 json 内容:
我们可以安装一个浏览器插件 https://www.baidufe.com/fehelper/index/index.html
安装之后我们在浏览器查看的 json 就会被自动美化: 打开“bom-ranges”: 就可以找到 SpringCloud 对应的 SpringBoot 版本,接下来大家需要知道这个网站:
https://mvnrepository.com/
就是查找各种 maven 依赖的,打开搜索 spring-cloud-dependencies:
比如我们使用了这个版本的:
点击版本号:
这里就会出现 maven 依赖,我们可以将其复制到我们的 pom 文件中:
或者我们可以打开 SpringCloud 的官网:https://spring.io/projects/spring-cloud
点击这个选项,然后往下可以找到这个:
也可以看到版本对应,然后下面也有相关 maven 依赖:
比如我们上面选择了 SpringCloud 的这个版本: 根据对应关系:
那我的 SpringBoot 选择和这个版本就是没问题的:
以上就是关于 SpringCloud 和 SpringBoot 的一个版本对应关系,这个需要先了解!
体验 SpringCloud
搭建注册中心
接下来我们就快速搭建一个 SpringCloud 的项目,带大家体现 SpringCloud,首先我 们新建 SpringBoot 项目(SpringCloud 依赖于 SpringBoot)
这里的创建应该没什么问题,我们 next 下一步:
这里注意 SpringBoot 的版本,然后我们先加入基本的 web 依赖,然后完成! 接着我们加入 SpringCloud 的依赖:
这里一定要注意位置!
那到这里就完事了吗?其实还没有,看下这里的项目名称:
我这里为什么叫做 springcloud-server 呢?那是因为对于 SpringCloud 来说,我们前 期就可以简单理解是一个服务的注册与发现,也就是通过 SpringCloud 我们可以启动 一些服务(提供者),然后把这些服务集中弄到一个地方(注册中心),然后其中的 一些服务(消费者)可以去这个注册中心找到所需要的服务从而去调用它来实现一些 功能,画个图就是这样的:
所以你知道我这里为什么叫做 springcloud-server 了吧,另外要实现这个功能就需要 使用到 SpringCloud 的服务注册与发现组件,你肯定听说过,就是 eureka,对于 eureka 它提供 server 和 client,那我们这个 springcloud-server 是要作为服务的注册 中心,所以需要引入 eureka 的 server 插件!
然后去 mvnrepository 搜索“eureka-server”
然后在我们的 pom 文件中引入: 如此一来我们的这个项目就具备了注册中心的功能,接下来需要一些配置,首先在启 动类上加上注解:
然后 women 就可以启动项目了: 启动成功,默认端口 8080,我们访问看下:
看到这个页面就代表成功了,一般来说,作为注册中心的同时也是可以作为客户端 的,所以会使得注册中心把自己也给当成客户端注册了,我们可以禁止这种行为,还 有默认的注册中心服务地址,我们都可以通过配置文件进行修改: 然后我们重新启动下看下: Ok,以上我们完成了注册中心,但是现在注册中心还是空的,所以接下来我们创建一 个服务提供者,也就是一个真正的客户端,然后将其注册到注册中心去!
创建 eureka 服务提供者
创建的方式和之前创建 springcloud-server 一样,只不过名字我改成了这个:
然后就是需要添加相应的客户端依赖,server 端我们添加的是这个:
这里是服务提供者,是一个 client 端,需要添加这个:
OK,同样的我们需要去添加相应的注解:
注意与注册中心的区别!
接下来我们还需要一些配置:
接下来启动项目:
正常启动,端口 8088,然后我们再去之前的注册中心页面看看(记得刷新下):
创建 eureka 服务消费者
那么到了这里我们搞定了一个注册中心,而且还弄了一个服务注册进去了,那接下来 还缺少一个服务消费者,用来消费服务提供者,其实服务提供者和服务消费者都是 client 端,只不过抽象成一个提供者和一个消费者,接下来我们就在创建一个服务消 费者:
然后下一步:
添加基本的 web 依赖即可,然后完成! 然后需要加上 SpringCloud 的依赖以及 eureka 的 client 依赖:
对了,一般我们加入新的依赖会出现这个按钮,点击一下:
会加载相关的依赖,等待完成即可!
接下来需要进行一些相关配置:
然后是在启动类上添加注解:
如果此时我们启动项目,那这个服务消费者会被注册到注册中心,我们看下:
互相调用
不过我们既然是服务消费者,其实说白了,就是要调用之前服务提供者提供的一些信 息,首先我们在服务提供者里面写上这么一个 controller:
注意这是在服务提供者中的 controller,然后我们在服务消费者中去调用这个,那该怎 么调用嘞?
这就使用到 RestTemplate,也就是实现两个服务之间互相调用,首先我们需要 在启 动类中添加这个:
当我们写上上面的代码之后,我们的服务消费者就具备了调用注册中心相关服务的功 能了,具体是这么操作的:
然后我们启动项目访问试一下: 如此一来,就实现了服务消费者调取服务提供者中的方法,从而获得相应信息的结 果!这也就实现了两者服务之间的互相调用!
以上,我们就快速体验了一遍 SpringCloud,包括基本的服务注册与发现,以及互相 调用等,其实还包含本地的负载均衡等,我们接下来在单独来看!
以上操作大家一定要实际自己动手操作一遍!
SpringCloud Ribbon 负载均衡
接下来来说说这个负载均衡,首先啊,需要先直白的理解下什么是负载均衡,说白 来,负载均衡就是为了分摊压力的,比如大家常见的超市收银员,如果人多的话,一 个收银员肯定是不行的,忙不过来啊,怎么办,所以一般会有好几个收银员,通过这
种增加收银员的策略来解决结账压力其实就是负载均衡的体现!
然后大家去排队结账的时候会主动去排队,然而大家会优先去那些人少的地方排队, 这就是一种均衡策略,放到负载均衡上来说,就是通过某种算法,让服务消费者优先 选择调取压力比较小的服务提供者,以免所有的消费请求全面积压到一个服务提供者 身上!
然后大家还会听过一种轮询算法,说白来,这个就是一替一下,比如两个服务,第一 个请求你处理,那第二个就我来处理,依次循环往复,这就是轮询,一替一个来! 那 SpringCloud 种是如何使用 ribbon 来实现负载均衡的呢?其实我们上面的 SpringCloud 体验案例种就使用到来 Ribbon,只不过它没有引入相应的依赖,只因为 它是默认集成也就是在内部直接引用来了!
我们在这里通过 restTemplate 去调取服务提供者的服务,所以关键就是这个 restTemplate,这里我们访问的提供者的服务地址是:
String url = “http://eureka-client/getOrder”;
这里要注意,我们使用到的是服务提供者注册到注册中心的名称,也就是这个:
也就是说我们的调取是通过注册中心来完成的,那既然是负载均衡,那肯定不止一个 服务提供者,比如我们在增加一个服务提供者也叫做“eureka-client”只不过端口不 一样,名称是一样的,然后我们这里要是再次这样调用:
那这个时候就要考虑那个服务提供者来接受我们的调用请求了,因为大家都叫做 “eureka-client”而且提供同样的服务,只不过端口不同,那该选用哪个呢?这个就 需要负载均衡来决定,也就是我们的 Ribbon 了,而完成这个只需要这一行注解:
当我们添加上这个注解之后,那我们的客户端就用了负载均衡,当我们这样发起调 用: Ribbon 就会帮我们选择合适的服务提供者,而其采用的正式轮询算法!
OK,那关于负载均衡 SpringCloud Ribbon 我们就暂且了解到这里!
声明式服务调用 SpringCloud Feign
接下来我们来介绍声明式调用,也就是 SpringCloud Feign!
我们通过一个例子来看! 首先,我们加入 feign 的依赖,对了因为我们还是调用,所以是在服务消费者里面加 上这个依赖:
再说一遍,相关 maven 依赖都可以去找个网站找:https://mvnrepository.com/
然后我们需要在启动类上加上 feign 的注解以将其开启:
接着我们写一个接口:
这什么意思呢?还记得之前我们使用 RestTemplate 调用的情况吗?我这里做个对比 大家就清楚了:
看清楚这之间的对应关系了吧,然后在看使用的对比:
然后我们启动调用试下:
完全没问题,这就是声明式调用 SpringCloud Feign 了! 不知道有人会不会想到之前说的 Ribbon 负载均衡,其实 Feign 是已经整合了 Ribbon 和 Hystrix 的,那什么又是 Hystrix 呢?
服务容错保护 SpringCloud Hystrix
接下来我们来看看这个 Hystrix 是什么?
那啥是 Hystrix 呢?简单来说,它就是一套保护机制,在我们的微服务中,其实当业务 量起来的时候,还是比较复杂的,尤其服务之间的互相调用,我们很难保证这些服务 之间调用一切正常,总会出现问题的,比如出现网络问题什么,导致服务出现问题, 从而影响系统稳定!
其实面对这些问题,SpringCloud 就提供了一套保护机制,那就是 Hystrix,它可以带 来一些相关的问题解决方案,像什么服务熔断,服务隔离,降级等等!
服务降级
服务降级是一个比较重要的概念,那什么是服务降级呢?简单的来说,就是在某些情 况下,我们为了保证核心业务不受影响,可以继续使用,但是在资源有限的前提下就 必须牺牲掉一些不重要,非核心的业务,让它们暂时不可用以节省资源来维持核心业 务的运行!
这就是服务降级啦!
下面我们通过一个案例来近距离看下什么是服务降级!
我们还继续使用我们之前创建的注册中心,以及服务提供者和消费者,接下来我们在 服务消费者的 pom 文件中添加以下依赖:
接着在启动类上添加相应注解:
虽然显示被弃用,但是使用依然有效!这个注解就是用来开启断路器功能! 然后我们开始对服务降级:
然后我们启动服务访问看下:
我们发现正常访问,没什么问题,接下来我们停掉服务提供者,也就是模拟服务提供 者不可用的时候: 我们发现这里激活里我们设置的降级函数,接着我们使用之前 feign 的调取:
看到没,使用服务降级会是的提示更加友好,这个实际上是增加用户体验的东西! 这就是服务降级了!而且当服务自身出现问题了,也是会触发降级的,比如这里:
我们知道这里会出现问题,那么依然会触发降级!
关于超时
我们来看一个例子,首先在我们的服务提供者中将服务休眠 2 秒:
然后启动服务!然后让服务消费者调用:
我们看到,此时触发了服务降级,原因就是服务提供者的休眠导致服务请求超时! 另外需要知道对于 Hystrix 来说,它默认的超时时间是 1 秒,所以你设置了 2 秒,自然 就超时了!
那怎么做呢?我们可以设置超时时间,不让它使用默认的 1 秒,也太短了,我们可以 这样设置:
我们将超时时间设置成 3 秒,然后我们再次访问:
为什么还是这样呢?不知道大家发现问题没有,看这里:
为了显示自身服务出问题也会触发降级的这行代码忘记删除了,所以即使我们设置了 超时时间为 3 秒还是会触发降级,这也验证了自身服务出问题也会触发降级,我们删 了这行代码再试试:
这下就好了!
可以看到我们服务请求用了 2.03 秒,所以不会降级!
服务熔断
这个服务熔断其实也是保护服务的一种,比如我们在一些高并发的情况下,达到某些 设定的界限的时候就直接拒绝服务被访问,以此来保护我们的服务,一般熔断都是和 降级一起使用的,接下来还是通过一个示例来看比较直观!
其实还是加注解的问题,一起来看下:
这里删除了之前的超时设置,添加了几个熔断相关的注解,另外我们对请求也添加了 参数设置,然后还需要注意的是,当你的方法增加了参数后,你的降级函数也要增 加,如下:
接着我们来分析上述代码,由于没有设置超时,那么我们直接访问的时候肯定是失败 的: 不过这样就可以成功:
这主要就是这些注解的作用: 这些注解都是一些界限设置,当达到某个界限就会导致服务可用与不可用!
具体的每个注解是什么意思,大家可以网上搜索 Hystrix Command 属性即可,这里不 再赘述!
SpringCloud Config 配置中心
这是一个可以帮助我们统一管理配置文件的项目,想一下我们之前的操作,如果我们 修改了配置文件,是不是还要重启项目配置才会生效,但是有了 SpringCloud Config 之后我们可以统一的管理配置,而且当配置发生变化可以实时读取最新的变化。
对于 SpringCloud 来说,它一般分为两个部分,一是服务端,我们称之为配置中心, 二是我们的客户端,实际上这个客户端也就是我们的微服务应用,也就是说 Config 其 实是一个单独的微服务模块,氛围服务端和客户端,然后为了方便集中管理配置,这 些配置是统一放在 git 上的,这点需要特别注意!
然后关于 Config 有这样的一个流程框架图:
接下来我们通过具体的例子来看一下这个配置中心到底是什么以及如何使用!
搭建配置中心
首先创建一个 SpringBoot 项目:
接着下一步: 选择以上两个依赖,接着完成! 然后我们看下加入的相关依赖:
之前也说了,这里的配置文件是放在 git 上的,那远程 git 仓库我们选择使用码云来搭 建,首先进入码云:
新建仓库: 接着按照如下操作: 接着往下:
我们这里存放之前服务消费者的配置信息,直接将之前的配置复制过来即可!然后点 击底部的提交即可! 然后我们回到之前创建的 springcloud-config-server 上,在启动类上添加相应注解:
接着去修改配置文件:
接着我们启动项目,访问如下地址:
记得是“consumer-a.yml”不是“consumer.yml”接着我们可以在仓库中再新建一个 文件:
这时候我们再看:
接着我们访问链接: 接着我们在 master 的基础上新建一个分之为 release:
然后在 release 分支上再创建一个文件:
接着访问: 注意访问的链接地址! 另外我们看这个图:
也就是远程 git 上的配置文件会被读取到本地的 git 中,那本地的在哪里呢?我们在启 动配置中心的时候,可以在控制台找到信息: 根据这个可以找到本地 git 的保存位置! 当然,这个本地 git 位置是可以改变的没,通过如下配置:
然后我们重启项目:
发现修改的指定位置生成了 git 目录! 至此,我们已经搭建好了一个配置中心!
配置客户端及使用
接下来我们来看看如何配置客户端 client!这里我们就使用之前的服务消费者 eurekaclient-consumer 来搭建!
首先添加依赖:
然后是修改配置文件:
注意了,改动还是比较大的,首先名称从“application”改成了“bootstrap”,这个 是启动项的意思,按照上述进行修改即可!
接下来需要写一个控制类:
然后我们启动项目:
这个时候会遇到上述错误,这个主要是我们把“application”改成了“bootstrap”的 缘故,这个时候我们需要添加一个依赖来解决这个问题:
然后我们继续启动项目,这个时候你还会遇到以下问题:
这里就要引出我们之前操作的一个错误的地方,首先去看你的配置中心的配置:
这里的名字要和你的客户端 client 的配置中心的这个一样: 这是第一个对应,然后还有很重要的一点,你看这里: 这是你客户端 client 配置的名字,我们知道这个名字就是注册到注册中心的服务名 称,而我们之前在码云上添加的配置文件也是这个客户端的,所以这里有个对应,这里的名字也就是“eureka-client-consumer”要和你在码云上添加的文件名称要对 应,也就是这样: 当然,你后面可以带上相应的 dev 或者 test,但是前面的命名必须和配置中心的名称 也就是注册到注册中心的服务名称一样! 这点需要特别注意! 然后我们就可以正常启动项目,然后访问: 可以看到,我们已经拿到配置文件中的 env 属性值了,也就是通过这里的配置: 我们可以非常方便的切换使用不同的配置文件! 然后还有个知识点需要知道,就是关于分支配置文件的问题,我们来看,首先看下我
们的主分支配置文件:
然后看一下 release 分支:
这个时候我们去看下我们的配置中心的配置:
我们这个时候没有加这个默认分支属性,那它使用的就是 master 主分支,然后我们去 访问不同的配置文件:
可以看到,我们访问的是 master 上的 test 配置文件,我们接着再访问:
发现问题没,我们的主分支上是没有 dev 的,那此时访问的就是这个: 也可以称这个为默认配置,也就是说如果访问分支没有的配置就会自动去访问默认配
置!
另外还有个重点就是,你在默认配置上配置的信息会默认同步到其他配置上,而非默
认配置的其他配置项则不会同步到默认配置上!
网关 SpringCloud Zuul
什么是网管呢?老规矩,我们通过一个案例来快速了解下!
搭建 Zuul
首先我们需要再次创建一个项目,这个项目是主要作为网关使用的:
然后下一步加入相关的依赖:
我们在这一步选择的时候发现这个 Zull 是无法选择的,这是为啥?说的简单点,Zuul 是属于网关的一种,出现的比较早,刚开始 SpringCloud 是使用这个 Zuul 网关,不过 由于它是一种阻塞的,性能上慢慢觉得不太行来,于是后来 SpringCloud 就自己搞了 一个属于自己的网关就是这个 Gateway 了,ok,明白咋回事了吧,所以我们使用 SpringBoot 2.5 这个版本的时候官方就让你使用自己的 Gateway 了,不过我们前期作 为学习还是先来看看这个 Zuul!
我们可以把 SpringBoot 的版本回退一下:
OK,我们完成即可! 然后我们看加入的相关 maven 依赖: 接下来就是进行相关配置: 然后在启动类上添加开启网关功能的注解: 然后我们启动项目:
可以看到我们的网关成功注册到注册中心!
路由功能
接下来我们看之前创建的服务消费者中的一个 controller 服务: 还记得这个声明式调用吗?不记得可以再去看看,我们调用看下: 以上是我们直接通过服务消费者自己去调用的,下面我们可以通过网关的形式去调 用:
看到没,看张图就更清楚了:
应该很清楚了吧,另外如果访问出错的话,可能是超时问题,加上以下配置试试:
自定义路由
这是啥?看一下就知道了,首先我们在配置文件中加上如下配置: 然后我们就可以这样访问: 注意看链接,其就是替换掉我们服务的注册名称,然后还有一个简洁写法:
看访问:
Zuul 过滤
路由是网关的一个核心功能,除此之外,还有一个重要功能,那就是过滤! 在这里面会听到两个专有名词,就是鉴权和限流,鉴权简单来说就是必须满足某个条 件才能访问,比如必须携带一个 token,还是实际来看个例子吧! 首先新建一个类用于过滤: 接下来我们重启然后重新访问这个: 这个时候就无法访问了,我们必须携带 token 才可以:
以上这个过滤称为前置 pre 过滤,主要用于鉴权,参数校验以及限流等,然后还有一 种叫做 post 后置过滤,用户统计生成日志等!这里就不再演示了!
然后还有限流,限流就是一种保护机制,比如可以防止网络攻击等!关于限流也不做 过多赘述没,感兴趣的可自行了解!
微信搜“庆哥Java”,关注后回复“SpringCloud”获取PDF和markdown文件
|