掘金 后端 ( ) • 2024-04-09 09:56

关注微信公众号 “程序员小胖” 每日技术干货,第一时间送达!

引言

在微服务架构中,服务注册与发现是至关重要的,而Alibaba Nacos正是这方面的优秀解决方案。它不仅功能强大、配置灵活,而且在Spring Cloud环境下的集成使用更是极大地提升了服务治理的效率。本文旨在向读者详细介绍Nacos的核心概念和功能,并通过实际案例展示其在Spring Cloud项目中的应用,帮助开发者实现服务的注册、发现和动态配置管理。无论是新手还是资深开发者,本文都将提供实用的指导,助力提升系统的稳定性和可维护性。

NACOS

Nacos (Dynamic Naming and Configuration Service): 一个更易于构建 云原生应用的动态服务发现、配置管理和服务管理平台。致力于帮助您发现、配置和管理微服务。提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

核心概念

服务 (Service): 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。

服务注册中心 (Service Registry): 服务注册中心,它是服务及其实例和元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。

服务元数据 (Service Metadata): 服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。

服务提供方 (Service Provider): 是指提供可复用和可调用服务的应用方。

服务消费方 (Service Consumer): 是指会发起对某个服务调用的应用方。

核心功能

服务注册: 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秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)

实战

Spring Cloud是一个微服务架构下的框架,它为开发者提供了快速构建分布式系统中的一些常见模式的工具。通过Spring Cloud,开发者可以轻松地实现服务的注册与发现、配置管理、负载均衡等功能,接下来我们来演实现 Spring Cloud 怎么集成Nacos.

nacos服务搭建

1、拉取官方Nacos Docker镜像:

  docker pull nacos/nacos-server

2、运行Nacos容器:

  docker run --name nacos -e MODE=standalone -p 8848:8848 -d nacos/nacos-server

以上命令会启动一个单机模式的Nacos服务器,您可以通过 http://localhost:8848/nacos 访问Nacos的管理界面。

Spring cloud整合Nacos

1、引入依赖: pom中引入nacos依赖

2、启动类上添加@EnableDiscoveryClient注解

3、yml配置文件中配置nacos注册中心地址

4、启动服务,nacos控制台查看是否注册成功

spring:
  application:
    name: order-center #微服务名称
    #配置nacos注册中心地址
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          namespace: e61a5c52-c635-4fbc-bba0-6cea232fecd1

要想完整的测试nacos是否注册成功且能正常调用,需要整合RestTemplate+Spring Cloud LoadBalancer 实现微服务调用 loadbalancer 常用的配置


spring:
  cloud:
  # 负载均衡配置
    loadbalancer:
 	  ribbon:
        #禁用ribbon
        enabled: false
      cache:
        #启用本地缓存, 根据实际情况权衡
        enabled: true
        #缓存空间大小
        capacity: 1000
        #缓存的存活时间, 单位s
        ttl: 2
        #caffeine缓存的配置, 需引入caffeine依赖
        caffeine:
          #initialCapacity初始的缓存空间大小,expireAfterWrite最后一次写入后经过固定时间过期
          spec: initialCapacity=500,expireAfterWrite=5s
      health-check:
        #重新运行运行状况检查计划程序的时间间隔。
        interval: 25s
        #运行状况检查计划程序的初始延迟值
        initial-delay: 30
      retry: #需要引入Spring Retry依赖
        #该参数用来开启重试机制,默认是关闭
        enabled: true
        #切换实例的重试次数
        max-retries-on-next-service-instance: 2
        #对当前实例重试的次数
        max-retries-on-same-service-instance: 0
        #对所有的操作请求都进行重试
        retry-on-all-operations: true
        #Http响应码进行重试
        retryable-status-codes: 500,404,502

Java代码示例

场景: 用户中心调用订单中心 查询用户的订单详情信息

1. 引入loadbalance依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

2. 使用RestTemplate进行服务调用 给RestTemplate实例添加@LoadBalanced注解,开启@LoadBalanced与loadbalancer集成

@Configuration
public class RestConfig {

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }
}

业务逻辑实现

@RequestMapping(value = "/findOrderByUserId/{id}")
public R findOrderByUserId(@PathVariable("id") Integer id) {
  //利用@LoadBalanced,restTemplate需要添加@LoadBalanced注解
  String url = "http://order-center/order/findOrderByUserI  d/"+id;
  R result = restTemplate.getForObject(url,R.class);
  return result;
}

测试: 访问http:localhost:8080/user/findOrderByUserId/{id}

常用配置

Nacos服务分级存储模型

Nacos提供的一种服务发现和配置管理的多层结构设计,它通过层级化的方式来组织和管理微服务架构中的服务实例。这个模型的核心目的是为了提高服务的可用性和容灾能力,同时优化服务的访问延迟。

Nacos的服务分级模型可以划分为三个层级:

服务(Service): 这是最顶层的抽象,代表了一个业务服务的逻辑概念。例如,一个用户服务可能被定义为一个服务。

集群(Cluster): 在服务的下一层是集群,它代表了服务在特定地理位置或数据中心的部署实例。例如,可以有上海的用户服务集群和北京的用户服务集群。

实例(Instance): 最底层是具体的服务实例,它们运行在服务器上并提供具体的服务。每个实例可以有自己的元数据和权重,用于负载均衡和健康检查。

