文章目录
前言
本文从spring和springboot 引出Spring Cloud,紧接着介绍Spring Cloud Alibaba。以及如何快速上手Spring Cloud Alibaba:Spring Cloud Alibaba核心技术与实战案例
Spring Cloud
等等。在我们深入研究Spring Cloud之前,让我们先了解一下Spring和Spring Boot。
Spring框架
我们都知道Spring框架已经存在很长时间了,它提供了以下功能:
- Spring JDBC
- Spring MVC
- Spring Security
- Spring AOP
- Spring ORM(与Hibernate进行映射)
- Spring Test 通过这些功能,Java开发人员过去通常使用Spring MVC开发Web应用程序,然后将Spring应用程序与任何ORM框架(如Hibernate)进行连接。
在那个时代,我们使用JSP页面调用Spring Controller来调用与数据库交互的Service层。然后我们需要运行一个独立的Web服务器(如tomcat),并将war/ear文件放入tomcat中来运行我们的Web应用程序。
很多年前,有一个著名的面试问题:
“如何将Spring与Hibernate集成?” - 我们都知道我们需要执行以下步骤:
- 创建applicatoncontext.xml文件
- 声明数据源并提供配置
- 声明Hibernate Session Factory并与数据源关联
- 最后,将Session Factory映射到Spring框架的HibernateTemplate 在进行了这些配置之后,Spring和Hibernate可以无缝地工作。
Spring Boot
Spring框架有很多功能,它是一个强大的框架,被Java开发人员广泛使用。但正如我们上面讨论的,它仍然存在一些缺点。世界正在朝着松耦合的架构发展,以使用任何可插拔的前端框架,如Angular、React等,但Spring框架与Spring MVC紧密耦合,使用JSP页面。
然后,Spring Boot框架出现了,它用于快速构建与任何UI框架插件相关的REST API。它还通过提供以下功能解决了Spring框架的所有缺点:
- 内嵌的Tomcat服务器
- Spring Data JPA(无需任何配置即可自动连接Hibernate)
- 默认日志记录器的自动记录
- 全局异常处理器(使用AOP来处理异常)
- 自动配置
- 内存数据库(非常适用于执行单元测试用例)
- Starter依赖项 在Spring Boot和微服务进化之后,传统的Spring框架的使用量已经减少,几乎每个组织都已经迁移到了Spring Boot,这是开发生产级Java Web应用程序的现代方式。
Spring Cloud
现在让我们来看看Spring Cloud领域。正如前面讨论的,Spring Boot用于编写独立的Java Web应用程序。那么如何配置它与外部系统或组件一起使用呢?答案是Spring Cloud。是的,你没听错。
Spring Cloud提供了以下对于现代分布式系统非常关键的功能:
- 分布式/版本化配置 一个集中的配置服务器用于维护应用程序配置 这可以与代码仓库分开维护,并且易于管理
- 服务注册和发现 所有服务都将其标识注册到注册服务器,其中最著名的是Eureka。 连接到中央服务器的客户端可以更新和检索地址。
- 服务间调用 服务可以通过以下步骤相互发现以进行通信:- 注册服务- 获取注册表- 查找下游服务- 解析底层IP地址- 使用RestTemplate调用REST端点
- 负载均衡 负载均衡的目标是最大化吞吐量,最小化响应时间,提高效率和优化资源使用。 使用带有负载均衡的多个组件可以通过冗余提高可靠性和可用性。 Eureka依赖项具有名为Ribbon的内置负载均衡器,它在单个服务的实例之间平衡负载。
- 断路器 当调用另一个微服务/另一个系统的API失败时,断路器用作回退机制。 它们使得打开和关闭电路以及在失败情况下该做什么成为可能。断路器能够优雅地处理这些故障。 Spring Boot中广泛使用的断路器是resilience4j。
- API网关 Spring Cloud Gateway是为Spring Boot应用程序设计的API网关。它具有以下功能:- 基于Spring框架5、项目反应器和Spring Boot 2.0构建- 能够根据任何请求属性匹配路由- 谓词和过滤器特定于路由- 断路器集成- Spring Cloud Discovery Client集成- 易于编写谓词和过滤器- 请求速率限制- 路径重写
- Spring Cloud安全 Spring Security集成,提供身份验证和授权 支持JWT令牌验证 Spring Cloud Security通过使用Spring Boot和Spring Security OAuth2提供了一组用于构建安全应用程序的基本功能 我们可以快速创建实现单点登录、令牌中继和令牌交换等常见模式的系统。
- 分布式跟踪 跟踪在微服务中非常有用,因为来自客户端的请求可能在多个微服务之间传递。对于开发人员来说,查看请求在服务之间的状态是至关重要的,而Spring Cloud通过提供以下依赖项来解决这个问题 我们可以向项目中添加Spring Cloud Sleuth库以启用跟踪。Sleuth负责记录时间,并生成用于延迟分析的请求ID。有了这个请求ID,我们可以跟踪请求在服务之间的传递情况。 Zipkin是一种专为分析微服务架构内的延迟问题而设计的分布式跟踪工具。它公开了用于收集输入数据的HTTP端点。如果我们需要向项目中添加跟踪功能,我们应该添加spring-cloud-starter-Zipkin依赖项。
- 分布式消息传递 Spring Cloud Bus通过轻量级消息代理将分布式系统的节点连接起来。然后可以使用AMQP和其他消息传递协议来广播应用程序中的状态更改。 这是微服务中非常常见的一种用例,通过将消息推送到RabbitMQ、Kafka、AWS SQS等实现异步通信。 Spring Cloud Stream是Spring Cloud中的另一个框架,用于构建与共享消息系统连接的高度可扩展的事件驱动微服务。它用于流处理。 正如我们上面所看到的,Spring Cloud具有许多用于分布式系统通信的功能,我们可以包含所需的依赖项并非常容易地使用它。
简而言之,Spring Boot是用于开发独立的微服务应用程序的应用程序,而Spring Cloud用于配置这些服务之间的通信。因此,为了实现生产级微服务系统,两者都是必需的。
Spring Cloud Alibaba
Spring Cloud作为微服务的大管家,可以管理众多微服务,因此需要很多小助手来提供帮助。
pring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
组件
- Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
- Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
- Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
- Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
- Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
如何使用如何引入依赖
如果需要使用已发布的版本,在 dependencyManagement 中添加如下配置。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0-RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后在 dependencies 中添加自己所需使用的依赖即可使用。
如何掌握Spring Cloud Alibaba
为了让大家快速上手掌握Spring Cloud Alibaba,给大家推荐一本书《Spring Cloud Alibaba核心技术与实战案例》
京东链接:https://item.jd.com/14010448.html
特色
不留遗漏:全面覆盖Dubbo核心知识点
直击要害:实战化案例精准定位技术细节
学以致用:精要式演示确保开发、学习不脱节
潜移默化:研磨式知识讲解渗透技术要点
提升效率:垂直式技术精讲不饶弯路
循序提升:渐进式知识点编排确保连贯
配套资源:赠送全书案例源文件助力学习
内容简介
本书从分布式系统的基础概念讲起,逐步深入分布式系统中间件Spring Cloud Alibaba进阶实战,重点介绍了使用Spring Cloud Alibaba框架整合各种分布式组件的完整过程,让读者不但可以系统地学习分布式中间件的相关知识,
而且还能对业务逻辑的分析思路、实际应用开发有更为深入的理解。
全书共分5大章节,第1章开篇部分,讲解分布式系统的演进过程和Spring Cloud Alibaba概述及版本的选择,以及单体架构/微服务架构的优缺点;
第2章讲解如何使用Spring Cloud Alibaba实现RPC通讯;
第3章在介绍主流Nacos组件时,介绍了三元的概念以及使用Nacos实现注册中心和配置中心,包含环境的动态切换、配置的动态刷新、通用型配置、版本回滚等核心技术,为微服务环境提供基础的架构;
第4章介绍了负责限流和熔断降级的Sentinel组件,包含收集系统运行状态、流量控制、熔断降级、热点、授权、系统规则、流控的异常处理、熔断的异常处理、规则持久化等;
第5章介绍了网关常用案例,以及在软件项目中常用的高频使用技术点,力求为开发微服务项目的程序员提供一个快速学习的捷径。
本书内容由浅入深、结构清晰、实例丰富、通俗易懂、实用性强,适合需要全方位学习Spring Cloud Alibaba相关技术的人员,也适合培训学校作为培训教材,还可作为大、中专院校相关专业的教学参考书。
以RocketMQ为例
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
下载并启动 RocketMQ
在接入 RocketMQ Binder 之前,首先需要启动 RocketMQ 的 Name Server 和 Broker。
- 下载RocketMQ最新的二进制文件,并解压
- 启动 Name Server
sh bin/mqnamesrv
- 启动 Broker
sh bin/mqbroker -n localhost:9876
引入依赖
修改
pom.xml
文件,引入 RocketMQ Stream Starter。
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-stream-rocketmq</artifactId></dependency>
简单示例
创建Topic
sh bin/mqadmin updateTopic -n localhost:9876 -c DefaultCluster -t test-topic
示例代码
配置 Input 和 Output 的 Binding 信息并配合
@EnableBinding
注解使其生效
@SpringBootApplication@EnableBinding({Source.class,Sink.class})publicclassRocketMQApplication{publicstaticvoidmain(String[] args){SpringApplication.run(RocketMQApplication.class, args);}}
配置 Binding 信息:
# 配置rocketmq的nameserver地址
spring.cloud.stream.rocketmq.binder.name-server=127.0.0.1:9876
# 定义name为output的binding
spring.cloud.stream.bindings.output.destination=test-topic
spring.cloud.stream.bindings.output.content-type=application/json
# 定义name为input的binding
spring.cloud.stream.bindings.input.destination=test-topic
spring.cloud.stream.bindings.input.content-type=application/json
spring.cloud.stream.bindings.input.group=test-group
应用启动
- 增加配置,在应用的 /src/main/resources/application.properties 中添加基本配置信息
spring.application.name=rocketmq-example
server.port=28081
- 启动应用,支持 IDE 直接启动和编译打包后启动。1. IDE 直接启动:找到主类
RocketMQApplication
,执行 main 方法启动应用。2. 打包编译后启动:首先执行mvn clean package
将工程编译打包,然后执行java -jar rocketmq-example.jar
启动应用。
消息处理
使用 name 为 output 对应的 binding 发送消息到 test-topic 这个 topic。
使用2个 input binding 订阅数据。
- input1: 订阅 topic 为 test-topic 的消息,顺序消费所有消息(顺序消费的前提是所有消息都在一个 MessageQueue 中)
- input2: 订阅 topic 为 test-topic 的消息,异步消费 tags 为 tagStr 的消息,Consumer 端线程池个数为20
配置信息如下:
spring.cloud.stream.rocketmq.binder.name-server=127.0.0.1:9876
spring.cloud.stream.bindings.output.destination=test-topic
spring.cloud.stream.bindings.output.content-type=application/json
spring.cloud.stream.bindings.input1.destination=test-topic
spring.cloud.stream.bindings.input1.content-type=text/plain
spring.cloud.stream.bindings.input1.group=test-group1
spring.cloud.stream.rocketmq.bindings.input1.consumer.orderly=true
spring.cloud.stream.bindings.input2.destination=test-topic
spring.cloud.stream.bindings.input2.content-type=text/plain
spring.cloud.stream.bindings.input2.group=test-group2
spring.cloud.stream.rocketmq.bindings.input2.consumer.orderly=false
spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=tagStr
spring.cloud.stream.bindings.input2.consumer.concurrency=20
消息发送
使用 MessageChannel 进行消息发送:
publicclassProducerRunnerimplementsCommandLineRunner{@AutowiredprivateMessageChannel output;// 获取name为output的binding@Overridepublicvoidrun(String... args)throwsException{Map<String,Object> headers =newHashMap<>();
headers.put(MessageConst.PROPERTY_TAGS,"tagStr");Message message =MessageBuilder.createMessage(msg,newMessageHeaders(headers));
output.send(message);}}
或者使用 RocketMQ 原生的 API 进行消息发送:
publicclassRocketMQProducer{DefaultMQProducer producer =newDefaultMQProducer("producer_group");
producer.setNamesrvAddr("127.0.0.1:9876");
producer.start();Message msg =newMessage("test-topic","tagStr","message from rocketmq producer".getBytes());
producer.send(msg);}
消息接收
使用
@StreamListener
注解接收消息:
@ServicepublicclassReceiveService{@StreamListener("input1")publicvoidreceiveInput1(String receiveMsg){System.out.println("input1 receive: "+ receiveMsg);}@StreamListener("input2")publicvoidreceiveInput2(String receiveMsg){System.out.println("input2 receive: "+ receiveMsg);}}
版权归原作者 程序员半夏 所有, 如有侵权,请联系我们删除。