本系列隨筆轉自:https://www.jianshu.com/p/9a8d94c0c90c
中篇見:Spring Cloud Alibaba 簡介(中) - Chen洋 - 博客園 (cnblogs.com)
下篇見:Spring Cloud Alibaba 簡介(下) - Chen洋 - 博客園 (cnblogs.com)
1.Spring Cloud Alibaba簡述
1.1 概述
2018年10月31日,SpringCloudAlibaba 正式入駐 SpringCloud 官方孵化器,並在 Maven 中央庫發布第一個版本。
Spring Cloud for Alibaba 0.2.0 released
The Spring Cloud Alibaba project, consisting of Alibaba’s open-source components and several Alibaba Cloud products,
aims to implement and expose well known Spring Framework patterns and abstractions to bring the benefits of Spring Boot
and Spring Cloud to Java developers using Alibaba products.
Spring Cloud for Alibaba,它是由一些阿里巴巴的開源組件和雲產品組成的。這個項目的目的是為了讓大家所熟知的 Spring 框架,
其優秀的設計模式和抽象理念,以給使用阿里巴巴產品的 Java 開發者帶來使用 Spring Boot 和 Spring Cloud 的更多便利。
Spring Cloud Alibaba 致力於提供微服務開發的一站式解決方案。該項目包含開發分布式應用微服務的必需組件,方便開發者通過 Spring Cloud 編程模型輕松使用這些組件來開發分布式應用服務。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以將 Spring Cloud 應用接入阿里微服務解決方案,通過阿里中間件來迅速搭建分布式應用系統。
1.2 主要功能
- 服務限流降級:默認支持 Servlet、Feign、RestTemplate、Dubbo 和 RocketMQ 限流降級功能的接入,可以在運行時通過控制台實時修改限流降級規則,還支持查看限流降級 Metrics 監控。
- 服務注冊與發現:適配 SpringCloud 服務注冊與發現標准,默認集成了 Ribbon的支持。
- 分布式配置管理:支持分布式系統中的外部化配置,配置更改時自動刷新。
- 消息驅動能力:基於 SpringCloudStream 為微服務應用構建消息驅動能力。
- 阿里雲對象存儲:阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。支持在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。
- 分布式任務調度:提供秒級、精准、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務。同時提供分布式的任務執行模型,如網格任務。網格任務支持海量子任務均勻分配到所有 Worker(schedulerx-client)上執行。
1.3 組件
- Sentinel:面向分布式服務架構的輕量級流量控制產品,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助您保護服務的穩定性。
- Nacos:阿里巴巴推出來的一個新開源項目,這是一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平台。
- RocketMQ:分布式消息系統,基於高可用分布式集群技術,提供低延時的、高可靠的消息發布與訂閱服務。
- Alibaba Cloud ACM:一款在分布式架構環境中對應用配置進行集中管理和推送的應用配置中心產品。
- Alibaba Cloud OSS: 阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。您可以在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。
- Alibaba Cloud SchedulerX: 阿里中間件團隊開發的一款分布式任務調度產品,提供秒級、精准、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務。
2.Spring Cloud Alibaba 創建依賴管理項目
當前 Spring Cloud Alibaba 的 2.1.0.RELEASE 版本基於 Spring Cloud Greenwich 開發, Spring Cloud Alibaba 項目都是基於 Spring Cloud,而 Spring Cloud 項目又是基於 Spring Boot 進行開發,
並且都是使用 Maven 做項目管理工具。在實際開發中,我們一般都會創建一個依賴管理項目作為 Maven 的 Parent 項目使用,
這樣做可以極大的方便我們對 Jar 包版本的統一管理。
創建依賴管理項目
創建文件夾
在電腦上創建一個文件夾hello-spring-cloud-alibaba當做項目的根目錄

用idea打開
用idea打開剛剛創建的文件夾:

創建子模塊
選擇hello-spring-cloud-alibaba根目錄鼠標右鍵
創建子模塊hello-spring-cloud-alibaba-dependencies

