Skip to content
On this page

Nacos

nacos.jpg

Nacos 更加全能的注册中心

Nacos(Naming Configuration Service)是一款阿里巴巴开源的服务注册与发现、配置管理的组件,相当于是Eureka+Config的组合形态。

安装与部署

Nacos服务器是独立安装部署的,因此我们需要下载最新的Nacos服务端程序,下载地址:下载地址,但是我们采用docker 的方式去安装nacos 。这里还是参考官网的部署方式文档地址

Clone 项目

shell
git clone https://github.com/nacos-group/nacos-docker.git
cd nacos-docker
1
2

单机模式 Derby

shell
docker-compose -f example/standalone-derby.yaml up
1

服务注册与发现

现在我们要实现基于Nacos的服务注册与发现,那么就需要导入SpringCloudAlibaba相关的依赖,我们在父工程将依赖进行管理:

xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!-- 这里引入最新的SpringCloud依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- 这里引入最新的SpringCloudAlibaba依赖,2021.0.1.0版本支持SpringBoot2.6.X -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

将项目改造成springcloud 项目导入依赖

xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
1
2
3
4

添加配置文件,将服务注册到nacos上

yaml
spring:
  cloud:
    nacos:
      discovery:
        # 配置Nacos注册中心地址
        server-addr: 172.31.2.27:8848
        # 自定义的名称空间
        namespace: '20057d6f-05e4-49a5-941e-5044fdda1fbf'
1
2
3
4
5
6
7
8

正常启动项目,查看nacos

微信图片编辑_20221017102231.jpg

在服务调用方使用openfeign 和之前一样编写接口和

xml
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- 这里需要单独导入LoadBalancer依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11

启动类添加注解@EnableFeignClients

java
@SpringBootApplication
@EnableFeignClients
public class BorrowApplication {
    public static void main(String[] args) {
        SpringApplication.run(BorrowApplication.class, args);
    }
}
1
2
3
4
5
6
7
java
@FeignClient("service-user")
public interface UserClient {
    
    @RequestMapping("/user/{uid}")
    User getUserById(@PathVariable("uid") int uid);
}
1
2
3
4
5
6

修改实现类

java
public class BorrowServiceImpl implements BorrowService {

    @Resource
    private BorrowMapper mapper;

    @Resource
    UserClient userClient;

    @Resource
    BookClient bookClient;

    @Override
    public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
        List<Borrow> borrow = mapper.getBorrowsByUid(uid);

        //RestTemplate支持多种方式的远程调用
        RestTemplate template = new RestTemplate();
        //这里通过调用getForObject来请求其他服务,并将结果自动进行封装
        //获取User信息
        User user = userClient.getUserById(uid);
        //获取每一本书的详细信息
        List<Book> bookList = borrow
                .stream()
                .map(b -> bookClient.getBookById(b.getBid()))
                .collect(Collectors.toList());
        return new UserBorrowDetail(user, bookList);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

临时实例

Nacos区分了临时实例和非临时实例:

微信截图_20221017103335.png

  • 临时实例:和Eureka一样,采用心跳机制向Nacos发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息。
  • 非临时实例:由Nacos主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为false,相当于会对某个实例状态持续地进行监控。

我们可以通过配置文件进行修改临时实例:

yaml
spring:
  application:
    name: service-user
  cloud:
    nacos:
      discovery:
        server-addr: 172.31.2.27:8848
        # 将ephemeral修改为false,表示非临时实例
        ephemeral: false
1
2
3
4
5
6
7
8
9

将服务下线后不会将服务删除

微信图片编辑_20221017103916.jpg

集群分区

在一个分布式应用中,相同服务的实例可能会在不同的机器、位置上启动,比如我们的用户管理服务,可能在成都有1台服务器部署、重庆有一台服务器部署,而这时,我们在成都的服务器上启动了借阅服务,那么如果我们的借阅服务现在要调用用户服务,就应该优先选择同一个区域的用户服务进行调用,这样会使得响应速度更快。

因此,我们可以对部署在不同机房的服务进行分区,可以看到实例的分区是默认:

yaml
spring:
  cloud:
    nacos:
      discovery:
        # 配置Nacos注册中心地址
        server-addr: 172.31.2.27:8848
        # 名称空间
        namespace: '20057d6f-05e4-49a5-941e-5044fdda1fbf'
        # 是否为临时示例 false: 非临时示例
        ephemeral: false
        # 集群分区
        cluster-name: Shanghai
1
2
3
4
5
6
7
8
9
10
11
12

7859B58E-081A-4242-A21D-C38B10C5B8AD.png

必须要提供Nacos的负载均衡实现才能开启区域优先调用机制,只需要在配制文件中进行修改即可:

yaml
spring:
  cloud:
    nacos:
      discovery:
        # 配置Nacos注册中心地址
        server-addr: 172.31.2.27:8848
        namespace: '20057d6f-05e4-49a5-941e-5044fdda1fbf'
        # 是否为临时示例 false: 非临时示例
        ephemeral: false
        # 集群分区
        cluster-name: Shanghai
    # 将loadbalancer的nacos支持开启,集成Nacos负载均衡
    loadbalancer:
      nacos:
        enabled: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

配置中心

bootstrap.yml中配置远程配置文件获取,然后再进入到配置文件加载环节,而Nacos也支持这样的操作,使用方式也比较类似,比如我们现在想要将借阅服务的配置文件放到Nacos进行管理,那么这个时候就需要在Nacos中创建配置文件:

yaml
spring:
  application:
    name: service-borrow
  cloud:
    nacos:
      config:
        server-addr: 172.31.2.27:8848
        namespace: '20057d6f-05e4-49a5-941e-5044fdda1fbf'
        # 配置文件后缀名
        file-extension: yml
1
2
3
4
5
6
7
8
9
10

Nacos还支持配置文件的热更新,比如我们在配置文件中添加了一个属性,而这个时候可能需要实时修改,并在后端实时更新。

java
@RestController
@RefreshScope
public class TestController {
    
    @Value("${test.txt}")  //我们从配置文件中读取test.txt的字符串值,作为test接口的返回值
    String txt;
    
    @RequestMapping("/test")
    public String test(){
        return txt;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

Released under the MIT License.