在前段時間為大家分享了SpringCloudAlibaba微服務項目實戰的課程,可是有很多同學反饋,我根本這方面不太瞭解,能不能有個普及教程呢,那麼今天來了,為大家分享一個SpringCloudAlibaba的基礎入門教程,在配合項目實戰教程學習就更容易入手啦!
本期將會為大家帶來什麼?
第一章:SpringCloudAlibaba簡述
第二章:基於Nacos構建分佈式註冊中心
第三章:基於Nacos構建分佈式配置中心
第四章:Sentinel服務治理
第一章:SpringCloudAlibaba簡述
微服務架構演變歷程
傳統單體架構
單體架構在小微企業比較常見,典型代表就是一個應用、一個數據庫、一個web容器就可以跑起來。
![SpringCloudAlibaba入門,Nacos註冊與配置,Sentinel服務治理](http://p2.ttnews.xyz/loading.gif)
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,登錄之後進入管理界面
![SpringCloudAlibaba入門,Nacos註冊與配置,Sentinel服務治理](http://p2.ttnews.xyz/loading.gif)
構建應用接入 Nacos
構建一個服務提供者以及一個服務消費者來驗證服務的註冊與發現
構建服務提供者
需要有 SpringBoot 基礎
第一步:創建一個新的 SpringBoot 應用,命名為 nacos-provider
第二步:添加依賴
添加父依賴
<code><
parent
><
groupId
>org.springframework.bootgroupId
><
artifactId
> spring-boot-starter-parentartifactId
><
version
>2.0.5.RELEASEversion
><
relativePath
/>parent
>/<code>
添加依賴管理器
<code><
dependencyManagement
><
dependencies
><
dependency
><
groupId
>org.springframework.cloud
groupId
><
artifactId
>spring-cloud-dependenciesartifactId
><
version
>Finchley.SR1version
><
type
>pomtype
><
scope
>importscope
>dependency
><
dependency
><
groupId
>org.springframework.cloudgroupId
><
artifactId
>spring-cloud-alibaba-dependenciesartifactId
><
version
>0.2.2.RELEASEversion
><
type
>pomtype
><
scope
>importscope
>dependency
>dependencies
>dependencyManagement
>/<code>
<code>添加依賴<
dependencies
><
dependency
><
groupId
>org.springframework.bootgroupId
><
artifactId
>spring-boot-starter-webartifactId
>dependency
><
dependency
><
groupId
>org.springframework.cloud
groupId
><
artifactId
>spring-cloud-starter-alibaba-nacos-discoveryartifactId
>dependency
><
dependency
><
groupId
>org.projectlombokgroupId
><
artifactId
>lombokartifactId
><
optional
>trueoptional
>dependency
>dependencies
>/<code>
第三步:創建啟動類並提供一個應用接口
<code>EnableDiscoveryClientpublic
class
Application
{public
static
void
main
(String[] args)
{ SpringApplication.run(Application.
class
,args
); } 4jstatic
class
TestController
{ ("/hello"
)public
Stringhello
(@RequestParam String name)
{ log.info("execute hello method with name : "
+ name);return
"hello "
+ name; } } }/<code>
- @SpringBootApplication 用於定義 SpringBoot 應用的啟動類
- @EnableDiscoveryClient Spring Cloud 提供的註解,用於開啟 Spring Cloud 的服務註冊與發現,由於這裡引入了 spring-cloud-starter-alibaba-nacos-discovery,所以服務註冊與發現會使用 Nacos 的實現。這與 Eureka 或者 Consul 的操作是一樣的。
第四步:配置服務名稱及 Nacos 地址
<code>server:
port:
8080
spring:
application:
name:
nacos-provider
cloud:
nacos:
discovery:
server-addr:
127.0
.0
.1
:8848
/<code>
第五步:啟動應用
如果打印如下日誌,表示註冊成功
<code>nacos
registry
,nacos-provider
10.32
.52
.236
:8080
register
finished
/<code>
修改端口號,同一個應用啟動多個實例,實現集群
訪問 Nacos 管理界面,通過 服務管理 \> 服務列表 界面查看已註冊的服務
點擊詳情,可以查看集群中每個服務實例的具體信息
構建服務消費者
第一步:創建一個新的 SpringBoot 應用,命名為 nacos-consumer
第二步:添加依賴,與上面的構建服務提供者的內容一樣
第三步:創建啟動類並提供一個應用接口,在該接口實現對服務提供者提供的接口進行調用
<code>nacos
registry
,nacos-provider
10.32
.52
.236
:8080
register
finished
/<code>
這裡使用了 Spring Cloud Common 中的 LoadBalancerClient 接口來挑選服務實例信息,使用負載均衡的算法,然後獲取被選中實例的URI,拼接上服務提供者接口的請求地址及參數,使用 RestTemplate 進行調用。
第四步:配置服務名稱及 Nacos 地址
跟上面的配置服務提供者基本一致,只是服務名及端口根據需要進行修改
<code>server:
port:
8082
spring:
application:
name:
nacos-consumer
cloud:
nacos:
discovery:
server-addr:
127.0
.0
.1
:8848
/<code>
第五步:啟動服務
訪問地址
http://localhost:8082/test,查看日誌輸出
<code>Invoke
:http
:Invoke
:http
:Invoke
:http
:Invoke
:http
:/<code>
可以看到,多次請求會被依次分配給 nacos-provider 服務集群中的兩個實例,可以分別查看兩個實例的日誌輸出進行驗證。
多種方式實現服務間調用
使用RestTemplate
第一步:註冊
<code>@Bean
@LoadBalanced
public RestTemplate restTemplate() {return
new
RestTemplate
(); }/<code>
@LoadBalanced 註解標記負載均衡
第二步:使用
<code>static
class
TestController
{ RestTemplate restTemplate; ("/test"
)public
Stringtest
()
{ String result = restTemplate.getForObject("http://nacos-provider/hello?name=nacos"
, String.
class
);return
"Return : "
+ result; } }/<code>
請求地址中,直接使用服務名代替 Host 部分,在真正調用時,SpringCloud 會將請求攔截,然後通過負載均衡器選出節點,並替換為具體節點的IP與端口執行調用。
使用Feign
第一步:消費者服務添加對 feign 的依賴
<code><
dependency
><
groupId
> org.springframework.cloudgroupId
><
artifactId
>spring-cloud-starter-openfeignartifactId
>dependency
>/<code>
第二步:修改服務啟動類,開啟 Feign 客戶端功能,並定義客戶端
<code>@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); } }/<code>
- @EnableFeignClients 註解用於開啟掃描 Feign 客戶端的功能
- @FeignClient 註解用於定義 Feign 客戶端,需要指定這個接口所要調用的服務名稱,接口中定義的方法使用 Spring MVC 的註解就可以來綁定服務提供方的 REST 接口。
注意:如果是 get 請求方式,@RequestParam 必須要帶,否則 get 請求會被轉換成 post 請求導致請求失效
第三步:通過 Spring 容器注入接口對象,直接調用
<code>public
class
FeignConsumerController
{private
Application.Client client;public
String test() { String result = client.hello("haha"
);return
"result : "
+ result; } }/<code>
優點:強類型檢查
第三章:基於Nacos構建分佈式配置中心
分佈式配置中心概念
Nacos配置讀取及動態刷新
接下來通過一個簡單的例子實現在 Nacos 中創建配置,在 SpringBoot 應用中加載 Nacos 配置並響應 Nacos 中的配置變化
創建配置
第一步:進入 Nacos 管理界面,選擇 配置管理 \> 配置列表,點擊右側 + 號創建新配置
重要的配置項說明:
- DataId:使用 {項目名}.{配置格式} 的格式,本次填入 nacos-config-client.properties
- Group:分組名,默認為 DEFAULT_GROUP,本次操作使用默認值
- 配置格式:默認為 properties,本次操作使用默認值,如果要使用其它格式則需要在應用中進行相應地配置
- 配置內容填寫為 course.title=nacos
創建應用
第一步:創建一個 SpringBoot 應用,命名為 nacos-config-client,保持跟上面的 DataId 一致第二步:添加依賴
添加父依賴
<code>nacos
registry
,nacos-provider
10.32
.52
.236
:8080
register
finished
/<code>
添加依賴管理器
<code>server:
port:
8082
spring:
application:
name:
nacos-consumer
cloud:
nacos:
discovery:
server-addr:
127.0
.0
.1
:8848
/<code>
添加依賴
<code><
dependencies
><
dependency
><
groupId
>org.springframework.bootgroupId
><
artifactId
>spring-boot-starter-webartifactId
>dependency
><
dependency
><
groupId
>org.springframework.cloudgroupId
><
artifactId
>spring-cloud-starter-alibaba-nacos-configartifactId
>dependency
><
dependency
><
groupId
>org.projectlombokgroupId
><
artifactId
>lombokartifactId
><
optional
>trueoptional
>dependency
>dependencies
>/<code>
示例中並沒有添加對 Nacos 服務註冊發現模塊的依賴,配置功能跟服務註冊發現功能是完全分離的,可以獨立使用。
第三步:配置
配置服務名稱及 Nacos 地址
<code>Invoke
:http
:Invoke
:http
:Invoke
:http
:Invoke
:http
:/<code>
spring.application.name 配置成與 Nacos 中創建的 DataId 一致
第四步:創建啟動類,並提供一個對外接口
<code>public
class
Application
{public
static
void
main
(String[] args)
{ SpringApplication.run(Application.
class
,args
); } 4jstatic
class
TestController
{ ("${course.title}"
)private
String title; ("/test"
)public
Stringhello
()
{return
title; } } }/<code>
接口實現很簡單,就是輸出配置文件中的 couse.title 的內容
- @Value 註解用於讀取配置文件中的配置
- @RefreshScope 註解用於支持動態刷新配置內容,有了這個註解,在 Nacos 修改配置內容,@Value 就會及時讀取到最新的內容
第五步:啟動應用在啟動日誌最開始可以看到兩行日誌,說明已經成功從 Nacos 中加載配置,而且是在應用啟動之前進行加載
<code>Loading nacos data, dataId:'nacos-config-client.properties'
, group:'DEFAULT_GROUP'
Located propertysource
: CompositePropertySource {name='NACOS'
, propertySource/<code>
第六步:驗證配置獲取
訪問接口
http://localhost:8083/test,如果一切正常,則會輸出 Nacos 中配置的 nacos
第七步:驗證配置動態更新
在 Nacos 管理後臺修改配置內容為 course.title=nacos changed,再次訪問接口,可以看到輸出的結果也會相應改變。
查看日誌,可以看到配置被重新加載
<code>Loading nacos data, dataId:'nacos-config-client.properties'
, group:'DEFAULT_GROUP'
Located propertysource
: CompositePropertySource {name='NACOS'
, propertySources=[NacosPropertySource {name='nacos-config-client.properties'
}]} ... Refresh keys changed: [course.title]/<code>
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 的完整的規則是
1
2
${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,這樣,應用加載到不同的文件時,輸出的值就會不一樣。
<code>/<code>
第二步:創建 SpringBoot 應用
名稱為 nacos-config-profile,配置 spring.profiles.active 為 dev
如果不知道如何創建一個 Nacos 配置中心的客戶端應用,請參考前面的章節
配置文件 bootstrap.yml 內容如下
<code>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
/<code>
第三步:啟動應用
查看啟動日誌,可以看到加載的日誌文件
<code>Loading nacos data, dataId:'nacos-config-profile-dev.yaml'
,group
:'NACOS_PROFILE'
/<code>
第四步:修改 profile 為 test,重啟應用
查看啟動日誌,可以看到加載的日誌文件
1
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
示例:
<code>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
/<code>
第四步:啟動應用
查看啟動日誌,可以看到加載的日誌文件
<code>Loading nacos data, dataId:'nacos-config-profile.yaml'
,group
:'NACOS_PROFILE'
/<code>
思考
通過 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 數據源配置
文件中有示例,只需要打開註釋並修改即可
<code>spring.datasource.platform
=mysqldb.num
=1
db.url.0
=jdbc:mysql://127.0
.0.1
:3316
/nacos?characterEncoding=utf8&connectTimeout=1000
&socketTimeout=3000
&autoReconnect=true
db.user
=testdb.password
=123456
/<code>
打完收工。重新訪問
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 數據源配置
文件中有示例,只需要打開註釋並修改即可
<code>@Bean
@LoadBalanced
public RestTemplate restTemplate() {return
new
RestTemplate
(); }/<code>
第四步:配置集群
在 Nacos 程序包的 conf 目錄下有一個 cluster.conf.example 文件,複製為 cluster.conf,內容為
第五步:啟動實例
因為本例需要在單機上啟動多個 Nacos 實例,只是端口不一樣,所以啟動實例時,需要設置端口。
<code>static
class
TestController
{ RestTemplate restTemplate; ("/test"
)public
Stringtest
()
{ String result = restTemplate.getForObject("http://nacos-provider/hello?name=nacos"
, String.
class
);return
"Return : "
+ result; } }/<code>
啟動三個實例,這樣 Nacos 集群已經配置完成,接下來使用 Nginx 進行反向代理。
第六步:配置 Nginx 反向代理
<code>@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); } }/<code>
這樣就可以通過 localhost:8080/nacos 訪問 Nacos 後臺了。
<code>歡迎關注艾編程,回覆關鍵詞“alibaba”看系列專輯教程/<code>