二:Nacos介绍及应用

160 阅读8分钟

1 Nacos介绍

Nacos是一个集注册中心-配置中心+服务管理平台(可视化的管理一些配置)于一体的平台。 Nacos的关键特性包括

  • 服务发现和服务健康监测
  • 动态配置服务
  • 动态DNS服务
  • 服务及其元数据管理(服务名称,服务远程地址,服务命名空间)

2 Nacos注册中心

管理所有的微服务,解决微服务之间调用关系的错综复杂、难以维护的问题

2.1 注册中心演变及其设计思想

2.1.1 原始的远程调用

假设当前业务是一个会员服务需要调用订单服务,拉取订单列表。使用spring提供的RestTemplate进行远程调用,如下代码所示,需要写远程服务的IP地址及端口号。

String url="http:/ip:port/order/findOrderByUserID/"+id;
ResponseEntity<List> responseEntity = restTemplate.getForEntity(url,List.class);
List<Order> orderList = responseEntity.getBody();

RestTemplate直接发起http远程调用,根据url。

  • 存在问题是订单服务的ip:port变更,需要修改代码。且修改代码后需要重新进行服务的重新部署、发布、上线

image.png

2.1.2 注册表

手动维护一份注册表以 解决上面问题,可以将服务地址注册到远程数据库或者注册表中,为防止每次请求的时候都要远程查询请求地址,可以在本地添加服务缓存。

  • 存在问题是,当服务进行水平扩容的问题及某个服务宕机无法感知。 image.png 为实现负载均衡,以前是引入Nginx 存在问题是成百上千个微服务的nginx配置文件会很复杂,运维困难。 当某个服务宕机时,nginx不能实现服务的状态监测 健康检查。(可以与引入第三方服务,但是较为麻烦)

image.png

2.1.3 注册中心

为实现服务的注册于发现,可以使用注册中心。注册中心可以需要单独的下载和启动,才能把服务注册进去。接口都是注册中心提供的。 注册中心有一个注册表,注册表存储服务元数据及其状态如下表所示。

image.png 思考:

  • 每次都要去注册中心拉取地址吗?可以在本地设置缓存。客户端定期拉取注册中心的服务列表,保证本地缓存的服务都是最新可用的。
  • 注册中心宕机了怎么办?心跳机制 服务在进行注册后,会定期的向注册中心发送心跳,证明当前服务在线可用。一旦没有发送心跳,当前服务可能存在问题,不可用,注册中心会将当前服务的状态修改为down。 当服务需要下线时,可用进行注销,停止服务,调用注销接口。

image.png 上图也就是Nacos的整体流程图。Nacos中重要的时服务发现

2.1.4 Nacos Discovery

Nacos discovery。每一个微服务都是Nacos的客户端。 服务发现是微服务架构中最关键的组件之一,手动为每一个客户端配置所有服务提供者的服务列表是很麻烦的,且不易服务的动态扩容和缩容。Nacos discover stater可帮助将服务自动注册到Nacos服务端,并且动态感知和刷新某个服务实例的服务列表。和springboot一样,通过导入一个stater,就可以一键启动。

<dependency> 
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId> 
<version>${latest.version}</version> </dependency>

3 Nacos核心功能

  • 服务注册:Nacos Client通过发送REST请求的方式向Nacos Server注册自己的服务,提供自己的元数据,(ip,端口号等信息),Server接收到后将这些信息存储在一个双层的Map中
  • 服务心跳:服务注册后,Nacos Client会维护一份定时心跳来持续通知Nacos Sever,说明服务一直处于可用状态,防止被剔除,默认5s发送一次心跳
  • 服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。leader raft
  • 服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取注册的服务清单,并缓存到本地,同时在本地开启一个定时任务拉取服务端最新的注册表信息更新本地缓存。
  • 服务健康检查:Nacos Serer开启一个定时任务检查注册的服务实例的健康状况,超过15秒没有收到心跳,则将健康状态置为False,超过30秒则直接剔除,(剔除的实例如果恢复心跳,则会重新注册)

4 主流的注册中心

CAP C一致性 A可用性 P分区容错性

Eureka是Netflix的,已经不再更新了,Zookeeper可以集成第三方的组件。Nacos是实现最全的,负载均衡也可以集成其他组件。 image.png

5 Nacos Server部署

