# RPC 服务方式集成
系统提供了动态服务定制的功能,允许用户在运行时扩展和定制系统的服务能力,无需重新编 译和部署。动态服务可以基于用户定义的业务逻辑,对外提供数据查询、数据处理、业务集 成等服务。
动态服务支持两种调用方式:
- 基于标准HTTP协议: 符合 RESTful 规范,第三方系统可以像调用标准的Web API一样调用 动态服务。
- 基于JVM内部调用:直接在运行时JVM里调用服务逻辑,方便系统内部模块间的集成。
无论使用哪种调用方式,动态服务的定义和管理都是统一的。用户只需定义好服务的执行逻 辑,并进行相应的配置,就可以将新的服务对外开放。
动态服务还提供了用户身份认证和访问控制的机制,确保服务的安全可靠。同时,平台内置了 服务发现和调用的支持,降低了集成复杂度。
# 动态服务提供者
动态服务是指由系统对外提供的服务,目前支持通过标准 HTTP 协议以及在 JVM 内部调用, 以实现类似 RPC 方式的调用。
首先需要定义一个 DynamicServiceProvider 对象,该对象的创建在菜单 开发定制 -> 动 态服务 -> 服务提供者
下。一个 DynamicServiceProvider 对象包含如下字段:
变量名称 | 变量类型 | 描述 |
---|---|---|
name | String | 服务唯一名称 |
logic | tech.muyan.dynamic.DynamicLogic | 服务的执行逻辑 |
active | Boolean | 是否激活 |
其中 logic
字段是一个 DynamicLogic 对象,用于定义服务的执行逻辑,该逻辑的类型为 DYNAMIC_SERVICE_CORE_LOGIC
。该逻辑执行时会注入以下参数:
变量名称 | 变量类型 | 描述 |
---|---|---|
user | tech.muyan.security.User | 执行用户 |
params | Map | 执行参数 |
protocol | tech.muyan.enums.DynamicServiceProtocol | 调用当前服务的方法,目前仅支持 HTTP 和 JVM |
log | Closure<?> | 用于打印执行日志的 log 闭包 |
配置好动态服务后还需要基于 User 创建对应的用户令牌,该用户令牌用于调用动态服务时的身份认证,用户令牌的创建在菜单 开发定制 -> 动态服务 -> 用户令牌
下,通过执行 生成用户令牌
Action 创建用户令牌,该用户令牌的创建需要指定对应的用户。
针对已经创建的用户令牌,可以设置其 是否生效中
字段用于启用或者禁用该用户令牌。
# 平台内动态服务调用
如果是基于本平台开发的应用,可以使用已经封装好的 DynamicServiceConsumerService
类来调用动态服务,该类的使用方法如下:
import tech.muyan.BeanHelper
import tech.muyan.service.DynamicServiceConsumerService
// 获取 DynamicServiceConsumerService 的 bean
// Get the bean of DynamicServiceConsumerService
DynamicServiceConsumerService dynamicServiceConsumerService = BeanHelper.getBean(DynamicServiceConsumerService)
// 调用 dynamicServiceConsumerService 的 invoke 方法
// Invoke the invoke method of dynamicServiceConsumerService
def res = dynamicServiceConsumerService.invoke(serviceName, params, userToken)
2
3
4
5
6
7
8
DynamicServiceConsumerService
的调用过程分为两部分,第一部分是服务发现,第二部分是服务调用。
# 动态服务发现
服务发现是指根据服务名称,从系统中查找对应的服务提供者。目前支持两种协议 HTTP
和 JVM
,如果是 HTTP
协议,则返回服务提供者的 URL,如果是 JVM
协议,则直接尝试通过 DynamicServiceProvider
调用服务提供者的逻辑。
HTTP 服务发现是基于系统配置 DynamicConfig 中的 dynamicService.http.hosts
去定位的,它的 Value 是一个以 ,
分隔的字符串,用于指定 HTTP 服务提供者的地址,如 http://localhost:8080/service,https://muyan.cloud/service
。URL中的 service
是固定前缀。
# 动态服务调用
调用动态服务时,需要指定服务名称,调用参数和用户令牌,其中服务名称需要符合以下几种类型:
- 直接填入服务名称, DynamicServiceConsumerService 会自动根据服务名称去服务发现中查找对应的服务提供者,如果找到多个服务提供者,则会随机选择一个服务提供者进行调用。
jvm://
开头的 uri 表示调用 JVM 服务,如jvm://some_service
,其中some_service
是服务名。http://
或者https://
开头的 uri 表示调用 HTTP 服务,如http://host/service/some_service
,其中service
是服务端域名,service
为固定 URL 前缀,some_service
为服务名。- 如果只是想指定使用 HTTP 作为服务调用方式,但是不想指定具体使用哪台服务提供者,则可以使用
http://ANY_PROVIDER/some_service
的方式,其中ANY_PROVIDER
表示由 DynamicServiceConsumerService 的服务发现来决定具体的调用方。
- 如果只是想指定使用 HTTP 作为服务调用方式,但是不想指定具体使用哪台服务提供者,则可以使用
# 第三方动态服务调用
如果是第三方客户端想接入本平台的动态服务,则需要自行通过 HTTP 协议实现服务发现和服务调用的逻辑:
- 客户端需要指定调用的服务端地址如
http://host/service/some_service
,使用 POST 请求 - 带上一个
X-MY-Token
的 HEADER,其值为用户令牌 - 参数以 JSON 格式填入 body 中
提示
需要注意服务名需要经过 url 编码以避免空格字符等特殊字符导致的问题