6小时精通springcloud第12讲:Spring Cloud综合案例

发布于:2022-11-28 ⋅ 阅读:(172) ⋅ 点赞:(0)

你好,我是你的 Spring Cloud 讲师尹吉欢,欢迎来到第 12 课时“综合案例”的学习。

综合案例架构图

Drawing 1.png

相信你对案例的架构图并不陌生,在开词篇中我有介绍过。经过几个月的学习,终于到了最后总结的时刻。

本课时中的综合案例也是为了让你能够巩固前面学习的知识点,同时可以在使用 Spring Cloud 作为微服务架构时能有一个能够落地的参考。

我们再来回顾下这张图,首先是客户端会发起请求到负载均衡器,比如 Nginx。然后 Nginx 将请求转发到网关上,网关再转发到具体的服务上。

上面是注册中心的集群,也就是 Eureka。还有配置中心 Apollo 和链路跟踪 Sleuth 加 ZipKin。ELK 用来收集链路日志展示查询。

在这个架构中,并不会将所有的东西都搭建出来,但是会将最底层的代码框架搭建出来。像 Nginx、ELK 等就不会再具体演示了。

案例项目模块

Drawing 2.png

接下来讲解案例的项目模块,整个项目采用 Maven 多模块的结构,总共 8 个模块。

  • article 是文章服务,提供文章获取接口,因为这里只是案例,所以不会做太多跟业务相关的事情。article-api 是接口的定义,所有文章相关的接口都在 api 中进行定义,同时也作为 Feign Client 的调用 SDK。article-provider 是服务提供者,article 服务最终是通过 article-provider 来启动暴露的,在 article-provider 中会实现 api 中定义的接口和业务逻辑。

  • common 中会放一些通用的工具类,比如 JsonUtils、DateUtils 等。

  • core 中主要是一些核心的逻辑,并且比较通用,比如像灰度发布的处理等。

  • eureka 就是我们的注册中心,相信你已经非常熟悉了。

  • hystrix-dashboard 是 hystrix 监控数据展示的 Web 控制台。

  • user 是用户服务,负责用户的登录、退出登录、用户信息查询等。

  • zuul 是我们的网关,负责访问控制、请求跨域处理等。

  • webpage 是一个 Web 项目,有页面的 Web 项目,整个案例肯定是前后端分离的,为了让大家理解和使用难度较低,这里直接采用 Spring MVC 的方式来创建一个项目模拟前端,如果用纯前端的方式,对不太懂前端的同学还是有难度的。

Web 中采用 Controller 来进行页面的跳转,到页面后通过 Vue 来渲染页面,通过 AJax 请求后端接口获取数据,跟完整的前后端分离不同的点在于路由是通过后端转发控制的,而不是通过前端框架去控制的路由,整体实现差不多,目的是为了让你了解前后端怎么交互。

前端页面

Drawing 3.png

前端页面只实现了 2 个,一个是登录的页面,负责登录的功能,一个是文章详情的页面,负责获取文章信息展示,同时在这边还有个退出登录的按钮,执行退出操作。

Drawing 4.png

案例实现功能

实现的业务功能主要有三个,分别是用户登、用户退出登录、查询文章信息。

实现的技术功能有网关验证、用户信息全局透传、服务灰度发布、调用链集成、Apollo 集成。

用户登录

首先我们来看业务功能用户登录,在 webpage 中有一个登录的页面,有一个表单,两个文本框,一个用户名一个密码。

还有一些非空的验证逻辑,重置按钮是清空表单的输入项,登录按钮才是执行真正的登录业务逻辑。可以看到登录我们调用了 user-provider 服务的登录接口,将用户名和密码传递过去,如果成功了则将返回的 Token 存储起来。

在 user-provider 中的 UserRestController 里实现了登录的逻辑,接口的定义在 UserAPI 中,同时也是作为 Feign 的 Client 使用。

逻辑比较简单,因为是示列程序,就简单的判断了下参数,然后固定的等于某个值就认为登录成功。使用我们的 Jwt 工具类生成用户对应的 Token 返回给调用方。

