盤古開發(fā)框架下實現(xiàn)微服務(wù)網(wǎng)關(guān)的缺省姿勢為基于 pangu-web 模塊的傳統(tǒng)接口調(diào)用模式,具體請參考文檔:如何發(fā)布微服務(wù) (API 網(wǎng)關(guān))题暖。本文提供另外一種通過集成Apache ShenYu 實現(xiàn)網(wǎng)關(guān)泛化調(diào)用 Dubbo 服務(wù)將其發(fā)布為 HTTP 接口的可選方法按傅。
ShenYu 網(wǎng)關(guān)介紹
ShenYu 網(wǎng)關(guān)基于 Webflex 非阻塞模型通過泛化調(diào)用后端 Dubbo 服務(wù)。依賴 Netty 不需要 Servlet 容器胧卤,不需要引入服務(wù)接口包即可通過 Dubbo 泛化調(diào)用服務(wù)接口的方式就可以將后端 Dubbo 服務(wù)轉(zhuǎn)換為 HTTP API唯绍。同時網(wǎng)關(guān)支持鑒權(quán)、動態(tài)限流枝誊、熔斷况芒、防火墻、灰度發(fā)布等叶撒。
相關(guān)名詞解釋
-
shenyu-admin
網(wǎng)關(guān)插件和元數(shù)據(jù)信息配置管理后臺绝骚。獨立 JAR,需要單獨部署祠够。 -
shenyu-gateway
網(wǎng)關(guān)模塊压汪,代理 Http 請求,泛化調(diào)用后端 Dubbo 服務(wù)古瓤。此模塊負(fù)責(zé)接收 Http 請求止剖。 -
數(shù)據(jù)同步
數(shù)據(jù)同步是指在 ShenYu-Admin 后臺操作數(shù)據(jù)以后,使用何種策略將數(shù)據(jù)同步到 ShenYu Gateway 網(wǎng)關(guān)模塊落君。ShenYu 當(dāng)前支持 ZooKeeper穿香、WebSocket、Http 長輪詢绎速、Nacos 皮获、Etcd 和 Consul 進(jìn)行數(shù)據(jù)同步。盤古開發(fā)使用的是 WebSocket 方式進(jìn)行數(shù)據(jù)同步纹冤。 -
插件
ShenYu 使用插件化設(shè)計思想魔市,實現(xiàn)插件的熱插拔主届。內(nèi)置豐富的插件赵哲,包括 RPC 代理待德、熔斷和限流、權(quán)限認(rèn)證枫夺、監(jiān)控等等将宪。 -
選擇器
每個插件可設(shè)置多個選擇器,對流量進(jìn)行初步篩選橡庞。 -
規(guī)則
每個選擇器可設(shè)置多個規(guī)則较坛,對流量進(jìn)行更細(xì)粒度的控制。
網(wǎng)關(guān)調(diào)用結(jié)構(gòu)圖
ShenYu 網(wǎng)關(guān)實戰(zhàn)
ShenYu 網(wǎng)關(guān)提供的功能非常多扒最,這里我們只關(guān)注 HTTP 請求代理功能丑勤。即代理前端 HTTP 請求,通過 Dubbo 泛化調(diào)用后端 Dubbo 服務(wù)吧趣。
安裝相關(guān)模塊
- 盤古 Parent
<parent>
<groupId>com.gitee.pulanos.pangu</groupId>
<artifactId>pangu-parent</artifactId>
<version>latest.version.xxx</version>
<relativePath/>
</parent>
- 基礎(chǔ)模塊
<dependency>
<groupId>com.gitee.pulanos.pangu</groupId>
<artifactId>pangu-spring-boot-starter</artifactId>
</dependency>
- Dubbo 模塊
<dependency>
<groupId>com.gitee.pulanos.pangu</groupId>
<artifactId>pangu-dubbo-spring-boot-starter</artifactId>
</dependency>
- 網(wǎng)關(guān)模塊
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shenyu</groupId>
<artifactId>shenyu-spring-boot-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shenyu</groupId>
<artifactId>shenyu-spring-boot-starter-sync-data-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shenyu</groupId>
<artifactId>shenyu-spring-boot-starter-plugin-apache-dubbo</artifactId>
</dependency>
基于 ShenYu 網(wǎng)關(guān)開發(fā)模式不需要引入 Dubbo 服務(wù)接口 Jar法竞,網(wǎng)關(guān)會根據(jù)服務(wù)接口的元數(shù)據(jù)信息,泛化調(diào)用 Dubbo 服務(wù)接口强挫。服務(wù)接口的元數(shù)據(jù)信息則根據(jù) Dubbo 服務(wù)應(yīng)用中的配置自動上傳到 ShenYu 網(wǎng)關(guān)管理系統(tǒng)岔霸。此內(nèi)容在下文會繼續(xù)講解。
本地配置
為便于理解俯渤,本文基于本地配置的方式編寫呆细。若改為標(biāo)準(zhǔn)的 Nacos 配置中心模式,請參閱:配置中心 章節(jié)八匠。
server:
port: 9090
spring:
main:
allow-bean-definition-overriding: true
shenyu:
cross:
enabled: true
allowedHeaders:
allowedMethods: "*"
allowedOrigin: "*"
allowedExpose: "*"
maxAge: "18000"
allowCredentials: true
switchConfig:
local: true
file:
enabled: true
maxSize : 10
sync:
websocket:
urls: ${shenyu.websocket.urls:ws://localhost:9095/websocket}
dubbo:
parameter: multi
exclude:
enabled: false
paths:
- /favicon.ico
extPlugin:
path:
enabled: true
threads: 1
scheduleTime: 300
scheduleDelay: 30
scheduler:
enabled: false
type: fixed
threads: 16
upstreamCheck:
enabled: false
timeout: 3000
healthyThreshold: 1
unhealthyThreshold: 1
interval: 5000
printEnabled: true
printInterval: 60000
關(guān)鍵配置項說明
-
shenyu.sync.websocket.urls
表示網(wǎng)關(guān)和 ShenYu Admin 之間使用 Websocket 的方式進(jìn)行數(shù)據(jù)同步絮爷,這里是配置 ShenYu Admin 提供的 Websocket 數(shù)據(jù)同步服務(wù)的地址(支持集群,逗號分割)梨树。
上表中提到到 ShenYu Admin 是 ShenYu 網(wǎng)關(guān)框架的配置 & 元數(shù)據(jù)管理后臺坑夯。這里包含了網(wǎng)關(guān)模塊自己的配置信息也包含了后臺服務(wù)接口元數(shù)據(jù)信息,這理的配置信息和元數(shù)據(jù)信息需要和網(wǎng)關(guān)模塊同步劝萤。ShenYu 支持多種數(shù)據(jù)同步方案渊涝,Websocket 只是盤古開發(fā)選用的一種缺省方案。
調(diào)用微服務(wù)接口
基于 ShenYu 的網(wǎng)關(guān)開發(fā)模式既不需要引入服務(wù)接口 JAR床嫌,也不需要編寫具體的調(diào)用代碼跨释。完全由網(wǎng)關(guān)根據(jù)服務(wù)接口元數(shù)據(jù)進(jìn)行 Dubbo 泛化調(diào)用。
網(wǎng)關(guān)是如何知道 Dubbo 服務(wù)接口元數(shù)據(jù)的呢厌处?
- 通過 ShenYu Admin 后臺系統(tǒng)鳖谈,『基礎(chǔ)配置->元數(shù)據(jù)管理』菜單,手工新增每一個接口的元數(shù)據(jù)阔涉,然后將數(shù)據(jù)自動同步到網(wǎng)關(guān)模塊缆娃。(不建議捷绒,量大的話太繁瑣)
- 對Dubbo服務(wù)提供者增加 ShenYu Client 支持,通過在接口方法上使用注解
@ShenyuDubboClient
來自動采集上傳接口元數(shù)據(jù)到 ShenYu Admin贯要,然后將數(shù)據(jù)自動同步到網(wǎng)關(guān)模塊暖侨。(具體實現(xiàn)見下文所述)
改造 Dubbo 服務(wù)端,自動上傳接口元數(shù)據(jù)
對原 Dubbo 服務(wù)端做一些配置變更崇渗,使其能自動將接口元數(shù)據(jù)上傳到 ShenYu Admin 后臺系統(tǒng)字逗。
安裝 ShenYu Client 依賴包
<dependency>
<groupId>org.apache.shenyu</groupId>
<artifactId>shenyu-spring-boot-starter-client-apache-dubbo</artifactId>
</dependency>
增加配置項
shenyu.client.register-type=http
shenyu.client.server-lists=${shenyu.server-lists:http://localhost:9095}
shenyu.client.props.contextPath=/dubbo
-
shenyu.client.register-type
服務(wù)接口元數(shù)據(jù)采集方式,可選 http 直連模式或配置中心 zookeeper宅广、etcd葫掉、consul 和 nacos。盤古開發(fā)采集接口元數(shù)據(jù)缺省選擇 http 直接 ShenYu Admin 的方式跟狱。 -
shenyu.client.server-lists
ShenYu Admin 地址或配置中心地址俭厚。集群時多個地址用逗號分開。 -
shenyu.client.props.contextPath
本服務(wù)在網(wǎng)關(guān)中的路由前綴,可自定義按需配置驶臊。
自動上報服務(wù)接口元數(shù)據(jù)
在 Dubbo 服務(wù)實現(xiàn)類的方法上使用注解 @ShenyuDubboClient
標(biāo)記挪挤,表示該接口方法元數(shù)據(jù)自動上傳到 ShenYu Admin。如下代碼所示资铡。
@Service(version = "1.0.0", group = "pangu-examples-dubbo-gateway-service")
public class UserServiceImpl implements UserService {
@Override
@ShenyuDubboClient(path = "/findUserEntity", desc = "查詢用戶信息")
public UserEntity findUserEntity(Long id) {
...
return userEntity;
}
}
配置網(wǎng)關(guān)泛化調(diào)用 Dubbo 服務(wù)所需的注冊中心地址
通過 ShenYu Admin 后臺系統(tǒng)『基礎(chǔ)配置->插件管理』菜單电禀,啟用 dubbo插件
并填入注冊中心地址。比如笤休,我測試用的注冊中心地址:nacos://169.188.88.140:1688?namespace=pangu-dev
尖飞。如下圖所示。
重啟服務(wù)提供者
-
進(jìn)入 ShenYu Admin 后臺系統(tǒng)的『基礎(chǔ)配置->元數(shù)據(jù)管理』菜單店雅,會看到自動上報的服務(wù)元數(shù)據(jù)信息政基。如下圖所示。
2-pangu-framework-shenyu-metadata.png -
進(jìn)入 ShenYu Admin 后臺系統(tǒng)的『插件列表-> proxy -> dubbo』菜單闹啦,會看到自動注冊的選擇器和規(guī)則信息沮明。如下圖所示。
3-pangu-framework-shenyu-plugin.png
啟動入口
@SpringBootApplication
public class WebApiGatewayApplication {
public static void main(String[] args) {
PanGuApplicationBuilder.init(WebApiGatewayApplication.class).run(args);
}
}
網(wǎng)關(guān)請求URL
至此窍奋,網(wǎng)關(guān)就可以調(diào)用 Dubbo 服務(wù)了荐健。但是,如何確定 Dubbo 服務(wù)對應(yīng)的請求 url 地址呢琳袄?
- 由網(wǎng)關(guān)模塊配置文件可知網(wǎng)關(guān)應(yīng)用端口是
9090
江场。 - Dubbo 服務(wù)的配置項 shenyu.client.props.contextPath 為
/dubbo
。 - Dubbo 方法通過 @ShenyuDubboClient 標(biāo)記的 path 屬性為:
/findUserEntity
窖逗。
綜上址否,Dubbo 服務(wù) UserService#findUserEntity 的完整請求地址為:http://localhost:9090/dubbo/findUserEntity
。
參數(shù)說明
通過 http 協(xié)議碎紊,post 方式訪問網(wǎng)關(guān)佑附。在 http body 中傳入 json 格式的參數(shù)樊诺。
請求示例
curl --location --request POST 'http://127.0.0.1:9090/dubbo/findUserEntity' \
--header 'Content-Type: application/json' \
--data '{id=1}'
{
"code": 200,
"message": "Access to success!",
"data": {
"name": "云南碼農(nóng)大熊",
"id": 1,
"userType": 2,
}
}
本范例源碼
- pangu-examples-dubbo-api:Dubbo 服務(wù)接口包
- pangu-examples-dubbo-gateway-shenyu-service:Dubbo 服務(wù)提供者(支持接口元數(shù)據(jù)上傳到網(wǎng)關(guān)系統(tǒng))
- pangu-examples-webapi-gateway-shenyu-based:基于 ShenYu 網(wǎng)關(guān)將 Dubbo 服務(wù)發(fā)布為 HTTP 接口