創建pom
在hello-spring-cloud-alibaba-dependencies下創建pom.xml文件
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.4.RELEASE</version> </parent> <groupId>com.wsl</groupId> <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId> <version>1.0.0-SNAPSHOT</version> <name>hello-spring-cloud-alibaba-dependencies</name> <inceptionYear>2019-Now</inceptionYear> <description>Demo project for Spring Boot</description> <packaging>pom</packaging> <properties> <!-- Environment Settings --> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Spring Settings --> <spring-cloud.version>Hoxton.SR1</spring-cloud.version> <spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.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>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <!-- Compiler 插件, 設定 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <showWarnings>true</showWarnings> </configuration> </plugin> <!-- 打包 jar 文件時,配置 manifest 文件,加入 lib 包的 jar 依賴 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <addMavenDescriptor>false</addMavenDescriptor> </archive> </configuration> <executions> <execution> <configuration> <archive> <manifest> <!-- Add directory entries --> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </execution> </executions> </plugin> <!-- resource --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> </plugin> <!-- install --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> </plugin> <!-- clean --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> </plugin> <!-- ant --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> </plugin> <!-- dependency --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> </plugin> </plugins> <pluginManagement> <plugins> <!-- Java Document Generate --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <executions> <execution> <phase>prepare-package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <!-- YUI Compressor (CSS/JS壓縮) --> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>yuicompressor-maven-plugin</artifactId> <version>1.5.1</version> <executions> <execution> <phase>prepare-package</phase> <goals> <goal>compress</goal> </goals> </execution> </executions> <configuration> <encoding>UTF-8</encoding> <jswarn>false</jswarn> <nosuffix>true</nosuffix> <linebreakpos>30000</linebreakpos> <force>true</force> <includes> <include>**/*.js</include> <include>**/*.css</include> </includes> <excludes> <exclude>**/*.min.js</exclude> <exclude>**/*.min.css</exclude> </excludes> </configuration> </plugin> </plugins> </pluginManagement> <!-- 資源文件配置 --> <resources> <resource> <directory>src/main/java</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build> <repositories> <repository> <id>aliyun-repos</id> <name>Aliyun Repository</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>sonatype-repos</id> <name>Sonatype Repository</name> <url>https://oss.sonatype.org/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>sonatype-repos-s</id> <name>Sonatype Repository</name> <url>https://oss.sonatype.org/content/repositories/snapshots</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>aliyun-repos</id> <name>Aliyun Repository</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
- parent:繼承了 Spring Boot 的 Parent,表示我們是一個 Spring Boot 工程
- package:pom,表示該項目僅當做依賴項目,沒有具體的實現代碼
- spring-cloud-alibaba-dependencies:在 properties 配置中預定義了版本號為 2.1.0.RELEASE ,表示我們的 Spring Cloud Alibaba 對應的是 Spring Cloud Greenwich 版本
- build:配置了項目所需的各種插件
- repositories:配置項目下載依賴時的第三方庫
將pom加到maven
添加pom文件到maven

目錄結構
依賴版本簡介
項目的最新版本是 2.1.0.RELEASE
1.5.x 版本適用於 Spring Boot 1.5.x
2.0.x 版本適用於 Spring Boot 2.0.x
2.1.x 版本適用於 Spring Boot 2.1.x
3.Spring Cloud Alibaba 服務注冊與發現(nacos)
由於SpringCloud之前采用的Eureka已經進入暫停維護階段,所以我們采用阿里巴巴提供的Nacos組件,畢竟論流量中國是世界之最,十年的雙十一經驗,阿里的服務支持還是很靠譜的。
Nacos 官網
acos
Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。
Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平台。 Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務范式、雲原生范式) 的服務基礎設施。
Nacos 地圖
- 特性大圖:要從功能特性,非功能特性,全面介紹我們要解的問題域的特性訴求
- 架構大圖:通過清晰架構,讓您快速進入 Nacos 世界
- 業務大圖:利用當前特性可以支持的業務場景,及其最佳實踐
- 生態大圖:系統梳理 Nacos 和主流技術生態的關系
- 優勢大圖:展示 Nacos 核心競爭力
- 戰略大圖:要從戰略到戰術層面講 Nacos 的宏觀優勢
Nacos 生態圖

安裝Nacos
安裝環境
Nacos 依賴 Java 環境來運行。如果你是從代碼開始構建並運行Nacos,還需要為此配置Maven環境,請確保是在以下版本環境中安裝使用:
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推薦選用 Linux/Unix/Mac。
- 64 bit JDK 1.8+
- Maven 3.2.x+
下載並安裝
# 下載源碼 git clone https://github.com/alibaba/nacos.git # 安裝到本地倉庫 cd nacos/ mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
第一次下載時間有點長,耐心等一會,install時間也不短.....
啟動Nacos
cd distribution/target/nacos-server-$version/nacos/bin # Linux ./startup.sh -m standalone # Windows startup.cmd

訪問服務
打開瀏覽器訪問:http://localhost:8848/nacos

