Spring Cloud Alibaba技术栈【上】

Spring Cloud Alibaba

来自阿里的微服务解决方案

一、项目简介

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

组件

在这里插入图片描述

项目地址

在这里插入图片描述

项目wiki

在这里插入图片描述

适合人群

  • 基础的分布式思想
  • 掌握Spring Boot
  • 了解Spring Cloud Netflix
  • 分布式中间件

认识了解阶段

在这里插入图片描述

使用阶段

在这里插入图片描述

深入理解阶段

理解概念和配置项

在这里插入图片描述
在这里插入图片描述

架构设计阶段

在这里插入图片描述

项目阶段

在这里插入图片描述
在这里插入图片描述

环境和必须的软件

  • windows7/10
  • JDK1.8
  • Maven3.5.4
  • IDEA
  • Git

版本校验

在这里插入图片描述
在这里插入图片描述

尤其注意(settings.xml)

在这里插入图片描述
在这里插入图片描述

依赖管理

Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。
在这里插入图片描述

一、版本管理规范

项目的版本号格式为 x.x.x 的形式,其中 x 的数值类型为数字,从 0 开始取值,且不限于 0~9 这个范围。项目处于孵化器阶段时,第一位版本号固定使用 0,即版本号为 0.x.x的格式。

由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且spring-cloud-commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此 Spring CloudAlibaba 采取跟 SpringBoot 版本号一致的版本:

  • 1.5.x 版本适用于 Spring Boot 1.5.x
  • 2.0.x 版本适用于 Spring Boot 2.0.x
  • 2.1.x 版本适用于 Spring Boot 2.1.x
  • 2.2.x 版本适用于 Spring Boot 2.2.x
    下表展示了 Spring Cloud Alibaba & Spring Cloud & Spring Boot 兼容关系:

The Spring Cloud Alibaba & Spring Cloud & Spring Boot compatibility table
在这里插入图片描述
在这里插入图片描述
以后我们的项目选择的版本为:

  • Spring Boot 2.2.3.RELEASE
  • Spring Cloud Hoxton.SR3
  • Spring Cloud Alibaba 2.2.0.RELEASE

二、依赖管理

Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。如果您是 Maven Central用户,请将我们的 BOM 添加到您的 pom.xml 中的 <dependencyManagement>部分。 这将允许您省略任何 Maven 依赖项的版本,而是将版本控制委派给 BOM。

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-dependencies</artifactId>
			<version>2.2.0.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

在下面的章节中,假设您使用的是 Spring Cloud Alibaba bom,相关 starter 依赖将不包含版本号。

三、父项目的创建

使用父项目能控制所有子项目依赖的全局版本,能有效的去除子项目里面重复的依赖,减少出错的几率。在此,我们将创建一个父 pom,让所有的子模块都继承该父 pom。

3.1 spring-cloud-alibaba-examples 项目的创建

spring-cloud-alibaba-examples 将作为我们子项目的最大父 pom 项目!

注意:在使用 IDEA 之前我们假设您已经设置了相应的 JDK 配置和 Maven 配置

3.1.1 使用 IDEA 创建一个 Maven 项目

创建一个新的 Maven 项目
在这里插入图片描述
选择 Next:
在这里插入图片描述
填写下面的相关信息:

Name:spring-cloud-alibaba-examples
Location:D:\workspace\spring-cloud-alibaba-examples(不要随便放)
GroupId:com.bjsxt
Version:1.0

最后,点击 finish完成创建的过程!

3.1.2 Spring Boot 版本的控制

我们采用<parent> 的方式来导入 Spriing Boot 的版本号。
打开项目的 pom.xml 文件,添加依赖内容:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.3.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

这样,我们的项目就已经规定了 Spring Boot 的版本为2.2.3.RELEASE 了。

3.1.3 Spring Cloud 版本的控制

我们使用依赖管理的方式来添加 Spring Cloud 的版本信息,在<properties> 里面定义版本信息,这里面我们选择 Hoxton.SR3 这个版本!

<properties>
	<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>

之后在<dependencyManagement>里面添加 spring-cloud 的 bom 信息,这将允许您省略任何 Maven 依赖项的版本,而是将版本控制委派给 BOM。

<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>

3.1.4 Spring Cloud Alibaba 版本的控制

同样,我们使用依赖管理的方式来添加 Spring Cloud Alibaba 的版本信息。在<properties>里面定义版本信息,这里面我们选择 2.2.0.RELEASE 这个版本!

<properties>
	...
	<com-alibaba-cloud.version>2.2.0.RELEASE</com-alibaba-cloud.version>
	...
</properties>

之后在 <dependencyManagement>里面添加 spring-cloud 的 bom 信息,这将允许您省略任何 Maven 依赖项的版本,而是将版本控制委派给 BOM。

