8. SpringCloud Alibaba Nacos 注册中心 + 配置中心 Nacos “分类配置” 超超详细使用+配置解析

8. SpringCloud Alibaba Nacos 注册中心 + 配置中心 Nacos “分类配置” 超超详细使用+配置解析

文章目录

  • 8. SpringCloud Alibaba Nacos 注册中心 + 配置中心 Nacos “分类配置” 超超详细使用+配置解析
  • 前言
  • 1. Spring Cloud Alibaba Nacos 概述
    • 1.2 安装 Spring Cloud Alibaba Nacos + 运行
  • 2. 创建 Spring Cloud Alibaba Nacos 服务实例(Nacos 作为注册中心)
    • 2.1 创建 Nacos 服务提供者
    • 2.2 创建 Nacos 的服务消费者
  • 3. Spring Cloud Alibaba Nacos AP 和 CP 切换-理论
  • 4. Spring Cloud Alibaba Nacos 配置中心实例
    • 4.1 注意事项和细节
  • 5. Spring Cloud Alibaba Nacos 分类配置(实现配置隔离)
    • 5.1 DataID 分类配置方案
    • 5.2 Group 分类配置方案
    • 5.3 Namespace 分类配置方案
    • 5.4 Namespace / Group / Data ID 三种分类配置方式的关系
  • 6. 总结:
  • 7. 最后:

前言

  • 对应上一篇学习内容:🌟🌟🌟 7. Spring Cloud Sleuth+ZipKin 链路监控的配置详细解析-CSDN博客
  • 对应下一篇学习内容:🌟🌟🌟

1. Spring Cloud Alibaba Nacos 概述

Spring Cloud Alibaba Nacos 官网地址:https://github.com/alibaba/Nacos

在这里插入图片描述

Nacos 是什么:

一句话:Nacos 就是注册中心[替代 Eureka] + 配置中心[替代 Config] ,简单的说:Nacos 和 Eureka 是一样的

Nacos : Dynamic Naming and Configuration Service

Nacos: 架构理论基础: CAP理论(支持AP和CP,可以切换)

1.2 安装 Spring Cloud Alibaba Nacos + 运行

下载: https://github.com/alibaba/nacos/releases/tag/1.2.1

在这里插入图片描述

解压,运行 bin/startup.cmd 即可。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

浏览器访问:http://localhost:8848/nacos

用户名和密码都是: nacos

在这里插入图片描述

特别注意:Nacos 是作为一个微服务独立运行的,想要使用 Nacos 的时候,不可以将命名控制台,关闭了,关闭了也就是将 Nacos 给关闭了

2. 创建 Spring Cloud Alibaba Nacos 服务实例(Nacos 作为注册中心)

2.1 创建 Nacos 服务提供者

在这里插入图片描述

创建 member-service-nacos-provider-10004 并注册到 NacosServer8848

  1. 参考 member-service-provider-10000 来创建 member-service-nacos-provider-10004 即 可
  2. 创 建 好 后 , 使 用 member-service-provider-10000 的 源 码 和 配 置 替 换 member-service-nacos-provider-10004 生成的代码
  3. 提醒,拷贝时不要忘记拷贝 resources/mapper/MemberMapper.xml 这些 xxx.xml 文 件
  1. 修改父项目 pom.xml 。导入 Naocs 依赖的 jar 。可以参考官网文档:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba#_dependency_management

在这里插入图片描述

<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

在这里插入图片描述

  1. 修改 pom.xml, 加入 spring-cloud-alibaba 依赖
    在这里插入图片描述
         <!--            配置 Spring Cloud Alibaba--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency>
  1. 创建 member-service-nacos-provider-10004 当中的 resources 类路径下,创建 application.yml, 同时在其中编写 Nacos 的相关配置。如下图所示:

在这里插入图片描述

在这里插入图片描述

spring:application:name: member-service-nacos-provider # 配置应用的名称# 配置 nacoscloud:nacos:discovery:server-addr: localhost:8848 # 配置注册到哪个 Nacos Server的地址
# 配置暴露所有的监控点:
management:endpoints:web:exposure:include: '*'

完整的 yaml 的编写:

server:port: 10004
spring:application:name: member-service-nacos-provider # 配置应用的名称# 配置 nacoscloud:nacos:discovery:server-addr: localhost:8848 # 配置注册到哪个 Nacos Server的地址datasource:type: com.alibaba.druid.pool.DruidDataSource # 配置 alibaba 的数据库连接池password: MySQL123username: rooturl: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8mybatis:mapper-locations: classpath:mapper/*.xml # 指定 mapper.xml 文件位置 classpath 表示 resources 目录下type-aliases-package: com.rainbowsea.springcloud.entity # 实例 bean 类所在的包,这样可以通过类名的方式# 配置暴露所有的监控点:
management:endpoints:web:exposure:include: '*'
  1. 创建主启动类:创建主启动类 MemberNacosProviderApplication10004

在这里插入图片描述

特别说明:必须在主启动(场景启动器)类上加上@EnableDiscoveryClient 注解(引用Nacos发现注解),才能启动使用上 Nacos 注册中心

package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;//@EnableDiscoveryClient  标注引入的是 Nacos 发现注解
@EnableDiscoveryClient
@SpringBootApplication
public class MemberApplication10004 {public static void main(String[] args) {SpringApplication.run(MemberApplication10004.class, args);}
}
  1. 为看到更好提示,修改 Controller。

