为了账号安全,请及时绑定邮箱和手机立即绑定

SpringCloud Alibaba学习:从入门到实践

概述

SpringCloud Alibaba学习主要涵盖了阿里巴巴开源的分布式服务框架Spring Cloud Alibaba的相关内容,包括服务注册与发现、配置管理、限流与熔断以及分布式事务等核心功能。通过集成Nacos、Sentinel、Seata等组件,开发者可以更便捷地构建高性能、高可用性的微服务应用。

SpringCloud Alibaba简介

Spring Cloud Alibaba 是阿里巴巴开源的一个基于Spring Cloud的分布式服务框架,主要包含了对阿里巴巴中间件的一系列适配,通过提供简单易用的API,使得开发者可以快速、高效地开发分布式系统。Spring Cloud Alibaba 提供了对Nacos、Sentinel、Seata等阿里巴巴中间件的支持,使得开发者可以便捷地使用这些组件来构建高性能、高可用性的微服务应用。

SpringCloud和Alibaba的结合

Spring Cloud 是一个基于Spring Boot的微服务框架,它提供了多种微服务集成方案,包括服务发现、配置中心、负载均衡、熔断器等,而Spring Cloud Alibaba正是在Spring Cloud的基础上,对阿里巴巴中间件进行集成,提供了一系列的组件来支持微服务开发。

  • 服务注册与发现:使用Nacos作为服务注册中心,替代原有的Eureka
  • 配置中心:同样使用Nacos作为配置中心,替代原有的Spring Cloud Config
  • 负载均衡:集成Sentinel,替代原有的Hystrix
  • 分布式事务:集成Seata,解决微服务之间的事务一致性问题

Spring Cloud Alibaba通过上述组件的集成,使得开发者可以更加方便地实现微服务的构建、部署和管理。

Nacos服务注册与发现

Nacos服务注册介绍

Nacos 是一个动态服务发现、配置管理和服务管理平台,它的主要功能包括服务发现与服务健康监测、动态配置服务、动态DNS服务。

服务发现是Nacos的核心功能之一,它可以让服务提供者将自身注册到Nacos中,而服务消费者可以通过Nacos获取服务提供者的信息,实现服务的发现与调用。服务注册是一个动态的过程,服务提供者可以在运行时将自身注册到Nacos中,并在服务发生变化时更新或注销服务。

服务发现与调用示例

下面是一个简单的示例,展示如何使用Nacos进行服务注册与发现:

  1. 服务提供者:将自身注册到Nacos中
  2. 服务消费者:通过Nacos获取服务提供者的地址,并调用服务

首先,我们需要引入Spring Cloud Alibaba Nacos的依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

服务提供者

创建一个Spring Boot应用作为服务提供者,代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceProvideController {

    @Autowired
    private ServiceProvideService serviceProvideService;

    @GetMapping("/sayHello")
    @RefreshScope
    public String sayHello() {
        return serviceProvideService.sayHello();
    }
}

服务消费者

创建另一个Spring Boot应用作为服务消费者,代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceConsumerController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/sayHello")
    public String sayHello() {
        // 通过DiscoveryClient获取服务提供者的地址列表
        List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
        if (instances.isEmpty()) {
            return "No service provider found";
        }
        ServiceInstance instance = instances.get(0);
        // 构造完整的URL
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/sayHello";
        // 发起HTTP请求调用服务提供者的sayHello方法
        return restTemplate.getForObject(url, String.class);
    }
}

通过上述代码,服务提供者将自身注册到Nacos中,而服务消费者通过Nacos获取服务提供者的地址,并调用服务。

快速搭建SpringCloud Alibaba开发环境
开发工具准备

开发工具的选择如下:

  • IDE:推荐使用IntelliJ IDEA或Eclipse
  • 构建工具:建议使用Maven或Gradle管理项目依赖
  • 语言:Java
  • 版本:Java 8及以上版本
创建SpringBoot项目

创建Spring Boot项目可以分为以下几个步骤:

  1. 创建项目:通过Maven或Gradle创建一个新的Spring Boot项目
  2. 引入依赖:在pom.xml或build.gradle文件中引入Spring Boot的starter依赖
  3. 配置文件:在resources目录下创建application.yml或application.properties文件

示例代码如下:

创建Spring Boot项目

使用Maven创建

<groupId>com.example</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

使用Gradle创建

plugins {
    id 'org.springframework.boot' version '2.3.4.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
}

mainClassName = 'com.example.Application'
引入SpringCloud Alibaba依赖