<dependencyManagement>
	<dependencies>
		...
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-dependencies</artifactId>
			<version>${com-alibaba-cloud.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		....
	</dependencies>
</dependencyManagement>

3.1.4 设置为 pom 的版本方式

添加项目的打包方式:

<packaging>pom</packaging>

这将保证我们的项目是以 pom 打包的。

3.1.5 完整的 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>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.bjsxt</groupId>
	<artifactId>spring-cloud-alibaba-examples</artifactId>
	<version>1.0</version>
	
	<properties>
		<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
		<com-alibaba-cloud.version>2.2.0.RELEASE</com-alibaba-cloud.version>
	</properties>
	
	<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>com.alibaba.cloud</groupId>
				<artifactId>spring-cloud-alibaba-dependencies</artifactId>
				<version>${com-alibaba-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
</project>

3.2 项目的打包

3.2.1 删除项目里面多余的文件夹

我们的项目仅仅是一个父 pom 文件,因此,项目只需要保留 pom.xml 即可,我们在此可以删除 src 目录。
在这里插入图片描述
点击 Delete 即可删除。

3.2.2 执行打包

使用 Maven 打包我们的项目。
在这里插入图片描述
最后在控制台出现:
在这里插入图片描述
代表项目打包成功!

3.2.3 观察打包后的效果

我们打开我们 Maven 设置的本地仓库地址,如图所示:
打开 Maven 里面的 settings.xml 文件,找到该标
在这里插入图片描述
发现我们本地仓库的地址位于 D 盘的 lib\jar 文件夹里面:
打开该文件夹:
在这里插入图片描述
发现该文件已经存在,证明我们的打包成功了。

Nacos

一、什么是 Nacos?

在这里插入图片描述
Nacos 致力于发现、配置和管理微服务。它提供了一组简单易用的特性集,帮助快速实现动态服务发现、服务配置、服务元数据及流量管理。使用 Nacos 可以更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

服务(Service)是 Nacos 世界的一等公民。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理:

  • Kubernetes Service.
  • gRPC & Dubbo RPC Service.
  • Spring Cloud RESTful Service
    在这里插入图片描述

二、Nacos 的关键特性

1.服务发现和服务健康监测 ,支持基于 DNS 和 RPC 的服务发现,支持基于传输层和应用层的监控检查;
2.动态配置服务 ,可以以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置,同时支持版本追踪和一键回滚等功能;
3.动态 DNS 服务 ,动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务;
4.服务及其元数据管理 ,管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

三、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 -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的 2 大场景。
  • 配置服务 (Configuration Service)
    在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。

Nacos注册中心

一、Nacos Discovery 简介

在这里插入图片描述
使用 Spring Cloud Alibaba Nacos Discovery,可基于 Spring Cloud 的编程模型快速接入 Nacos服务注册功能。

服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于服务的动态扩缩容。Nacos Discovery 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery 也将服务实例自身的一些元数据信息-例如 host,port, 健康检查 URL,主页等内容注册到 Nacos。

二、Nacos Server 安装

在使用 Nacos 之前我们首先要获取和安装 Nacos。

2.1 Nacos Server 的下载

因为 Spring Cloud Alibaba 2.2.0.RELEASE 内置的 Nacos client 版本为 1.1.4,所以我们使用这个版本的 Nacos。Nacos 下载地址:https://github.com/alibaba/nacos/releases
在这里插入图片描述
我们找到 1.1.4 版本后点击:
在这里插入图片描述
找到相关系统的压缩包,这里面我使用的是 window 系统,所以我们选择
nacos-server-1.1.4.zip 该文件,来点击下载他。

2.2 Nacos Server 目录的说明

将下载的 nacos-server-1.1.4 复制到我们的开发工具的文件夹里面。(没有的可以新建一个,养成一个良好的习惯)
在这里插入图片描述
使用压缩软件解决到当前的文件夹,这里我使用的是 7-zip(其他的压缩软件类似):
在这里插入图片描述
解压完成后,进入 Nacos 目录里面:
在这里插入图片描述
bin:可执行文件夹目录,包含:启动、停止命令等等
conf:配置文件目录
target:存放 naocs-server.jar
LICENSE:授权信息,Nacos 使用 Apache License Version 2.0 授权
NOTICE:公告信息

2.3 配置 Nacos Server

进入${Nacos}/conf目录里面,使用文件编辑器打开application.properties 文件,这里面我使用的是 sublime text:
在这里插入图片描述
打开后,如下图所示:
在这里插入图片描述
Nacos 默认使用嵌入式数据库实现数据的存储,并不方便观察数据存储的基本情况,这里面我们修改为使用 Mysql 数据库做数据的存储,方便我们观察数据的结构。
在配置文件末尾添加如下配置:

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTi
meout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

注意:

  • 上面的 url 地址是我的服务器地址,如果你的 mysql 安装在虚拟机或云服务器上面,就填写真实的地址。
  • db.user 用户名
  • db.password 密码

2.4 Mysql 表的导入

提示:Nacos 建议使用 5.7 以上的 Mysql 数据库,版本较低可能存储兼容性问题 我使用的 Mysql 数据库版本为 5.7
打开${Nacos}/conf/文件夹:
在这里插入图片描述
其中nacos-mysql.sql就是 nacos 提供给我们的 sql 语句。
新建数据库:
在这里插入图片描述
新建 Nacos 的的数据库:
在这里插入图片描述
点击确定完成创建。
导入sql语句:
在这里插入图片描述
选择我们 nacos-mysql.sql文件:
在这里插入图片描述
点击开始,完成导入:
在这里插入图片描述
已经成功导入,包含如下的表:
在这里插入图片描述
具体表的细节和设计,我将在源码分析的阶段讲解。

2.5 Nacos Server 的启动

上面工作都完成后,现在我们来启动一个单机版的 Nacos 服务器。
进入到${Nacos}/bin 目录里面:
在这里插入图片描述
双击 startup.cmd 文件,完成 nacos 的启动。
在这里插入图片描述
直到日志出现:
在这里插入图片描述
代表我们已经成功的启动了一个 Nacos 单机版的实例。
在浏览器里面输入:
http://localhost:8848/nacos ,即可访问启动 Nacos 实例。
在这里插入图片描述
Nacos 默认用户名和密码都是 nacos

输入正确的用户名和密码提交后,出现 Nacos 的控制台界面。
在这里插入图片描述
至此,Nacos Server 已经安装成功。

三、框架的搭建

在这里插入图片描述
我们将使用搭建所示的测试案例。

3.1 创建 nacos-examples 的父项目

我们将为 Nacos 创建一个单独项目,方便我们来学习和管理 nacos 的相关功能。

使用 IDEA 创建一个 Maven 模块:
在这里插入图片描述
在这里插入图片描述
点击 next:
在这里插入图片描述
Name:nacos-examples
其他项将会自动的填充进去。
点击 Finish 完成创建。

修改 nacos-examples 里面的 pom.xml 文件,在此我们引入:

  • spring-boot-starter-web (spring-boot-web 开启的最基础的依赖)
  • spring-cloud-alibaba-nacos-discovery(nacos 做服务发现的最基础的依赖)

<dependencies>添加这 2 个依赖:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
	</dependency>
</dependencies>

修改 nacos-examples 项目的打包方式:

<packaging>pom</packaging>

最后,完整的 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>spring-cloud-alibaba-examples</artifactId>
		<groupId>com.bjsxt</groupId>
		<version>1.0</version>
	</parent>
	<modelVersion>4.0.0</modelVersion>
	<artifactId>nacos-examples</artifactId>
	<packaging>pom</packaging>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
		</dependency>
	</dependencies>
</project>

3.2 创建服务的提供者 provider

服务提供者将为以后的服务消费者提供一些接口的供远程调用。

使用 IDEA 为 nacos-examples 创建一个子模块:
在这里插入图片描述
将 Next 进入下一步操作:
在这里插入图片描述
注意:我们的 parent 必须选择为 nacos-examples。
Name:provider(服务的提供者)
其他的项将自动的填充,不需要我们修改。
Provider 的依赖分析:
在这里插入图片描述
我们的 provider 已经自动的从 nacos-exmaples 里面把这 2 个依赖继承过来了。

3.3 创建服务的消费者

服务消费者将远程调用服务提供者提供的接口。
使用 IDEA 为 nacos-examples 创建一个子模块:
在这里插入图片描述
将 Next 进入下一步操作:
在这里插入图片描述
注意:我们的 parent 必须选择为 nacos-examples。
Name:consumer(服务的提供者)
其他的项将自动的填充,不需要我们修改。

Consumer 的依赖分析:
在这里插入图片描述
我们的 consumer 已经自动的从 nacos-exmaples 里面把这 2 个依赖继承过来了。
至此,我们项目的骨架已经搭建完成。如下图所示:
在这里插入图片描述

四、使用 Nacos 做注册中心

4.1 provider 项目的完善

Provider 现在还是一个空的项目,里面没有任何的数据接口。

4.1.1 添加一个 application.yml 配置文件

我们给 provider 添加一个配置文件:
在这里插入图片描述
文件的名称为:
在这里插入图片描述
完成创建后,IDEA 能自动的识别该 yml 文件。
在这里插入图片描述
编辑该配置文件,添加如下的配置:

server:
	port: 8080
spring:
	application:
		name: provider-service
	cloud: # nacos注册中心地址的配置法
		nacos:
			discovery:
				server-addr: localhost:8848

配置说明:

  • server.port provider 服务端口为 8001 ;
  • spring.application.name 服务名称为 provider-service;
  • spring.cloud.nacos.server-addr ,指定 Nacos 注册中心的地址;

4.1.2 添加一个启动类

Provider 还没有启动类,我们需要给他添加一个。
在这里插入图片描述
名称为:com.bjsxt.ProviderApplication
在这里插入图片描述
com.bjsxt 为包名,ProviderApplicaton 为类的名称,创建完成后,自动的出现:
在这里插入图片描述
在该类里面添加如下的代码:

@SpringBootApplication // 标记为 SpringBoot 的应用
@EnableDiscoveryClient // 启用服务发现和注册的功能
public class ProviderApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(ProviderApplication.class,args) ;
	}
}

