构建弹性可扩展的微服务架构:基于Spring Cloud Alibaba 的实践

news2024/11/19 17:51:49
  • 💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】
  • 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】
  • 💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】

在这里插入图片描述

前言

随着互联网业务的不断发展,传统的单体应用逐渐无法满足日益复杂的业务需求和用户量的增长。微服务架构应运而生,它将应用拆分成一系列小型、自治的服务,使得应用的开发、测试、部署和扩展更加灵活高效。Spring Cloud Alibaba 是 Spring Cloud 与 Alibaba 开源的一系列微服务组件的集合,为构建弹性可扩展的微服务架构提供了强有力的支持。

1. 什么是微服务架构?

微服务架构是一种将应用拆分为一系列小型、独立的服务的软件设计风格。每个服务都有自己的业务逻辑和数据存储,并且能够独立部署和扩展。微服务架构的优点包括高度解耦、独立部署、可扩展性好等,但同时也带来了分布式系统带来的复杂性和挑战。

2. Spring Cloud Alibaba 简介

Spring Cloud Alibaba 是 Spring Cloud 与 Alibaba 合作推出的开源项目,它集成了多个优秀的开源组件,为构建微服务应用提供了丰富的功能和解决方案。其中关键组件包括 Nacos(服务注册与发现、配置中心)、Sentinel(流量控制、熔断降级)、RocketMQ(消息队列)等。

3. 构建微服务应用

我们将从零开始构建一个简单的微服务应用,包含一个服务提供者和一个服务消费者。服务提供者暴露 RESTful API 供服务消费者调用,服务消费者通过Feign实现对服务提供者的调用。

4.1 创建服务提供者

首先,我们使用 Spring Boot 创建一个服务提供者项目,并引入Spring Cloud Alibaba 的相关依赖。然后,我们定义一个Controller类,暴露一个简单的API接口。

// 服务提供者的Controller类
@RestController
public class ProviderController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from the provider!";
    }
}

4.2 创建服务消费者

接下来,我们创建一个服务消费者项目,并同样引入 Spring Cloud Alibaba 的相关依赖。使用Feign声明式调用服务提供者的API。

// Feign客户端
@FeignClient(name = "provider-service") // 指定服务提供者的名称
public interface ProviderClient {

    @GetMapping("/hello")
    String sayHello();
}

4.3 使用Nacos作为服务注册中心

在服务提供者和服务消费者项目中,我们配置 Nacos 作为服务注册中心。

# 服务提供者的application.yml配置
spring:
  application:
    name: provider-service
  cloud:
    alibaba:
      nacos:
        discovery:
          server-addr: localhost:8848
# 服务消费者的application.yml配置
spring:
  application:
    name: consumer-service
  cloud:
    alibaba:
      nacos:
        discovery:
          server-addr: localhost:8848

4.4 使用Feign实现服务间调用

在服务消费者项目中,通过 Feign 客户端调用服务提供者的API。

@RestController
public class ConsumerController {

    private final ProviderClient providerClient;

    @Autowired
    public ConsumerController(ProviderClient providerClient) {
        this.providerClient = providerClient;
    }

    @GetMapping("/invoke-provider")
    public String invokeProvider() {
        return providerClient.sayHello();
    }
}

5. 实现弹性与容错

5.1 服务降级

在高并发或资源紧张的情况下,为了保护系统的稳定性,我们可以实现服务降级。当服务提供者出现故障或超时时,服务消费者可以返回一个默认值或者友好提示,而不是直接抛出异常。

// 在ProviderClient接口上增加fallback属性,指定降级处理类
@FeignClient(name = "provider-service", fallback = ProviderFallback.class)
public interface ProviderClient {
    // ...
}
// 编写降级处理类ProviderFallback
@Component
public class ProviderFallback implements ProviderClient {

    @Override
    public String sayHello() {
        return "Service is temporarily unavailable. Please try again later.";
    }
}

5.2 服务熔断

服务熔断是指当服务的错误率或响应时间达到阈值时,自动触发断路器,暂时禁止对该服务的调用,并执行快速失败,防止故障扩散。

# 服务提供者的application.yml配置,开启Sentinel的熔断保护
spring:
  application:
    name: provider-service
  cloud:
    alibaba:
      nacos:
        discovery:
          server-addr: localhost:8848
      sentinel:
        transport:
          dashboard: localhost:8080 # Sentinel控制台地址

在Spring Boot启动类上添加@EnableCircuitBreaker注解,开启熔断功能。

