一、 Nacos简介
1 简介
Nacos是由阿里巴巴提供的一款专门构建云本地应用的动态服务发现、配置中心和服务管理平台。
在Spring Cloud Alibaba中常使用Nacos作为注册中心和分布式配置中心。
Nacos 官网地址:
https://nacos.io/en-us/ |
---|
Nacos github地址:
https://github.com/alibaba/nacos |
---|
2 特性
2.1 服务发现和管理
动态服务发现是以服务为中心(例如微服务或云原生)体系结构的关键。Nacos支持基于DNS和基于RPC(Dubbo,gRPC)的服务发现,并提供实时服务运行状况检查,以防止将路由请求发送到不正常的主机或服务实例。使用Nacos,您还可以轻松地为您的服务安装断路器。
2.2 动态配置服务
动态配置服务使您可以集中,外部化和动态地管理所有环境中的配置。动态配置使您不必在配置更新时重新部署应用程序和服务。您可以实施无状态服务并轻松实现按需扩展。
2.3 动态DNS服务
通过支持加权路由,动态DNS(域名系统,Domain Name System)服务可帮助您在数据中心内的生产环境中实现中间层负载均衡,更灵活的路由,流量控制和DNS解析服务。动态DNS服务还使您更容易实现基于DNS的服务发现,从而最大程度地降低了耦合到特定于供应商的服务发现API的风险。
3 为什么使用Nacos
3.1 易于使用
动态服务发现,配置管理和动态DNS服务的一站式解决方案
20多种现成的功能,以服务为中心的体系结构
轻巧的生产就绪控制台
3.2 更适合云架构
无缝支持kubernetes和Spring Cloud
易于在流行的公共云(例如AliCloud和AWS(亚马逊AWS(Amazon Web Services)))上部署和运行
支持多租户和多环境
3.3 生产等级
源自阿里巴巴集团经过时间考验的内部产品
支持数百万种服务的大规模方案
具有企业级SLA(服务级别协议)的开源产品
3.4 丰富的互联网应用场景亲和力
支持速率调节,大型促销计划以及多区域双活架构
直接或稍微扩展支持各种基于Internet的相关用例
流量调度和服务治理
4 谁在使用Nacos
二、 Nacos架构
1 架构图
2 核心概念
u 服务 (Service)
服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.
u 服务注册中心 (Service Registry)
服务注册中心,它是服务实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。
u 服务元数据 (Service Metadata)
服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据
u 服务提供方 (Service Provider)
是指提供可复用和可调用服务的应用方
u 服务消费方 (Service Consumer)
是指会发起对某个服务调用的应用方
u 配置 (Configuration)
在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。
u 配置管理 (Configuration Management)
在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。
u 名字服务 (Naming Service)
提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。
u 配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
三、 基于Docker安装Nacos
1 拉取Nacos镜像
docker pull nacos/nacos-server
2 创建目录及配置文件
创建两个目录,分别是初始化目录和日志目录。
# mkdir -p /opt/nacos/init.d /opt/nacos/logs
新建配置文件
# vim /opt/nacos/init.d/custom.properties
在文件中添加以下内容
management.endpoints.web.exposure.include=* |
---|
3 创建并启动容器
端口8848
Mode=standalone 单机版
挂载配置文件和日志文件
—restart always 自动启动容器
使用内置Derby(Apache的一款小巧数据库)数据库。也可以修改为MySQL数据库,需要额外配置-e环境变量,具体如下:
# docker run -d -p 8848:8848 -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /opt/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /opt/nacos/logs:/home/nacos/logs —restart always —name nacos nacos/nacos-server
4 访问Nacos可视化管理界面
启动过程需要花费一定时间,需要稍等一会才能访问。
访问: http://192.168.8.128:8848/nacos
默认的用户名和密码都是nacos
四、 使用Nacos作为注册中心
Nacos支持HTTP和RPC协议访问。在导入Nacos依赖后内置Ribbon。和Eureka相同,都支持同名应用程序的负载均衡。
所以在使用Nacos作为注册中心的时候除了和Eureka依赖及配置文件不一样,其他流程都是一样的。
注意:Spring Cloud Alibaba依赖的Spring Boot最高版本只能是2.3.x。更高版本的spring boot和 spring cloud alibaba有兼容错误。启动失败。
注意:spring cloud alibaba 2021版本依赖,在使用openfeign技术做远程服务调用的时候,需要spring boot2.4.2及更高版本中的loadbalancer支持。但是启动的时候,必须使用spring boot 2.3.x版本中的spring-boot-context才能启动。有依赖冲突。无法实现服务的正常发现。暂时使用spring cloud alibaba2.2.x版本可以正常基于openfeign实现远程服务调用。
1 新建父项目
新建项目NacosParent。
在pom.xml导入相关依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.5.RELEASE</version> </parent><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR10</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> |
---|
2 新建Provider项目
2.1 配置pom.xml
<dependencies> <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> </dependencies> |
---|
2.2 编写配置文件
新建application.yml。
server-addr:配置nacos的ip和端口。
server: port: 8080 spring: application: name: provider cloud: nacos: discovery: server-addr: 192.168.8.128:8848 |
---|
2.3 新建控制器
新建com.bjsxt.controller.ProviderController。
该控制器是为了让另一个项目调用的。
@RestController public class ProviderController { @RequestMapping(“/provider”) public String provider(){ return “provider-controller”; } } |
---|
2.4 新建启动类
新建com.bjsxt.ProviderApplication
@SpringBootApplication @EnableDiscoveryClient public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class,args); } } |
---|
2.5 启动项目
3 新建Consumer项目
3.1 配置pom.xml
<dependencies> <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> </dependencies> |
---|
3.2 新建配置文件
在resources下新建application.yml.
注意:
端口和应用程序名不要重复了。
server: port: 8081 spring: application: name: consumer cloud: nacos: discovery: server-addr: 192.168.8.128:8848 |
---|
3.3 新建配置类
新建com.bjsxt.config.ConsumerConfig
@Configuration public class ConsumerConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } } |
---|
3.4 新建service及实现类
新建com.bjsxt.service.ConsumerService及实现类。
http://provider/provider 中第一个provider是另一个项目的应用程序名。第二个provider是控制器名称。
public interface ConsumerService { String consumer(); } |
---|
@Service public class ConsumerServiceImpl implements ConsumerService { @Autowired private RestTemplate restTemplate; @Override public String consumer() { String result = restTemplate.getForObject(“http://provider/provider“, String.class); return result; } } |
3.5 新建控制器
新建com.bjsxt.controller.ConsumerController
@RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @RequestMapping(“/consumer”) public String consumer(){ return consumerService.consumer(); } } |
---|
3.6 新建启动类
新建com.bjsxt.ConsumerApplication
@SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class,args); } } |
---|
3.7 运行项目,测试是否注册成功
4 测试服务调用
在浏览器地址栏输入http://localhost:8081/consumer
如果是下面结果,说明使用Nacos作为注册中心案例成功。
五、 使用Nacos作为Dubbo的注册中心
1 新建父项目
1.1 配置pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.5.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <version>2.2.3.RELEASE</version> </dependency> </dependencies> </dependencyManagement> |
---|
2 新建API子项目
2.1 新建接口
新建com.bjsxt.api.DemoApiService。接口名和包名不要和其他项目重复了,尤其不要和Consumer的Service接口名重复了。
public interface DemoApiService { String demo(); } |
---|
3 新建Provider子项目
3.1 配置pom.xml
在依赖中要依赖api项目
<dependencies> <dependency> <artifactId>api</artifactId> <groupId>com.bjsxt</groupId> <version>1.0-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> </dependencies> |
---|
3.2 新建配置文件
新建application.yml。
dubbo.scan.backages: 扫描@DubboService所在包。
dubbo: # scan: # base-packages: com.bjsxt.service.impl # cloud: # subscribed-services: dubbo-provider # 订阅的服务,默认 *protocol: # dubbo 协议 name: dubbo # dubbo 协议端口( -1 表示自增端口,从 20880 开始) port: -1 registry: # 挂载到注册中心 address: nacos://192.168.8.128:8848 spring: application: # Dubbo 应用名称 name: dubbo-provider # main: # Spring Boot 2.1 需要设定 # allow-bean-definition-overriding: true cloud: nacos: # Nacos 服务发现与注册配置 discovery: server-addr: 192.168.8.128:8848 |
---|
3.3 新建实现类
新建com.bjsxt.service.impl.DemoServiceImpl
@DubboService public class DemoServiceImpl implements DemoApiService { @Override public String demo() { return “dubbo-provider-service”; } } |
---|
3.4 新建启动类
新建com.bjsxt.ProviderApplication
@SpringBootApplication @EnableDiscoveryClient @EnableDubbo public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class,args); } } |
---|
4 新建Consumer项目
4.1 配置pom.xml
<dependencies> <dependency> <artifactId>api</artifactId> <groupId>com.bjsxt</groupId> <version>1.0-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> </dependencies> |
---|
4.2 新建配置文件
新建application.yml
dubbo: registry: # 挂载到 Spring Cloud 注册中心 address: nacos://192.168.8.128:8848 # cloud: # subscribed-services: dubbo-provider protocol: # dubbo 协议 name: dubbo # dubbo 协议端口( -1 表示自增端口,从 20880 开始) port: -1 server: port: 8081 spring: application: # Dubbo 应用名称 name: dubbo-consumer # main: # Spring Boot 2.1 需要设定 # allow-bean-definition-overriding: true cloud: nacos: # Nacos 服务发现与注册配置 discovery: server-addr: 192.168.8.128:8848 |
---|
4.3 新建service及实现类
新建com.bjsxt.service.ConsumerService
public interface ConsumerService { String consumer(); } |
---|
@Service public class ConsumerServiceImpl implements ConsumerService { @DubboReference private DemoApiService demoApiService; @Override public String consumer() { return demoApiService.demo(); } } |
4.4 新建控制器
新建com.bjsxt.controller.ConsumerController
@RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @RequestMapping(“/consumer”) public String consumer(){ return consumerService.consumer(); } } |
---|
4.5 新建启动类
新建com.bjsxt.ConsumerApplication
@SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class,args); } } |
---|
4.6 基于OpenFeign实现远程服务调用
4.6.1 修改pom.xml
增加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> |
---|
4.6.2 定义OpenFeign调用接口
@FeignClient(“dubbo-provider”) public interface CallProviderInterface { @RequestMapping(“/provider”) String test(); } |
---|
4.6.3 修改控制器
@RestController public class ConsumerController { @Autowired private ConsumerService consumerService; @Autowired private CallProviderInterface callProviderInterface; @RequestMapping(“/consumer2”) public String consumer(){ return callProviderInterface.test(); } @RequestMapping(“/consumer”) public String consumer(){ return consumerService.consumer(); } } |
---|
4.6.4 修改启动类
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class,args); } } |
---|
4.6.5 小结
由此可见。使用Spring Cloud Alibaba Dubbo技术开发微服务工程时,远程调用机制基于OpenFeign更加方便快捷。此方式为现今常见开发应用方式
5 测试结果
在浏览器输入 http://localhost:8081/consumer
六、 实现Nacos作为配置中心
1 在nacos中新建配置文件
1.1 访问Nacos可视化管理界面
1.2 添加配置文件信息
Data ID:名称任意。此名称作为配置文件名称(又可以叫前缀(prefix))
Group: 在没有自己建立组时默认为DEFAUL_GROUP。此值不需要修改
配置格式:选择properties或yml。此配置影响到客户端加载配置文件时配置。
配置内容:根据所选配置格式,按照指定格式填写内容。
1.3 点击发布按钮后弹出配置文件信息
1.4 在配置列表中查看
2 新建项目
3 编写pom.xml
spring-cloud-stater-aliobaba-nacos-config 是nacos配置中心客户端依赖。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.5.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.3.RELEASE</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> |
---|
4 编写配置文件
新建配置文件。
新建bootstrap.yml
server: port: 8070 spring: cloud: nacos: discovery: server-addr: 192.168.8.128:8848 config: # 指定配置中心的地址和配置中心使用的数据格式 server-addr: 192.168.8.128:8848 # 默认加载文件扩展名为properties file-extension: properties # group默认值为DEFAULT_GROUP # group: DEFAULT_GROUP # 加载的配置文件名称默认值为应用程序名 # prefix: ${spring.application.name} application: name: config-client |
---|
5 新建service及实现类
新建com.bjsxt.service.ConfigClientService及实现类。
Nacos支持动态刷新功能。在获取分布式配置中心内容的类上添加@RefreshScope可以热刷新。
public interface ConfigClientService { String configClient(); } |
---|
@Service @RefreshScope public class ConfigClientServiceImpl implements ConfigClientService { @Value(“${my.name}”) private String name; @Value(“${my.age}”) private Integer age; @Override public String configClient() { return name+“—-“+age; } } |
6 新建控制器
com.bjsxt.controller.ConfigServerController
@RestController public class ConfigServerController { @Autowired private ConfigClientService configClientService; @RequestMapping(“/“) public String configServer(){ return configClientService.configClient(); } } |
---|
7 新建启动类
新建com.bjsxt.ConfigClientApplication
@SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class,args); } } |
---|