博文配套代码环境说明
springcloud的版本说明:
当前项目环境版本:springboot 2.3.12.RELEASE、springcloud alibaba 2.2.7.RELEASE
一、认识Nacos
1.1、简介
nacos 中文网站
介绍:Nacos不仅仅提供注册中心,还提供了配置中心,在配置中心中我们可以对不同组的服务来进行隔离能够更有效的进行开发,同时还具备登录的一个功能,其中的配置中心还提供了数据持久化。【注册中心不需要数据库、配置中心需要】
Nacos是阿里巴巴新推出的开源项目,致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
Nacos 支持如下核心特性:
1、服务发现: 支持 DNS 与 RPC 服务发现,也提供原生 SDK 、OpenAPI 等多种服务注册方式和 DNS、HTTP 与 API 等多种服务发现方式。
2、服务健康监测: Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。
3、动态配置服务: Nacos 提供配置统一管理功能,能够帮助我们将配置以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
4、动态 DNS 服务: Nacos 支持动态 DNS 服务权重路由,能够让我们很容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务。
5、服务及其元数据管理: Nacos 支持从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。
1.2、常见的注册中心
目前市面上的注册中心如下:
1、Eureka(原生,2.0遇到瓶颈,停止维护)
2、Zookeeper(支持,专业的独立产品。例如:dubbo)
3、Consul(原生,GO语言开发)
4、Nacos(阿里巴巴)
相对于 Spring Cloud Eureka 来说,Nacos 更强大。Nacos = Spring Cloud Eureka + Spring Cloud Config
Nacos 可以与 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config。
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。
Nacos与eureka的区别:
共同点:
都支持服务注册和服务拉取。
都支持服务提供者心跳的方式做健康检测。
不同点:
nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式(一般情况下都使用临时实例,主动检测消费的服务器资源较大,服务器压力大)。
临时实例心跳不正常会被剔除,非临时实例则不会被剔除。
nacos支持服务列表变更的消息推送模式,服务列表更新及时。
nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;eureka采用AP方式。
画图举例(直接引用的课件图):
很明显的两个区别:eureka注册中心没有登录,对于不同服务并没有分组
在nacos中不仅仅会有不同的命名空间,在一个空间中还可以进行分组划分隔离:
1.3、下载、启动及使用Nacos
windows环境
nacos 下载地址
1、下载安装包
选择zip下载即可:
2、修改bin/start.up可执行文件中的配置
我们之后是通过bin目录下的startup.cmd来启动nacos服务,在2.0.3版本中,cmd里是默认设置以集群模式来进行启动的,所以若是我们只是单机启动一个就会报错,那么如何修改模式为单机呢?
set MODE="standalone"
3、mysql中创建nacos数据库以及导入表
nacos中配备有用户登录以及配置中心的功能,所以一些数据内容需要进行持久化存储,所以的话我们需要搭配mysql来进行使用。
MySQL版本:5.7最佳,8.0暂未试过。
首先我们找到nacos提供给我们的sql文件:
接着在数据库中创建【nacos】,接着导入sql即可,最终效果如下:
此时默认用户表中包含一条记录我们之后可以来用其进行登录:
用户名:nacos 密码:nacos # 密码是采用bcrypt加盐加密的
4、修改nacos的配置文件,开启mysql的配置项
进入到conf文件中,来编辑properties配置文件,将下面的五项连接数据库的内容取消注释:
5、启动Nacos并登录
进入到bin目录中,执行命令:
start startup.cmd
看到successful字样说明我们已经启动成功!
来访问下管理页面把:http://192.168.10.37:8848/nacos/index.html#/login
使用用户密码nacos、nacos来登录,我们可以在结点列表中查看到自己的节点ip地址:
1.4、Nacos的核心概念
服务(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 -> LockOwner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2 大场景。
配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
二、注册中心
2.1、实战一:搭建nacos服务注册
目标:搭建两个服务并进行注册到nacos中,主要是进行命名空间以及分组的熟悉。
client-a:namespace以及group都不书写,那么默认namespace就是public、group就是DEFAULT_GROUP。
client-b:指定namespace以及group。
首先来搭建工程环境,这里我们使用阿里云的服务地址来进行快速创建springboot项目:
都选择使用nacos的注册发现依赖以及web模块:
<properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.12.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version> </properties> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
01-nacos-client-a
1、开启服务发现:在启动器上
@EnableDiscoveryClient //开启服务发现
2、编写配置文件:application.yaml
server: port: 8081 spring: application: name: nacos-client-a # 服务名 cloud: nacos: # 如果不指定命名空间会默认注册到public里面去 如果没有指定分组 会注册到DEFAULT_GROUP server-addr: localhost:8848 # 指定服务注册地址 username: nacos password: nacos discovery: # namespace: 477245fa-d5e1-47e0-9580-4a8e268c3f58 # 若是不指定,默认就是public # group: A_GROUP # 若是不指定,默认是DEFAULT_GROUP service: nacos-client-a # 默认使用的是spring.application.name,这里可以进行指定
02-nacos-client-b
与上述相同,同样也是开启注册发现以及编写配置文件,这里就贴下配置文件:
server: port: 8082 spring: application: name: nacos-client-b # 服务名 cloud: nacos: # 如果不指定命名空间会默认注册到public里面去 如果没有指定分组 会注册到DEFAULT_GROUP server-addr: localhost:8848 # 指定服务注册地址 username: nacos password: nacos discovery: namespace: 477245fa-d5e1-47e0-9580-4a8e268c3f58 # 若是不指定,默认就是public group: B_GROUP # 若是不指定,默认是DEFAULT_GROUP service: nacos-client-b # 默认使用的是spring.application.name,这里可以进行指定
其中的namespace的一长串id是我们创建的命名空间的值,我们在nacos控制台来创建下面的nacos-demo命名空间即可,旁边则是ID:
接下来我们来启动项目,并进行nacos控制台进行查看:
首先是client-a,在该工程模块中并没有指明命名空间和组名,所以就会默认public命名空间以及DEFAULT_GROUP组。
接下来是client-b:果然在我们之前创建的nacos-demo命名空间中进行了创建
2.2、实战二:集成feign与gateway组件
目标:创建gateway网关,通过使用动态路由去访问网关来进行路由转发到client-a服务去远程调用client-b服务。
①nacos-client-a服务集成feign组件
要想nacos-client-a服务能够去远程调用client-b的服务,那么首先b就需要对外暴露一个接口:
package com.changlu.nacosclientb.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.UUID; /** * @Description: * @Author: changlu * @Date: 9:15 PM */ @RestController public class MemberController { @GetMapping("/info") public String info() { String info = "client-b:" + UUID.randomUUID().toString(); return info; } }
接着就开始``client-a`模块的集成feign:
集成feign的话,那么就需要指定springcloud的版本依赖以及引入cloud-feign的组件依赖:
<properties> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> </properties> <!-- 集成feign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
1、接着我们在启动器上添加开启feign包扫描注解:
com.changlu.nacosclienta.NacosClientAApplication:
@EnableFeignClients //开启feign包扫描
2、编写指定的feign接口
com.changlu.nacosclienta.feign.MemberFeign: package com.changlu.nacosclienta.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; /** * @Description: * @Author: changlu * @Date: 9:17 PM */ @FeignClient(value = "nacos-client-b") public interface MemberFeign { @GetMapping("/info") String info(); }
3、最后就是在client-a服务中也编写一个服务,该服务会去远程调用服务b
package com.changlu.nacosclienta.controller; import com.changlu.nacosclienta.feign.MemberFeign; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: changlu * @Date: 9:19 PM */ @RestController public class TestController { @Autowired private MemberFeign memberFeign; @GetMapping("/testClientA") public String testClientA() { String info = memberFeign.info(); return info; } }
此时client-a中的指定命名空间以及组名都已经改为与client-b一致:
②创建gateway模块进行路由转发
Gateway的底层是基于netty的,所以我们无需引入web模块,只需要引入一个nacos的注册发现以及一个gateway组件依赖即可:
<properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.12.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
1、application.yaml:在yaml配置中来打开动态路由以及注册服务的一些配置:
server: port: 81 spring: application: name: gateway-service # 服务名 cloud: nacos: # 如果不指定命名空间会默认注册到public里面去 如果没有指定分组 会注册到DEFAULT_GROUP server-addr: localhost:8848 # 指定服务注册地址 username: nacos password: nacos discovery: namespace: 477245fa-d5e1-47e0-9580-4a8e268c3f58 # 若是不指定,默认就是public group: B_GROUP # 若是不指定,默认是DEFAULT_GROUP service: gateway-service # 默认使用的是spring.application.name,这里可以进行指定 gateway: # 网关配置 discovery: locator: enabled: true # 开启动态路由 lower-case-service-id: true
2、在启动器上添加一个开启服务注册的注解:
@EnableDiscoveryClient
此刻我们的feign以及gateway组件就已经集成完毕了!
测试
额外说明:对于在nacos中feign的远程调用只允许调用相同命名空间中的相同组里的某个服务!否则就会报异常找不到该服务,已进行过测试。
准备工作:开启nacos服务器,以及启动gateway网关以及client-a、client-b服务。
首先来直接调用client-a的接口试试:http://localhost:8081/testClientA
没问题之后,我们来进行调用网关的的动态路由接口,看能够直接路由到client-a服务中去:
到此,测试完成!
2.3、注册中心的常用配置
2.4、实战三:nacos的集群服务搭建
思路:nacos的集群服务也是比较简单的,在同一台机子中修改不同的端口号以及在cluster.conf配置文件中修改指定的ip以及端口,然后同时进行启动即可完成nacos的集群服务搭建。
搭建nacos集群(三个nacos服务)
为了方便三个服务同时来进行启动,我们准备了三个nacos服务:
分别是:8081、8083、8085端口
三个nacos中分别去修改application.properties文件以及cluster.conf配置文件:
application.properties:
cluster.conf:
#2022-07-30T22:23:32.909 192.168.10.37:8081 192.168.10.37:8083 192.168.10.37:8085
ok,接下来我们去启动三个nacos服务,也就是集群,在三个文件的bin目录下执行:``start startup.cmd`
在2.0.3中cmd启动命令文件中默认是cluster模式,所以我们可以直接启动就好!
进行服务注册与查看不同服务
我们来启动client-a、client-b以及gateway,三个服务的注册地址都填写8081端口,之后我们来打开其他nacos服务的管理页面看是否能够进行同步。
ok,此时我们去到管理界面来查看一下:
成功!