Spring Cloud 从零到一:如何基于 Maven 构建微服务多模块系统

举报
bug菌 发表于 2024/11/28 23:22:46 2024/11/28
【摘要】 前言 🌟当你身处微服务架构的海洋中,是否曾因项目日渐膨胀而头痛?是不是在不断拆解一个大系统时,总是有种“拆东墙补西墙”的感觉?别担心,今天我们要用一种简洁优雅的方式来打破这个困局。通过 Spring Cloud 与 Maven 的完美配合,我们不仅能让项目模块化管理变得轻松,还能让微服务架构更加灵活且易于扩展。在这篇文章中,我将带你从零开始,基于 Maven 构建一个 Spring Cl...

前言 🌟

当你身处微服务架构的海洋中,是否曾因项目日渐膨胀而头痛?是不是在不断拆解一个大系统时,总是有种“拆东墙补西墙”的感觉?别担心,今天我们要用一种简洁优雅的方式来打破这个困局。通过 Spring CloudMaven 的完美配合,我们不仅能让项目模块化管理变得轻松,还能让微服务架构更加灵活且易于扩展。

在这篇文章中,我将带你从零开始,基于 Maven 构建一个 Spring Cloud 多模块程序,轻松应对大规模微服务架构中的“拆分”挑战。准备好了吗?让我们一起“破茧成蝶”,探索 Spring Cloud 的奥秘吧!🦋

🛠️ Spring Cloud 多模块架构的价值

模块化的美好

有多少开发者在面对庞大项目时感到焦头烂额?单一模块的代码越来越多,功能越来越复杂,迭代也愈发困难。没错,模块化正是我们解锁项目高效开发和维护的关键。借助 Spring CloudMaven,我们可以轻松地将一个大项目拆分成多个功能独立的模块,让每个模块只关注它自己的业务功能,从而提高开发效率、降低耦合度,同时也让微服务架构变得更加清晰。

Maven 的魔力

提到 Maven,你一定不陌生。它不仅是一个强大的构建工具,还能帮助我们高效地管理项目的依赖和版本。通过父子模块关系,Maven 可以让所有子模块共享配置和依赖,避免重复劳动,实现统一管理。

所以,Maven + Spring Cloud 组合,就是解救大型微服务项目的超级武器!🔨

🏗️ 创建我们的多模块 Spring Cloud 项目

1. 目录结构大揭秘

让我们首先创建一个基础项目框架,确保每个模块的功能清晰且互不干扰。以下是我们的项目结构:

spring-cloud-multi-module
│
├── pom.xml                  // 父POM,集中管理依赖
│
├── service-api              // 公共接口模块
│   └── pom.xml
│
├── service-eureka           // Eureka 服务注册中心
│   └── pom.xml
│
├── service-provider         // 提供者服务模块
│   └── pom.xml
│
└── service-consumer         // 消费者服务模块
    └── pom.xml

2. 父 POM 文件

在根目录下创建父 pom.xml 文件,用于集中管理所有模块的依赖和插件配置,避免每个模块重复配置。这个文件定义了 Spring Cloud 的版本管理,并且指定了所有子模块。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>spring-cloud-multi-module</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>service-api</module>
        <module>service-eureka</module>
        <module>service-provider</module>
        <module>service-consumer</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

代码解析:

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

这个 pom.xml 文件是一个多模块的 Spring Cloud 项目的父 POM 文件,包含了多个子模块,并为各个模块提供了依赖管理和插件配置。以下是对各部分的详细解析:

  1. 基本项目信息
<groupId>com.example</groupId>
<artifactId>spring-cloud-multi-module</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
  • groupId: 项目的组标识符,通常是公司域名的反转,如 com.example
  • artifactId: 项目的构件标识符,在同一组内唯一。这里是 spring-cloud-multi-module
  • version: 项目的版本号,这里使用 1.0-SNAPSHOT 表示开发中的版本。
  • packaging: 项目打包类型,这里是 pom,表示这是一个父 POM 文件,用来管理多个子模块。
  1. 子模块
<modules>
    <module>service-api</module>
    <module>service-eureka</module>
    <module>service-provider</module>
    <module>service-consumer</module>
</modules>
  • modules: 这个部分定义了项目中的子模块。每个 <module> 元素代表一个子模块,这些子模块会在构建时一起管理。
  • 例如,service-api 可能是一个公共接口模块,service-eureka 是一个用于 Eureka 服务注册的模块,service-provider 是服务提供者模块,而 service-consumer 是服务消费者模块。
  1. 依赖管理
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • dependencyManagement: 这部分是为了集中管理项目中所有子模块的依赖版本。它允许你在父 POM 中定义依赖版本,避免在每个子模块中重复指定。
  • spring-cloud-dependencies: 这是 Spring Cloud 的依赖管理 POM,版本 2021.0.2。通过 import 类型,它会引入 Spring Cloud 所需要的所有依赖及其版本。
  • scope: import 表示我们是引入一个 POM 文件作为依赖管理,而不是直接依赖某个库。
  1. 插件管理