在项目中引入Spring Cloud Alibaba的相关依赖,示例如下:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

或者在Gradle中:

dependencies {
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel'
}
实战Nacos服务注册与发现

Nacos服务注册与发现实现了一个完整的动态服务发现和健康监测的功能。服务提供者将自身注册到Nacos中,服务消费者通过Nacos获取服务提供者的地址列表,从而实现服务的调用。Nacos支持基于DNS的服务发现、基于HTTP的服务发现、基于SDK的服务发现等,可以通过多种方式获取服务实例,满足不同场景下的需求。

Nacos的服务注册过程如下:

  1. 服务提供者:通过Nacos注册中心将服务实例注册到Nacos中。
  2. 服务消费者:通过Nacos获取服务提供者的地址列表,并实现服务的调用。
  3. 服务变更:服务提供者在运行时可以更新服务实例的状态(如变动IP、端口等)或者注销服务实例。

Nacos服务注册与发现的功能设计使得服务发现的过程变得非常简单,不需要服务消费者手动管理服务实例的地址列表,只需要通过Nacos获取即可。

服务发现与调用示例

继续之前的示例,我们进一步展示如何使用Nacos进行服务注册和发现。

服务提供者

在服务提供者的application.yml中配置Nacos服务注册:

spring:
  nacos:
  discovery:
    server-addr: 127.0.0.1:8848

在服务提供者中使用@EnableDiscoveryClient注解来开启服务发现功能:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProvideApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceProvideApplication.class, args);
    }
}

服务消费者

在服务消费者的application.yml中配置Nacos服务发现:

spring:
  nacos:
  discovery:
    server-addr: 127.0.0.1:8848

在服务消费者中使用@EnableDiscoveryClient注解来开启服务发现功能:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }
}

通过上述配置,服务提供者将自身注册到Nacos中,服务消费者通过Nacos获取服务提供者的地址列表,并通过这些地址调用服务提供者提供的服务。这样实现了服务的动态注册与发现,使得微服务架构下的服务管理变得更加灵活和高效。

实战Sentinel限流与熔断
Sentinel原理简介

Sentinel 是阿里巴巴开源的一款轻量级的、高性能的流量控制组件,主要针对微服务架构中的流量控制、熔断降级、系统负载保护等功能。Sentinel的核心功能包括:

  • 流量控制:根据规则限制通过的流量,支持链路的维度,对流量进行控制。
  • 熔断降级:在负载较高的情况下自动熔断降级,避免系统过载。
  • 系统保护:提供多个维度的系统指标监控,对系统负载进行实时保护。
  • 权限控制:允许设置白名单,对特定的流量进行放行。

Sentinel的工作原理如下:

  1. 检测:通过用户自定义的规则,检查流量是否符合预设的条件。
  2. 熔断:当检测到流量超过阈值或系统负载过重时,动态地将流量切换到降级模式。
  3. 降级:通过预设的降级逻辑,减少流量或限制某些流量的访问,以保证系统稳定性。
  4. 恢复:在适当的时候,自动或手动恢复到正常服务状态。

Sentinel 通过这些机制,可以有效地保护系统免受异常流量的影响,并且在系统过载时,可以自动调整服务策略,确保系统的稳定性和可用性。

实现服务的限流与熔断

在Spring Cloud Alibaba中,可以通过引入spring-cloud-starter-alibaba-sentinel依赖来使用Sentinel,实现服务的限流和熔断功能。

整合Sentinel

首先,在项目中添加Sentinel的相关依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

在配置文件application.yml中配置Sentinel的相关配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080

创建资源

在Spring Boot应用中使用@SentinelResource注解来标记需要进行流量控制的接口:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SentinelController {

    @GetMapping("/test")
    @SentinelResource(value = "test", blockHandler = "handleException")
    public String test() {
        return "Hello, Sentinel!";
    }

    public String handleException(BlockException ex) {
        return "Blocked by Sentinel!";
    }
}

创建规则

在Sentinel管理控制台中,可以通过界面对具体的资源进行流量控制和熔断降级的规则配置。

  1. 流量控制:设置QPS限制,当超过限制时,Sentinel会自动阻塞后续请求。
  2. 熔断降级:设置熔断阈值,当请求失败率达到一定比例,Sentinel会自动触发降级逻辑。
  3. 系统保护:根据系统指标(如CPU、系统负载等)触发保护策略,避免系统过载。