参考 nacos.io/en-us/docs/… nacos.io/zh-cn/docs/… 在windows上部署。

  • 下载Nacos的源码,放到指定的盘。
git clone https://github.com/alibaba/nacos.git

(截图的cmd默认在C盘打开,下载后移动到指定盘或者在指定位置打开cmd进行下载。)

image.png

  • 进入 /nacos目录
cd nacos/
  • 使用Apache Maven构建Nacos 项目。
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
  • mvn: 表示执行Maven命令。
  • -Prelease-nacos: 激活名为"release-nacos"的Maven配置文件中定义的配置项。这通常用于指定不同的构建配置,例如发布版本的构建配置。
  • -Dmaven.test.skip=true: 跳过执行测试。通常在构建过程中,会执行项目中的测试代码,但使用该参数可以跳过测试的执行。
  • clean install: 清理之前构建的文件,并重新执行整个构建过程,包括编译、测试和打包等。
  • -U: 强制从远程仓库下载最新的依赖项。

项目构建完成后,进入如下目录开始启动 image.png

Server默认的端口号是server.port=8848,可在application.properties文件中进行修改 image.png 进入bin目录,使用命令如下,以单机模式启动服务

startup.cmd -m standalone

image.png

image.png 可通过启动时显示的网址进行管理平台的访问,按照官方文档配置启动,默认是不需要登录的。

image.png 登陆鉴权参考nacos.io/zh-cn/docs/…

6 Nacos Client部署

6.1 分布式架构Demo

Demo地址:github.com/zljya/sprin…

我们写一个订单服务和一个库存服务,当生成一个订单时,要对库存做相应的修改。此时订单服务需要远程调用库存服务。Restful风格的调用时,Spring 提供了RestTemplate可以实现服务的远程调用。 官方推荐采用Builder的方式去构造RestTemplate

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
    //Builder模式,官方推荐这样构造template
    RestTemplate restTemplate = builder.build();
    return restTemplate;
}

假设库存的接口为

@RestController
@RequestMapping("/stock")
public class StockController {
    @RequestMapping("/reduce")
    public String reduce(){
        System.out.println("减少库存");
        return "库存减少成功";
    }
}

则订单接口在调用库存服务时,可以直接注入RestTemplate

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    RestTemplate restTemplate;
    @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功");
        String msg = restTemplate.getForObject("http://localhost:8081/stock/reduce",String.class);
        return "hello world"+msg;
    }
}

但是我们发现,当订单服务调用库存服务时,请求地址是固定的,必须要维护远程服务地址,当库存服务进行负载均衡或者服务下架、服务扩展等造成IP地址发生变化,会影响订单服务。当各种各样的服务增加,调用错综复杂,无法管理。因此便可以采用一个注册中心,来进行服务的动态调用。 因此SOA采用了一个治理中心,只需要通过服务名称便可以调用远程服务。微服务架构对治理中心进行了组件化,形成了微服务架构中的一个组件,称为注册中心。

6.2 使用Nacos改进Demo

Demo地址:github.com/zljya/sprin…

需要在父POM文件中加入springcloudalibaba,spring boot和springcloud的依赖, 版本之间的对应参照  github.com/alibaba/spr…

image.png 同时在子模块中添加依赖 image.png

同时在配置文件进行服务注册和发现的配置修改修改

image.png

order-nacos和stock-nacos模块启动后,显示注册完成 image.png

服务成功注册到nacos后,管理界面成功显示对应的服务。

image.png

可点击详情查看服务的元数据

image.png

当我们直接访问order服务时,会报错500如下,

image.png 因为Nacos无法直接解析服务地址,需要依靠负载均衡器介绍服务名称,需要添加@LoadBalanced进行负载均衡。

@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder){
    //Builder模式,官方推荐这样构造template
    RestTemplate restTemplate = builder.build();
    return restTemplate;
}

当还报上述错误时,需要在pom文件中添加相应的LoadBalancer依赖。

因为老版本的springcloud(2021之前的版本)默认使用ribbon,nacos-discovery自动依赖ribbon,参考解释www.cnblogs.com/minejava/p/…

新版本已移除ribbon需要添加spring-cloud-starter-loadbalancer依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

就能成功访问

image.png

默认采用轮询的负载均衡机制,轮着调用每一个服务。