4.1.3 添加一个 API 接口

提供者通过提供 API 接口供服务提供者调用。
在 provider 里面创建一个类:
在这里插入图片描述
名称为 controller.EchoController
在这里插入图片描述
成功后,如下图所示:
在这里插入图片描述
添加一个接口:

@RestController
public class EchoController {
    
    
	/**
	* echo message
	* @param message
	* @return reply content
	*/
	@GetMapping("/echo/{message}")
	public ResponseEntity<String> echo(@PathVariable("message")
	String message){
    
    
		return ResponseEntity.ok(String.format("hello,%s",message)) ;
	}
}

该接口将会对访问的人输入一个 hello,xxx。

4.1.4 启动 provider 测试

现在我们的 provider 已经准备就绪,启动看能否注册到 Nacos 上面 。
在这里插入图片描述
发现 provider 已经启动成功了。
打开 Nacos 页面观察 provider 是否上
在这里插入图片描述
服务的提供者已经成功的上线了。

4.2 consumer 项目的完成

Consumer 现在还是一个空的项目,里面没有任何的数据接口,也没有对服务的提供者进行调用。

4.2.1 添加一个 application.yml 配置文件

我们给 consumer 添加一个配置文件
在这里插入图片描述
名称为:application.yml
在这里插入图片描述
IDEA 能自动的识别该配置文件的:
在这里插入图片描述
编辑该文件,给该文件添加如下的配置信息:

server:
	port: 8090
spring:
	application:
		name: consumer-service
	cloud:
		nacos:
			discovery:
				server-addr: localhost:8848

4.2.2 添加一个启动类

Consumer 现在还没有任何的启动类,我们需要给他添加一个。
在这里插入图片描述
名称为:com.bjsxt.ConsumerApplication
在这里插入图片描述
创建成功后,如下图所示:
在这里插入图片描述
在该类里面添加如下代码:

@SpringBootApplication // 标记为 SpringBoot 的应用
@EnableDiscoveryClient // 开启服务的发现和注册功能
public class ConsumerApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(ConsumerApplication.class,args) ;
	}
}

4.2.3 服务发现的测试

继续改造启动类,在里面添加如下代码:

@Autowired
private DiscoveryClient discoveryClient ;// 快速服务的发现
@GetMapping("/discovery/{serviceName}")
public ResponseEntity<List<String>> discovery(@PathVariable("serviceName")
String serviceName){
    
    
	/**
	* 通过服务的 ID / 名称得到服务的实例列表
	*/
	List<ServiceInstance> instances =
discoveryClient.getInstances(serviceName);
	if(instances==null || instances.isEmpty()){
    
    
		return ResponseEntity.notFound().build() ;
	}
	List<String> services = new ArrayList<>(instances.size());
	instances.forEach(instance->{
    
    
		services.add(instance.getHost()+":"+instance.getPort());
	});
	return ResponseEntity.ok(services) ;
}

因为我们在启动类里面添加了接口,所以要必须添加@RestController 该注解来标记该类:
在这里插入图片描述
最后,我们启动 consumer-service 项目:
在这里插入图片描述
观察 consumer-service 是否成功的注册到了 Nacos 上面:
在这里插入图片描述
Consumer-service 已经成功了上线了。

在浏览器输入:
http://localhost:8090/discovery/provider-service
其中:provider-service 代表服务的名称
服务器给我们响应:
在这里插入图片描述
代表服务已经发现成功。
输入一个不存在的服务名称:
http://localhost:8090/discovery/provider
服务器给我们响应:
在这里插入图片描述
代表,该服务还没有服务的提供者。

4.2.4 远程调用的测试

在 consumer,我们调用 provider 里面的 echo 接口
继续改造我们的启动类,注册一个 RestTemplate 对象:

/**
* 在容器里面注入一个 RestTempalte 对象
* @return
*/
@Bean
public RestTemplate restTemplate(){
    
    
	return new RestTemplate() ;
}

调用测试:

@Autowired
private RestTemplate restTemplate ;

