盘古开发框架下实现微服务网关的缺省姿势为基于 pangu-web 模块的传统接口调用模式,具体请参考文档:如何发布微服务 (API 网关)。本文提供另外一种通过集成Apache ShenYu 实现网关泛化调用 Dubbo 服务将其发布为 HTTP 接口的可选方法。
ShenYu 网关基于 Webflex 非阻塞模型通过泛化调用后端 Dubbo 服务。依赖 Netty 不需要 Servlet 容器,不需要引入服务接口包即可通过 Dubbo 泛化调用服务接口的方式就可以将后端 Dubbo 服务转换为 HTTP API。同时网关支持鉴权、动态限流、熔断、防火墙、灰度发布等。
ShenYu 网关提供的功能非常多,这里我们只关注 HTTP 请求代理功能。即代理前端 HTTP 请求,通过 Dubbo 泛化调用后端 Dubbo 服务。
com.gitee.pulanos.pangu
pangu-parent
latest.version.xxx
com.gitee.pulanos.pangu
pangu-spring-boot-starter
com.gitee.pulanos.pangu
pangu-dubbo-spring-boot-starter
org.springframework.boot
spring-boot-starter-webflux
org.apache.shenyu
shenyu-spring-boot-starter-gateway
org.apache.shenyu
shenyu-spring-boot-starter-sync-data-websocket
org.apache.shenyu
shenyu-spring-boot-starter-plugin-apache-dubbo
基于 ShenYu 网关开发模式不需要引入 Dubbo 服务接口 Jar,网关会根据服务接口的元数据信息,泛化调用 Dubbo 服务接口。服务接口的元数据信息则根据 Dubbo 服务应用中的配置自动上传到 ShenYu 网关管理系统。此内容在下文会继续讲解。
为便于理解,本文基于本地配置的方式编写。若改为标准的 Nacos 配置中心模式,请参阅:配置中心 章节。
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
上表中提到到 ShenYu Admin 是 ShenYu 网关框架的配置 & 元数据管理后台。这里包含了网关模块自己的配置信息也包含了后台服务接口元数据信息,这理的配置信息和元数据信息需要和网关模块同步。ShenYu 支持多种数据同步方案,Websocket 只是盘古开发选用的一种缺省方案。
基于 ShenYu 的网关开发模式既不需要引入服务接口 JAR,也不需要编写具体的调用代码。完全由网关根据服务接口元数据进行 Dubbo 泛化调用。
@ShenyuDubboClient
来自动采集上传接口元数据到 ShenYu Admin,然后将数据自动同步到网关模块。(具体实现见下文所述)对原 Dubbo 服务端做一些配置变更,使其能自动将接口元数据上传到 ShenYu Admin 后台系统。
安装 ShenYu Client 依赖包
org.apache.shenyu
shenyu-spring-boot-starter-client-apache-dubbo
增加配置项
shenyu.client.register-type=http
shenyu.client.server-lists=${shenyu.server-lists:http://localhost:9095}
shenyu.client.props.contextPath=/dubbo
自动上报服务接口元数据
在 Dubbo 服务实现类的方法上使用注解 @ShenyuDubboClient
标记,表示该接口方法元数据自动上传到 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;
}
}
配置网关泛化调用 Dubbo 服务所需的注册中心地址
通过 ShenYu Admin 后台系统『基础配置->插件管理』菜单,启用 dubbo插件
并填入注册中心地址。比如,我测试用的注册中心地址:nacos://169.188.88.140:1688?namespace=pangu-dev
。如下图所示。
重启服务提供者
@SpringBootApplication
public class WebApiGatewayApplication {
public static void main(String[] args) {
PanGuApplicationBuilder.init(WebApiGatewayApplication.class).run(args);
}
}
至此,网关就可以调用 Dubbo 服务了。但是,如何确定 Dubbo 服务对应的请求 url 地址呢?
9090
。/dubbo
。/findUserEntity
。综上,Dubbo 服务 UserService#findUserEntity 的完整请求地址为:http://localhost:9090/dubbo/findUserEntity
。
通过 http 协议,post 方式访问网关。在 http body 中传入 json 格式的参数。
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": "云南码农大熊",
"id": 1,
"userType": 2,
}
}