在前段時間為大家分享了SpringCloudAlibaba微服務項目實戰的課程,可是有很多同學反饋,我根本這方面不太了解,能不能有個普及教程呢,那么今天來了,為大家分享一個SpringCloudAlibaba的基礎入門教程,在配合項目實戰教程學習就更容易入手啦!
本期將會為大家帶來什么?
第一章:SpringCloudAlibaba簡述
第二章:基於Nacos構建分布式注冊中心
第三章:基於Nacos構建分布式配置中心
第四章:Sentinel服務治理
第一章:SpringCloudAlibaba簡述
微服務架構演變歷程
傳統單體架構
單體架構在小微企業比較常見,典型代表就是一個應用、一個數據庫、一個web容器就可以跑起來。
SOA架構(面向服務)
隨着單體架構應用業務越來越復雜,開始對應用進行水平拆分、垂直拆分,慢慢的下沉的就成了基礎組件,上浮的就成了業務系統,架構的本質就是不斷的拆分重構:分的過程是把系統拆分為各個子系統/模塊/組件,拆的時候,首先要解決每個組件的定位問題,然后才能划分彼此的邊界,實現合理的拆分。合就是根據最終要求,把各個分離的組件有機整合在一起。拆分的結果使開發人員能夠做到業務聚焦、技能聚焦,實現開發敏捷,合的結果是系統變得柔性,可以因需而變,實現業務敏捷。
SOA架構是一套松耦合的架構,服務的拆分原則是服務內部高內聚,服務之間低耦合。
微服務架構
微服務架構目前並沒有一個嚴格的定義,
微服務架構是一種架構模式,它提倡將單一應用程序划分成一組小的服務,服務之間互相協調,互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務間采用輕量級的通信機制互相溝通,每個服務都圍繞着具體業務進行構建,並且能夠被獨立部署到生產環境,類生產環境等。
-
單一職責,對於每個服務而言,其處理的業務邏輯能夠單一。
-
輕量級通信,通常基於HTTP,能讓服務間通信變得標准化,無狀態化,REST是輕量級通信機制
-
獨立性,應用交付過程中,開發,測試以及部署保持獨立
-
進程隔離
簡單來說,微服務架構是 SOA 架構思想的一種擴展,更加強調服務個體的獨立性、拆分粒度更小
微服務的好處有:服務獨立、擴展性好、可靠性強,但同時,也面臨一些新的問題,比如運維復雜性,分布式復雜性、監控復雜性等等。
SOA架構與微服務架構之間的對比
SOA | 微服務 |
---|---|
企業級,自頂向下開展實施 | 團隊級,自底向上開展實施 |
由多個子系統組成,粒度大 | 拆分成多個服務,粒度細 |
企業服務總線,集中式的服務架構 | 無集中式總線,松散的服務架構 |
集成方式復雜(ESB/WS/SOAP) | 集成方式簡單(HTTP/REST/JSON) |
相互依賴,部署復雜 | 服務獨立部署 |
SpringCloud與SpringCloudAlibaba
pringCloud是基於SpringBoot的一整套實現微服務的框架。它提供了微服務開發所需的配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分布式會話和集群狀態管理等組件。最重要的是,基於SpringBoot,會讓開發微服務架構非常方便。
Spring Cloud Alibaba中的開源組件都直指Netflix OSS中的重要組件,Eureka 已經閉源,Hystrix已經不再更新,所以自Spring Cloud Alibaba發布第一個Release以來,就備受國內開發者的高度關注。雖然Spring Cloud Alibaba還沒能納入Spring Cloud的主版本管理,但是畢竟擁有阿里的背景。
Spring Cloud 加盟重量級成員Spring Cloud Alibaba,打造更符合中國國情的微服務體系
本次課程我們將會介紹由 SpringCloudAlibaba 提供的開源組件 Nacos 及 Sentinel
基於Nacos構建分布式注冊中心
分布式服務注冊中心概念
概念
-
服務注冊:每個服務在啟動的時候,告訴注冊中心自己的位置信息。
-
服務發現:商品服務想要調用訂單服務,先找注冊中心獲取到所有服務的位置信息,然后找到訂單服務的地址,發起調用。
-
心跳機制:服務啟動之后,每過30秒向注冊中心心跳一次(就是發送一個消息,告訴注冊中心自己還活着),如果注冊中心長時間沒有收到某個服務的心跳,那么就會認為這個服務已經宕機,就從服務注冊列表中刪除。
Nacos簡介
Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。
Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平台。Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務范式、雲原生范式) 的服務基礎設施。
中文文檔:https://nacos.io/zh-cn/docs/what-is-nacos.html
Nacos安裝
下載地址:https://github.com/alibaba/nacos/releases
本文版本:1.2.1
下載完成之后,解壓,在 bin 目錄下有啟動程序。
-
window:startup.cmd
-
linux:startup.sh
啟動之后,訪問 http://localhost:8848/nacos/
,進入 Nacos 的登錄界面,默認用戶名密碼為:nacos,登錄之后進入管理界面
構建應用接入 Nacos
構建一個服務提供者以及一個服務消費者來驗證服務的注冊與發現
構建服務提供者
需要有 SpringBoot 基礎
第一步:創建一個新的 SpringBoot 應用,命名為 nacos-provider
第二步:添加依賴
添加父依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent>
添加依賴管理器
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
添加依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Nacos服務注冊與發現模塊 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>
第三步:創建啟動類並提供一個應用接口
EnableDiscoveryClient @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Slf4j @RestController static class TestController { @GetMapping("/hello") public String hello(@RequestParam String name) { log.info("execute hello method with name : " + name); return "hello " + name; } } }
-
@SpringBootApplication
用於定義 SpringBoot 應用的啟動類 -
@EnableDiscoveryClient
Spring Cloud 提供的注解,用於開啟 Spring Cloud 的服務注冊與發現,由於這里引入了spring-cloud-starter-alibaba-nacos-discovery
,所以服務注冊與發現會使用 Nacos 的實現。這與Eureka
或者Consul
的操作是一樣的。
第四步:配置服務名稱及 Nacos 地址
server: port: 8080 spring: application: name: nacos-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848
第五步:啟動應用
如果打印如下日志,表示注冊成功
nacos registry, nacos-provider 10.32.52.236:8080 register finished
修改端口號,同一個應用啟動多個實例,實現集群
訪問 Nacos 管理界面,通過 服務管理 \> 服務列表
界面查看已注冊的服務
點擊詳情,可以查看集群中每個服務實例的具體信息
構建服務消費者
第一步:創建一個新的 SpringBoot 應用,命名為 nacos-consumer
第二步:添加依賴,與上面的構建服務提供者的內容一樣
第三步:創建啟動類並提供一個應用接口,在該接口實現對服務提供者提供的接口進行調用
@EnableDiscoveryClient @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Slf4j @RestController static class TestController { @Autowired LoadBalancerClient loadBalancerClient; @GetMapping("/test") public String test() { ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider"); String url = serviceInstance.getUri() + "/hello?name=" + "nacos"; RestTemplate restTemplate = new RestTemplate(); String result = restTemplate.getForObject(url, String.class); return "Invoke : " + url + ", return : " + result; } } }
這里使用了 Spring Cloud Common
中的 LoadBalancerClient
接口來挑選服務實例信息,使用負載均衡的算法,然后獲取被選中實例的URI,拼接上服務提供者接口的請求地址及參數,使用 RestTemplate
進行調用。
第四步:配置服務名稱及 Nacos 地址
跟上面的配置服務提供者基本一致,只是服務名及端口根據需要進行修改
server: port: 8082 spring: application: name: nacos-consumer cloud: nacos: discovery: server-addr: 127.0.0.1:8848
第五步:啟動服務
訪問地址 http://localhost:8082/test
,查看日志輸出
Invoke : http://10.32.52.236:8080/hello?name=nacos, return : hello nacos Invoke : http://10.32.52.236:8081/hello?name=nacos, return : hello nacos Invoke : http://10.32.52.236:8080/hello?name=nacos, return : hello nacos Invoke : http://10.32.52.236:8081/hello?name=nacos, return : hello nacos
可以看到,多次請求會被依次分配給 nacos-provider
服務集群中的兩個實例,可以分別查看兩個實例的日志輸出進行驗證。
多種方式實現服務間調用
使用RestTemplate
第一步:注冊
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
@LoadBalanced 注解標記負載均衡
第二步:使用
@RestController static class TestController { @Autowired RestTemplate restTemplate; @GetMapping("/test") public String test() { String result = restTemplate.getForObject("http://nacos-provider/hello?name=nacos", String.class); return "Return : " + result; } }
請求地址中,直接使用服務名代替 Host 部分,在真正調用時,SpringCloud 會將請求攔截,然后通過負載均衡器選出節點,並替換為具體節點的IP與端口執行調用。
使用Feign
第一步:消費者服務添加對 feign
的依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
第二步:修改服務啟動類,開啟 Feign 客戶端功能,並定義客戶端
@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @FeignClient("nacos-provider") public static interface Client { @GetMapping("/hello") String hello(@RequestParam String name); } }
-
@EnableFeignClients
注解用於開啟掃描 Feign 客戶端的功能 -
@FeignClient
注解用於定義 Feign 客戶端,需要指定這個接口所要調用的服務名稱,接口中定義的方法使用 Spring MVC 的注解就可以來綁定服務提供方的 REST 接口。
注意:如果是 get 請求方式,@RequestParam 必須要帶,否則 get 請求會被轉換成 post 請求導致請求失效
第三步:通過 Spring 容器注入接口對象,直接調用
@RestController public class FeignConsumerController { @Autowired private Application.Client client; @GetMapping("/testWithFeign") public String test() { String result = client.hello("haha"); return "result : " + result; } }
優點:強類型檢查
第三章:基於Nacos構建分布式配置中心
分布式配置中心概念
Nacos配置讀取及動態刷新
接下來通過一個簡單的例子實現在 Nacos 中創建配置,在 SpringBoot 應用中加載 Nacos 配置並響應 Nacos 中的配置變化
創建配置
第一步:進入 Nacos 管理界面,選擇 配置管理 \> 配置列表
,點擊右側 +
號創建新配置
重要的配置項說明:
-
DataId:使用
{項目名}.{配置格式}
的格式,本次填入nacos-config-client.properties
-
Group:分組名,默認為
DEFAULT_GROUP
,本次操作使用默認值 -
配置格式:默認為
properties
,本次操作使用默認值,如果要使用其它格式則需要在應用中進行相應地配置 -
配置內容填寫為
course.title=nacos
創建應用
第一步:創建一個 SpringBoot 應用,命名為 nacos-config-client
,保持跟上面的 DataId
一致第二步:添加依賴
添加父依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent>
添加依賴管理器
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
添加依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Nacos配置模塊 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
示例中並沒有添加對 Nacos 服務注冊發現模塊的依賴,配置功能跟服務注冊發現功能是完全分立的,可以獨立使用。
第三步:配置
配置服務名稱及 Nacos 地址
server.port=8083 spring.application.name=nacos-config-client spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name
配置成與 Nacos 中創建的 DataId
一致
第四步:創建啟動類,並提供一個對外接口
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Slf4j @RestController @RefreshScope static class TestController { @Value("${course.title}") private String title; @GetMapping("/test") public String hello() { return title; } } }
接口實現很簡單,就是輸出配置文件中的 couse.title
的內容
-
@Value
注解用於讀取配置文件中的配置 -
@RefreshScope
注解用於支持動態刷新配置內容,有了這個注解,在 Nacos 修改配置內容,@Value
就會及時讀取到最新的內容
第五步:啟動應用在啟動日志最開始可以看到兩行日志,說明已經成功從 Nacos 中加載配置,而且是在應用啟動之前進行加載
Loading nacos data, dataId: 'nacos-config-client.properties', group: 'DEFAULT_GROUP' Located property source: CompositePropertySource {name='NACOS', propertySource
第六步:驗證配置獲取
訪問接口 http://localhost:8083/test
,如果一切正常,則會輸出 Nacos 中配置的 nacos
第七步:驗證配置動態更新
在 Nacos 管理后台修改配置內容為 course.title=nacos changed
,再次訪問接口,可以看到輸出的結果也會相應改變。
查看日志,可以看到配置被重新加載
Loading nacos data, dataId: 'nacos-config-client.properties', group: 'DEFAULT_GROUP' Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='nacos-config-client.properties'}]} ... Refresh keys changed: [course.title]
Nacos配置多環境管理
在軟件開發流程中,最基本需要經歷 開發 > 測試 > 生產 等幾個步驟,其中測試還可以折分 sit測試、uat測試、壓力測試等,每個步驟都可能會存在相同的配置項,但是需要配置不同的配置值。以數據庫為例,開發數據庫供開發人員使用及自測,測試數據庫供測試人員使用,生產數據庫供線上使用。對於程序來說,只需要對數據源進行操作,而數據源具體連接哪個數據庫,則完全由配置值進行限定。所謂多環境管理,就是為每個環境准備一套配置文件,在相應環境部署應用時,讀取相應的配置文件即可,這些對於程序而言是透明的。
Nacos配置加載規則
涉及配置項:
-
spring.cloud.nacos.config.prefix:配置文件前綴,如果沒有配置,則默認使用
spring.application.name
值 -
spring.cloud.nacos.config.file-extension:配置文件后綴,默認為 properties
-
spring.cloud.nacos.config.group:配置文件分組,默認為 DEFAULT_GROUP
-
spring.profiles.active:配置當前 profile
Nacos 采用 Group + DataId
進行配置文件定位,其中 DataId
的完整的規則是
${spring.cloud.nacos.config.prefix}-${spring.profile.active}.${spring.cloud.nacos.config .file-extension}
使用 Profile 實現多環境管理
分別設置 spring.profile.active
為 dev 與 test,實現應用自動加載 Nacos 中不同的配置文件。
第一步:在 Nacos 管理后台創建兩個配置文件
兩個文件的 DataId 分別為 nacos-config-profile-dev.yaml
與 nacos-config-profile-test.yaml
,Group 都為 NACOS_PROFILE
,配置格式都選擇為 yaml
,內容配置項都為 course.title
,配置值分別為 nacos-dev
與 nacos-test
,這樣,應用加載到不同的文件時,輸出的值就會不一樣。