通过上述配置和代码,实现了服务的限流与熔断功能,确保了系统的稳定性和可用性。

使用Seata实现分布式事务
分布式事务的概念与挑战

分布式事务是指在分布式系统中,保证事务的ACID属性(原子性、一致性、隔离性、持久性)。在传统的单体应用中,事务管理相对简单,通过数据库的事务机制即可实现。但在微服务架构中,不同的服务运行在不同的进程中,数据分散在不同的数据库中,使得事务的管理变得更加复杂。

分布式事务的挑战

  • 一致性:如何确保分布式系统的数据一致性成为最大的挑战。
  • 性能:分布式事务需要协调多个服务和数据库的事务状态,增加了系统的复杂度和延迟。
  • 扩展性:传统两阶段提交(2PC)方式在扩展性上存在瓶颈。

分布式事务的解决方案

  • XA协议:一种标准的分布式事务协议,但执行效率较低。
  • TCC协议:Try-Confirm-Cancel机制,通过业务补偿实现分布式事务。
  • SAGA协议:通过事务链来实现分布式事务的最终一致性。
  • Seata:阿里巴巴开源的分布式事务解决方案,支持TCC、SAGA、XADL多种分布式事务模式,本文以TCC模式为例说明如何使用Seata实现分布式事务。
使用Seata实现分布式事务

Seata 是阿里巴巴开源的一个致力于微服务架构下分布式事务的开源解决方案,支持TCC、SAGA、XADL多种分布式事务模式,本文以TCC模式为例说明如何使用Seata实现分布式事务。

整合Seata

首先,引入Seata的依赖:

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>

在配置文件application.yml中配置Seata的相关配置:

seata:
  application-id: service-provider
  tx-service-group: default
  server:
    enable: true
    ip: 127.0.0.1
    port: 8091
  config:
    type: file
    file: ./conf/seata.txt
  registry:
    type: file
    file: ./conf/seata.txt

开发TCC模式

在Spring Boot应用中使用TCC模式实现分布式事务:

  1. 定义业务服务接口:定义TCC事务的接口。
public interface OrderService {
    String createOrder(TccOrderRequest request) throws Exception;
    void confirmOrder(String id) throws Exception;
    void cancelOrder(String id) throws Exception;
}
  1. 实现业务服务接口:在实现中使用Seata的TransactionTemplate进行事务管理。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.TransactionalTransaction;
import io.seata.tm.api.TransactionStatus;
import io.seata.tm.api.TransactionalTransaction;
import io.seata.tm.api.TransactionalTransaction;
import io.seata.tm.api.TransactionalTransaction;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private TransactionalTransaction transactionalTransaction;

    @Override
    @GlobalTransactional
    public String createOrder(TccOrderRequest request) {
        // 创建订单
        String orderId = createOrderInDB(request);
        // 提交事务
        transactionalTransaction.commit();
        return orderId;
    }

    private String createOrderInDB(TccOrderRequest request) {
        // 模拟数据库操作
        return "123456";
    }

    @Override
    @GlobalTransactional
    public void confirmOrder(String id) {
        // 确认订单
        confirmOrderInDB(id);
        // 提交事务
        transactionalTransaction.commit();
    }

    private void confirmOrderInDB(String id) {
        // 模拟数据库操作
    }

    @Override
    @GlobalTransactional
    public void cancelOrder(String id) {
        // 取消订单
        cancelOrderInDB(id);
        // 提交事务
        transactionalTransaction.commit();
    }

    private void cancelOrderInDB(String id) {
        // 模拟数据库操作
    }
}

通过上述代码,实现了TCC模式下的分布式事务管理,确保了事务的原子性和一致性。

实战SpringCloud Alibaba微服务项目
微服务项目的设计思路

在设计微服务项目时,需要考虑以下几个方面:

  1. 服务划分:将系统拆分为多个独立的服务,每个服务负责一个子模块的业务逻辑。
  2. 服务通信:服务之间通过HTTP协议进行通信。
  3. 服务注册与发现:使用Nacos作为服务注册中心,实现服务的注册与发现。
  4. 配置管理:使用Nacos作为配置中心,实现服务的动态配置管理。
  5. 限流与熔断:使用Sentinel实现服务的限流与熔断,保证服务的稳定性。
  6. 事务管理:使用Seata实现分布式事务,确保数据的一致性。
  7. 监控与日志:收集服务的运行状态和日志信息,方便后续的维护和调试。

实例详解

下面以一个简单的电商系统为例,展示如何设计和实现一个微服务项目。

