Nacos作为注册中心
一、原理与机制
1、naocs架构
服务 (Service)
服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。
服务注册中心 (Service Registry)
服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。
服务元数据 (Service Metadata)
服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。
服务提供方 (Service Provider)
是指提供可复用和可调用服务的应用方。
服务消费方 (Service Consumer)
是指会发起对某个服务调用的应用方。
配置 (Configuration)
在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。
配置管理 (Configuration Management)
在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。
名字服务 (Naming Service)
提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。
配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
2、注册中心原理
-
服务实例在启动时注册到服务注册表,并在关闭时注销
-
服务消费者查询服务注册表,获得可用实例
-
服务注册中心需要调用服务实例的健康检查API来验证它是否能够处理请求
- 客户端发送心跳的周期默认是 5 秒,Nacos 服务端会在15 秒没收到心跳后将实例设置为不健康,在 30 秒没收到心跳时将这个临时实例摘除。
服务注册
Spring Cloud Nacos Discovery 遵循了 spring cloud common 标准,实现了 AutoServiceRegistration、ServiceRegistry、Registration 这三个接口。
在 spring cloud 应用的启动阶段,监听了 WebServerInitializedEvent 事件,当Web容器初始化完成后,即收到 WebServerInitializedEvent 事件后,会触发注册的动作,调用 ServiceRegistry 的 register 方法,将服务注册到 Nacos Server。
服务发现
NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入,默认集成了Ribbon。
如果需要有更加自定义的可以使用 @Autowired 注入一个 NacosRegistration 实例,通过其持有的 NamingService 字段内容直接调用 Nacos API。
二、部署Nacos
1、单机部署
2、集群部署
三、使用
1、添加依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
2、启动一个 Provider 应用
application.properties 配置。一些关于 Nacos 基本的配置也必须在 application.properties(也可以是application.yaml)配置,如下所示: application.properties
server.port=8081
spring.application.name=nacos-producer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*
在启动类上加@EnableDiscoveryClient,开启服务注册发现功能
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderDemoApplication {
public static void main(String[] args) {
SpringApplication.run(NacosProducerDemoApplication.class, args);
}
@RestController
public class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Discovery " + string;
}
}
}
3、服务的 EndPoint
spring-cloud-starter-alibaba-nacos-discovery 在实现的时候提供了一个EndPoint,EndPoint的访问地址为 http://ip:port/actuator/nacos-discovery
。 EndPoint 的信息主要提供了两类:
- subscribe: 显示了当前有哪些服务订阅者
- NacosDiscoveryProperties: 显示了当前服务实例关于 Nacos 的基础配置
4、启动一个 Consumer 应用
pom.xml 和 application.properties 的配置可以参考 Provider 。
1) LoadBalanceClient 和 RestTemolate 结合的方式来访问。 启动一个 Consumer应用的示例代码如下所示:
@SpringBootApplication @EnableDiscoveryClient public class NacosConsumerApp { @RestController public class NacosController{ @Autowired private LoadBalancerClient loadBalancerClient; @Autowired private RestTemplate restTemplate; @Value("${spring.application.name}") private String appName; @GetMapping("/echo/app-name") public String echoAppName(){ //使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问 ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider"); String url = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName); System.out.println("request url:"+url); return restTemplate.getForObject(url,String.class); } } //实例化 RestTemplate 实例 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(NacosConsumerApp.class,args); } }
2)添加 @LoadBlanced 注解,使得 RestTemplate 接入 Ribbon
@SpringBootApplication @EnableDiscoveryClient @LoadBalancerClients({ @LoadBalancerClient("service-provider") }) public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
3)也可以是用OpenFeign调用:
@FeignClient(name = "service-provider") public interface EchoService { @GetMapping(value = "/echo/{str}") String echo(@PathVariable("str") String str); }
四、更多配置项
配置项 | key | 默认值 | 说明 |
---|---|---|---|
服务端地址 | spring.cloud.nacos.discovery.server-addr | ||
服务名 | spring.cloud.nacos.discovery.service | ${spring.application.name} | 注册到Nacos上的服务名称,默认值为应用名称 |
权重 | spring.cloud.nacos.discovery.weight | 1 | 取值范围 1 到 100,数值越大,权重越大 |
网卡名 | spring.cloud.nacos.discovery.network-interface | 当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址 | |
注册的IP地址 | spring.cloud.nacos.discovery.ip | 优先级最高 | |
注册的IP地址类型 | spring.cloud.nacos.discovery.ip-type | IPv4 | 可以配置IPv4和IPv6两种类型,如果网卡同类型IP地址存在多个,希望制定特定网段地址,可使用spring.cloud.inetutils.preferred-networks 配置筛选地址 |
注册的端口 | spring.cloud.nacos.discovery.port | -1 | 默认情况下不用配置,会自动探测 |
命名空间 | spring.cloud.nacos.discovery.namespace | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 | |
AccessKey | spring.cloud.nacos.discovery.access-key | ||
SecretKey | spring.cloud.nacos.discovery.secret-key | ||
Metadata | spring.cloud.nacos.discovery.metadata | 使用Map格式配置 | |
日志文件名 | spring.cloud.nacos.discovery.log-name | ||
集群 | spring.cloud.nacos.discovery.cluster-name | DEFAULT | Nacos集群名称 |
接入点 | spring.cloud.nacos.discovery.endpoint | 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 | |
是否集成LoadBalancer | spring.cloud.loadbalancer.nacos.enabled | false | |
是否开启Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | false | 可以设置成true来开启 watch |
是否启用Nacos | spring.cloud.nacos.discovery.enabled | true | 默认启动,设置为false时会关闭自动向Nacos注册的功能 |