SpringCloud Alibaba - Eureka注册中心,Nacos配置中心

Eureka

1、创建服务端

bash 复制代码
server:
  port: 8761 # eureka 默认端口

spring:
  application:
    name: eureka-server # 应用名称(微服务中建议必须定义应用名称)
java 复制代码
@SpringBootApplication
@EnableEurekaServer // 开启eureka注册中心功能
public class EurekaServerApplication {

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

}

2、创建客户端

bash 复制代码
# 应用服务 WEB 访问端口
server:
  port: 8080

spring:
  application:
    name: eureka-client-a

eureka:
  client:
    service-url: # 指定注册地址
      defaultZone: http://localhost:8761/eureka
java 复制代码
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientBApplication {

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

}
bash 复制代码
# 应用服务 WEB 访问端口
server:
  port: 8081

spring:
  application:
    name: eureka-client-b

eureka:
  client:
    service-url: # 指定注册地址
      defaultZone: http://localhost:8761/eureka

服务端(注册中心)配置

服务端(注册中心)配置需要考虑的问题:

  • 在注册中心维护一个容器列表,保存服务应用的信息
  • 应用下线以后,及时从容器中移除
  • 应用之间访问应该向注册中心缓存一份服务列表,但是如何避免脏读问题
java 复制代码
server:
  port: 8761 # eureka 默认端口

spring:
  application:
    name: eureka-server # 应用名称(微服务中建议必须定义应用名称)

# eureka 配置分为三类:server client 实例
eureka:
  server:
    eviction-interval-timer-in-ms: 10000 # 服务端每隔10s做定期删除工作(删除过期服务)
    renewal-percent-threshold: 0.85 # 续约百分比阈值(超过85%的服务没有续约,那么eureka会保护服务 不糊剔除任何一个)
  instance: # 实例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} # 主机名称:应用名称:端口号
    hostname: localhost # 主机名称或者服务的ip
    prefer-ip-address: true # 以 ip 的形式显示具体的服务信息
    lease-renewal-interval-in-seconds: 5 # 实例的续约时间间隔

客户端配置

java 复制代码
# 应用服务 WEB 访问端口
server:
  port: 8080

spring:
  application:
    name: eureka-client-a

eureka:
  client:
    service-url: # 指定注册地址
      defaultZone: http://localhost:8761/eureka
    register-with-eureka: true # 可以不向 eureka 注册服务
    fetch-registry: true # 是否缓存一份服务列表到本地
    registry-fetch-interval-seconds: 10 # 拉取的时间间隔(缓解服务列表脏读的问题)
  instance:
    hostname: localhost # 主机或ip
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
    prefer-ip-address: true # 显示ip
    lease-renewal-interval-in-seconds: 10 # 续约的时间

构建 eureka-server 集群

eureka 是一种非主从模式的去中心化的集群模式,多个节点之间互相注册同步自己的服务列表;下面我们除了上面创建好的 eureka-server(8761),再创建两台服务端(注册)节点:

  • 需要在这3个服务端都配置注册地址(添加除自己之外的注册地址,相当于把自己当做一个 client)

创建 eureka-server-b:

bash 复制代码
server:
  port: 8762 # eureka 默认端口

spring:
  application:
    name: eureka-server # 应用名称(微服务中建议必须定义应用名称)

# eureka 配置分为三类:server client 实例
eureka:
  instance: # 实例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} # 主机名称:应用名称:端口号
    hostname: localhost # 主机名称或者服务的ip
    prefer-ip-address: true # 以 ip 的形式显示具体的服务信息
    lease-renewal-interval-in-seconds: 5 # 实例的续约时间间隔
  client:
    service-url: # 指定注册地址
      defaultZone: http://localhost:8761/eureka,http://localhost:8763/eureka

创建 eureka-server-c:

bash 复制代码
server:
  port: 8763 # eureka 默认端口

spring:
  application:
    name: eureka-server # 应用名称(微服务中建议必须定义应用名称)

# eureka 配置分为三类:server client 实例
eureka:
  instance: # 实例的配置
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} # 主机名称:应用名称:端口号
    hostname: localhost # 主机名称或者服务的ip
    prefer-ip-address: true # 以 ip 的形式显示具体的服务信息
    lease-renewal-interval-in-seconds: 5 # 实例的续约时间间隔
  client:
    service-url: # 指定注册地址
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka

给 eureka-server-b 和 eureka-server--c 添加注解: @EnableEurekaServer

Nacos 和 Eureka 区别:

  • nacos 有命名空间的概念来隔离不同项目中相同的服务名称,但是 eureka 并不能隔离开(可以通过服务名称拼接项目名称的方式来隔离)

修改 application.yml:

bash 复制代码
server:
  port: 8080

spring:
  application:
    name: nacos-client-a
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # 向这个地址注册自己
        username: nacos
        password: nacos