修改 com/rainbowsea/springcloud/controller/MemberController.java 的输出信息。

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.springcloud.controller;import com.rainbowsea.springcloud.entity.Member;
import com.rainbowsea.springcloud.entity.Result;
import com.rainbowsea.springcloud.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;@RestController
@Slf4j
public class MemberController {@Resourceprivate MemberService memberService;/*说明:1. 我们的前端如果是以 json 格式来发送添加信息的Member,那么我们需要使用 @RequestBody才能将数据封装到对应的 bean,同时保证http的请求的 content-type 是对应2. 如果前端是以表单形式提交了,则不需要使用@RequestBody,才会进行对象bean参数封装,同时保证 http的请求的 content-type 是对应*//*** 添加方法/接口** @param member* @return*/@PostMapping("/member/save")public Result save(@RequestBody Member member) {// 注意:微服务组件通信的坑点:// 这里我们使用 RestTemplate 传输发送的数据格式是以 json 格式的所以要添加撒谎给你 @RequestBody// 将json 格式的字符串转换为 bean对象进行赋值// 同时,我们 bean 对象传输过程中是需要序列化的。log.info("member-service-provider-10000 save member={}", member);int affected = memberService.save(member);if (affected > 0) { // 说明添加成功return Result.success("添加会员成功 member-service-nacos-provider-10004 ", affected);} else {return Result.error("401", "添加会员失败");}}/*** 这里我们使用 url占位符 + @PathVariable** @param id* @return*/@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id, HttpServletRequest request) {Member member = memberService.queryMemberById(id);String color = request.getParameter("color");String age = request.getParameter("age");// 模拟超时 ,这里暂停 5秒/* try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}*/// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功 member-service-nacos-provider-10004  color" + color + "age" + age, member);} else {return Result.error("402", "ID" + id + "不存在 member-service-nacos-provider-10004 ");}}}
  1. 测试:
  1. 启动 Nacos Server 8848
  2. 启动 member-service-nacos-provider-10004
  3. 观察 nacos 服务是否注册成功

在这里插入图片描述

在这里插入图片描述

浏览器: http://localhost:10004/member/get/1

在这里插入图片描述

  1. 创建 member-service-nacos-provider-10006 并注册到 NacosServer8848

创建 member-service-nacos-provider-10006

  1.        参考member-service-nacos-provider-10004  来创建 member-service-nacos-provider-10006  即可
    
  2.        创 建 好 后 , 使 用  member-service-nacos-provider-10004   的 源 码 和 配 置 替 换 member-service-nacos-provider-10006 生成的代码
    