@SpringBootApplication
@EnableCircuitBreaker
public class ProviderApplication {
    // ...
}

然后,在服务提供者的 Controller 方法上添加@SentinelResource注解,标识资源的入口,以及指定熔断时的处理方法。

@RestController
public class ProviderController {

    @GetMapping("/hello")
    @SentinelResource(value = "hello", fallback = "fallbackHandler")
    public String sayHello() {
        // 业务逻辑代码
    }

    // 熔断时的处理方法
    public String fallbackHandler() {
        return "Service is currently unavailable. Please try again later.";
    }
}

5.3 服务限流

服务限流是一种保护系统的措施,防止某个服务由于高并发访问而导致资源耗尽。我们可以配置Sentinel的流控规则,限制服务的访问频率。

// 编写一个Sentinel的流控规则配置类
@Configuration
public class SentinelConfig {

    @PostConstruct
    public void initRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("provider-service"); // 针对的资源名
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流阈值的维度,这里设置为QPS
        rule.setCount(10); // 每秒最多允许10次请求
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

6. 配置中心化管理

6.1 使用Nacos作为配置中心

Nacos 不仅可以作为服务注册中心,还可以作为配置中心。在 Nacos 中配置各个微服务的配置信息,实现配置的集中管理。

# 服务提供者的bootstrap.yml配置,配置Nacos作为配置中心
spring:
  application:
    name: provider-service
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
# 服务消费者的bootstrap.yml配置,配置Nacos作为配置中心
spring:
  application:
    name: consumer-service
  cloud:
    nacos:
      config:
        server-addr: localhost:8848

6.2 动态刷新配置

在配置中心更新配置后,我们希望微服务应用能够实时获取最新的配置,而不需要重启应用。

@RestController
@RefreshScope // 启用配置刷新
public class ConsumerController {

