## 概述 在 Spring Cloud Netflix 阶段我们采用 Eureka 做作为我们的服务注册与发现服务器,现利用 Spring Cloud Alibaba 提供的 Nacos 组件替代该方案。 [Nacos 官网](https://nacos.io/zh-cn/) ## 什么是 Nacos Nacos是一款比较新的技术产品,在2018年7月开源,它致力于发现、配置和管理微服务,可以作为服务的注册中心和配置中心。Nacos 提供了一组简单易用的特性集,以“服务”为中心,能够提供快速实现动态服务发现、服务配置、服务元数据及流量管理能力。 ![](https://img.kancloud.cn/d0/f9/d0f9f56b71851b3b1a25d1b4a8c68930_1130x495.png) ## Nacos数据模型 在Nacos的架构中有一个名字服务 (Naming Service),提供了分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,解决了namespace到clusterId的路由问题。Nacos数据模型相对复杂,因为Nacos为服务的管理提供了很多特性,这些特性都被体现在数据的建模上。下面我们先来看看这张图: ![](https://img.kancloud.cn/00/00/0000d2b3791f8043d23c46644f7e0ae5_1217x768.png) 服务层和实例层很好理解,因为在分布式中一个服务必然会有多个节点,但是Nacos在服务层与实例层中间新增了一个集群层,一个服务对应多个集群,一个集群对应多个实例。这个集群层带来了以下收益: * Nacos的隔离性也从物理节点级别上升到了集群级别; * 在进行水平扩缩容的时候,也可以进行集群级别的伸缩; * 在应用需要使用Nacos时候,可以直接以集群为单位进行支撑。 实例分为两种临时实例和持久化实例: * 临时实例:使用客户端上报模式,需要能够自动摘除不健康实例,并且不需要持久化,而上层的业务服务,例如微服务或者 Dubbo 服务,服务的 Provider 端支持添加汇报心跳的逻辑,就可以作为临时实例进行注册。 * 持久化实例:服务端来主动探测是否健康,因为客户端不会上报心跳,那么自然就不能去自动摘除下线的实例。一些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。 上面是从服务出发的数据模型。下面则是把视野放大,从不同环境出发,建立起更广泛的数据模型,也可以理解为对不同环境的相同服务做了数据隔离。 ## 不同粒度的服务数据隔离 ![](https://img.kancloud.cn/e9/0d/e90db8791f0aa5fc13315fbde16d5cc3_485x401.png) 从命名空间到单个实例,中间经历了组、服务、集群的层级划分。每一个层级对应着不一样的粒度的数据隔离,有效的满足多业务多环境下的不同数据隔离需求。 这种图要表达的意思很简单,在Service层外面还包有两层,分别是命名空间和组。 * 命名空间:业务在开发的时候可以将开发环境和生产环境分开,或者根据不同的业务线存在多个生产环境,命名空间常用场景之一就是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 * 组:对服务进行分组,可以满足接口级别的隔离。 ## 一致性协议 Nacos作为服务的注册中心,同样也需要面对数据的一致性问题,也就是需要在CAP理论中选择,在最新的版本中,Nacos支持AP原则和CP原则两种原则。 Nacos中的CP原则实现是基于简化的Raft,主要是一主多从策略,Raft有三类角色Leader(领袖)、Follower(群众)以及Candidate(候选人)。Raft的选举过程和上一小节将到的ZAB协议选举过程是一样的,也需要获得半数以上的票才能够成功选出Leader。有一点小的区别是,ZAB的Follower在投票给一个Leader之前必须和Leader的日志达成一致,而Raft的Follower则简单地说是谁的term高就投票给谁。Raft 协议也和ZAB协议一样强依赖 Leader 节点的可用性来确保集群数据的一致性。只有Leader节点才有权力领导写操作。它的写操作流程跟我在上一小节讲到的ZAB协议流程一样类似于二阶段提交的流程。在心跳检测中Raft协议的心跳是从Leader到Follower, 而ZAB协议则相反。Raft和ZAB如此相似,归根结底是因为Raft和ZAB都是Paxos算法的简化和优化,并且把Paxos更加的具象化,让人易于实现和理解。 Nacos中的AP原则实现基于阿里自研协议 Distro。Distro 协议则是参考了内部 ConfigServer 和开源 Eureka。该实现没有主从之分,当客户端请求的某个节点挂了后,不会有类似于选主的过程,客户端请求会自动切换到新的Nacos节点,当宕机的节点恢复后,又会重新回到集群管理内。所要做的就是同步一些新的服务注册信息给重启的Nacos节点,达到数据一致的效果。 在Nacos中如何切换AP原则和CP原则,主要切换的条件是注册的服务实例是否是临时实例。如果是临时实例,则选用的是Nacos中的AP原则。 ## 服务注册中心技术对比 ![](https://img.kancloud.cn/1d/f5/1df59f5920cc17caa24003cd64902ed9_1751x742.png) ## eureka与nacos的区别 * eureka采用AP模式实现注册中心,无中心节点无leader概念,采用peertopeer集群架构 * nacos 默认采用AP模式,在1.0版本之后增加了AP+CP的混合模式实现注册中心,采用raft协议,有leader概念 ## 安装部署 ### 准备环境 Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行 Nacos,还需要为此配置 Maven 环境,请确保是在以下版本环境中安装使用: * 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。 * 64 bit JDK 1.8+ ### 启动 * windowd启动方式 ``` D:\open-capacity-platform\register-center>h: H:\>cd alibaba H:\alibaba>cd open-capacity-platform H:\alibaba\open-capacity-platform>cd register-center H:\alibaba\open-capacity-platform\register-center>cd nacos-server H:\alibaba\open-capacity-platform\register-center\nacos-server>cd bin H:\alibaba\open-capacity-platform\register-center\nacos-server\bin>startup.cmd ``` * Linux启动方式 ./startup.sh -m standalone ## 访问服务 打开浏览器访问:http://localhost:8848/nacos ![](https://img.kancloud.cn/1d/c1/1dc1245c9b1a77a0f9e19a0df0ddf181_1920x753.png) **注:从 0.8.0 版本开始,需要登录才可访问,默认账号密码为 nacos/nacos** ## nacos服务注册,可参考user-ceneter 引入POM ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> ``` bootstrap.yml增加以下配置 ``` spring: cloud: nacos: discovery: server-addr: ip:prot #nacos的地址 ``` 工程启动类添加以下注解 ``` @EnableDiscoveryClient ``` ## nacos API > 用API服务注册,由于未心跳检测,服务发现服务不会一直有效 ### 服务注册API ![](https://img.kancloud.cn/a3/89/a389514090e691500b44458b9a472daa_1718x417.png) ### 服务发现API ![](https://img.kancloud.cn/b4/fd/b4fd86b96178a319748c26faf12b2f05_1708x702.png) ### 控制台查看 ![](https://img.kancloud.cn/91/40/9140c967ac967f2ee003fb676e9784b2_1909x474.png) ## nacos源码分析 ### nacos数据结构 ![](https://img.kancloud.cn/eb/94/eb942db612db49dfa908b8b005934b1b_1137x569.png) ### nacos 整体结构 ![](https://img.kancloud.cn/39/66/3966d5879d1cb084697fc3dc4c3ec6f2_954x766.png) ### 功能说明 ServiceManager是nacos naming server中service核心管理类。在启动时会执行一次本地信息到其他服务器,while(true)发生改变的service队列内容进行本地更新,同时启动对com.alibaba.nacos.naming.domains.meta.前缀的key的监听;在运行过程中,执行controller接受的相关请求的功能,完成本地状态和远程服务器同步。 ## nacos流程图 ![](https://img.kancloud.cn/da/df/dadf4b5214a7f5a62e9e13241d25c0b4_7146x6173.png)