退出登录

退出登录的按钮在 index 页面中,调用的接口也是 user-provider 中的,退出登录的时候会判断要注销的 Token 和当前用户是不是同一个人,防止被人非法操作。验证成功后我们将注销的 Token 放入 Redis 中,然后在网关中加一层过滤的逻辑,如果访问的 Token 在注销的 Redis 中就拦截。这边需要注意的是 user-provider 中的 Redis 和网关中是同一个,如果是不同的,则需要在 user-provider 中通过其他的方式告诉网关。

查询文章信息

文章信息也在 index 页面中显示,在页面加载的时候就会去调用 article-provider 的接口获取文章信息,然后显示。

article-provider 中会调用 user-provider 中的用户信息接口,拿到用户名组装结果返回给调用方。这边也是固定写好的数据,没有做数据库相关的操作,只是为了让示列更加简单,方便大家本地启动。

网关验证

网关是所有外部请求的入口,必须守好这道防线。对于请求必须验证,有的特殊的请求可以不进行验证,比如登录接口,你想想看,如果登录都被拦截了,那就陷入死循环当中了。所以我们需要有一个白名单的功能,并且还需要能够实时修改并生效,这时候配置中心的作用就提现出来了。

在 Zuul 中定义一个验证的过滤器,同时还需要定义一个接口白名单的 List, 关联上 Apollo。

在 run 方法中我们会判断当前请求的接口是否在白名单中,如果在就直接放行,不在才进行 Token 的校验。

对于没有带 Token 或者带了 Token 但是校验失败的,直接将校验结果返回,如果校验通过了取出 Token 中的用户 ID,添加到请求头中向后端服务进行传递。

用户信息全局透传

在网关验证通过,用户的 ID 也获取到了,这只是在网关中的逻辑。一个请求会转发到后端的 N 个服务上,在这些服务里同样也需要知道当前登录的用户是谁,这个时候我们就需要将用户信息进行全局传递。

在 core 模块中定义了一个用于接收用户 ID 信息的 HttpHeaderParamFilter,在过滤器中接收然后存到 ThreadLocal 中。为了能够让代码复用所以定义在了 core 模块中,要用的项目只要依赖了 core 模块,然后配置一些这个过滤器即可。

为了更方便,在 core 中配置的逻辑也写好了,通过 @ConditionalOnProperty 来控制是否启用,只要在使用的项目中配置了 user.info.enabled=true 即可启用。

这样在使用时我们就可以直接从 ThreadLocal 中获取了。如果用了 Hystrix 的线程隔离模式, ThreadLocal 会失效,对于解决的并发策略也在 core 中进行了配置,同样的也是通过配置文件可以启用。

然后就可以将用户信息传递到其他的服务中,一般有两种调用方式,Feign 和 RestTemplate,我们在 core 中定义了两个拦截器,分别来处理不同调用方式的用户信息传递。同样也是采用配置的方式来启用,对于 Feign 拦截器的配置采用的 @ConditionalOnClass 来判断当前 classpath 中是否有指定的类,因为有的项目依赖了 core,但是不需要使用 Feign,也就没有 Feign 的依赖,这个时候就会报错了,像网关中就是这样,所以加了 @ConditionalOnClass 来判断。

服务灰度发布

灰度发布的集成,也在 core 中,灰度这个功能是所有服务都要用的。主要是 2 个策略,一个是 Zuul 中的,针对网关的处理,一个是普通服务的处理,同样也是可以通过配置的方式启用。对于 discovery Maven 的依赖,Eureka、Apollo、Hystrix 三个通用的就默认依赖了,对于 Zuul 和 service 需要依赖方收到后去指定,主要是处理 Zuul 和普通 service 的区别。

调用链集成

对于调用链没什么特殊的代码,只需要配置 sleuth 和 Zipkin 的 Maven 依赖即可,然后配置好 Zipkin 的服务端地址,案例中用的是 HTTP 方式的传输,如果要换成 RabbitMq 你可以自己去修改配置。