    @Value("${message:Default Message}")
    private String message;

    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}

在上述代码中,@RefreshScope注解标识了该类需要支持动态刷新配置。通过@Value注解将配置值注入到message字段中。当配置中心的message配置发生变化时,可以通过访问/actuator/refresh端点来触发配置的刷新。

7. 服务网关与统一访问入口

7.1 使用Gateway构建服务网关

服务网关是微服务架构中的一个重要组件,用于将所有的服务请求导向到相应的微服务实例。Spring Cloud Gateway 是 Spring Cloud Alibaba 提供的网关实现。

# 服务网关的application.yml配置
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true # 开启服务发现
      routes:
        - id: provider-route # 路由的ID
          uri: lb://provider-service # 路由的目标服务URI
          predicates:
            - Path=/provider/** # 匹配的请求路径

7.2 实现动态路由

我们可以实现动态路由,将路由信息存储在 Nacos 的配置中心,实现动态调整路由规则。

# 在配置中心中配置路由规则
spring:
  cloud:
    gateway:
      routes:
        - id: custom-route
          uri: https://example.com # 动态路由目标URI
          predicates:
            - Path=/custom/** # 匹配的请求路径

然后,我们可以通过调用Nacos的API来动态更新路由规则。

8. 分布式事务处理

8.1 概述分布式事务

分布式事务是在微服务架构中需要面对的挑战之一。在涉及多个服务的业务操作中,需要保证这些操作要么全部成功,要么全部失败。

8.2 使用Seata实现分布式事务

Seata 是一款开源的分布式事务解决方案,它为分布式事务的管理和协调提供了支持。

(这里省略具体 Seata 的配置和代码实现,可以展示如何在微服务架构中引入Seata,并通过 Seata 来管理分布式事务。)

9. 监控与日志

9.1 使用 Sleuth 与 Zipkin 实现分布式链路追踪

在微服务架构中,由于请求可能跨越多个服务,因此排查问题变得更加复杂。Sleuth 与 Zipkin 可以帮助我们实现分布式链路追踪,监控请求的调用链路。

9.2 使用ELK Stack收集与分析日志

日志是排查问题和监控系统运行状况的重要依据。使用 Elasticsearch、Logstash、Kibana 等工具,我们可以搭建ELK Stack来收集和分析微服务的日志。

10. 总结

Spring Cloud Alibaba为构建弹性可扩展的微服务架构提供了丰富的功能和解决方案。通过使用 Nacos 作为服务注册中心和配置中心,我们实现了服务的自动注册与发现,以及配置的集中管理和动态刷新。Feign 的使用简化了服务间的调用,而 Sentinel 的引入则加强了系统的弹性与容错能力。同时,使用 Spring Cloud Gateway 构建了服务网关,实现了统一的访问入口,并且通过Seata管理了分布式事务。最后,通过 Sleuth 与 Zipkin 的应用,我们成功实现了对微服务架构的监控与日志管理。

借助 Spring Cloud Alibaba 提供的这些组件和工具,开发者可以更加高效地构建复杂的微服务应用,同时保证系统的稳定性和可伸缩性。然而,微服务架构也并非银弹,开发者在使用过程中仍需认真思考如何根据具体业务场景合理地拆分服务,以及如何处理分布式系统带来的新挑战。希望本文对读者对构建微服务架构有所启发,能够在实践中取得更多的成功。

好书推荐

《深入浅出Java虚拟机:JVM原理与实战》

在这里插入图片描述

内容简介

本书主要以 Java 虚拟机的基本特性及运行原理为中心,深入浅出地分析 JVM 的组成结构和底层实现,介绍了很多性能调优的方案和工具的使用方法。最后还扩展介绍了 JMM 内存模型的实现原理和 Java 编译器的优化机制,让读者不仅可以学习 JVM 的核心技术知识,还能夯实 JVM 调优及代码优化的技术功底。本书适合已具有一定 Java 编程基础的开发人员、项目经理、架构师及性能调优工程师参考阅读,同时,本书还可以作为广大职业院校、计算机培训班相关专业的教学参考用书。

📚 京东购买链接:《深入浅出Java虚拟机:JVM原理与实战》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/830752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty:ByteBuf可以写入字节数

说明 可以用ByteBuf的maxWritableBytes()得到当前ByteBuf最多还可写入多少字节的数据&#xff0c;它的值等于ByteBuf的最大容量减去当前的writerIndex。 可以使用writableBytes()获得ByteBuf当前还可以写入多少字节的数据&#xff0c;它的值等于ByteBuf的容量减去当前的writer…

连接数据库报错:Bad pocket type 包校验失败

用db连接正式库报错 Bad pocket type 换一个 navicat一样的报错&#xff0c;后来发现是用的数据库不对&#xff0c;沙雕了 重新建立连接&#xff0c;更换成mysql 成功&#xff01;&#xff01;&#xff01;

深度学习(34)—— StarGAN(1)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09; 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09;1. 背景2. 基本思路3. 整体流程4. StarGAN v2(1) 网络结构(2) mapping network(3) style encoder(4)Loss 和之前…

Spring-1-透彻理解Spring XML的必备知识

学习目标 能够说出Spring的体系结构 能够编写IOC-DI快速入门 思考:为什么学习Spring而不是直接学习SpringBoot 1 Spring介绍 思考:我们为什么要学习Spring框架&#xff1f; 工作上面 Java拥有世界上数量最多的程序员 最多的岗位需求与高额薪资 95%以上服务器端还是要用Jav…

金蝶云星空和吉客云单据接口对接

金蝶云星空和吉客云单据接口对接 接入系统&#xff1a;吉客云 吉客云是基于“网店管家”十五年电商ERP行业和技术积累基础上顺应产业发展需求&#xff0c;重新定位、全新设计推出的换代产品&#xff0c;从业务数字化和组织数字化两个方向出发&#xff0c;以构建流程的闭环为依归…

通过nvm工具快捷切换node.js版本、以及nvm的安装

使用nvm可以实现多个Node.js版本之间切换 步骤目录&#xff1a; 先卸载掉本系统中原有的node版本 去github上下载nvm安装包 安装node 常用的一些nvm命令 1、先卸载掉本系统中原有的node版本 2、去github上下载nvm安装包 https://github.com/coreybutler/nvm-windows/re…

完全背包(从二维到一维)

图片来源活动 - AcWing 有 N件物品和一个容量为 V 的背包&#xff0c;每件物品有各自的价值且能被选择无数次&#xff0c;要求在有限的背包容量下&#xff0c;装入的物品总价值最大。 一&#xff0c;暴力解法&#xff08;容易超时&#xff09; #include<iostream> usi…

安卓逆向 - 基础入门教程

一、引言 1、我们在采集app数据时&#xff0c;有些字段是加密的&#xff0c;如某麦网x-mini-wua x-sgext x-sign x-umt x-utdid等参数&#xff0c;这时候我们需要去分析加密字段的生成。本篇将以采集的角度讲解入门安卓逆向需要掌握的技能、工具。 2、安卓&#xff08;Androi…

vscode 格式问题

1、EditorConfig for VS Code 插件 shift alt f 格式化文件&#xff08;VS Code格式化按键&#xff09;&#xff0c;如下图&#xff0c;每个缩进4空格 代码如下 创建文件名 .editorconfig root true [*] charset utf-8 indent_style space indent_size 2 end_of_…

【Linux多线程】一个基于环形队列实现的案例

环形队列 前言sem信号量程序代码pthread.hpp代码说明RingQueue.cc代码说明Makefile 运行 前言 sem信号量 sem_t 是信号量&#xff08;Semaphore&#xff09;的数据类型&#xff0c;用于在多线程或多进程环境中实现线程同步和资源控制。 信号量是一个计数器&#xff0c;用来控…

小红书2023“家生活”趋势白皮书

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 近年来&#xff0c;年轻人与家的关系愈发紧密。 在小红书上&#xff0c;我们观察到了家居家装内容的蓬勃生长&#xff0c;3 年来相关内容的笔记规模增长了6倍&#xff0c;相关品类的搜索量增加的 3.…

10个学习JavaScript的理由

当你决心学习一门语言的时候&#xff0c;很难选择到底应该学习哪一门&#xff0c;常用的语言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-C和SQL&#xff0c;但这并不是完整的列表。 文章目录 一、命名&#xff1a;JavaScript的由来 二、学习JavaSc…

SAP MDG —— MDG on S/4HANA 2023 创新汇总(Central Governance)

文章目录 MDG 基于SAP S/4HANA 2023的创新集中治理MDG通用架构相关基于已激活的数据刷新快照和未激活数据在文件上载时&#xff0c;将导入的源文件附到生成的变更申请附件中文件上载中新的层次结构更新模式文件下载中使用字段描述替换字段技术名称 MDG财务主数据相关当在MDG搜索…

Element的el-select下拉框多选添加全选功能

先看效果图 全选&#xff1a; 没有选中时&#xff1a; 选中部分&#xff1a; 作者项目使用的是vue3写法&#xff0c;如果是vue2的自己转换一下 html代码&#xff1a; js代码&#xff1a; 拓展 另一种方法&#xff0c;如果不想使用勾选框&#xff0c;可以试试下面的方…

Bigemap 在林业调研工作中的应用

1. 工作内容&#xff1a;做人工造林计划&#xff0c;生态林业规划设计。 2. 使用场景&#xff1a;主要用 bigemap 软件下载地图 &#xff0c;套合自己用 app 实地采集的数据&#xff0c;比如&#xff1a;林地占 用案件调查&#xff1b;扶贫工作&#xff1b;森林防火灾害面积…

【iOS RunLoop】

文章目录 前言-什么是RunLoop&#xff1f;默认情况下主线程的RunLoop原理 1. RunLoop对象RunLoop对象的获取 CFRunLoopRef源码部分&#xff08;引入线程相关&#xff09; 2. RunLoop和线程3. RunLoop相关的类RunLoop相关类的实现CFRunLoopModeRef五种运行模式CommonModes CFRun…

【力扣】206. 反转链表 <链表指针>

【力扣】206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3 输入&#xff1a…

超详细|ChatGPT辅助论文编写教程

本教程讲述在论文编写中使用ChatGPT进行辅助&#xff0c;提供思路&#xff0c;提升效率 祝看到本教程的小伙伴们都完成论文&#xff0c;顺利毕业。 可以加QQ群交流&#xff0c;一群&#xff1a; 123589938 第一章 论文框架搭建 1.1 明确论文题目 1.1.1 适合的研究方向 首先赋…

产品使用手册编写指南工具,我推荐这几个!

在编写产品使用手册时&#xff0c;有许多工具可以帮助我们更高效地完成任务。因为产品手册不仅是一份使用说明书&#xff0c;更是互联网企业宣传和推销自己产品的一种普遍形式&#xff0c;是对产品外观及内容的客观介绍&#xff0c;是对业务操作流程的详细讲解&#xff0c;是对…

【Apollo学习笔记】—— 相机仿真

文章目录 前言相关代码整理 测试实践文件目录包管理BUILD文件以及cyberfile.xml文件源程序BUILD运行结果其他参考CameraOutput channels启动camera驱动启动camera video compression驱动 前言 本文是对Cyber RT的学习记录,文章可能存在不严谨、不完善、有缺漏的部分&#xff0…