不断踩坑并解决问题是每个程序员进阶到资深的必要经历并以此获得满足感,而不断阅读开源项目源码和总结思想是每个架构师成长最佳途径。本篇拉开SpringCloud Alibaba最新版本实战和原理序幕,以工程实践的简单完整实战示例为主线,步步深入并可为实际项目中带来启发 Nacos GitHub源码地址 https://github.com/alibaba/nacos ,目前源码基于高性能RPC的2.1.0,和基于HTTP RESTFUL的1.4.3版本的两条分支,因此2.X系列Nacos性能比1.X版本至少提升2倍以上,我们这边下载研究的是2.1.0版本的源码。
Nacos 官网地址 https://nacos.io/zh-cn/docs
Spring-Cloud-Alibaba GitHub源码地址
前面的《主流微服务一站式解决方案Spring Cloud Alibaba入门看这篇就足够了-开篇》我们已经简单介绍Spring Cloud Alibaba一站式解决方案的入门,对Spring Cloud Alibaba有了基本认识,开发人员可以通过 Spring Cloud 编程模型轻松使用其生态组件来来开发分布式应用服务,而这过程只需添加一些注解和少量配置就可以将 Spring Cloud 应用接入阿里的分布式应用解决方案,最终通过阿里中间件来迅速搭建分布式应用系统。此外阿里云同时还提供了 Spring Cloud Alibaba 企业版 微服务解决方案(包括无侵入服务治理全链路灰度,无损上下线,离群实例摘除等,企业级 Nacos 注册配置中心和企业级云原生网关等众多产品),分布式功能更加强大完善,有兴趣的伙伴可以自行前往了解。
Nacos官网提供Nacos2.0.0-ALPHA2 服务发现性能测试报告,其他的如1.0和2.0配置模块压测报告,1.0服务发现模块的压测报告等都可以去详细查阅官网


Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施,致力于发现、配置和管理微服务,可以快速实现动态服务发现、服务配置、服务元数据及流量管理。简单来说就是集注册中心和配置中心于一体,几乎支持所有市面同类型产品的所有功能,Nacos 支持主流的服务生态包括Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful,可以说是目前国内最主流、最强大、性能最好的注册中心和配置中心的选型,下面为Nacos与其他同类型产品的对比



Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。命名空间 》组 》Service/DataId.

如果有鉴权和配置加密的需求官方也提供相关插件支持。
官方提供多种部署方式,包括下载二进制文件部署、基于Docker和K8S部署,我们这里选择Docker-Compose方式部署
克隆项目
git clone --depth 1 https://github.com/nacos-group/nacos-docker.gitcd nacos-docker#目前版本为2.0.4,可以编辑vi example/.env进行修改NACOS_VERSION=v2.0.4Standalone Mysql
# Using mysql 5.7 也可以选择 mysql 8 docker-compose -f example/standalone-mysql-5.7.yaml up -d

创建命名空间simple_ecommerce(简单电商网站),提交后默认生成命名空间ID为a2b1a5b7-d0bc-48e8-ab65-04695e61db01

创建用户itxs,密码为itxs123

用户itxs绑定CONFIG_MANAGER(配置管理员角色)

为角色CONFIG_MANAGER添加命名空间资源和可读写的操作权限

Nacos官方基于Java技术栈提供多种开发使用的方式,包括基于原生Java、Spring整合、SpringBoot整合、Spring Cloud整合、Dubbo整合等。我们本篇主要是以Spring Cloud Alibaba整合代码开发方式来做示例为主。基于Spring Cloud Alibaba使用方式如果用于生产环境,建议使用对应的官网版本说明,详细可以查看Spring Cloud Alibaba Wiki
组件版本关系:每个 Spring Cloud Alibaba 版本及其自身所适配的各组件对应版本(经过验证,自行搭配各组件版本不保证可用)如下表所示(最新版本用*标记):

下表为按时间顺序发布的 Spring Cloud Alibaba 以及对应的适配 Spring Cloud 和 Spring Boot 版本关系(由于 Spring Cloud 版本命名有调整,所以对应的 Spring Cloud Alibaba 版本号也做了对应变化)

