命令中心服务 - Nebula.Fides

使用场景

xx

这里涉及3个对象:

  • 命令的发布者:【云端】的各个应用程序
  • 命令的执行者:【云下】的客户端程序
  • 二端的协调者:用于连接各个应用程序和云下客户端。

执行流程介绍:

  • 客户端,以死循环的方式执行下面步骤:
    • (1)使用HTTP协议调用Fides拉取命令
    • (4)在获取到命令后,交给后台线程来执行,然后上传命令的执行结果(5)
    • (_)重新执行 (1) 步骤
  • Fides,监听HTTP端口,接收命令的发布和上传结果
    • (3)当接收到命令发布时,Fides会立即将命令返回给客户端
    • 如果没有收到命令,Fides则将客户端的请求挂起,直到命令出现或者达到超时
  • 应用程序
    • (2)根据业务需要,使用HTTP协议给Fides发布命令,并等待执行结果(6)

Fides的价值:

  • 简化【云端应用程序】调用【云下客户端】的过程
  • 对于【云端应用程序】来说,只需要对Fides发起一次HTTP调用即可得到结果





API调用

应用程序--发布命令--并等待--执行结果

POST http://hostxxxxxx/v20/api/fides/cmd/publish HTTP/1.1
Content-Type: application/json
x-token: .......jwt-token.................

{
  "ActionName": "actionx",
  "ClientId": "Client-3",
  "Caller": "Caller-111"
}

响应示例:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "ServerId": "e0e194b0bbc84db98f8eac6dff15e126",
    "CallbackId": "5459a6fe9b7541d59b9af53358044da8",
    "TenantId": "FISHDEV-WIN10",
    "ClientId": "Client-3",
    "ClientReceiveTime": "2022-07-13T18:51:34.9975544+08:00",
    "ClientStartTime": "2022-07-13T18:51:34.9975544+08:00",
    "ClientEndTime": "2022-07-13T18:51:34.9975544+08:00",
    "ServerReceiveTime": "2022-07-13T18:51:35.0918622+08:00",
    "ResponseResult": "FISHDEV-WIN10#Client-3 execute actionx OK!",
    "ClientAddition": "addition is ..xxx..",
    "RequestId": "92eeaf0008e543a6846748d6a0615892"
}

请求体的数据结构如下:

public sealed class PublishArgs
{
    /// 要执行命令的客户端Id
    [Required]
    public string ClientId { get; set; }

    /// 命令名称
    [Required]
    public string ActionName { get; set; }

    /// 命令的调用参数
    public string Args { get; set; }

    /// 命令的发布者
    public string Sender { get; set; }

    /// 发布命令的功能场景
    public string Caller { get; set; }

    /// 命令是单向的,不需要等待执行结果
    public int IsOneWay { get; set; }

    /// 服务端的最大等待时间
    public int ServerWaitSecond { get; set; }

    /// 客户端的最大等待时间
    public int ClientWaitSecond { get; set; }

    /// 客户端执行命令时,如果发生异常,最大的允许多少次重试
    public int MaxExecuteRetryCount { get; set; }

    /// 客户端上传结果时,如果发生异常,最大的允许多少次重试
    public int MaxUploadRetryCount { get; set; }

    /// 客户端遇到异常做重试时,中间间隔多少秒
    public int ErrorWaitSecond { get; set; }
}

响应体的数据结构如下:

public sealed class CommandResult
{
    /// 服务端节点Id
    public string ServerId { get; set; }

    /// 服务端当前请求ID
    public string RequestId { get; set; }

    /// 引用 ClientCommand.CallbackId
    public string CallbackId { get; set; }

    public string TenantId { get; set; }
    public string ClientId { get; set; }
    public DateTime ClientReceiveTime { get; set; }
    public DateTime ClientStartTime { get; set; }
    public DateTime ClientEndTime { get; set; }
    public DateTime ServerReceiveTime { get; set; }

    /// 客户端的响应结果
    public string ResponseResult { get; set; }

    /// 客户端的结果响应类型,,可参考HTTP的 Content-Type 响应头
    public string ResponseContentType { get; set; }

    /// 客户端的结果响应的编码方式,可参考HTTP的 Content-Encoding 响应头
    public string ResponseContentEncoding { get; set; }

    /// 客户端的一些附加描述信息
    public string ClientAddition { get; set; }