通过这种分级模型,Nacos能够实现以下几个关键功能:

容灾: 通过在不同地域部署服务实例,当一个地域的服务不可用时,可以通过Nacos自动切换到其他地域的服务,从而保证服务的高可用性。

负载均衡: Nacos支持多种负载均衡策略 包括基于权重的轮询、随机选择 最少活跃调用等,可以根据业务需求和实例的健康状况智能地分配流量。

服务发现: 服务消费者可以通过Nacos发现和服务提供者的实例,Nacos会根据配置的规则返回最合适的服务实例列表。

Nacos的服务分级存储模型为微服务架构提供了一种灵活、可靠和高效的服务管理方式,使得服务的部署、发现和调用更加智能和稳定。

集群配置

在原有配置加入以下配置

spring:
  application:
    name: order-center #微服务名称
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          namespace: e61a5c52-c635-4fbc-bba0-6cea232fecd1
          cluster-name: SH

跨集群调用优先本地集群的场景实现

利用cluster-name可以实现跨集群调用时,优先选择本地集群的实例,本地集群不可访问时,再去访问其他集群。 下面是Ribbon的NacosRule实现的负载均衡算法,就是利用了cluster-name实现了优先调用本地集群实例

LoadBalancer默认情况下使用的ReactiveLoadBalancer实现是RoundRobinLoadBalancer。要切换到不同的实现,无论是针对所选服务还是所有服务,您都可以使用自定义LoadBalancer配置机制。


public class CustomLoadBalancerConfiguration {

  @Bean
  ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
    LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties){
    String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class),name,nacosDiscoveryProperties);
  }
}

在启动类上添加@LoadBalabcerClient注解

@SpringBootApplication
@LoadBalancerClient(value = "order-center", configuration = CustomLoadBalancerConfiguration.class)
public class UserCenterApplication {

  public static void main(String[] args) {
    SpringApplication.run(UserCenterApplication.class, args);
  }
}

服务逻辑隔离

Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是DEFAULT_GROUP。

Namespace 隔离设计

命名空间(Namespace)用于进行租户(用户)粒度的隔离,Namespace 的常用场景之一是不同环境的隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

spring:
  application:
    name: order-center #微服务名称
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          namespace: test
          cluster-name: SH

只有在同一个命名空间(Namespace)下的服务才可以通信。

group服务分组

不同的服务可以归类到同一分组,group也可以起到服务隔离的作用。yml中可以通过spring.cloud.nacos.discovery.group参数配置。group更多应用场景是配置分组。

spring:
  application:
    name: order-center #微服务名称
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          namespace: test
          cluster-name: SH
          # 配置分组,通常用于区分不同环境或模块的配置
          group: DEFAULT_GROUP  

临时实例和持久化实例

问:临时实例和持久化怎么区分的?

答:通过健康检查方式区分临时实例和持久化实例

问:怎么通过健康检查区分两个实例呢?

答:临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。 问:还有其他的吗?

答:临时实例需要能够自动摘除不健康实例,而且无需持久化存 储实例。持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳, 所以不能自动摘除

问:怎么设置服务为临时实例或者持久化实例呢?

答:默认情况下,服务实例注册为临时实例,但是想要改成持久化实例的化需要增加一条配置信息

spring:
  application:
    name: order-center #微服务名称
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          namespace: test
          cluster-name: SH
          # 配置分组,通常用于区分不同环境或模块的配置
          group: DEFAULT_GROUP  
          # 持久化实例
          ephemeral: false

nacos开启权限认证

nacos server端 conf/application.properties添加如下配置

# 开启认证
nacos.core.auth.enabled=true
# 配置自定义身份识别的key(不可为空)和value(不可为空)
#这两个属性是auth的白名单,用于标识来自其他服务器的请求。具体实现见com.alibaba.nacos.core.auth.AuthFilter
nacos.core.auth.server.identity.key=authKey
nacos.core.auth.server.identity.value=nacosSecurty

对应的微服务端 application.yml中添加账号密码配置

spring:
  application:
    name: order-center #微服务名称
    cloud:
      nacos:
        discovery:
          server-addr: 27.0.0.1:8848
          username: nacos
          password: nacos
          namespace: test
          cluster-name: SH
          # 配置分组,通常用于区分不同环境或模块的配置
          group: DEFAULT_GROUP  
          # 持久化实例
          ephemeral: false

如果没有配置username,password,微服务端启动会抛出如下错误:

总结

随着微服务架构在软件开发领域的广泛应用,作为架构师,精通Nacos已成为提升设计能力和系统稳定性的关键。Nacos不仅提供了服务发现和配置管理的高效解决方案,还为微服务间的通信和协作提供了强大的支持。通过本文的深入探讨,我们了解到Nacos的核心特性、实际应用案例以及如何将其整合到现有的微服务架构中。架构师们应当把握这一趋势,不断学习和实践,以便在未来的项目中更好地利用Nacos优化微服务设计,构建更加灵活、可靠和可扩展的系统。让我们携手Nacos,迈向微服务架构的新高度。

image.png

参考文档:

https://nacos.io/zh-cn/docs/v2/guide/user/auth.html

https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

https://docs.spring.io/spring-cloud-commons/docs/4.0.4/reference/html/#spring-cloud-loadbalancer