第二步:創建 SpringBoot 應用
名稱為 nacos-config-profile
,配置 spring.profiles.active
為 dev
如果不知道如何創建一個 Nacos 配置中心的客戶端應用,請參考前面的章節
配置文件 bootstrap.yml 內容如下
server: port: 8084 spring: application: name: nacos-config-profile cloud: nacos: config: server-addr: 127.0.0.1:8848 prefix: ${spring.application.name} file-extension: yaml group: NACOS_PROFILE profiles: active: dev
第三步:啟動應用
查看啟動日志,可以看到加載的日志文件
Loading nacos data, dataId: 'nacos-config-profile-dev.yaml', group: 'NACOS_PROFILE'
第四步:修改 profile
為 test
,重啟應用
查看啟動日志,可以看到加載的日志文件
Loading nacos data, dataId: 'nacos-config-profile-test.yaml', group: 'NACOS_PROFILE'
思考
從上面的示例看出,實現多環境管理非常簡單,只需要配置當前應用的 profile,應用就會自動加載相應 profile 名稱的配置文件。
-
優點:與 SpringCloudConfig 配置一樣,方便從 SpringCloudConfig 項目遷移過來
-
缺點:Nacos 面向的整個微服務,而不是單個應用,如果微服務數量很多,配置列表將會出現不同應用,不同環境交織在一起,維護將會變得困難
-
建議:服務數量少時使用
使用 namespace 實現多環境管理
為了讓配置列表不那么太雜亂,最簡單的辦法就是把一個大的列表轉換成 N 個小的列表,這樣每一個列表就會顯得整齊起來,這也是 namespace 的作用。
第一步:在 Nacos 管理后台創建 namespace
根據 dev
及 test
兩個環境創建兩個相應的 namespace
namespace 的 ID 可以設置,也可以自動生成,后面配置需要用到,本例 ID 使用與名稱一樣的值
回到配置列表界面,可以看到左上角除了一直存在的 public 之外,出現了剛剛定義了 dev 及 test 兩個標簽頁
其中 public 標簽中可以看到之前創建的配置文件,而 dev 及 test 標簽下則沒有配置文件
第二步:在 dev 及 test 標簽下分別創建配置文件
兩個文件的 DataId 都為 nacos-config-profile.yaml
,Group 都為 NACOS_PROFILE
,配置格式都選擇為 yaml
,內容配置項都為 course.title
,配置值分別為 nacos-namespace-dev
與 nacos-namespace-test
,
第三步:在應用配置文件中添加 spring.cloud.nacos.config.namespace
配置項,內容填寫 namespace 的 ID
示例:
server: port: 8084 spring: application: name: nacos-config-profile cloud: nacos: config: server-addr: 127.0.0.1:8848 prefix: ${spring.application.name} file-extension: yaml group: NACOS_PROFILE namespace: test profiles: active: test
第四步:啟動應用
查看啟動日志,可以看到加載的日志文件
Loading nacos data, dataId: 'nacos-config-profile.yaml', group: 'NACOS_PROFILE'
思考
通過 namespace
實現多環境配置簡單易用,方便維護,也是官方推薦的方式。
不同的環境使用不同的 profile,如果通過修改配置文件的方式來修改 profile,需要在不同環境發布前先修改一次配置文件,在發布腳本的啟動命令中使用
-Dspring.profiles.active=DEV
的方式來動態指定,會更加靈活。
Nacos配置持久化到數據庫
在前面的課程中,我們已經學習了 Nacos 作為服務注冊中心及配置中心,與 Spring Cloud 體系結合的基礎使用方法,其中 Nacos 都是以單機模式運行,數據默認保存在本地的內嵌數據庫中,用於學習這沒有問題,但是生產環境中基於高可用原則則需要對 Nacos 進行集群部署,那么數據保存本地則會出現一致性問題。為了解決這個問題,Nacos 采用了集中式存儲的方式來支持集群化部署,目前只支持 MySQL 存儲。
實操
第一步:安裝 Mysql 數據庫,版本要求:5.6.5+
目前不支持 8.0 以上版本,可以通過修改源碼解決
第二步:初始化數據庫初始化腳本在 Nacos 程序包下的 conf
目錄下的 nacos-mysql.sql
文件
第三步:配置 Nacos修改 Nacos 程序包下 conf/application.properties
文件,添加 MySQL 數據源配置
文件中有示例,只需要打開注釋並修改即可
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://127.0.0.1:3316/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=test db.password=123456
打完收工。重新訪問 http://localhost:8848/nacos/
,並根據之前學習的 基於Nacos構建分布式配置中心
中的步驟可以再重新操作一篇,同時可以登錄數據庫查看,驗證數據是否成功入庫。
Nacos集群部署
官方集群部署說明文檔 https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
根據官方文檔說明,Nacos的集群架構如下圖所示

