什么是Nacos

即注册中心+配置中心+服务管理平台

Nacos注册中心

管理所有微服务,解决微服务之间繁琐的调用,难以维护的问题。

注册中心的演变思路

最开始的时候,我们需要维护每一个微服务的远程调用地址,例如:

  1. String msg = restTemplate.getForObject("http://localhost:8011/stock/reduce", String.class);

一旦该服务器的地址发生了变化,那么在代码中就需要手动修改地址,重新发布,非常麻烦。

优化方式1:将地址放进数据库中,维护数据库中的地址即可。

该优化方式保证了业务代码不需要进行修改,而是从数据库中读取地址。那么地址变化的时候只需要修改数据库中的地址即可。

缺点:

  • 每次请求都需要读取一次数据库
  • 实现负载均衡很麻烦

优化方式2:用Nginx来维护服务地址列表

缺点:

  • 没有健康检查,也就是说当某个服务宕机以后,Nginx并不知道,因此仍然会向该服务地址发起请求
  • 成百上千的微服务地址都配置在Nginx的配置文件中,维护起来非常麻烦,运维心态爆炸。

优化方式3:注册中心

image.png

  • 采用心跳机制来判断是否服务是否健康,5S没心跳就把Status改成Down,30S没心跳就删除掉该服务
  • 不再使用Nginx做负载均衡,而是采用客户端的负载均衡。

Nacos的功能

首先明确:

  • 每一个Nacos微服务称之为Nacos Client;
  • 微服务注册在Nacos server中。

功能:

  • 服务注册:Nacos client通过发送REST请求的方式向Nacos server注册自己的服务,提供自身的元数据,比如IP,端口等。Nacos Server 会将这些元数据保存在内存的Map中
  • 服务心跳:即Nacos client每隔5秒会向Nacos Server发送心跳请求,确保Nacos Server知道自己还活着
  • 服务同步:Nacos Server是一个集群,互相会同步服务实例,保证信息一致性;
  • 服务发现:待定
  • 服务健康检查:Nacos Server会开启一个定时任务用来检查服务实例的健康情况,15S没收到心跳就将healthy改成false, 30S没收到心跳就剔除该服务。

Nacos Server的部署

下载

首先,下载对应版本的Nacos,我们使用的是SpringCloud Alibaba 2.2.6版本,因此要下载1.4.2的Nacos
image.png

单机下的启动

下载后解压,进入到bin目录下,右键startup.cmd,编辑。

set MODE="cluster"改成set MODE="standalone".

Nacos Client的部署

修改Springboot项目的版本(根据下方的版本依赖来修改)
image.png

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.3.2.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>

在父项目中添加依赖:

<dependencyManagement>
  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Hoxton.SR9</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>2.2.6.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

在子项目中分别添加依赖:

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

在application.yml中配置:

spring:
  application:
    name: stock-service
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        username: nacos
        password: nacos
        namespace: public

启动项目:发现日志中有nacos注册的info
image.png

访问本地的nacos访问地址,发现注册成功:
image.png

通过以下方式进行微服务之间的调用(不再是写死的IP地址,而是服务名称):

String msg = restTemplate.getForObject("http://stock-service/stock/reduce", String.class);

此时如果访问[http://localhost:8010/order/add](http://localhost:8010/order/add)会报500的错误,这是因为没有添加负载均衡器,根据下图可以看到,服务间的调用是需要通过负载均衡器的。Nacos本身是无法解析服务名称的。
image.png

所以我们需要给RestTemplate加上@LoadBalanced注解:

@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    RestTemplate restTemplate = builder.build();
    return restTemplate;
}

然后重启项目,重新访问,访问成功:
image.png