Zipkin server 的 jar 你可以自己去官网下载,本案例中不提供。

Apollo 集成

Apollo 的集成只需要在配置文件中指定 appid 和 metaserver 地址,案例中用的官方提供的演示地址。为了能够让你方便的运行本案例,目前所有的配置还在项目中,你可以将项目中的信息移动到 Apollo 中即可。

演示

最后演示下案例的效果,将 Eureka 和 zuul、webpage、article-provider、user-provider 启动,访问 webpage,进行登录,登录成功后调整到文章详情页面,获取到了文章的信息。右上角退出登录的按钮用于注销。

好了,到这里本专栏的内容就全部讲完了,在最后的彩蛋中,我将分享第二代微服务架构 Spring Cloud Alibaba,记得按时来听课啊,下节课见。


你好,我是你的 Spring Cloud 讲师尹吉欢,欢迎来到彩蛋:Spring Cloud Alibaba。

Spring Cloud Alibaba 简介

我们先来简单了解下什么是 Spring Cloud Alibaba?Spring Cloud Alibaba 是由一些阿里巴巴的开源组件和云产品组成的。

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

依托 Spring Cloud Alibaba,你只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

Spring Cloud Alibaba 主要功能

服务限流降级

Spring Cloud Alibaba 默认支持 WebServlet、WebFlux、OpenFeign、RestTemplate、Spring Cloud Gateway、Zuul、Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。

服务注册与发现

Spring Cloud Alibaba 适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。

分布式配置管理

Spring Cloud Alibaba 支持分布式系统中的外部化配置,配置更改时自动刷新。

消息驱动能力

Spring Cloud Alibaba 基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。

分布式事务

Spring Cloud Alibaba 使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。

Spring Cloud Alibaba 主要组件

Spring Cloud Alibaba 主要包含 Sentinel、Nacos、RocketMQ、Dubbo、Seata 等组件。

Sentinel

Sentinel 把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保障服务的稳定性。

Sentinel 目前在 GitHub 的关注超过了 1 万,接入使用的公司也比较多,Sentinel 主要分为两部分,一部分是客户端,也就是在我们的程序中集成,对 Dubbo/Spring Cloud 等框架也有较好的支持。另一部分是控制台,基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

利用 Sentinel 流量控制功能可以对网关,服务进行过载保护,像电商的秒杀场景就非常需要限流功能。另一个核心功能是熔断降级,这功能跟 Hystrix 的效果是一致的。

Sentinel 另一个优势在于控制台,在控制台中看到接入应用的单台机器秒级数据,数据监控的可视化做的非常好。同时提供简单易用、完善的 SPI 扩展接口。你可以通过实现扩展接口来快速的定制逻辑。例如定制限流规则,规则可以对接不同的存储,比如 Nacos、Apollo。

Nacos

Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。主要的功能有注册中心和配置中心。也就是说你可以用 Nacos 代替 Eureka 和 Apollo 两个组件,这也是它的优势。

目前的 Nacos 还在高速发展中,版本更新很快,目前最新的版本是 1.1.4 版本,可以直接用于生产,我自己所在公司目前生产环境也在使用 Nacos。

RocketMQ

RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

消息队列在工作中你或多或少都会接触到,有用 Kafka 的,也有用 RabbitMQ 的。在 Spring Cloud Alibaba 体系中,推荐使用的就是 RocketMQ 了。

使用消息队列可以让服务之间更加解耦,可以进行流量消峰,还有一个场景就是利用事务消息来实现分布式事务。

Dubbo

Apache Dubbo™ 是一款高性能 Java RPC 框架。在国内已被各大互联网公司用于生产环境,在Spring Cloud Alibaba 体系中,服务之间的通信可以使用 Dubbo 来进行远程调用。大家都知道Spring Cloud 中服务之间的通信是 Rest 风格的 API,是通过 Feign 来调用的。Rest 的优势在于通用性较强,无语言限制,调试也非常方便,美中不足的就是性能没有 Dubbo 好,Dubbo 是二进制传输的,而 Rest 一般都是 JSON 格式,报文较大。

