7. RPC服务

7.1. 概述

RPCServer采用gRPC实现的远程过程调用系统,采用HTTP/2 传输协议,使用Protobuf 作为接口描述语言,实现系统间的高效交互。

功能上支持处理节点请求、基于流模式的消息订阅,通信上支持TLS单向和双向认证、流控机制等。

7.2. 配置说明

rpc:
  # 模式,当前仅支持grpc方式
  provider: grpc
  # 监听端口
  port: 12301
  # 检查链配置TrustRoots证书变化时间间隔,实现自动刷新,单位:s,最小值为10s
  check_chain_conf_trust_roots_change_interval: 60
  # 流量控制配置,采用令牌桶限流
  ratelimit:
    # 每秒补充令牌数,取值:-1-不受限;0-默认值(10000)
    token_per_second: -1
    # 令牌桶大小,取值:-1-不受限;0-默认值(10000)
    token_bucket_size: -1
  subscriber:
    # 历史消息订阅流控,实时消息订阅不会进行流控
    ratelimit:
      # 每秒补充令牌数,取值:-1-不受限;0-默认值(1000)
      token_per_second: 100
      # 令牌桶大小,取值:-1-不受限;0-默认值(1000)
      token_bucket_size: 100
  tls:
    # TLS模式:
    #   disable - 不启用TLS
    #   oneway  - 单向认证
    #   twoway  - 双向认证
    mode:           twoway
    priv_key_file:  ./certs/node/consensus1/consensus1.tls.key
    cert_file:      ./certs/node/consensus1/consensus1.tls.crt

7.3. 接口定义

service RpcNode {
	// 交易消息请求处理
	rpc SendRequest(TxRequest) returns (TxResponse) {};

	// 消息订阅请求处理
	rpc Subscribe(TxRequest) returns (stream SubscribeResult) {};

	// 更新日志级别
	rpc RefreshLogLevelsConfig(LogLevelsRequest) returns (LogLevelsResponse) {};

	// 获取长安链版本
	rpc GetChainMakerVersion(ChainMakerVersionRequest) returns(ChainMakerVersionResponse) {};

	// 检查链配置并动态加载新链
	rpc CheckNewBlockChainConfig(CheckNewBlockChainConfigRequest) returns (CheckNewBlockChainConfigResponse) {};
}

7.4. 关键逻辑

7.4.1. 交易请求结构说明

交易请求(TxRequest)包含交易头(TxHeader)、Payload和签名(Signature),Payload是字节数组,根据不同的TxType可以解码成各种类型的Payload

7.4.2. 消息订阅(事件通知)实现原理

(1)订阅者发起消息订阅请求,当前支持订阅区块消息和交易消息;

(2)如果只是订阅历史数据,直接从账本存储(Store)中获取后返回给订阅者;

(3)如果需要订阅实时数据,则会有Subscriber发起订阅事件,将chan注册到订阅者列表中,当Core模块有新区块产生,会发送事件通知,通过chan通知到Subscriber,通过RPCServer返回给订阅者;

(4)如果需要同时订阅历史和实时数据,则会分别从账本存储(Store)以及消息订阅发布者获取,而后返回给订阅者;

(5)若订阅消息发送完,RPCServer会主动关闭订阅通道,避免资源浪费。

7.4.3. 限流说明

RPCServer采用令牌桶方式进行限流,可以对接口请求调用消息订阅事件推送分别进行限流,后者仅会对历史消息进行流控,对实时消息未做限制(实时消息可以通过接口请求调用限流来进行流控)。

  • 接口请求调用限流配置

  # 流量控制配置,采用令牌桶限流
  ratelimit:
    # 每秒补充令牌数,取值:-1-不受限;0-默认值(10000)
    token_per_second: -1
    # 令牌桶大小,取值:-1-不受限;0-默认值(10000)
    token_bucket_size: -1
  • 消息订阅事件推送限流配置

  subscriber:
    # 历史消息订阅流控,实时消息订阅不会进行流控
    ratelimit:
      # 每秒补充令牌数,取值:-1-不受限;0-默认值(1000)
      token_per_second: 100
      # 令牌桶大小,取值:-1-不受限;0-默认值(1000)
      token_bucket_size: 100