注:從 0.8.0 版本開始,需要登錄才可訪問,默認賬號密碼為 nacos/nacos
4.Spring Cloud Alibaba 創建服務提供者
概述
通過一個簡單的示例來感受一下如何將服務注冊到 Nacos,其實和 Eureka 沒有太大差別。
POM
創建一個工程名為 hello-spring-cloud-alibaba-nacos-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"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.wsl</groupId> <artifactId>hello-spring-cloud-alibaba-dependencies</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../hello-spring-cloud-alibaba-dependencies/pom.xml</relativePath> </parent> <artifactId>hello-spring-cloud-alibaba-provider</artifactId> <packaging>jar</packaging> <name>hello-spring-cloud-alibaba-provider</name> <properties> <java.version>1.8</java.version> </properties> <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>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- Spring Cloud End--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.wsl.provider.ProviderApplication</mainClass> </configuration> </plugin> </plugins> </build> </project>
Application
package com.wsl.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); } }
通過 @EnableDiscoveryClient注解表明是一個Nacos客戶端,該注解是 SpringCloud 提供的原生注解。
application.yml
spring: application: name: nacos-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848 server: port: 8081 management: endpoints: web: exposure: include: "*"

controller
@RestController public class NacosProviderController { @Value("${server.port}") private String port; // 注入配置文件上下文 @Autowired private ConfigurableApplicationContext applicationContext; @GetMapping(value = "/test/{message}") public String test(@PathVariable String message) { return "Hello Nacos Discovery " + message + " i am from port " + port; } // 從上下文中讀取配置 @GetMapping(value = "/hi") public String sayHi() { return "Hello " + applicationContext.getEnvironment().getProperty("user.name"); } }
啟動工程
通過瀏覽器訪問 http://localhost:8848/nacos,即 Nacos Server 網址

你會發現一個服務已經注冊在服務中了,服務名為 nacos-provider
這時打開 http://localhost:8081/test/hi ,你會在瀏覽器上看到:

服務的端點檢查
spring-cloud-starter-alibaba-nacos-discovery 在實現的時候提供了一個 EndPoint, EndPoint 的訪問地址為 http://ip:port/actuator/nacos-discovery。 EndPoint 的信息主要提供了兩類:
1、subscribe: 顯示了當前有哪些服務訂閱者
2、NacosDiscoveryProperties: 顯示了當前服務實例關於 Nacos 的基礎配置
通過瀏覽器訪問 http://localhost:8081/actuator/nacos-discovery 你會在瀏覽器上看到:
Nacos Starter 更多配置項信息
| 配置項 | Key | 默認值 | 說明 |
|---|---|---|---|
| 服務端地址 | spring.cloud.nacos.discovery.server-addr | 無 | Nacos Server 啟動監聽的ip地址和端口 |
| 服務名 | spring.cloud.nacos.discovery.service | ${spring.application.name} | 給當前的服務命名 |
| 權重 | spring.cloud.nacos.discovery.weight | 1 | 取值范圍 1 到 100,數值越大,權重越大 |
| 網卡名 | spring.cloud.nacos.discovery.network-interface | 無 | 當IP未配置時,注冊的IP為此網卡所對應的IP地址,如果此項也未配置,則默認取第一塊網卡的地址 |
| 注冊的IP地址 | spring.cloud.nacos.discovery.ip | 無 | 優先級最高 |
| 注冊的端口 | spring.cloud.nacos.discovery.port | -1 | 默認情況下不用配置,會自動探測 |
| 命名空間 | spring.cloud.nacos.discovery.namespace | 無 | 常用場景之一是不同環境的注冊的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等。 |
| AccessKey | spring.cloud.nacos.discovery.access-key | 無 | 當要上阿里雲時,阿里雲上面的一個雲賬號名 |
| SecretKey | spring.cloud.nacos.discovery.secret-key | 無 | 當要上阿里雲時,阿里雲上面的一個雲賬號密碼 |
| Metadata | spring.cloud.nacos.discovery.metadata | 無 | 使用 Map 格式配置,用戶可以根據自己的需要自定義一些和服務相關的元數據信息 |
| 日志文件名 | spring.cloud.nacos.discovery.log-name | 無 | |
| 接入點 | spring.cloud.nacos.discovery.enpoint | UTF-8 | 地域的某個服務的入口域名,通過此域名可以動態地拿到服務端地址 |
| 是否集成 Ribbon | ribbon.nacos.enabled | true | 一般都設置成 true 即可 |