服务划分

假设我们的电商系统包含以下主要模块:

  • 用户服务:负责用户相关的业务逻辑,如注册、登录、个人信息管理等。
  • 订单服务:负责订单相关的业务逻辑,如创建订单、确认订单、取消订单等。
  • 商品服务:负责商品相关的业务逻辑,如商品展示、商品详情、商品搜索等。

服务通信

服务之间通过HTTP协议进行通信,可以使用Spring Cloud的RestTemplate或Feign客户端进行HTTP请求的发送和接收。

服务注册与发现

每个服务在启动时,将其自身的地址信息注册到Nacos服务注册中心。服务消费者在需要调用服务时,通过Nacos获取服务提供者的地址列表,然后通过这些地址调用服务。

配置管理

使用Nacos作为配置中心,实现服务的动态配置管理。每个服务在启动时,从Nacos中获取配置信息,可以实时更新配置信息而无需重启服务。

限流与熔断

使用Sentinel实现服务的限流与熔断功能,通过预设的规则,当请求流量超过阈值或服务负载过高时,自动触发限流和熔断逻辑,确保服务的稳定性和可用性。

事务管理

使用Seata实现分布式事务,确保服务间的数据一致性。例如,在创建订单时,需要同时更新订单表和库存表,通过Seata的TCC模式实现分布式事务的管理。

监控与日志

通过集成Spring Boot Actuator插件,收集服务的运行状态和日志信息,通过Nacos Dashboard或自定义的监控系统展示这些信息,方便后续的维护和调试。

微服务项目实战

下面我们通过一个简单的订单服务示例,展示如何实现微服务的设计和开发。

创建订单服务

首先,创建一个名为order-service的Spring Boot项目,该服务提供订单相关的业务逻辑。

  1. 引入依赖

在pom.xml中添加Spring Cloud Alibaba相关的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <dependency>
        <groupId>io.seata</groupId>
        <artifactId>seata-spring-boot-starter</artifactId>
    </dependency>
</dependencies>
  1. 服务注册与发现

在application.yml中配置Nacos的相关配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: public

使用@EnableDiscoveryClient注解开启服务发现功能:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
  1. 配置管理

在Nacos中创建配置文件,并在项目中读取配置。

order:
  service:
    timeout: 5000

在代码中读取配置:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class OrderServiceConfig {
    @Value("${order.service.timeout}")
    private int timeout;

    public int getTimeout() {
        return timeout;
    }
}
  1. 实现订单服务

创建订单相关的服务实现:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/create")
    public String createOrder() {
        return orderService.createOrder();
    }
}

实现具体的订单逻辑:

import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private OrderServiceConfig config;

    @Autowired
    public OrderService(OrderServiceConfig config) {
        this.config = config;
    }

    public String createOrder() {
        // 创建订单逻辑
        return "Order created";
    }
}
  1. 限流与熔断

使用Sentinel进行限流和熔断:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SentinelController {

    @GetMapping("/test")
    @SentinelResource(value = "test", blockHandler = "handleException")
    public String test() {
        return "Hello, Sentinel!";
    }

    public String handleException(BlockException ex) {
        return "Blocked by Sentinel!";
    }
}
  1. 分布式事务

实现订单创建时的分布式事务:

import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private TransactionalTransaction transactionalTransaction;

    @Override
    @GlobalTransactional
    public String createOrder(OrderRequest request) {
        // 创建订单逻辑
        String orderId = createOrderInDB(request);
        // 提交事务
        transactionalTransaction.commit();
        return orderId;
    }

    private String createOrderInDB(OrderRequest request) {
        // 模拟数据库操作
        return "123456";
    }

    @Override
    @GlobalTransactional
    public void confirmOrder(String orderId) {
        // 确认订单
        confirmOrderInDB(orderId);
        // 提交事务
        transactionalTransaction.commit();
    }

    private void confirmOrderInDB(String orderId) {
        // 模拟数据库操作
    }

    @Override
    @GlobalTransactional
    public void cancelOrder(String orderId) {
        // 取消订单
        cancelOrderInDB(orderId);
        // 提交事务
        transactionalTransaction.commit();
    }

    private void cancelOrderInDB(String orderId) {
        // 模拟数据库操作
    }
}

通过上述步骤,我们完成了订单服务的设计和实现,包括服务注册与发现、配置管理、限流与熔断、分布式事务等。这样,我们就构建了一个完整的微服务项目,能够满足系统的需求。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消