  3.        提醒,拷贝时不要忘记拷贝  resources/mapper/MemberMapper.xml  这些  xxx.xml  文 件
    

在该 ‘member-service-nacos-provider-10006’ 项目 pom.xml 。导入 Naocs 依赖的 jar

在这里插入图片描述

创建 member-service-nacos-provider-10006 当中的 resources 类路径下,创建 application.yml, 同时在其中编写 Nacos 的相关配置。如下图所示:

在这里插入图片描述

server:port: 10006
spring:application:name: member-service-nacos-provider # 配置应用的名称# 配置 nacoscloud:nacos:discovery:server-addr: localhost:8848 # 配置注册到哪个 Nacos Server的地址datasource:type: com.alibaba.druid.pool.DruidDataSource # 配置 alibaba 的数据库连接池password: MySQL123username: rooturl: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8mybatis:mapper-locations: classpath:mapper/*.xml # 指定 mapper.xml 文件位置 classpath 表示 resources 目录下type-aliases-package: com.rainbowsea.springcloud.entity # 实例 bean 类所在的包,这样可以通过类名的方式# 配置暴露所有的监控点:
management:endpoints:web:exposure:include: '*'

创建主启动类 MemberNacosProviderApplication10006:

在这里插入图片描述

修改 com/rainbowsea/springcloud/controller/MemberController.java 的输出信息。

在这里插入图片描述

package com.rainbowsea.springcloud.controller;import com.rainbowsea.springcloud.entity.Member;
import com.rainbowsea.springcloud.entity.Result;
import com.rainbowsea.springcloud.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;@RestController
@Slf4j
public class MemberController {@Resourceprivate MemberService memberService;/*说明:1. 我们的前端如果是以 json 格式来发送添加信息的Member,那么我们需要使用 @RequestBody才能将数据封装到对应的 bean,同时保证http的请求的 content-type 是对应2. 如果前端是以表单形式提交了,则不需要使用@RequestBody,才会进行对象bean参数封装,同时保证 http的请求的 content-type 是对应*//*** 添加方法/接口** @param member* @return*/@PostMapping("/member/save")public Result save(@RequestBody Member member) {// 注意:微服务组件通信的坑点:// 这里我们使用 RestTemplate 传输发送的数据格式是以 json 格式的所以要添加撒谎给你 @RequestBody// 将json 格式的字符串转换为 bean对象进行赋值// 同时,我们 bean 对象传输过程中是需要序列化的。log.info("member-service-provider-10006 save member={}", member);int affected = memberService.save(member);if (affected > 0) { // 说明添加成功return Result.success("添加会员成功 member-service-nacos-provider-10006 ", affected);} else {return Result.error("401", "添加会员失败");}}/*** 这里我们使用 url占位符 + @PathVariable** @param id* @return*/@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id, HttpServletRequest request) {Member member = memberService.queryMemberById(id);String color = request.getParameter("color");String age = request.getParameter("age");// 模拟超时 ,这里暂停 5秒/* try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}*/// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功 member-service-nacos-provider-10006  color" + color + "age" + age, member);} else {return Result.error("402", "ID" + id + "不存在 member-service-nacos-provider-10006 ");}}}

测试
保证 Nacos Server 8848 是启动的
启动 member-service-nacos-provider-10006
观察 nacos 服务是否注册成功。

在这里插入图片描述

在这里插入图片描述

浏览器: http://localhost:10006/member/get/1

在这里插入图片描述

2.2 创建 Nacos 的服务消费者

需求说明/图解:

在这里插入图片描述

创建 member-service-nacos-consumer-80 并注册到 NacosServer8848。如下图所示:

参考 member-service-consumer-80 来创建 member-service-nacos-consumer-80 即可

在这里插入图片描述

修改 member-service-nacos-consumer-80 模块当中的 pom.xml 文件,导入相关的 jar 依赖。如下图所示:在这里插入图片描述

<?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"><parent><artifactId>e-commerce-center</artifactId><groupId>com.rainbowsea</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>member-service-nacos-consumer-80</artifactId><!--    引入相关的依赖:我们引入了当前所需要的依赖,后面如果有其它的需要,再灵活添加--><dependencies><!--引入 alibaba-nacos -discovery   --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--        引入 web-starter 说明:我们使用版本仲裁(从父项目继承了版本)--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--1. starter-actuator 是sprng boot 程序的监控系统,可以实现健康检查,info 信息等2. 访问http://localhost:10000/actuator 可以看到相关链接,还可以做相关配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--        lombok 引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--        引入 test-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--        引入我们自己对 bean 封装成 api 的模块内容--><dependency><groupId>com.rainbowsea</groupId><artifactId>e_commerce_center-common-api</artifactId><version>${project.version}</version></dependency></dependencies></project>

编写 resoucse 其中的application.yaml 文件当中,编写对于 Nacos 的相关的配置信息。如下图所示:

在这里插入图片描述

server:port: 80
spring:application:name: member-service-nacos-consumer-80#配置 nacos 注册中心cloud:nacos:discovery:server-addr: localhost:8848 # 配置 nacos server的地址

创建该模块的,主启动类/(场景启动器)。注意如果需要使用 Nacos ,需要在主启动类上加上了``注解,引用Nacos 的注解,启用 Nacos 的注册中心。

在这里插入图片描述

package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient  // 表示引入 Nacos 注册中心,启动 nacos 发现注解
public class MemberNacosConsumerApplication80 {public static void main(String[] args) {SpringApplication.run(MemberNacosConsumerApplication80.class, args);}
}

创建配置类 com/rainbowsea/springcloud/config/CustomizationBean.java

特别说明:nacos 本身就集成了 Ribbon, 直接支持 Ribbon+RestTemplate 调用

在这里插入图片描述

package com.rainbowsea.springcloud.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*
配置类
配置注入 RestTemplate bean /对象*/
@Configuration
public class CustomizationBean {// nacos 本身就集成了 Ribbon ,直接支持 Ribbon + RestTemplate 调用/*配置注入 RestTemplate bean /对象这里的 @LoadBalanced 就是赋予 RestTemplate 负载均衡的能力默认是使用轮询算法来访问远程调用接口/地址*/@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}}

创建 com/rainbowsea/springcloud/controller/MemberNacosConsumerController.java

在这里插入图片描述

详细内容如下:

package com.rainbowsea.springcloud.controller;import com.rainbowsea.springcloud.entity.Member;
import com.rainbowsea.springcloud.entity.Result;
import lombok.extern.slf4j.Slf4j;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.List;@RestController
@Slf4j
public class MemberNacosConsumerController {private static final String MEMBER_SERVICE_NACOS_PROVIDER_URL = "http://member-service-nacos-provider"; //// 后面这里地方会修改成提供服务模块的注册别名,可以在 nacos 当中查看到,对应的服务名// 装配 RestTemplate bean/对象@Resourceprivate RestTemplate restTemplate;@Resource // 装配到 Spring ioc 容器当中private DiscoveryClient discoveryClient;@PostMapping("/member/nacos/consumer/save")public Result<Member> save(Member member) {log.info("member-service-consumer-80 save member={}", member);return restTemplate.postForObject(MEMBER_SERVICE_NACOS_PROVIDER_URL + "/member/save", member, Result.class);}// 注意:有两个是这个包下的 : org.springframework.cloud.client.discovery.DiscoveryClient/*** 方法/接口,调用服务接口,返回 member 对象信息** @param id* @return*/@GetMapping("/member/nacos/consumer/get/{id}")public Result<Member> getMemberById(@PathVariable("id") Long id) {// 这里就用两个参数// 第一个参数,因为是查询,所以这里我们直接字符串拼接上去// 这里通过return restTemplate.getForObject(MEMBER_SERVICE_NACOS_PROVIDER_URL + "/member/get/" + id, Result.class);}// 注意:想要获取到服务端信息,还需要在SpringBoot 启动场景上加上:@EnableDiscoveryClient // 启用服务发现 注解才行@GetMapping("/member/consumer/discovery")public Object discovery() {List<String> services = discoveryClient.getServices();// 遍历 servicesfor (String service : services) {log.info("服务名==={}", service);// 再根据服务名获取更加详细的信息List<ServiceInstance> instances = discoveryClient.getInstances(service);for (ServiceInstance instance : instances) {log.info("id={},host={},uri={}", instance.getServiceId(), instance.getHost(), instance.getUri());}}return this.discoveryClient;}
}

启动 Nacos Server 8848
启动 member-service-nacos-provider-10004/10006
启动 member-service-nacos-consumer-80
浏览器: http://localhost/member/nacos/consumer/get/1

浏览器输入: http://localhost/member/nacos/consumer/get/1 注意观察是否轮询调用。

在这里插入图片描述

在这里插入图片描述

同样的,我们也可以不采用 Nacos 默认的 “轮询的负载均衡”,而采用自己自定义的负载均衡的算法。

这里我们配置自己的:配置自己的负载均衡算法——> 这里我们通过配置类 的方式,配置负载均衡算法。如下:

在这里插入图片描述

package com.rainbowsea.springcloud.config;import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*
特别说明: Nacos 不需要额外的在场景启动器上指明该使用的“负载均衡”算法。
因为 Nacos 本身就包含了 这些,直接使用注解即可,直接使用配置类上加上注解就行*/
@Configuration
public class RibbonRule {//配置注入自己的负载均衡算法@Beanpublic IRule myRibbonRule() {
//这里老师返回的是 RandomRule,当然小伙伴也可以自己指定return new RandomRule();}
}

运行测试:查看是否是,随机的负载均衡算法。注意:因为这里我们修改了源码,所以需要重新启动服务。

在这里插入图片描述

3. Spring Cloud Alibaba Nacos AP 和 CP 切换-理论

各种注册中心对比:

在这里插入图片描述

选择 AP 还是 CP