Spring Cloud Alibaba 中可以将 Dubbo 和 Feign 结合使用,也就是你的服务可以暴露 Dubbo 协议,也可以暴露 Rest 协议,调用方可以选择对应的协议进行调用,对于性能有极高要求的场景可以使用 Dubbo,其他的可以使用 Rest。

Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC 等事务模式,为用户打造一站式的分布式解决方案。

分布式事务一向是微服务架构中的难题,其中最简单的是使用消息队列来实现最终一致性,但某些场景还是存在强一致性的需求,所以 Seata 的出现为我们解决了困扰了很久的分布式事务问题。

Spring Cloud 二代架构

Spirng Cloud 二代架构在一代架构的基础上替换了几个组件,主要是 Eureka 替换成了 Nacos,二代架构引入了 Spring Cloud Alibaba,Nacos 就是其中比较重要的一个组件。Eureka 之前官方也宣布了暂停了 2.X 版本的开发,1.X 的版本还会维护。其实对于一般的服务规模,目前的 Eureka 完全够用了。而 Nacos 作为后起之秀,目前更新频率很高,社区也更活跃,使用 Nacos 是一个正确的选择。

Apollo 也替换成了 Nacos,Nacos 是既可以做注册中心,又可以做配置中心,替换的原因在于既然我们都用 Nacos 做注册中心了,顺便就用它的配置功能,这样我们就可以少维护一个组件。

网关从 Zuul 替换成 Spring Cloud Gateway,在 Spring Cloud Gateway 出现之前,网关都是用 Zuul 构建的,虽然 Netflix 开源了 Zuul2,由于各种原因,官方并没有打算将 Zuul2 集成到 Spring Cloud 体系中。

而是自己研发了一个全新的网关 Spring Cloud Gateway,由于 Zuul1 基于 Servlet 构建,使用的是阻塞的 IO,性能并不是很理想。Spring Cloud Gateway 则基于 Spring 5、Spring boot 2 和 Reactor 构建,使用 Netty 作为运行时环境,比较完美的支持异步非阻塞编程。

官方提供的压测报告显示 Spring Cloud Gateway 的性能是 Zuul 的 1.5 倍,Spring Cloud Gateway 刚出不久,稳定性有待验证,主要是缺乏大规模流量的验证,而 Zuul 开源的时间较长,同时在 Netflix 内部经过了大规模流量的验证,比较稳定。长期发展来说,Spring Cloud Gateway 的优势比较大,毕竟官方主推。

Hystrix 替换成了 Sentinel,Hystrix 也停止了开发,这个时候 Spring Cloud Alibaba 中的 Sentinel 的优势就很明显了,Sentinel 支持多样化的流量控制,熔断降级等功能,完全可以替代 Hystrix。

Spring Cloud Alibaba 的出现,对于社区,对于开发者都是福音,意味着我们在 Spring Cloud 体系中又多了一种选择,可以选择一开始的 Netflix 中的组件,也可以选择 Alibaba 中的组件。

技术选型推荐

最后,总结使用 Spring Cloud 来构建微服务架构时我们可以使用哪些框架,为大家做技术选型提供一个参考:

  • 服务注册与发现:Nacos

  • 服务熔断限流:Sentinel

  • 服务通信调用:Feign

  • 配置中心:Nacos

  • 服务网关:Spring Cloud Gateway

  • 分布式事务:Seata

  • 消息队列:RocketMQ

  • 调用链监控:Sleuth+Zipkin

  • 分布式任务调度:XXL-JOB

好了,到这里本专栏的全部内容就讲完了,希望你可以在项目中结合所学的知识,融会贯通,也感谢你对本专栏的支持,谢谢。


精选评论

**威:

撒花 完结

**8010:

学习知识要善于思考,思考,再思考。—爱因斯坦


网站公告

今日签到

点亮在社区的每一天
去签到