本部落格的例子程式碼可以在github找到下載連結:程式碼下載
SpringBoot、SpringCloud Alibaba系列部落格專欄:連結
1、分散式理論
1.1、分散式基本定義
《分散式系統原理與範型》定義:
“分散式系統是若干獨立計算機的集合,這些計算機對於使用者來說就像單個相關係統”
分散式系統(distributed system)是建立在網路之上的軟體系統。
1.2、架構發展演變
架構的發展是由最初的單一應用架構構建的,一般就是ORM框架方便資料庫操作。
不過隨著系統越來越複雜,單一應用架構會變得難以維護,所以架構逐漸演變出了垂直應用架構,所謂垂直應用架構其實就是安裝業務模板進行拆分,比如可以安裝業務將一個電商系統分為訂單模組,使用者資訊管理模組,商品管理模組等等,這時候MVC框架就派上用場,MVC框架可以協助系統更好的按業務拆分,不過業務拆分後雖然是比單一應用架構更好維護了。
不過隨著系統越來約複雜,發現很多共用的模組很難複用起來,這時候分散式服務架構登場了,分散式架構是將一些核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,當應用需要時,就去服務中心調服務就可以,而實現這種服務註冊的肯定是RPC框架了。
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率,這時候就需要流動計算架構(SOA)[ Service Oriented Architecture],用於提高機器利用率的資源排程,SOA是一個治理中心,綜上所述,到目前,軟體系統架構演變經歷了:單一應用架構->垂直應用架構->分散式應用架構->流動計算架構,下面Dubbo官網的圖片可以很好的描述
1.3、什麼是RPC?
RPC概念
RPC【Remote Procedure Call】是指遠端過程呼叫,是一種程式間通訊方式,他是一種技術的思想,而不是規範。它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的過程或函式,而不用程式設計師顯式編碼這個遠端呼叫的細節。
RPC核心模組
RPC有兩個核心模組:通訊和序列化
2、什麼是Dubbo框架?
2.1、Apache Dubbo 定義
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高效能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠端方法呼叫,智慧容錯和負載均衡,以及服務自動註冊和發現。
2.2、Dubbo角色
-
Provider:暴露服務的服務提供者
-
Container:服務執行的容器
-
Consumer:呼叫遠端服務的消費者
-
Registry:服務註冊和發現的註冊中心
-
Minitor:統計服務呼叫次數和時間的監控中心
2.3、Apache Dubbo原理
Dubbo的服務治理:
Dubbo原理圖片,圖片來自Dubbo官網:
呼叫過程:
下面根據我的理解說明一下
-
0:伺服器容器負責啟動、載入、執行服務提供者
-
1:服務提供者在啟動後就可以向註冊中心暴露服務
-
2:服務消費者在啟動後就可以向註冊中心訂閱想要的服務
-
3:註冊中心向服務消費者返回服務呼叫列表
-
4:服務消費者基於軟負載均衡演算法呼叫服務提供者的服務,這個服務提供者有可能是一個服務提供者列表,呼叫那個服務提供者就是根據負載均衡來呼叫了
-
5:服務提供者和服務消費者定時將儲存在記憶體中的服務呼叫次數和服務呼叫時間推送給監控中心
3、Dubbo Spring Cloud
3.1 概念定義
Spring Cloud Alibaba Dubbo是Spring Cloud Alibaba專案中的一個,擴充套件了分散式服務呼叫能力,不僅能使 Apache Dubbo 和 OpenFeign 共存,還允許 Spring Cloud 標準呼叫底層通過 Dubbo 支援的通訊協議傳輸
3.2、功能特性對比
功能特徵直接引用官網的歸納:
4、實驗環境準備
- 環境準備:
- 64bit JDK 1.8
- SpringBoot2.3.7.RELEASE
- SpringCloud(Hoxton.SR9)
- SpringCloudAlibaba2.2.2.RELEASE
- Maven 3.2+
- 開發工具
- IntelliJ IDEA
- smartGit
5、API工程建立
使用maven命令
mvn archetype:generate -DgroupId=com.example.springcloud -DartifactId=dubbo-sample-api -Dversion=0.0.1-SNAPSHOT -DinteractiveMode=false
也可以自己建立一個maven專案
建立好的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.springcloud</groupId>
<artifactId>artifact-dubbo-sample-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>artifact-dubbo-sample-api</name>
<description>Demo project for Spring Boot</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
寫個api介面:
package com.example.springcloud.api.service;
/**
* <pre>
* ApiService
* </pre>
*
* <pre>
* @author mazq
* 修改記錄
* 修改後版本: 修改人: 修改日期: 2021/01/19 14:57 修改內容:
* </pre>
*/
public interface ApiService {
String echo(String message);
}
6、啟動Nacos服務中心
詳情可以參考官網:https://nacos.io/zh-cn/docs/quick-start.html,需要先下載nacos服務端原始碼,下載原始碼後編譯啟動專案:
window+R啟動cmd視窗,cd到nacos server的bin目錄,linux系統直接使用cd ${nacos_server_home}/bin
./startup.sh -m standalone
window系統使用命令startup.cmd -m standalone
啟動成功,訪問:http://127.0.0.1:8848/nacos,賬號密碼都是nacos
登入成功,來到主頁:
7、服務提供者工程建立
新建專案,使用阿里的service url:
選擇jdk版本,打包方式:
選擇元件:
自動生成專案:加上@EnableDiscoveryClient
支援服務註冊到nacos
package com.example.springcloud.provider.nacosdiscovery;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
@EnableDiscoveryClient
@Configuration
public class NacosDiscoveryConfiguration {
}
使用@DubboService
提供dubbo服務:
package com.example.springcloud.provider.service;
import com.example.springcloud.api.service.ApiService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Service;
/**
* <pre>
* EchoServiceImpl
* </pre>
*
* <pre>
* @author mazq
* 修改記錄
* 修改後版本: 修改人: 修改日期: 2021/01/19 15:13 修改內容:
* </pre>
*/
@DubboService
public class EchoServiceImpl implements ApiService {
@Override
public String echo(String message) {
return String.format("echo:%s",message);
}
}
application.properties配置:
# 應用名稱
spring.application.name=dubbo-provider-sample
# dubbo 協議
dubbo.protocol.id=dubbo
dubbo.protocol.name=dubbo
# dubbo 協議埠( -1 表示自增埠,從 20880 開始)
dubbo.protocol.port=-1
# Dubbo 消費端訂閱服務端的應用名,多個服務提供者用逗號分隔
# 這裡訂閱"自己",會被忽略掉,請根據實際情況新增
dubbo.cloud.subscribed-services=dubbo-provider-sample
# dubbo 服務掃描基準包
dubbo.scan.base-packages=com.example.springcloud.provider
# Actuator Web 訪問埠
management.server.port=8082
management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# 應用服務 WEB 訪問埠
server.port=8080
# Nacos幫助文件: https://nacos.io/zh-cn/docs/concepts.html
# Nacos認證資訊
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服務發現與註冊配置,其中子屬性 server-addr 指定 Nacos 伺服器主機和埠
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 註冊到 nacos 的指定 namespace,預設為 public
spring.cloud.nacos.discovery.namespace=public
啟動專案,到nacos服務檢視服務
8、服務消費者工程建立
新建一個dubbo-consumer-sample服務消費者工程,建立過程和服務提供者工程一樣,不過配置需要進行修改,避免埠衝突
# 應用名稱
spring.application.name=dubbo-consumer-sample
# 應用服務 WEB 訪問埠
server.port=9090
# Actuator Web 訪問埠
management.server.port=9091
management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# Nacos幫助文件: https://nacos.io/zh-cn/docs/concepts.html
# Nacos認證資訊
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服務發現與註冊配置,其中子屬性 server-addr 指定 Nacos 伺服器主機和埠
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 註冊到 nacos 的指定 namespace,預設為 public
spring.cloud.nacos.discovery.namespace=public
# Dubbo服務配置
# dubbo 協議
dubbo.protocol.id=dubbo
dubbo.protocol.name=dubbo
# dubbo 協議埠( -1 表示自增埠,從 20880 開始)
dubbo.protocol.port=-1
# Dubbo 消費端訂閱服務端的應用名,多個服務提供者用逗號分隔
dubbo.cloud.subscribed-services=dubbo-provider-sample
使用@DubboReference
訂閱服務:
package com.example.springcloud.consumer;
import com.example.springcloud.api.service.ApiService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DubboConsumerSampleApplication {
@DubboReference
private ApiService echoService;
@GetMapping("/echo")
public String echo(String message) {
return echoService.echo(message);
}
public static void main(String[] args) {
SpringApplication.run(DubboConsumerSampleApplication.class, args);
}
}
linux測試介面使用命令curl,window直接到瀏覽器或者postman測試:
curl http://127.0.0.1:9090/echo?message=nacos
echo:nacos