@GetMapping("/rpcv1/{message}")
public ResponseEntity<String> rpcV1(@PathVariable("message") String message){
    
    
	ResponseEntity<String> responseEntity = restTemplate.getForEntity(
		"http://localhost:8081/echo/{message}",
		String.class,
		message
	);
	if(responseEntity.getStatusCode()==HttpStatus.OK){
    
    
		return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
	}
	return ResponseEntity.badRequest().body("远程调用失败") ;
}

@GetMapping("/rpcv2/{message}")
public ResponseEntity<String> rpcV2(@PathVariable("message") String message){
    
    
	List<ServiceInstance> instances =
	discoveryClient.getInstances("nacos-provider");
	if(instances==null || instances.isEmpty()){
    
    
		return ResponseEntity.badRequest().body("当前服务没有服务的提供者") ;
	}
	ServiceInstance serviceInstance = instances.get(0);
	String instance =
	serviceInstance.getHost()+":"+serviceInstance.getPort() ;
	ResponseEntity<String> responseEntity = restTemplate.getForEntity(
		String.format("http://%s/echo/{message}",instance),
		String.class,
		message
	);
	if(responseEntity.getStatusCode()==HttpStatus.OK){
    
    
		return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
	}
	return ResponseEntity.badRequest().body("远程调用失败") ;
}

@GetMapping("/rpcv3/{message}")
public ResponseEntity<String> rpcV3(@PathVariable("message") String message){
    
    
	List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
	if(instances==null || instances.isEmpty()){
    
    
		return ResponseEntity.badRequest().body("当前服务没有服务的提供者") ;
	}
	ServiceInstance serviceInstance = loadbalance(instances);
	System.out.println(serviceInstance);
	String instance =
	serviceInstance.getHost()+":"+serviceInstance.getPort() ;
	ResponseEntity<String> responseEntity = restTemplate.getForEntity(
		String.format("http://%s/echo/{message}",instance),
		String.class,
		message
	);
	if(responseEntity.getStatusCode()==HttpStatus.OK){
    
    
		return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
	}
	return ResponseEntity.badRequest().body("远程调用失败") ;
}

其中,loadBalance 的实现逻辑为:

/**
* 从一个服务的实例列表里面选择一个服务的实例
* @param instances
* 实例列表
* @return
* 具体的实例
*/
private ServiceInstance loadbalance(List<ServiceInstance> instances) {
    
    
	Random random = new Random(System.currentTimeMillis());
	return instances.get(random.nextInt(instances.size())) ;
}

重启 Consummer-service:
在这里插入图片描述
在浏览器里面输入:
http://localhost:8090/rpc/world
服务器给我们相应的数据为:
在这里插入图片描述
远程调用已经成功!

五、负载均衡测试

当服务压力突然变大时,我们需要通过对服务进行弹性伸缩和动态的扩容,让服务展示更强的并发能力和容错能力。

5.1 修改服务提供者的数据接口

修改服务提供者的接口,可以让我们很清晰的看到,我们当前调用的是那一台服务提供者。
让我们来修改 provider 里面 EchoController 这个类
在这里插入图片描述
代码如下:

@RestController
public class EchoController {
    
    
	@Value("${server.port}")
	private Integer port ;
	/**
	* echo message
	* @param message
	* @return reply content
	*/
	@GetMapping("/echo/{message}")
	public ResponseEntity<String> echo(@PathVariable("message") String
	message){
    
    
		return ResponseEntity.ok(String.format("hello,%s,我是服务提供者:%s",message,port)) ;
	}
}

因为我们在同一台机器上启动多个服务提供者,那服务提供者的端口肯定不相同,我们在此使用 port 作为服务提供者的唯一标示。
@Value : 从 env 里面注入这个值

5.2 启动多个服务的提供者

先停止所有的服务:
在这里插入图片描述
在启动一个服务的提供者:
在这里插入图片描述
启动成功后:
在这里插入图片描述
启动其他 1 个:
在这里插入图片描述
进入编辑页面:
在这里插入图片描述
2 个操作:
Name:不能重复,这里我修改为 ProviderApplication-2
Program arguments--server.port=8081这句话的意思是,在启动该服务时,添加一个变量: server.port=8081,类似我们使用这样的命令启动:

java -jar xxx.jar --server.port=8081

--server.port该 值 将 会 被 添 加 到 spring 的 env 里 面 , 并 且 该 方 式 的 优 先 级 高 于application.yml 里面的配置值。所以,系统会使用该 port 来启动服务。
修改完毕后,点击 ok。
现在启动我们的复制的 ProviderApplicaton-2:
在这里插入图片描述
观察 Nacos 里面的数据:
在这里插入图片描述
服务:provider-service 已经有 2 个实例了,点击详情:
在这里插入图片描述
可以手动的下线该服务。

5.3 测试负载均衡

修改 consumer 里面的 ConsumerApplication ,在里面的末尾添加如下的代码:

@Autowired
private LoadBalancerClient loadBalancerClient ;

@GetMapping("/choose/{serviceName}")
public ResponseEntity<String> choose(@PathVariable("serviceName") String serviceName){
    
    
	ServiceInstance instance = loadBalancerClient.choose(serviceName);
	System.out.println(String.format("本次选择的实例
	为:%s:%s",instance.getHost(),instance.getPort()));
	return ResponseEntity.ok(instance.getHost()+":"+instance.getPort()) ;
}

其中:

  • LoadBalancerClient :Ribbon 提供给我们最外层的接口,使用它我们可以很轻易的实现负载均衡。
  • LoadBalancerClient.choose(serviceName):通过给定的服务名称,Ribbon 底层通过负载均衡的算法得到一个可以进行远程的实例。

现在,启动 Consumer 进行测试:
在浏览器里面输入:
http://localhost:8090/choose/provider-service
得到:
在这里插入图片描述
刷新页面:
在这里插入图片描述
并且后台输出:
在这里插入图片描述
发现负载均衡已经完成。

5.4 更简单的远程调用测试

在之前,我们在 consumer 使用 RestTemplate 调用 provider 时,手动实现了负载均衡,url的拼接:
在这里插入图片描述
代码相当的冗余。现在,我们使用 Ribbon 的方式来实现:

在注入 RestTemplate 的方法上添加注解:
在这里插入图片描述
远程调用的代码变为:

@GetMapping("/rpc/ribbon/{message}")
public ResponseEntity<String> rpcByRibbon(@PathVariable("message") String
message){
    
    
	ResponseEntity<String> responseEntity =
restTemplate.getForEntity("http://provider-service/echo/" + message,
String.class);
	if(responseEntity.getStatusCode()==HttpStatus.OK){
    
    
		return ResponseEntity.ok("调用成功,provider-service 相应给我们的数据为:"+responseEntity.getBody()) ;
	}
	return ResponseEntity.badRequest().body("调用失败,provider-service 的相应码为:"+responseEntity.getStatusCode()) ;
}

在这里插入图片描述
重启 consumer 测试:
在浏览器里面输入:
http://localhost:8090/rpc/ribbon/{message}
在这里插入图片描述
刷新测试:
在这里插入图片描述
负载均衡已经完成了。

六、Nacos Discovery 对外暴露的 Endpoint

Nacos Discovery 内部提供了一个 Endpoint, 对应的 endpoint id 为 nacos-discovery。我们通过该 Endpoint,能获取到:

  • 当前服务有哪些服务订阅者 ;
  • 当前应用 Nacos 的基础配置信息 ;

6.1 给项目添加依赖

假设我们想看服务提供者(provider)有那些订阅者,以及 Nacos 的基础配置信息。

我们就需要给 provider 项目的 pom.xml 文件里面添加:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-actuator</artifactId>
	</dependency>
</dependencies>

6.2 修改配置文件

Endpoint 本身对外界隐藏显示,我们需要在配置里面开启对 Endponit 的显示支持。

修改 application.yml 配置文件,在里面添加如下的配置:

management:
	endpoints:
		web:
			exposure:
				include: "*"

说明:

  • exposure.include:对外界保留那些 Endpoint,若是所有则使用*

6.3 查询效果

重启项目,浏览器访问:
http://localhost:8081/actuator/nacos-discovery
效果为:
在这里插入图片描述

七、Nacos Discovery Starter 更多的配置项

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Nacos 配置中心

一、Nacos Config 简介

在这里插入图片描述
使用 Spring Cloud Alibaba Nacos Config,可基于 Spring Cloud 的编程模型快速接入 Nacos 配置管理功能。

上一节 Spring Cloud Alibaba Nacos 注册中心记录了 Nacos 作为注册中心的使用方式,这节继续记录下Nacos作为配置中心的使用方式。本节使用的Spring Cloud版本为Hoxton.SR3,Spring Cloud Alibaba 版本为 2.2.0.RELEASE,Spring Boot 版本为 2.2.3.RELEASE。

二、项目的搭建

在这里插入图片描述
我们将在我们 nacos-examples 的基础上,搭建一个 config-client,用来 nacos 配置中心的案例测试。

2.1 创建 config-client 项目

使用 IDEA 创建一个 Maven 模块:
在这里插入图片描述
选择 Maven:
在这里插入图片描述
点击下一步:
在这里插入图片描述
Parent:选择 nacos-examples
Name:config-client
其他的项,保持默认。
点击 FINISH 完成创建的过程:
在这里插入图片描述

2.2 添加依赖

我们的项目继承自 nacos-examples,它里面已经包含 2 个基本的依赖:

  • 服务注册和发现:spring-cloud-alibaba-nacos-discovery 这个是微服务里面必不可缺的组件
  • Web 开发相关:spring-boot-starter-web 开发 web 项目最基础的依赖现在,我们在里面添加今天我们要学习的配置获取的组件:
spring-cloud-alibaba-nacos-config

编辑 config-client 里面的 pom.xml 文件,添加以下的内容:

<dependencies>
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
	</dependency>
</dependencies>

在添加一个 mavne 的打包插件:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

查看项目所有的依赖:
在这里插入图片描述
现在,项目里面已经包含上面的 3 个依赖了。

2.3 完整的 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>nacos-examples</artifactId>
		<groupId>com.bjsxt</groupId>
		<version>1.0</version>
	</parent>
	<modelVersion>4.0.0</modelVersion>
	<artifactId>config-client</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

至此,项目的搭建完成了。

三、在 nacos-server 里面添加配置

相关的工作图,如图:
在这里插入图片描述
Nacos-client 会从 Nacos-Server 里面获取配置文件,首先,Nacos-Server 里面需要有配置文件才能获取。
新建如下所示的配置信息:
在这里插入图片描述
打开 Nacos 的管理页面:
在这里插入图片描述
现在我们看见,里面还没有任何的配置信息。
点击:
在这里插入图片描述
让我们来新建一个配置项:
填写的表单如下:
在这里插入图片描述
点击发布,完成配置文件的发表任务:
在这里插入图片描述
返回后,配置信息已经发布成功:
在这里插入图片描述

四、获取配置信息

我们将演示在 config-client 里面获取上面我们写的 2 个配置信

4.1 添加一个配置文件

在这里插入图片描述
文件名称为:
在这里插入图片描述
注意:不是 application.yml ,bootstrap.yml 比 application 有更高的优先级。

Idea 能自动的识别该文件的格式:
在这里插入图片描述

编辑该文件,添加以下内容:

server:
	port: 8070
spring:
	cloud:
		nacos:
			discovery:
				server-addr: localhost:8848
			config: # 指定配置中心的地址和配置中心使用的数据格式
				server-addr: localhost:8848
				file-extension: properties
	application:
		name: config-clien

配置说明:
server.port: 服务的运行端口
在这里插入图片描述

4.2 新建一个启动类

在这里插入图片描述
名称为:com.bjsxt.ConfigClientApplication
在这里插入图片描述
编辑该类:

@SpringBootApplication
@EnableDiscoveryClient
@RefreshScope
@RestController
public class ConfigClientApplication {
    
    
	@Value("${user.name}")
	private String userName ;
	
	@Value("${user.age}")
	private Integer userAge ;
	
	public static void main(String[] args) {
    
    
		SpringApplication.run(ConfigClientApplication.class,args) ;
	}
	
	/**
	* 获取配置文件里面用户的信息
	* @return
	*/
	@GetMapping("/user/info")
	public ResponseEntity<String> getUser(){
    
    
		return ResponseEntity.ok(
			String.format("从配置中心获取的信息为:user:%s,
	age:%s",userName,userAge)) ;
	}
}

说明:
@RefreshScope:代表配置文件是可以被刷新的
@Value:从 env 里面获取配置信息

4.3 启动测试

在这里插入图片描述
在浏览器里面输入:
http://localhost:8070/user/info
在这里插入图片描述
效果已经完成了。

五、获取配置规则

nacos 配置中心通过 namespace、dataId 和 group 来唯一确定一条配置。

  • Namespace:即命名空间。默认的命名空间为 public,我们可以在 Nacos 控制台中新建命名空间;
  • dataId:即配置文件名称
  • Group:即配置分组,默认为 DEFAULT_GROUP,可以通过 spring.cloud.nacos.config.group配置。

其中:dataId 是最关键的配置字段:格式如下:

${
    
    prefix} - ${
    
    spring.profiles.active} .${
    
    file-extension}

说明:

  • prefix 默 认 为 spring.application.name的 值 , 也 可 以 通 过 配 置 项spring.cloud.nacos.config.prefix来配置;
  • spring.profiles.active即为当前环境对应的 profile。注意,当 spring.profiles.active为空时,对应的连接符-也将不存在,dataId 的拼接格式变成${prefix}.${file-extension};
  • file-extension 为 配 置 内 容 的 数 据 格 式 , 可 以 通 过 配 置 项spring.cloud.nacos.config.file-extension来配置。

这就是上面我们为什么能获得到配置的原因了。

六、配置划分实战

在这里插入图片描述
Nacos 配置中心的 namespace、dataId 和 group 可以方便灵活地划分配置。比如,我们现在有一个项目需要开发,项目名称为 bjsxt,项目开发人员分为两个组:GROUP_A 和 GROUP_B,
项目分为三个环境:开发环境 dev、测试环境 test 和生产环境 prod。
Bjsxt->GRUOR_A->dev

6.1 在 Nacos 控制台中新建一个名称为 bjsxt 的命名空

在这里插入图片描述
点击新建命令空间:
填写以下的内容:
在这里插入图片描述
点击确定,完成创建。
完成后,如图所示:
在这里插入图片描述
新建完成后:我们看见它自动帮我们生产了一个 ID:

8defab18-df88-49e5-b13e-526f89da87ad

记录该 ID 值

6.2 在 Nacos 新建

在这里插入图片描述
切换完成后,点击 +:
在这里插入图片描述
填写以上的信息。点击发布:
在这里插入图片描述
完成后:
在这里插入图片描述
已经完成创建。

6.3 获取配置文件

修改 config-client 里的 bootstrap.yml 文件:

server:
	port: 8070
spring:
	cloud:
		nacos:
			discovery:
				server-addr: localhost:8848
			config: # 指定配置中心的地址和配置中心使用的数据格式
				server-addr: localhost:8848
				file-extension: yml #properties
				group: GROUP_A # 获取 GROUP_A 里面的配置
				namespace: 8defab18-df88-49e5-b13e-526f89da87ad # 命名空间,注意写 id的值不是name
# prefix: ${
    
    spring.application.name} # 前缀,默认为应用的名称,不需要修改
	application:
		name: config-client
	profiles:
		active: dev # 使用的 dev 环境的配

在这里插入图片描述

6.4 重启 config-client 测试

在这里插入图片描述

浏览器访问:
http://localhost:8070/user/info
得到:
在这里插入图片描述
配置信息已经获取成功。

七、配置回滚

Nacos 中,修改配置点击发布后会创建一个对应的历史版本快照,我们可以在 Nacos 控制台的历史版本列表中找到这些快照。

7.1 动态刷新

在这里插入图片描述
该注解,可以刷新配置。故无需启动就能看见最新的配置信息。

7.2 修改配置文件

在这里插入图片描述
修改 user.name ,user.age:
在这里插入图片描述
点击发布。
出现对比页面:
在这里插入图片描述
点击确认发布:
在这里插入图片描述
然后点击返回。

7.3 历史版本的查询

在这里插入图片描述

在这里插入图片描述
可以看见修改的日期。

7.4 回滚

将配置信息回滚为之前的版本:
在这里插入图片描述
根据修改时间,我们将 12:38:53 的数据回滚为 12:25:12 的数据:
在这里插入图片描述
已经自动的展示回滚的内容了,点击回滚配置:
在这里插入图片描述
点击确认,完成回滚:
在这里插入图片描述
再次测试:
浏览器输入:
http://localhost:8070/user/info
已经回滚成功了:
在这里插入图片描述

八、获取多个配置

除了通过上面的方式指定一个唯一配置外,我们还可以同时获取多个配置文件的内容。

8.1 修改 config-client 里面的配置文件

server:
	port: 8070
spring:
	cloud:
		nacos:
			discovery:
				server-addr: localhost:8848
			config:
				extension-configs: # 多个配置
				- dataId: test-a.yml
					group: DEFAULT_GROUP
					refresh: true
				- dataId: test-b.yml
					group: DEFAULT_GROUP
					refresh: false
				# 指定配置中心的地址和配置中心使用的数据格式
				# server-addr: localhost:8848
				# file-extension: yml #properties
				# group: GROUP_A # 获取 GROUP_A 里面的配置
				# namespace: 8defab18-df88-49e5-b13e-526f89da87ad # 命名空间,写 id 的值
				## prefix: ${
    
    spring.application.name} # 前缀,默认为应用的名称,不需要修改
	application:
		name: config-client
	profiles:
		active: dev # 使用的 dev 环境的配置

说明:

  • spring.cloud.nacos.config.extension-configs[n].dataId,指定多个配置的 dataId,必须包含文件格式,支持 properties、yaml 或 yml;
  • spring.cloud.nacos.config.extension-configs[n].group,指定分组;
  • spring.cloud.nacos.config.extension-configs[n].refresh,是否支持刷新。
    上 面 的 配 置 中 , 我 们 分 别 从DEFAULT_GROUP 中 获 取 了 config-client-a.ymlconfig-client-b.yml配置内容,并且 config-client-a.yml支持刷新,config-client-b.yml不支持刷新。

注意:没有 namespace 的配置,言外之意就是 Nacos 目前还不支持多个配置指定不同的命名空间。

8.2 在 Nacos 里面完成这 2 个配置文件的创建

config-client-a.yml:
切换 namespace:
在这里插入图片描述
点击 + 完成创建:
在这里插入图片描述
点击发布。
config-client-b.yml
在这里插入图片描述
在这里插入图片描述
完成后:
在这里插入图片描述

8.3 获取配置信息

重启 config-client,测试:
浏览器访问:

九、Spring Cloud Alibaba Nacos Config 常用的配置

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42588990/article/details/121512011