# 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 dynamicServiceConsumerService = BeanHelper.getBean(DynamicServiceConsumerService)
def res = dynamicServiceConsumerService.invoke(serviceName, params, userToken)
1
2
3
4

DynamicServiceConsumerService 的调用过程分为两部分,第一部分是服务发现,第二部分是服务调用。

# 动态服务发现

服务发现是指根据服务名称,从系统中查找对应的服务提供者。目前支持两种协议 HTTPJVM,如果是 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://host/service/some_service,使用 POST 请求
  • 带上一个 X-MY-Token 的 HEADER,其值为用户令牌
  • 参数以 JSON 格式填入 body 中

提示

需要注意服务名需要经过 url 编码以避免空格字符等特殊字符导致的问题

最后更新: 2024/5/26 15:43:38