Nacos 注册中心
一、概述
1.关键特性
(1)服务发现和服务健康监测
Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生 SDK、OpenAPI、或一个 独立的 Agent TODO 注册 Service 后,服务消费者可以使用 DNS TODO 或 HTTP&API 查找和发现服务。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP) 和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测 2 种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。
(2)动态配置服务
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
Nacos 提供了一个简洁易用的 UI 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
(3)动态 DNS 服务
动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务。动态 DNS 服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。
Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.
(4)服务及其元数据管理
Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。
二、Nacos 地图
- 特性大图:要从功能特性,非功能特性,全面介绍我们要解的问题域的特性诉求
- 架构大图:通过清晰架构,让您快速进入 Nacos 世界
- 业务大图:利用当前特性可以支持的业务场景,及其最佳实践
- 生态大图:系统梳理 Nacos 和主流技术生态的关系
- 优势大图:展示 Nacos 核心竞争力
- 战略大图:要从战略到战术层面讲 Nacos 的宏观优势
三、Nacos 架构
1基本架构及概念
(1)服务 (Service)
服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.
(2)服务注册中心 (Service Registry)
服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。
(3)服务元数据 (Service Metadata)
服务元数据是指包括服务端点 (endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据
(4)服务提供方 (Service Provider)
是指提供可复用和可调用服务的应用方
(5)服务消费方 (Service Consumer)
是指会发起对某个服务调用的应用方
(6)配置 (Configuration)
在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。
(7)配置管理 (Configuration Management)
在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。
(8)名字服务 (Naming Service)
提供分布式系统中所有对象 (Object)、实体 (Entity) 的 “名字” 到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的 2 大场景。
(9)配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
2.逻辑架构及其组件介绍
- 服务管理: 实现服务 CRUD,域名 CRUD,服务健康状态检查,服务权重管理等功能
- 配置管理: 实现配置管 CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能
- 元数据管理: 提供元数据 CURD 和打标能力
- 插件机制: 实现三个模块可分可合能力,实现扩展点 SPI 机制
- 事件机制: 实现异步化事件通知,sdk 数据变化异步通知等逻辑
- 日志模块: 管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码 + 帮助文档
- 回调机制: sdk 通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性
- 寻址模式: 解决 ip,域名,nameserver、广播等多种寻址模式,需要可扩展
- 推送通道: 解决 server 与存储、server 间、server 与 sdk 间推送性能问题
- 容量管理: 管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性
- 流量管理: 按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制
- 缓存机制: 容灾目录,本地缓存,server 缓存机制。容灾目录使用需要工具
- 启动模式: 按照单机模式,配置模式,服务模式,dns 模式,或者 all 模式,启动不同的程序 + UI
- 一致性协议: 解决不同数据,不同一致性要求情况下,不同一致性机制
- 存储模块: 解决数据持久化、非持久化存储,解决数据分片问题
- Nameserver: 解决 namespace 到 clusterid 的路由问题,解决用户环境与 nacos 物理环境映射问题
- CMDB: 解决元数据存储,与三方 cmdb 系统对接问题,解决应用,人,资源关系
- Metrics: 暴露标准 metrics 数据,方便与三方监控系统打通
- Trace: 暴露标准 trace,方便与 SLA 系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通
- 接入管理: 相当于阿里云开通服务,分配身份、容量、权限过程
- 用户管理: 解决用户管理,登录,sso 等问题
- 权限管理: 解决身份识别,访问控制,角色管理等问题
- 审计系统: 扩展接口方便与不同公司审计系统打通
- 通知系统: 核心数据变更,或者操作,方便通过 SMS 系统打通,通知到对应人数据变更
- OpenAPI: 暴露标准 Rest 风格 HTTP 接口,简单易用,方便多语言集成
- Console: 易用控制台,做服务管理、配置管理等操作
- SDK: 多语言 sdk
- Agent: dns-f 类似模式,或者与 mesh 等方案集成
- CLI: 命令行对产品进行轻量化管理,像 git 一样好用
四.Nacos 安装
1.概述
Nacos 官方提供了 Docker 版本,方便我们快速部署。
2.操作步骤
mkdir /usr/local/docker
cd /usr/local/docker
git clone https://github.com/nacos-group/nacos-docker.git #git克隆
cd nacos-docker/
docker-compose -f example/standalone-mysql.yaml up -d #单机模式
docker-compose -f example/standalone-mysql.yaml logs -f #可选:查看日志
3.访问页面
http://192.168.88.135:8848/nacos #账号密码均为nacos
4.采坑
在安装nacos时,运行完docker-compose 命令后,docker容器中的两个mysql容器无法启动.
SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。
vi /etc/sysconfig/selinux
更改内容 SELINUX=disabled
reboot #重启
五.服务注册与发现
1.概述
这里实现一个简单的 echo service
演示如何在您的 Spring Cloud 项目中启用 Nacos 的服务发现功能,如下图示:
2.创建父工程
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lxm</groupId>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-cloud-alibaba</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<!--开源协议-->
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>lay3399@outlook.com</email>
</developer>
</developers>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
3.服务提供者
服务提供方: 是指提供可复用和可调用服务的应用方
POM
创建一个名为 hello-spring-cloud-alibaba-provider
的服务提供者项目,pom.xml
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<groupId>com.lxm</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hello-spring-cloud-alibaba-provider</artifactId>
<packaging>jar</packaging>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>lay3399@outlook.com</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.provider.ProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
# 服务名
name: service-provider
cloud:
nacos:
discovery:
# 服务注册中心
server-addr: (你的nacos服务器地址):8848
server:
# 服务端口
port: 8070
management:
# 端点检查(健康检查)
endpoints:
web:
exposure:
include: "*"
Application启动器
通过 Spring Cloud 原生注解 @EnableDiscoveryClient
开启服务注册发现功能
package com.lxm.spring.cloud.alibaba.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
controller
package com.lxm.spring.cloud.alibaba.provider.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Provider " + string;
}
}
服务端点检查
健康检查: 以指定方式检查服务下挂载的实例 (Instance) 的健康度,从而确认该实例 (Instance) 是否能提供服务。根据检查结果,实例 (Instance) 会被判断为健康或不健康。对服务发起解析请求时,不健康的实例 (Instance) 不会返回给客户端。
通过浏览器访问 http://localhost:8070/actuator/nacos-discovery
{
"subscribe": [
{
"jsonFromServer": "",
"name": "service-provider",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-provider",
"valid": true,
"keyEncoded": "service-provider"
},
{
"jsonFromServer": "",
"name": "service-consumer",
"groupName": "DEFAULT_GROUP",
"clusters": null,
"cacheMillis": 1000,
"hosts": [],
"lastRefTime": 0,
"checksum": "",
"allIPs": false,
"key": "service-consumer",
"valid": true,
"keyEncoded": "service-consumer"
}
],
"NacosDiscoveryProperties": {
"serverAddr": "192.168.141.132:8848",
"endpoint": "",
"namespace": "",
"watchDelay": 30000,
"logName": "",
"service": "service-provider",
"weight": 1,
"clusterName": "DEFAULT",
"namingLoadCacheAtStart": "false",
"metadata": {
"preserved.register.source": "SPRING_CLOUD"
},
"registerEnabled": true,
"ip": "192.168.141.1",
"networkInterface": "",
"port": 8070,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}
4.服务消费者
服务消费方: 是指会发起对某个服务调用的应用方
服务消费者的创建与服务提供者大同小异,这里采用最原始的一种方式,即显示的使用 LoadBalanceClient 和 RestTemplate 结合的方式来访问
POM
创建一个名为 hello-spring-cloud-alibaba-consumer
的服务消费者项目,pom.xml
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>hello-spring-cloud-alibaba</artifactId>
<groupId>com.lxm</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>hello-spring-cloud-alibaba-consumer</artifactId>
<packaging>jar</packaging>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>lay3399</id>
<name>XiaoMeng Lu</name>
<email>lay3399@outlook.com</email>
</developer>
</developers>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.spring.cloud.alibaba.consumer.ConsumerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
# 服务名
name: service-consumer
cloud:
nacos:
discovery:
# 服务注册中心
server-addr: 192.168.88.132:8848
server:
# 服务端口
port: 8080
management:
# 端点检查(健康检查)
endpoints:
web:
exposure:
include: "*"
Application
通过 Spring Cloud 原生注解 @EnableDiscoveryClient
开启服务注册发现功能
package com.lxm.spring.cloud.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Configuration
package com.lxm.spring.cloud.alibaba.configure;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConsumerConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
controller
package com.lxm.spring.cloud.alibaba.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
private final RestTemplate restTemplate;
@Autowired
public TestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/echo/{str}")
public String echo(@PathVariable String str) {
// 使用服务名请求服务提供者
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
}
安全检查同上
结果
访问消费者的接口http://localhost:8080/echo/hi,消费者则通过注册中心请求提供者服务并返回数据
六、Feign
Feign 是一个声明式的伪 HTTP 客户端,它使得写 HTTP 客户端变得更简单。使用 Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解。Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,Nacos 也很好的兼容了 Feign,默认实现了负载均衡的效果
- Feign 采用的是基于接口的注解
- Feign 整合了 Ribbon
1.pom
在 hello-spring-cloud-alibaba-consumer
项目中增加 org.springframework.cloud:spring-cloud-starter-openfeign
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.Application
通过 @EnableFeignClients
注解开启 Feign 功能
package com.lxm.spring.cloud.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
3.Service
创建业务结构,通过 @FeignClient("服务名")
注解来指定调用哪个服务
package com.lxm.spring.cloud.alibaba.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "service-provider")
public interface EchoService {
@GetMapping(value = "/echo/{string}")
String echo(@PathVariable("string") String string);
}
4.controller
@GetMapping(value = "/feign/echo/{str}")
public String echofeign(@PathVariable String str) {
return echoService.echo(str);
}
5.验证是否成功
通过浏览器访问 http://localhost:8080/feign/echo/hi
七、分布式配置中心
1.概述
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件
2.什么是 Nacos Config
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
Spring Cloud Alibaba Nacos Config 是 Spring Cloud Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。
3.接入配置中心
pom
以 service-consumer
项目为例,修改 pom.xml
,引入 Nacos Config Starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
Controller
完成上述两步后,应用会从 Nacos Config 中获取相应的配置,并添加在 Spring Environment 的 PropertySources 中。这里我们使用 @Value
注解来将对应的配置注入到 TestEchoController
的 username
字段,并添加 @RefreshScope
打开动态刷新功能
package com.lxm.spring.cloud.alibaba.controller;
import com.lxm.spring.cloud.alibaba.service.EchoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RefreshScope
public class TestController {
private final RestTemplate restTemplate;
@Autowired
private EchoService echoService;
@Autowired
public TestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/echo/{str}")
public String echo(@PathVariable String str) {
// 使用服务名请求服务提供者
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
@GetMapping(value = "/feign/echo/{str}")
public String echofeign(@PathVariable String str) {
return echoService.echo(str);
}
//这里是config验证代码
@Value("${user.name}")
private String username;
@GetMapping(value = "/config")
public String config() {
return echoService.echo(username);
}
}
使用控制台发布配置
通过浏览器访问 nacos Server 点击“配置管理”-“配置列表”添加配置
Data ID: service-consumer-config.yaml
配置内容
spring:
application:
# 服务名
name: service-consumer
cloud:
nacos:
discovery:
# 服务注册中心
server-addr: {服务注册中心服务器ip}:8848
server:
# 服务端口
port: 8080
management:
# 端点检查(健康检查)
endpoints:
web:
exposure:
include: "*"
user:
name: "我是配置服务A~"
例图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xKF6lL2c-1570002181571)(F:\工作\笔记\笔记\SpringCloudAli\img\regiest.png)]
修改客户端配置
创建名为 bootstrap.properties
的配置文件并删除之前创建的 application.yml
配置文件
spring.application.name=service-consumer-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
通过浏览器访问http://localhost:8080/config,浏览器输出如下
Hello Nacos Provider 我是配置服务A~
注意: Spring Boot 配置文件的加载顺序,依次为 bootstrap.properties
-> bootstrap.yml
-> application.properties
-> application.yml
,其中 bootstrap.properties 配置为最高优先
4.Nacos多环境配置
概述
我们在做项目开发的时候,生产环境和测试环境的一些配置可能会不一样,有时候一些功能也可能会不一样,所以我们可能会在上线的时候手工修改这些配置信息。Spring 为我们提供了 Spring Boot Profile 这个功能(Maven 也为我们提供了 Maven Profile)。我们只需要在启动的时候添加一个虚拟机参数,激活自己环境所要用的 Profile 就可以了。
操作起来很简单,只需要为不同的环境编写专门的配置文件,如:application-dev.yml
、application-prod.yml
, 启动项目时只需要增加一个命令参数 --spring.profiles.active=
环境配置即可
java -jar 1.0.0-SNAPSHOT.jar --spring.profiles.active=prod
什么是 Nacos Config Profile
spring-cloud-starter-alibaba-nacos-config
在加载配置的时候,不仅仅加载了以 dataid 为 ${spring.application.name}.${file-extension:properties}
为前缀的基础配置,还加载了 dataid 为 ${spring.application.name}-${profile}.${file-extension:properties}
的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过 Spring 提供的 ${spring.profiles.active}
这个配置项来配置。
使用 Nacos Config Profile
我们以 service-provider
项目为例,演示多环境配置效果,不要忘记依赖 Nacos Config Starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
使用控制台发布配置
注意: 控制台发布配置时不要加注释,否则打成 Jar 包后运行会报无法解析配置文件的错误
通过浏览器访问 http://localhost:8848/navcos,访问 Nacos Server
- 发布一个名为
service-provider-config.yaml
的 测试环境 配置
spring:
application:
# 服务名
name: service-provider
cloud:
nacos:
discovery:
# 服务注册中心
server-addr: 192.168.88.132:8848
server:
# 服务端口
port: 8070
management:
# 端点检查(健康检查)
endpoints:
web:
exposure:
include: "*"
- 发布一个名为
service-provider-config-prod.yaml
的 生产环境 配置
spring: application: # 服务名 name: service-provider cloud: nacos: discovery: # 服务注册中心 server-addr: 192.168.141.132:8848server: # 修改了上面的端口号,区分配置的不同 port: 8071management: # 端点检查(健康检查) endpoints: web: exposure: include: "*"
修改客户端配置
- 创建名为
bootstrap.properties
的配置文件并删除之前创建的application.yml
配置文件
spring.application.name=service-provider-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
- 创建名为
bootstrap-prod.properties
的配置文件
spring.profiles.active=prod
spring.application.name=service-provider-config
spring.cloud.nacos.config.server-addr=192.168.88.132:8848
spring.cloud.nacos.config.file-extension=yaml
测试多环境配置
此时我们有两个配置文件,分别为 bootstrap.properties
和 bootstrap-prod.properties
,我们需要指定启动时加载哪一个配置文件
Run -> Edit Configurations -> Active profiles:
运行项目并观察日志
由上图可知,我们成功加载了不同环境的配置