  1. CP: 服务可以不能用,但必须要保证数据的一致性。
  2. AP:数据可以短暂不一致,但最终是需要一致的,无论如何都要保证服务的可用
  3. 取舍:只能在 CP 和 AP 选择一个平衡点,大多数都是选择 AP模式。

Nacos 集群默认支持的是CAP原则中的AP原则,但是也可切换为CP原则(一般不切
换)

  • CURL切换命令: curl -X PUT ‘$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&va lue=CP’
  • URL指令:$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP
  • 参考文档:https://www.jianshu.com/p/c56e22c222bb

4. Spring Cloud Alibaba Nacos 配置中心实例

Nacos 不仅是注册中心 ,也是配置中心 。如下我们进行 Nacos 的配置中心进行操作。

需求分析/图解

在这里插入图片描述

在 Nacos Server 加入配置:

特别说明:不要关闭 Nacos 命令窗口,在浏览器上输入:http://localhost:8848/nacos。账号和密码都是:nacos

核心操作: 进入 Nacos 可视化界面,添加配置信息。如下我们添加:Data ID: e-commerce-nacos-config-client-dev.yaml 的配置。加入配置, 特别提醒: 文件后缀.yaml ,不可以是别的。

在这里插入图片描述

在这里插入图片描述

config:ip: "127.0.0.1"name: "RainbowSea"

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

创建 Nacos 配置客户端模块 e-commerce-nacos-config-client5000

在这里插入图片描述

修改 pom.xml 引入相关 jar 依赖。

在这里插入图片描述

<?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"><parent><artifactId>e-commerce-center</artifactId><groupId>com.rainbowsea</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>e-commerce-nacos-config-client5000</artifactId><!--    引入相关的依赖:我们引入了当前所需要的依赖,后面如果有其它的需要,再灵活添加--><dependencies><!--nacos-config--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--引入 alibaba-nacos-discovery  即场景启动器,使用版本仲裁 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--        引入 web-starter 说明:我们使用版本仲裁(从父项目继承了版本)--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--1. starter-actuator 是sprng boot 程序的监控系统,可以实现健康检查,info 信息等2. 访问http://localhost:10000/actuator 可以看到相关链接,还可以做相关配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--        lombok 引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--        引入 test-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--        引入我们自己对 bean 封装成 api 的模块内容--><dependency><groupId>com.rainbowsea</groupId><artifactId>e_commerce_center-common-api</artifactId><version>${project.version}</version></dependency></dependencies></project>

创建 application.yml。编写配置 Nacos 配置中心的信息。

在这里插入图片描述

spring:profiles:active: dev # 指定环境,常见的环境有 dev(开发)/test(测试)/prod(生产)

特别说明:

  • 开发环境(dev): 开发环境是程序员,专门用于开发的服务器,配置可以比较随意,为了开发调用方便,一般打开全部错误报告。
  • 测试环境(test): 一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把他发布到生产机器上。
  • 生产环境(prod): 是直接正是提供对外服务的,一般会关掉错误报告,打开错误日志。

三个环节也可以说是系统开发的三个阶段:开发->测试->上线,其中生产环境也就是通常说的真实环境。

在 resoures 创建 bootstrap.yml

在这里插入图片描述

server:port: 5000spring:application:#    name: e-commerce-nacos-configname: e-commerce-nacos-config-client# 配置 nacoscloud:nacos:discovery:server-addr: localhost:8848 # 配置服务注册中心地址config:server-addr: localhost:8848 # 配置中心地址file-extension: yaml # 指定yaml格式的配置,配置中心放的配置是 yaml格式的配置#        group: order # 指定 order组,默认DEFAULT_GROUP#        group: search # 指定 seckill组,默认DEFAULT_GROUP
#        namespace: f87c69cd-9fd2-4326-b58a-9a5d326c3af1 # 指定 namespace id 百度的
#        namespace: cd4b7aa7-ae61-4d5d-9eb5-efb29a07f702 # 指定对应 namespace id 阿里的

bootstrap.yml 配置文件编写的说明:

# 解读:
# 1. nacos 配置客户端/当前的微服务模块,会根据配置,找到配置中心的数据(配置文件)
# 2. config.server-addr: localhost:8848 可以找到配置中心
# 3. spring.application.name 对应是 DataId e-commerce-nacos-config
# 4. 在 application.yaml: 配置 spring.profiles.active dev
# 5. spring.cloud.nacos.config.file-extension 配置文件的扩展名 .yaml
# 6. 小结: 根据配置就是到localhost:8848 下的 e-commerce-nacos-config-dev.yaml
# 获取配置信息/数据
# 7. 规则就是:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 来定位配置中心的 Data ID

在这里插入图片描述

业务类:创建 NacosConfigClientController

在这里插入图片描述

package com.rainbowsea.springcloud.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RefreshScope  // 实现配置自动更新: Spring Cloud 原生注解,实现了配置数据的自动刷新
public class NacosConfigClientController {/*特别说明:1. client 会拉取 nacos server 的 e-commerce-nacos-config-client-dev.yaml- config:ip: "122.22.22.22"name: "RainbowSea"2. @Value("${config.ip}") 会将 config.ip 赋给 configIP3. 这里的@"${config.ip}" 不能乱写,要有依据,如果有一点不一致的都会,报错,无法运行的是在: org.springframework.beans.factory.annotation.Value 包下的*///@Value("${config:ip}")  // 使用 : 也是可以的@Value("${config.ip}")  // 使用 : 也是可以的private String configIp;@Value("${config.name}")private String configName;@GetMapping("/nacos/config/ip")public String getConfigIp() {return configIp;}@GetMapping("/nacos/config/name")public String getConfigName() {return configName;}
}

讲解说明:

使用 @Value() 注解的方式,可以获取到 Nacos 配置中心,所配置的信息。

语法:@Value("${config.ip}") 或者是 @Value("${config:ip}"),

@Value(“${config.ip}”), 是 import org.springframework.beans.factory.annotation.Value 包下的内容。

同时特别注意:ip 和 你在 Nacos 当中编写配置的信息是一定必须要保持一致的。一定出现了不一致的问题,便会运行不起来。

    //@Value("${config:ip}")  // 使用 : 也是可以的@Value("${config.ip}")  // 使用 : 也是可以的private String configIp;@Value("${config.name}")private String configName;

在这里插入图片描述

更多配置信息,大家可以移步至:https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

在这里插入图片描述

测试:
启动 Nacos Server
启动 e-commerce-nacos-config-client5000
浏览器: http://localhost:5000/nacos/config/ip

在这里插入图片描述

浏览器输入: http://localhost:5000/nacos/config/name

在这里插入图片描述

4.1 注意事项和细节

  1. @Value(“${config.ip}”), 是 import org.springframework.beans.factory.annotation.Value
  2. 配置文件 application.yml 和 bootstrap.yml 结合会得到配置文件/资源的地址
  3. 参考文档: https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

在这里插入图片描述

  1. 注意在 Nacos Server 的配置文件的后缀是 .yaml , 而不是 .yml
  2. 在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动, 也就是说如果项目不能正确的获取到 Nacos Server 的配置数据,项目是启动不了的。也就是要让你@Value(xxx.xx) 要与在 Nacos Server 的配置数据要保持一致。不然,是无法获取到 Nacos 配置中心当中编写的配置信息,也就是拉取失败了。运行测试。

在这里插入图片描述

  1. @RefreshScope 是 springcloud 原 生 注 解 , 实 现 配 置 信 息 自 动 刷 新 , 如 果 在 Nacos Server 修改了配置数据,Client 端就会得到最新配置。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5. Spring Cloud Alibaba Nacos 分类配置(实现配置隔离)

Nacos 作为一个配置中心,存储着在多个服务之间的配置信息,配置信息之间,需要相互分类,相互隔离开来。

关于 Spring Cloud Alibaba Nacos 分类配置(实现配置隔离) 有三种方案:

  1. DataID 分类配置方案
  2. Group 分类配置方案
  3. Namespace 分类配置方案

友人会说可以通过:config 这样前缀进行分类鸭。

在这里插入图片描述

可以是可以,但是存在一个致命的问题,我们知道一旦我们的服务拉取不到 Nacos 配置中心的配置信息,服务就直接宕机,无法运行了。所以一旦,我们将所以服务的配置信息都配置到一个Nacos 的 yaml 文件当中的话,一旦这个 Nacos 宕机了,那么我们整个微服务就无法使用了。

所以为了提高 我们配置中心的可用性,我们也可以配置多个 Nacos 配置中心,这样一个 Nacos 就无法宕机了,其它的 Nacos 配置依旧可以正常运行。不受影响。

5.1 DataID 分类配置方案

需求分析/图解

在这里插入图片描述

通过创建多个不同的 Data ID 进行隔离,分类配置信息。

如下:

在 nacos server 创建新的配置:

  • e-commerce-nacos-config-client-test.yaml
  • e-commerce-nacos-config-client-dev.yaml

在这里插入图片描述

在这里插入图片描述

修改 application.yml,修改为 test 。这里我们读取 e-commerce-nacos-config-client-test.yaml 的配置信息。

在这里插入图片描述

测试
浏览器: http://localhost:5000/nacos/config/name

在这里插入图片描述
浏览器输入: http://localhost:5000/nacos/config/ip

在这里插入图片描述

5.2 Group 分类配置方案

需求分析/图解

在这里插入图片描述

对于 Nacos 的配置中心的,配置分类,还可以通过 group 组进行分类。

在这里插入图片描述

首先:我们需要进入到 Nacos 服务当中,同时注意:我们对应的 Nacos 的命令窗口不可以关闭。关闭了,则是无法获取到对应上的 Nacos (配置中心)当中的配置信息的,拉取配置信息是失败的,也是无法运行启动的。

在这里插入图片描述

在 nacos server 创建新的配置:Data Id 是为:e-commerce-nacos-config-client-dev.yaml ,分组在 order 当中。

在这里插入图片描述

config:ip : "127.0.0.1 (order) 组当中的 IP "name: "RainbowSea (order) 组当中的 Name" 

在 nacos server 创建新的配置 Data Id 为 e-commerce-nacos-config-client-dev.yaml,分组在: seckill

在这里插入图片描述

config:ip: "127.0.0.1 (seckill) 组当中的 IP"name: "RainbowSea(seckill) 组当中的 Name"

在这里插入图片描述

修改 application.yml 为 dev 开发环境。如下图所示:

在这里插入图片描述

spring:profiles:active: dev # 指定环境,常见的环境有 dev(开发)/test(测试)/prod(生产)

修改 bootstrap.yml;为其增加 group 的分组的参数。如下图所示:

在这里插入图片描述

server:port: 5000spring:application:#    name: e-commerce-nacos-configname: e-commerce-nacos-config-client# 配置 nacoscloud:nacos:discovery:server-addr: localhost:8848 # 配置服务注册中心地址config:server-addr: localhost:8848 # 配置中心地址file-extension: yaml # 指定yaml格式的配置,配置中心放的配置是 yaml格式的配置group: order # 指定 order组,默认DEFAULT_GROUP#        group: search # 指定 seckill组,默认DEFAULT_GROUP
#        namespace: f87c69cd-9fd2-4326-b58a-9a5d326c3af1 # 指定 namespace id 百度的
#        namespace: cd4b7aa7-ae61-4d5d-9eb5-efb29a07f702 # 指定对应 namespace id 阿里的# 解读:
# 1. nacos 配置客户端/当前的微服务模块,会根据配置,找到配置中心的数据(配置文件)
# 2. config.server-addr: localhost:8848 可以找到配置中心
# 3. spring.application.name 对应是 DataId e-commerce-nacos-config
# 4. 在 application.yaml: 配置 spring.profiles.active dev
# 5. spring.cloud.nacos.config.file-extension 配置文件的扩展名 .yaml
# 6. 小结: 根据配置就是到localhost:8848 下的 e-commerce-nacos-config-dev.yaml
# 获取配置信息/数据
# 7. 规则就是:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 来定位配置中心的 Data ID

测试:
浏览器: http://localhost:5000/nacos/config/ip

浏览器输入: http://localhost:5000/nacos/config/name

在这里插入图片描述

5.3 Namespace 分类配置方案

第三种方案,我们可以通过 Namespace 命令空间,进行一个分类配置划分,隔离。

但是其实:是 Namespace 命名空间 + group 组。两个结合起来使用,进行一个隔离,配置分类划分。

需求分析/图解

在这里插入图片描述

在 nacos server 创建新的 namespace , baidu 和 alibaba

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

同时创建 alibaba 的命名空间。如下图所示:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在 nacos server 服务UI界面当中创建,在 alibaba 的命名空间下,创建一个 一个 Data Id 为 e-commerce-nacos-config-client .yaml, group 分组为 : seckill 的配置信息。如下图,所示:

在这里插入图片描述

在这里插入图片描述

config:ip: "127.0.0.1 (阿里巴巴)秒杀开发小组的模块的IP "name: "RainbowSea(阿里巴巴)秒杀开发小组的模块的Name"

同理我们 在 nacos server 服务UI界面当中创建,在 baidu的命名空间下,创建一个 一个 Data Id 为 e-commerce-nacos-config-client .yaml, group 分组为 : search 的配置信息。如下图,所示:

在这里插入图片描述

在这里插入图片描述

修改 application.yaml 的配置信息;修改为 dev 的开发环境的信息。

在这里插入图片描述

spring:profiles:active: dev # 指定环境,常见的环境有 dev(开发)/test(测试)/prod(生产)

修改 bootstrap.yaml 的配置信息,在其中添加上,Namespace 命名空间,Group 的组的配置。如下图所示:

在这里插入图片描述

在这里插入图片描述

浏览器: http://localhost:5000/nacos/config/name
浏览器输入: http://localhost:5000/nacos/config/ip

测试:

在这里插入图片描述

我们再次修改 applicaton.yaml 和 bootstrap.yaml 的配置信息 ,获取到 baidu 所配置的信息。如下图所示:

在这里插入图片描述

重启启动服务器,因为我们修改了相关的配置信息。

浏览器: http://localhost:5000/nacos/config/name
浏览器输入: http://localhost:5000/nacos/config/ip

在这里插入图片描述

5.4 Namespace / Group / Data ID 三种分类配置方式的关系

一图胜千言

在这里插入图片描述