實操
因為是用於學習,我們沒有多台服務器可以使用,所以本例將在單機上同時啟動多個 Nacos 實例,每一個實例使用不同的端口。
啟動三個 Nacos 實例構成集群,端口分別為 8848、8849、8850,然后使用 Nginx 對三台 Nacos 進行反向代理
第一步:安裝 Mysql 數據庫
第二步:初始化數據庫初始化
腳本在 Nacos 程序包下的 conf
目錄下的 nacos-mysql.sql
文件
第三步:配置 Nacos 數據源
修改 Nacos 程序包下 conf/application.properties
文件,添加 MySQL 數據源配置
文件中有示例,只需要打開注釋並修改即可
spring.datasource.platform=mysqldb.num=1db.url.0=jdbc:mysql://127.0.0.1:3316/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=truedb.user=testdb.password=123456
第四步:配置集群
在 Nacos 程序包的 conf
目錄下有一個 cluster.conf.example
文件,復制為 cluster.conf
,內容為
第五步:啟動實例
因為本例需要在單機上啟動多個 Nacos 實例,只是端口不一樣,所以啟動實例時,需要設置端口。
復制 startup.cmd 為 startup-8849.cmd,並設置端口 set "JAVA_OPT=%JAVA_OPT% -Dserver.port=8849" 復制 startup.cmd 為 startup-8850.cmd,並設置端口 set "JAVA_OPT=%JAVA_OPT% -Dserver.port=8850"
啟動三個實例,這樣 Nacos 集群已經配置完成,接下來使用 Nginx 進行反向代理。
第六步:配置 Nginx 反向代理
upstream nacosserver { server 127.0.0.1:8848; server 127.0.0.1:8849; server 127.0.0.1:8850; } ... server { listen 8080; server_name localhost; location /nacos/ { proxy_pass http://nacosserver/nacos/; } }
這樣就可以通過 localhost:8080/nacos
訪問 Nacos 后台了。
歡迎關注艾編程,回復關鍵詞“alibaba”看系列專輯教程