<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
  • pluginManagement: 这部分配置了 Maven 插件的管理,指定了在构建过程中使用的插件和版本。它只影响子模块中没有显式指定插件的情况。
  • spring-boot-maven-plugin: 用于构建 Spring Boot 应用,打包为可执行的 JAR 或 WAR 文件。所有子模块如果需要构建 Spring Boot 应用,都可以直接使用这个插件。
  1. 总结

这个父 pom.xml 文件的作用是统一管理一个多模块 Spring Cloud 项目的构建配置。它通过引入 Spring Cloud 依赖管理 POM 来统一管理依赖版本,同时通过 <modules> 定义了多个子模块,允许每个子模块继承该父 POM 配置。

每个子模块(如 service-apiservice-eureka 等)都可以继承父 POM 文件的配置,自动获得统一的依赖版本和构建插件配置。

3. 公共接口模块 service-api

这个模块定义了各个微服务间的通信协议,所有服务都依赖它。你可以在这个模块里创建接口文件和 DTO 类。比如,我们创建一个简单的支付接口:

public interface PaymentService {
    String processPayment(String amount);
}

service-api/pom.xml 文件中,我们只需要添加一些基础的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

代码解析:

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

在你的例子中,PaymentService 是一个接口,它定义了一个处理支付的基本方法 processPayment,该方法接收一个字符串类型的金额并返回一个支付处理结果。接下来,你在 service-api 模块中的 pom.xml 文件中添加了基础依赖,主要是 Spring Cloud 的基础启动器 spring-cloud-starter

  1. PaymentService 接口
public interface PaymentService {
    String processPayment(String amount);
}

PaymentService 是一个简单的接口,它定义了一个方法 processPayment,用于处理支付。这个接口可以被多个支付实现类(如支付宝支付、微信支付等)实现,每个实现类会根据自己的需求处理支付逻辑。

  1. service-api/pom.xml 配置

service-api 模块的 pom.xml 文件中,你引入了 spring-cloud-starter

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

spring-cloud-starter 是 Spring Cloud 提供的基础启动器,通常会包括一些常见的 Spring Cloud 组件,如服务发现、负载均衡、配置中心等。在这个模块中,spring-cloud-starter 用来提供基本的 Spring Cloud 功能支持,为 PaymentService 提供基础的组件,方便后续扩展。

  1. 进一步扩展 service-api

通常,service-api 模块不仅会定义接口,还可能包含一些共享的模型类或其他通用功能。举个例子,可能会有一个 PaymentRequest 类,代表支付请求的详细信息:

public class PaymentRequest {
    private String amount;
    private String paymentMethod;
    
    // getters and setters
}

或者一个通用的支付响应类:

public class PaymentResponse {
    private String transactionId;
    private String status;
    
    // getters and setters
}

service-api 模块的 pom.xml 主要关注于添加和管理基础依赖和接口类的定义。实际的支付逻辑通常会被定义在 service-provider 模块中。

  1. 依赖管理

如果你的项目包含多个子模块(如 service-providerservice-consumer),在父 POM (spring-cloud-multi-modulepom.xml) 中,你可以集中管理各个模块的依赖,避免在每个子模块中重复声明。

总结

  • PaymentService 接口 定义了支付的核心方法 processPayment,其他模块可以实现这个接口来完成具体的支付逻辑。
  • service-api/pom.xml 添加了 Spring Cloud 的基础依赖 spring-cloud-starter,它提供了 Spring Cloud 的核心支持。
  • 其他模块(如 service-provider)可以实现 PaymentService 接口,并根据不同的支付方式(如支付宝、微信支付)实现具体的支付逻辑。

4. Eureka 服务注册中心 service-eureka

Eureka 是 Spring Cloud 提供的服务发现与注册工具。我们通过创建一个 Eureka 服务器,让所有的微服务都能互相找到。接下来,创建一个 Eureka 服务模块,并在启动类中添加 @EnableEurekaServer 注解启动服务注册功能:

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

代码解析:

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