  1. Nacos 默认的命名空间是: public,Namespace 主要用来实现配置隔离,隔离范围大
  2. Group 默认是 DEFAULT GROUP, GROUP 可以把不同的微服务划分到同一个分组里面去
  3. Service 就是微服务,相同的 Service 可以是一个 Cluster(簇/集群),Instance 就是微服务的实例

Nacos的配置管理模型:

数据模型: Nacos 使用的核心数据模型包括 NamespaceGroupData ID ,实现了配置的逻辑隔离和分组管理。

Namespace VS Group

  • Namespace: 是用于逻辑隔离 的最高级别单位,不同的 Namespace 之间是完全隔离的。服务实例,配置等资源都不会在不同的 Namespace 之间共享。
  • Group: 是用于同一 Namespace内 的服务进行进一步分组 的单位。可以用于将同一个 namesapce 中的服务按业务分类或功能模块进行管理,例如:一个 Namespace 可以包含多个 Group ,如 paymentorderinventory 等。

Namespace VS Data ID

  • Data ID: 是 Nacos 配置管理中的概念,表示具体的配置信息项。每个配置项通过 Data ID 来标识,用于管理具体的配置内容。
  • Namespace: 则是用来将多个 Data ID 进行隔离管理的,不同的 Namespace 可以有相同的 Data ID ,但它们所代表的配置信息是独立的。

特别说明:

Nacos 客户端维护一个本地缓存,客户端接受到配置更新后,会自动刷新本地缓存的配置,当与Nacos服务器的连接出现异常或服务器不可用时,可以从本地缓存中读取配置 ,保证系统的基本运行不受影响。这个缓存机制也有助于减少服务器压力,提高系统的可用性。 所以当面试官问你 Nacos 配置中心挂了实例会不会立马收到影响呢,答案是:不会的,因为存在本地缓存的机制。

6. 总结:

  1. 一句话:Nacos 就是注册中心[替代 Eureka] + 配置中心[替代 Config] ,简单的说:Nacos 和 Eureka 是一样的
  2. 特别说明:必须在主启动(场景启动器)类上加上@EnableDiscoveryClient 注解(引用Nacos发现注解),才能启动使用上 Nacos 注册中心
  3. Nacos 不仅是注册中心 ,也是配置中心 。如下我们进行 Nacos 的配置中心进行操作。
  4. 关于 Spring Cloud Alibaba Nacos 分类配置(实现配置隔离) 有三种方案:
    1. DataID 分类配置方案
    2. Group 分类配置方案
    3. Namespace 分类配置方案
  5. 特别注意:设置配置当中的注意事项和细节
  6. Namespace / Group / Data ID 三种分类配置的关系。

7. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux安装部署mysql资料

安装虚拟机 等待检查完成 选择中文 软件选择 网络和主机名 开始安装 设置root密码 ADH-password 创建用户 等待安装完成 重启 接受许可证 Centos 7 64安装完成 安装mysql开始 Putty连接指定服务器 在 opt目录下新建download目录 将mysql文件传到该目录下 查看linux服务器的…

【Python入门】Python数据类型

文章一览 前言一、变量1.1.如何使用变量1.2.如何定义变量的名字&#xff08;标识符&#xff09; 二、数据类型2.1 整型数据2.2 浮点型数据2.3 布尔型&#xff08;bool&#xff09;数据2.4 复数型数据2.5 字符串类型1 > 字符串相加&#xff08;合并&#xff09;&#xff08;&…

MySQL - 表的增删查改

文章目录 1.新增1.1语法1.2单行插入1.3多行插入1.4插入后更新1.5替换 2.查找2.1语法2.2使用 3.修改3.1语法3.2使用 4.删除4.1语法4.2使用4.3截断表 5.插入查询结果5.1语法5.2使用 1.新增 1.1语法 INSERT [INTO] table_name [(column1, column2, ...)] VALUES (value1, value2…

Mac 系统上控制台常用性能查看命令

一、top命令显示 在macOS的控制台中&#xff0c;top命令提供了系统当前运行的进程的详细信息以及整体系统资源的利用情况。下面是对输出中各个字段的解释&#xff1a; Processes: 483 total: 系统上总共有483个进程。 2 running: 当前有2个进程正在运行。 481 sleeping: 当前有…

小程序-基于java+SpringBoot+Vue的微信小程序养老院系统设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

单片机知识总结(完整)

1、单片机概述 1.1. 单片机的定义与分类 定义&#xff1a; 单片机&#xff08;Microcontroller Unit&#xff0c;简称MCU&#xff09;是一种将微处理器、存储器&#xff08;包括程序存储器和数据存储器&#xff09;、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型…

如何监控Elasticsearch集群状态?

大家好&#xff0c;我是锋哥。今天分享关于【如何监控Elasticsearch集群状态&#xff1f;】面试题。希望对大家有帮助&#xff1b; 如何监控Elasticsearch集群状态&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 监控 Elasticsearch 集群的状态对于确保…

命令行使用ssh隧道连接远程mysql

本地电脑A 跳板机B 主机2.2.2.2 用户名 B ssh端口号22 登录密码bbb 远程mysql C 地址 3.3.3.3 端口号3306 用户名C 密码ccc A需要通过跳板机B才能访问C; navicat中配置ssh可以实现在A电脑上访问C 如何实现本地代码中访问C呢? # 假设本地使…

Rook入门:打造云原生Ceph存储的全面学习路径(下)

文章目录 六.Rook部署云原生CephFS文件系统6.1 部署cephfs storageclass6.2 创建容器所需cephfs文件系统6.3创建容器pod使用rook-cephfs提供pvc6.4 查看pod是否使用rook-cephfs 七.Ceph Dashboard界面7.1 启用dashboard开关7.2 ceph-dashboard配置外部访问7.3 Dashboard web ad…

知识库助手的构建之路:ChatGLM3-6B和LangChain的深度应用

ChatGLM3-6B和LangChain构建知识库助手 安装依赖库 使用pip命令安装以下库&#xff1a; pip install modelscope langchain0.1.7 chromadb0.5.0 sentence-transformers2.7.0 unstructured0.13.7 markdown3.0.0 docx2txt0.8 pypdf4.2.0依赖库简介&#xff1a; ModelScope&a…

面经-综合面/hr面

面经-综合面/hr面 概述1.大学期间遇到的困难&#xff0c;怎么解决的2. 大学期间印象最深/最难忘的是什么3. 大学里面担任了什么职务没&#xff1f;做了什么工作&#xff1f;4. 大学最大的遗憾是什么&#xff1f;5. 对自己的未来规划6. 对自己的评价7. 自己的优缺点8. 对公司的认…

群控系统服务端开发模式-应用开发-邮箱配置功能开发

邮箱配置主要是将管理员数据做归属。具体见下图&#xff1a; 一、创建表 1、语句 CREATE TABLE cluster_control.nc_param_mail (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 编号,title varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT…

sd webui整合包怎么安装comfyui

环境: sd webui整合包 comfyui 问题描述: sd webui整合包怎么安装comfyui 扩展安装不成功 解决方案: 1.直接下载 ,解压到SD文件夹里(或者git拉一下) 2.ComfyUI模型共享:如果本机部署过Webui,那么ComfyUI可以与WebUI公用一套模型,防止复制大量模型浪费空间 将…

python基础(二)

函数 函数定义 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一或相关联功能的代码段。 python函数定义规则&#xff1a; def my_max(a,b): #定义函数用def关键字开头&#xff0c;函数名-》my_max ()定义参数 if a>b: #函数体以&#xff1a…

【Springboot入门知识总结】

SpringBoot Web入门 一.Spring1.springBoot入门程序2.Spring官方脚手架连接不上的解决方案3.为什么一个main方法就将web应用 二. HTTP协议1.http协议的概念和特点2.Get请求和Post请求的区别3.http响应状态码分类4.获取http的参数 三.springBoot中的常用注解四.分层解耦五.总结 …

华为IPD流程学习之——深入解读123页华为IPD流程体系设计方法论PPT

该方案全面介绍了华为IPD流程体系设计方法论&#xff0c;包括流程体系建设的背景、理念、架构、核心特征、构建模型、与组织和战略的关系、运营机制、数字化转型以及流程管理组织等内容&#xff0c;旨在为企业提供一套系统的流程体系建设指导&#xff0c;以提升运营效率、质量和…

使用docker搭建hysteria2服务端

原链接&#xff1a;https://github.com/apernet/hysteria/discussions/1248 官网地址&#xff1a;https://v2.hysteria.network/zh/docs/getting-started/Installation/ 首选需要安装docker和docker compose 切换到合适的目录 cd /home创建文件夹 mkdir hysteria创建docke…

力扣hot100

文章目录 力扣hot100-哈希题目&#xff1a;两数之和方法1-暴力方法2-哈希 题目&#xff1a;字母异位词分组题解 题目&#xff1a;最长连续序列题解解释代码 力扣hot100-双指针题目&#xff1a;移动零题解 题目&#xff1a;盛最多水的容器题解 题目&#xff1a;三数之和题解 题目…

Scala身份证上的秘密以及Map的遍历

object test {def main(args: Array[String]): Unit {val id "42032220080903332x"//1.生日是&#xff1f;//字符串截取val birthday id.substring(10,14) //不包括终点下标println(birthday)val year id.substring(6,10) //println(year)//性别&#xff1a;倒数第…

设置ip和代理DNS的WindowsBat脚本怎么写?

今天分享一个我们在工作时&#xff0c;常见的在Windows中通过批处理脚本&#xff08;.bat 文件&#xff09;来设置IP地址、代理以及DNS 相关配置的示例&#xff0c;大家可以根据实际需求进行修改调整。 一、设置静态IP地址脚本示例 以下脚本用于设置本地连接&#xff08;你可…