添加 @EnableDiscoveryClient 注解:

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现客户端
public class NacosClientAApplication {

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

}

注意 SpringBoot 和 SpringCloud Alibaba 版本对应 :版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub

配置中心

1、nacos 创建配置:

2、编写 SpringBoot配置文件 bootstrap.yml:

bash 复制代码
server:
  port: 8081

spring:
  application:
    name: nacos-config-a
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        prefix: nacos-config-a # dataId 默认选择 spring.application.name
        file-extension: yml # 配置文件的格式
#        namespace: # 默认 public
#        group: # 默认 DEFAULT_GROUP

这里的 prefix 就相当于是 data id (应用名称),将来就是配置文件的名称

3、编写测试类

注意:这里写得并不标准,实际开发中的写法看下面的动态配置刷新章节

java 复制代码
@RestController
public class TestController {

    @Value("${hero.name}")
    private String name;

    @Value("${hero.age}")
    private Integer age;

    @Value("${hero.address}")
    private String address;

    @GetMapping("/info")
    public String getInfo(){
        return name+":"+age+":"+address;
    }

}

4、测试

动态配置刷新

实现配置动态刷新很简单,添加注解 @RefreshScope 即可,具体添加的位置:

如果是上面的代码,可以直接添加在 controller 类上,因为下面就是我们的配置属性:

java 复制代码
@RestController
@RefreshScope
public class TestController {

    @Value("${hero.name}")
    private String name;

    @Value("${hero.age}")
    private Integer age;

    @Value("${hero.address}")
    private String address;

    @GetMapping("/info")
    public String getInfo(){
        return name+":"+age+":"+address;
    }

}

但是我们一般会添加在配置类Bean上面:

1、编写配置类

上面我们直接在 controller 中使用 @Value 来读取配置,实际开发中我们一般会单独创建一个配置类。创建 config 包,并创建 Hero 这个配置类:

1.1、写法1(推荐)

这里我们使用 @ConfigurationProperties + @Component 实现配置类的注入

java 复制代码
package com.lyh.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@RefreshScope
@ConfigurationProperties(prefix = "hero")
public class Hero {
    private String name;

    private Integer age;

    private String address;
}

使用 @ConfigurationProperties 注解需要添加该依赖:

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

1.2、写法2

使用 @Value + @Component 实现自动注入

java 复制代码
package com.lyh.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@RefreshScope
public class Hero {
    @Value("${hero.name}")
    private String name;

    @Value("${hero.age}")
    private Integer age;

    @Value("${hero.address}")
    private String address;
}

2、编写 controller

java 复制代码
@RestController
public class TestController {

    @Autowired
    private Hero hero;

    @GetMapping("/info")
    public String getInfo(){
        return hero.getName()+":"+hero.getAge()+":"+hero.getAddress();
    }

}

3、测试即可

配置回滚

配置文件的读取方式

nacos 配置中心通过 namespace,dataId 和 group 来唯一确定一条配置。

  • namespace:默认 public
  • dataId:配置文件名称
  • group:组别,默认是 DEFAULT_GROUP

其中,dataId 是最重要的配置,格式为:

{prefix}-{spring.profiles.active}.${file-extension}

注意 :在web控制台在写 dataId 时一定要添加文件类型后缀,比如:nacos-config-dev.yml

一个项目中读取多个配置文件(extension-configs)

注意:目前一个项目中要读取多个配置文件只支持在一个命名空间下!

如何读取相同 命名空间下不同组的配置文件:

编辑配置:

共享配置文件(shared-configs)

比如多个项目都需要操作同一个数据源(比如 mybatis,redis),那么我们可以通过共享配置文件把数据源统一进行管理。

现在我们在 nacos 创建一个共享文件:application.yml 。

写法1(不能修改 group,只能在默认组):

bash 复制代码
server:
  port: 8082
spring:
  application:
    name: nacos-config-test
  cloud:
    nacos:
      config:
        namespace: 19519eb4-c512-4907-9127-9bda8a575125
        group: A_GROUP
        username: nacos
        password: nacos
        server-addr: localhost:8848
        file-extension: yml
        prefix: user-center
        shared-configs:
          - application-dev.yml # 这种写法只能在 DEFAULT_GROUP
  profiles:
    active: dev

写法2(可以修改组)

bash 复制代码
server:
  port: 8082
spring:
  application:
    name: nacos-config-test
  cloud:
    nacos:
      config:
        namespace: 19519eb4-c512-4907-9127-9bda8a575125
        group: A_GROUP
        username: nacos
        password: nacos
        server-addr: localhost:8848
        file-extension: yml
        prefix: user-center
        shared-configs:
          - dataId: application-dev.yml
            group: A_GROUP
            refresh: true
相关推荐
Scott9999HH2 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大7 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json