Nacos是一个基于云原生思想构建的动态服务发现、配置管理和服务管理平台。主要作用是提供服务注册、发现和配置管理等功能,为微服务架构提供支持。
实现原理:
Nacos主要由两部分组成:命名空间和实例。命名空间用于隔离不同的环境和应用,实例用于标识一个服务提供者或消费者。Nacos通过注册中心的方式实现服务发现,当服务提供者启动时,会向Nacos注册中心注册服务,消费者通过向Nacos注册中心查询服务列表来实现服务发现。同时,Nacos还提供了配置管理的功能,应用可以动态获取配置信息,当配置信息发生变化时,Nacos会自动通知应用进行更新。
底层实现:
Nacos底层采用了Raft算法实现了高可用的服务注册和服务发现。同时,Nacos还提供了一些插件,如DNS解析、灰度发布、流量管理等,可以根据具体业务需求进行扩展。
作用:
Nacos提供了服务注册、发现和配置管理等功能,可以帮助应用实现动态的服务发现和配置管理,为微服务架构提供支持。同时,Nacos还提供了高可用、可扩展、可插拔的架构设计,可以满足不同的业务需求。
示例代码:
以下是一个基于Spring Cloud的服务注册和发现的示例代码:
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件
spring.application.name=example-service
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
服务提供者示例代码
@RestController
public class ExampleController {
@GetMapping("/hello")
public String hello() {
return "Hello, Nacos!";
}
}
服务消费者示例代码
@RestController
public class ExampleController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello")
public String hello() {
String url = "http://example-service/hello";
return restTemplate.getForObject(url, String.class);
}
}
服务注册:Nacos Client 会通过发送 REST 请求的方式向 Nacos Server 注册自己的服务,提供自身的元数据,比如ip地
址、端口等信息。Nacos Server 接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。
服务心跳:在服务注册后,Nacos Client 会维护一个定时心跳来持续通知 Nacos Server,说明服务一直处于可用状态,防
止被剔除。默认5s发送一次心跳。
服务同步:Nacos Server 集群之间会互相同步服务实例,用来保证服务信息的一致性。
服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面
注册的服务清单,并且缓存在 Nacos Client 本地,同时会在 Nacos Client 本地开启一个定时任务定时拉取服务端最新的注
册表信息更新到本地缓存。
服务健康检查:Nacos Server 会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳
的实例会将它的 healthy 属性置为 false (客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该
实例(被剔除的实例如果恢复发送心跳则会重新注册)。
可以设置为0-1之间的浮点数,它其实是⼀个⽐例值(当前服务健康实例数/当前服务总实例数)。
⼀般流程下, nacos是服务注册中⼼,服务消费者要从nacos获取某⼀个服务的可⽤实例信息,对于服务实例有健康/不健康状态之分, nacos在返回给消费者实例信息的时候,会返回健康实例。这个时候在⼀些⾼并发、⼤流量场景下会存在⼀定的问题。
假如现在有一个服务,本来有10个实例,但是现在挂掉了8个,剩下2个正常实例,此时本来由10个实例处理的流量,就全部交给这个两个正常实例来处理了,此时这两个实例很有可能是处理不过来的,最终导致被压垮,为了应对这种情况,Nacos提供了保护阈值这个功能,我们可以给某个服务设置一个0-1的阈值,比如0.5,那就表示,一旦实例中只剩下一半的健康实例了,比如10个实例,只剩下5个健康实例了,那么消费者在进行服务发现时,则会把该服务的所有实例,也包括不健康的实例都拉取到本地,然后再从所有实例中进行负载均衡,选出一个实例进行调用,在这种情况下,选出来的即可能是一个健康的实例,也可能是挂掉的实例,但是通过这种方式,很好的保护的剩下的健康实例,至少保证了一部分请求能正常的访问,而不至于所有请求都不能正常访问,这就是Nacos中的保护阈值,同时,这个功能在Spring Cloud Tencent中叫全死全活。
当服务A健康实例数/总实例数 < 保护阈值 的时候,说明健康实例真的不多了,这个时候保护阈值会被触发(状态true)。
nacos将会把该服务所有的实例信息(健康的+不健康的)全部提供给消费者,消费者可能访问到不健康的实例,请求失败,但这样也⽐造成雪崩要好,牺牲了⼀些请求,保证了整个系统的⼀个可⽤。
Nacos的负载均衡指的是,在进行服务发现时进行负载均衡,正常情况下,在进行服务发现时,会根据服务名从Nacos中拉取所有的实例信息,但是Nacos中提供了一个功能,就是可以在拉取实例时,可以根据随机策略只拉取到所有实例中的某一个,这就是Nacos中的负载均衡,它跟Ribbon的负载均衡并不冲突,可以理解为Ribbon的负载均衡是发生在Nacos的负载均衡之后的。
在Nacos中,服务的负载均衡是通过服务发现来实现的。当消费者需要调用某个服务时,它会向Nacos注册中心查询服务列表,并从中选择一个可用的服务实例进行调用。
Nacos支持多种负载均衡算法,包括随机算法、轮询算法、加权随机算法、加权轮询算法等。默认情况下,Nacos使用的是加权轮询算法。在Nacos中,可以通过配置文件或代码来开启或关闭负载均衡功能。
下面以配置文件方式为例,介绍如何开启Nacos的负载均衡功能。
在Nacos中,可以通过在nacos-server和nacos-client的配置文件中进行相关配置来开启或关闭负载均衡功能。在nacos-server的配置文件中,需要配置以下参数:
# 开启nacos-server的负载均衡功能
nacos.server.enable-load-balance=true
在nacos-client的配置文件中,需要配置以下参数:
nacos.client.enable-load-balance=true
在上述配置中,将enable-load-balance参数设置为true即可开启负载均衡功能。配置完成后,Nacos就会自动进行服务实例的负载均衡。
除了配置文件,还可以通过代码方式来开启Nacos的负载均衡功能。在Spring Boot应用中,可以在启动类中添加@EnableDiscoveryClient注解来开启服务注册与发现功能,也就是开启Nacos的负载均衡功能。
示例代码如下:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
在上述代码中,通过@EnableDiscoveryClient注解来开启服务注册与发现功能,也就是开启Nacos的负载均衡功能。
需要注意的是,在使用Nacos的负载均衡功能时,需要引入相关的依赖包。在Spring Boot应用中,需要引入spring-cloud-starter-alibaba-nacos-discovery依赖。