    /// 客户端引发的异常类型
    public string ExecptionType { get; set; }

    /// 客户端引发的异常描述
    public string ExecptionText { get; set; }    
}





客户端--拉取命令

GET http://hostxxxxxx/v20/api/fides/cmd/pull HTTP/1.1
x-token: .......jwt-token.................
x-expect-count: 1
x-client-timeoutms: 110000

请求头说明:

  • x-expect-count 明确告诉服务端:一次只返回一个ClientCommand对象。
    如果不指定,则以数组形式返回(也只有一个对象)
    这个参数主要是为了解决兼容性问题,建议指定,且 value 只能设置为 1
  • x-client-timeoutms 告诉服务端:客户端的超时时间
    如果不指定此参数,请求在服务端挂起的时间由服务端决定,此时客户端的超时时间必须大于服务端的挂起时间。

响应示例:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "CommandGuid": "ddcd19465244410cb8030701e029bf97",
    "CreateTime": "2022-07-13T19:06:55.8980434+08:00",
    "ServerId": "e0e194b0bbc84db98f8eac6dff15e126",
    "CallbackId": "f5e12ca3a8f642f8a2945009461e6769",
    "ActionName": "actionx",
    "Caller": "Caller-111",
    "IsOneWay": 0,
    "UserId": "11111",
    "UserType": "admin",
    "TenantId": "FISHDEV-WIN10",
    "ClientId": "Client-3",
    "ClientWaitSecond": 0,
    "ServerWaitSecond": 20,
    "MaxExecuteRetryCount": 0,
    "MaxUploadRetryCount": 0,
    "ErrorWaitSecond": 0
}

响应体的数据结构如下:

public sealed class ClientCommand
{
    /// 服务端创建时间
    public DateTime CreateTime { get; set; }

    /// 服务端节点Id
    public string ServerId { get; set; }

    /// 客户端上传结果后的回调通知ID,【始终应该使用这个字段来做唯一ID】
    public string CallbackId { get; set; }

    public string ActionName { get; set; }
    public string Args { get; set; }
    public string Caller { get; set; }

    /// 命令是单向的,不需要等待执行结果
    public int IsOneWay { get; set; }

    public string UserId { get; set; }
    public string UserType { get; set; }
    public string TenantId { get; set; }
    public string ClientId { get; set; }

    public int ClientWaitSecond { get; set; }
    public int ServerWaitSecond { get; set; }
    public int MaxExecuteRetryCount { get; set; }
    public int MaxUploadRetryCount { get; set; }
    public int ErrorWaitSecond { get; set; }
}





客户端--上传--命令执行结果

POST http://hostxxxxxx/v20/api/fides/cmd/upload HTTP/1.1
Content-Type: application/json
x-token: .......jwt-token.................

{
    "CallbackId": "..............",
    "ClientStatus": 200,
    "ResponseResult": ".............."
}

响应示例:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "CallbackId": "5459a6fe9b7541d59b9af53358044da8"
}

请求体的数据结构如下:

public sealed class UploadArgs
{
    /// 引用 ClientCommand.CallbackId
    [Required]
    public string CallbackId { get; set; }

    public DateTime ClientReceiveTime { get; set; }
    public DateTime ClientStartTime { get; set; }
    public DateTime ClientEndTime { get; set; }

    /// 客户端对于执行结果的状态码表示
    public int ClientStatus { get; set; }

    /// 客户端的响应结果
    public string ResponseResult { get; set; }

    /// 客户端的结果响应类型
    public string ResponseContentType { get; set; }

    /// 客户端的结果响应的编码方式,可参考HTTP的 Content-Encoding 响应头
    public string ResponseContentEncoding { get; set; }

    /// 客户端的一些附加描述信息
    public string ClientAddition { get; set; }

    /// 客户端引发的异常类型
    public string ExecptionType { get; set; }

    /// 客户端引发的异常描述
    public string ExecptionText { get; set; }
}





日志&问题排查

发布命令时,Fides会记录一些重要数据到Oprlog日志中,可以在Venus/Kibana中查看:

xx

日志字段含意

  • bizId: CallbackId
  • bizName: ActionName
  • text2: TenantId
  • text3: ClientId

其中 CallbackId 贯穿了 publish/pull/upload 3个阶段,可以根据此数据来查询对应的日志:

xx