我们这里不是生产环境,用于开发测试学习的话可以选择最新也即是向下兼容的思想,因此Nacos还是使用上面的2.0.4,踩坑了再来解决还能更深刻理解原理。
本示例采用MySQL数据库,以docker方式部署MySQL 8.0.28版本
CREATE DATABASE IF NOT EXISTS storageDEFAULT CHARACTER SET utf8DEFAULT COLLATE utf8_chinese_ci;DROP TABLE IF EXISTS `storage_tbl`;CREATE TABLE `storage_tbl` ( `id` int(11) NOT NULL AUTO_INCREMENT, `commodity_code` varchar(255) DEFAULT NULL, `count` int(11) DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY (`commodity_code`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS orderDEFAULT CHARACTER SET utf8DEFAULT COLLATE utf8_chinese_ci;DROP TABLE IF EXISTS `order_tbl`;CREATE TABLE `order_tbl` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` varchar(255) DEFAULT NULL, `commodity_code` varchar(255) DEFAULT NULL, `count` int(11) DEFAULT 0, `money` int(11) DEFAULT 0, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS accountDEFAULT CHARACTER SET utf8DEFAULT COLLATE utf8_chinese_ci;DROP TABLE IF EXISTS `account_tbl`;CREATE TABLE `account_tbl` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` varchar(255) DEFAULT NULL, `money` int(11) DEFAULT 0, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;创建工程主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>cn.itxs</groupId> <artifactId>simple_ecommerce</artifactId> <version>1.0</version> <modules> <module>ecom_bom</module> <module>ecom_commons</module> <module>ecom_storage</module> </modules> <name>simple_ecommerce</name> <packaging>pom</packaging> <description>a simple electronic commerce platform demo tutorial</description> <properties> <java.verson>1.8</java.verson> <encoding>UTF-8</encoding> <spring-boot.version>2.6.4</spring-boot.version> <spring.cloud.verison>2021.0.1</spring.cloud.verison> <spring.cloud.alibaba.verison>2021.0.1.0</spring.cloud.alibaba.verison> <ecom.bom.version>1.0</ecom.bom.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <!--统一项目整体第三方依赖版本--> <dependency> <groupId>cn.itxs</groupId> <artifactId>ecom_bom</artifactId> <version>${ecom.bom.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--统一版本spring-boot、spring-cloud、spring.cloud.alibaba--> <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>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.verison}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.verison}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement></project>管理第三方依赖Bom的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>cn.itxs</groupId> <artifactId>ecom_bom</artifactId> <name>ecom_bom</name> <packaging>pom</packaging> <version>1.0</version> <description>manage third-party package versions</description> <properties> <ecom.commons.version>1.0</ecom.commons.version> <seata-spring-boot.version>1.4.2</seata-spring-boot.version> <mysql.version>8.0.28</mysql.version> <druid.version>1.2.8</druid.version> <mybatis-plus.version>3.5.1</mybatis-plus.version> <lombok.version>1.18.22</lombok.version> <hutool-all.verison>5.7.22</hutool-all.verison> <apm-toolkit-trace.version>8.7.0</apm-toolkit-trace.version> <jetcache.redis.version>2.6.2</jetcache.redis.version> <fastjson.version>1.2.80</fastjson.version> <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version> <velocity.version>2.3</velocity.version> </properties> <dependencyManagement> <dependencies> <!--ecom-commons 版本--> <dependency> <groupId>cn.itxs</groupId> <artifactId>ecom_commons</artifactId> <version>${ecom.commons.version}</version> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>${seata-spring-boot.version}</version> </dependency> <!--database--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool-all.verison}</version> </dependency> <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <version>${apm-toolkit-trace.version}</version> </dependency> <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>${jetcache.redis.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>${mybatis-plus-generator.version}</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>${velocity.version}</version> </dependency> </dependencies> </dependencyManagement></project>公共commons模块的Pom文件,包含Spring Cloud Alibaba常见组件的客户端依赖而不仅仅是本篇的Nacos客户端,后续如增加再逐步补充
<?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>simple_ecommerce</artifactId> <groupId>cn.itxs</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ecom_commons</artifactId> <name>ecom_commons</name> <packaging>jar</packaging> <description>a commons module</description> <version>1.0</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!--undertow 性能比tomcat稍高--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <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-openfeign</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> </dependencies></project>创建库存微服务模块,其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"> <parent> <artifactId>simple_ecommerce</artifactId> <groupId>cn.itxs</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ecom_storage</artifactId> <packaging>jar</packaging> <version>1.0</version> <name>ecom_storage</name> <description>a simple electronic commerce platform demo tutorial for storage service</description> <dependencies> <dependency> <groupId>cn.itxs</groupId> <artifactId>ecom_commons</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 指定该Main Class为全局的唯一入口 --> <mainClass>com.aotain.cu.underly.infra.xx1.Xx1ServiceApplication</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> </goals> </execution> </executions> </plugin> </plugins> </build></project>并创建库存微服务SpringBoot启动类和bootstrap.yml,至此大体工程框架雏形已具备

计划是每个微服务本地bootstrap.yml里只需配置Nacos配置中心的地址,其他配置项全部放在配置中心里管理,因此我们先从Nacos配置中心开始。