这段代码展示了一个 Spring Boot 应用程序,用于启动一个 Eureka 服务注册中心。@EnableEurekaServer 注解告诉 Spring Cloud 启动 Eureka 服务器,允许其他服务注册到这个服务器上。@SpringBootApplication 是 Spring Boot 的主要注解,表示这是一个 Spring Boot 应用程序,包含了自动配置和组件扫描等功能。

  1. @SpringBootApplication

    • @SpringBootApplication 是一个复合注解,实际上包含了三个常用的注解:
      • @EnableAutoConfiguration:启用 Spring Boot 的自动配置功能,它会根据项目的依赖自动配置 Spring 应用上下文。
      • @ComponentScan:启用组件扫描,自动扫描当前包及其子包中的所有组件。
      • @Configuration:声明当前类是一个配置类,Spring 会读取并应用该类中的 Bean 定义。
  2. @EnableEurekaServer

    • @EnableEurekaServer 是 Spring Cloud 提供的注解,表示该应用程序将充当 Eureka 服务注册中心。Eureka 作为服务注册和发现工具,允许微服务应用注册到该服务器,并可以查询其他已注册的服务。
    • Eureka 服务器管理了服务实例的注册、心跳、以及服务的发现等。
  3. SpringApplication.run(EurekaApplication.class, args)

    • 通过调用 SpringApplication.run() 方法来启动 Spring Boot 应用程序,它会启动嵌入式服务器(如 Tomcat)并初始化应用上下文,最终启动 Eureka 服务器。

完整的 EurekaApplication

@EnableEurekaServer // 启动 Eureka 服务注册中心
@SpringBootApplication // 标记这是一个 Spring Boot 应用
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args); // 启动应用
    }
}

配置文件

启动 Eureka 服务器时,通常需要在 application.propertiesapplication.yml 配置一些基本的设置,如服务的端口、Eureka 的客户端连接、服务注册等信息。下面是一个常见的 application.yml 配置文件:

server:
  port: 8761 # Eureka 服务的端口

eureka:
  client:
    registerWithEureka: false # 当前服务器不需要注册到 Eureka
    fetchRegistry: false # 当前服务器不需要从 Eureka 拉取注册信息
  server:
    enableSelfPreservation: false # 禁用自我保护模式

5. 服务提供者模块 service-provider

服务提供者是我们实现具体业务逻辑的地方。它会注册到 Eureka 服务注册中心,并暴露一些接口,供其他微服务调用。在 service-provider 中,我们创建一个简单的 REST 控制器:

@RestController
public class PaymentController implements PaymentService {
    @Override
    public String processPayment(String amount) {
        return "支付成功,金额:" + amount;
    }
}

代码解析:

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

这段代码展示了一个简单的 Spring Boot 控制器类 PaymentController,实现了 PaymentService 接口,并定义了一个支付处理方法 processPayment。当调用 processPayment 时,它会返回一个简单的支付成功消息,附带传入的金额。

  1. @RestController 注解

    • @RestController 是 Spring Web 模块提供的注解,用于定义一个 RESTful 风格的控制器。它相当于 @Controller@ResponseBody 的结合体,意味着:
      • 类中的每个方法都会自动将返回值转为 JSON 格式的响应体。
      • 适用于开发 Web API。
  2. PaymentController implements PaymentService

    • PaymentController 实现了 PaymentService 接口。实现接口是为了规范支付服务的操作(如支付的处理方法)。这是一个典型的服务接口实现方式,使得控制器可以对外提供 API 服务。
  3. processPayment(String amount) 方法

    • 这是控制器的核心方法,接受一个字符串参数 amount,并返回一个表示支付成功的消息。
    • 在实际应用中,processPayment 方法可能会涉及更复杂的逻辑,如验证金额、调用支付网关等,但这里只是简单返回支付成功的信息。

完整的 PaymentController

@RestController
public class PaymentController implements PaymentService {

    @Override
    public String processPayment(String amount) {
        return "支付成功,金额:" + amount;
    }
}

PaymentService 接口

为了使代码更完整,假设 PaymentService 接口是这样定义的:

public interface PaymentService {
    String processPayment(String amount);
}

使用场景

  • 这个控制器提供了一个简单的 RESTful API 来处理支付请求。在实际应用中,可能会有多个支付方式,每种支付方式都实现 PaymentService 接口,并通过 Spring @RestController 提供相应的支付接口。
  • 例如,可以进一步扩展支付方式,如支付宝支付、微信支付等,每个支付方式都实现 PaymentService 接口,并在不同的控制器中提供 API 服务。

测试方法

假设你运行了这个 Spring Boot 应用并启动了一个 Web 服务(比如默认的 localhost:8080),你可以通过访问如下 URL 来模拟支付请求:

GET /payment/process?amount=100

如果你使用 @RequestParam 注解来处理请求参数,PaymentController 会像这样:

@RestController
public class PaymentController implements PaymentService {

    @Override
    @GetMapping("/payment/process")
    public String processPayment(@RequestParam String amount) {
        return "支付成功,金额:" + amount;
    }
}

这样,当访问 /payment/process?amount=100 时,返回的响应将是:

支付成功,金额:100

6. 服务消费者模块 service-consumer

消费者模块通过 FeignRestTemplate 来调用服务提供者暴露的接口。在 service-consumer 中,我们通过 Feign 来消费 service-provider 提供的服务。

@FeignClient("service-provider")
public interface PaymentServiceConsumer extends PaymentService {
}

代码解析:

在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。

这段代码使用了 Spring Cloud OpenFeign 来定义一个用于消费 service-provider 服务的 PaymentServiceConsumer 接口。

@FeignClient("service-provider")

  • @FeignClient 是 Spring Cloud OpenFeign 提供的注解,用于声明一个 Feign 客户端。
  • value = "service-provider" 指定了 Feign 客户端要连接的服务的名称,这个名称通常对应于注册到 Eureka 服务注册中心的服务名称,service-provider 就是该服务的名称。
  • 通过 Feign 客户端,Spring 会自动生成代码,帮你与远程服务建立连接,并自动处理 HTTP 请求和响应。

public interface PaymentServiceConsumer extends PaymentService

  • PaymentServiceConsumer 是一个接口,继承自 PaymentService,意味着 PaymentServiceConsumer 会继承 PaymentService 中定义的方法(例如 processPayment)。
  • 因为 Feign 客户端的接口通常只是声明远程服务调用的方法,所以 PaymentServiceConsumer 接口可以被用来作为一个代理,调用 service-provider 服务中的 processPayment 方法。
  • 继承接口的方式使得 PaymentServiceConsumerPaymentService 保持一致,且只需在 service-provider 中实现 PaymentService 接口的方法。

使用 Feign 客户端的步骤

添加 Feign 依赖
pom.xml 中添加 Spring Cloud Feign 依赖,确保可以使用 Feign 客户端。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

启用 Feign 客户端
在 Spring Boot 应用的主类或配置类中启用 Feign 客户端:

@SpringBootApplication
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

定义 Feign 客户端接口
如你所示,PaymentServiceConsumer 接口声明了要调用的服务接口,它会自动代理远程 service-provider 服务。

@FeignClient("service-provider")
public interface PaymentServiceConsumer extends PaymentService {
}

在这里,PaymentServiceConsumer 继承了 PaymentService,因此它将自动具有 processPayment 方法的远程调用能力。

调用 Feign 客户端接口
在消费者服务中,可以注入 PaymentServiceConsumer 来调用远程的 processPayment 方法:

@RestController
public class PaymentController {
    
    @Autowired
    private PaymentServiceConsumer paymentServiceConsumer;
    
    @GetMapping("/pay")
    public String pay(@RequestParam String amount) {
        return paymentServiceConsumer.processPayment(amount);
    }
}

当调用 /pay?amount=100 时,PaymentController 将使用 Feign 客户端通过 PaymentServiceConsumer 调用远程服务 service-provider 中的 processPayment 方法。

配置 Eureka 服务发现
如果你使用了 Eureka 作为服务注册与发现的工具,确保在 application.ymlapplication.properties 文件中正确配置了服务的注册信息:

   spring:
     application:
       name: payment-service-consumer
     cloud:
       discovery:
         enabled: true
       nacos:
         discovery:
           server-addr: localhost:8848

这将确保 payment-service-consumer 可以通过 Eureka 注册并发现 service-provider 服务。

7. 启动微服务

完成上述配置后,我们可以启动各个服务。启动顺序如下:

  1. 启动 Eureka 服务注册中心。
  2. 启动 service-provider 服务。
  3. 启动 service-consumer 服务。

一旦启动成功,消费者服务会自动从 Eureka 注册中心获取到提供者服务的地址,并进行调用。这样,微服务架构的基本功能就搭建完成了!🎉

结语 🎉

通过这篇文章,你应该已经掌握了如何使用 MavenSpring Cloud 构建一个多模块的微服务项目。在实际的开发中,这种模块化管理不仅能帮助我们高效开发,还能提高代码的可维护性和可扩展性。

随着微服务架构的普及,掌握这种模块化的开发方式将极大提升你的开发效率。希望你能通过本文的示范,轻松上手 Spring Cloud,并在微服务开发的道路上越走越远!准备好了吗?去搭建属于你的微服务架构吧!🚀

🧧福利赠与你🧧

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。

最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

✨️ Who am I?

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。

-End-

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。