tarsdocs
  • Readme.md
  • CLA
  • LICENSE
  • 基础介绍
    • 简介
    • 基础概念
    • 基础通信协议 Tars
    • 统一通信协议 Tup
    • 开发模式介绍
    • 模板配置
    • 服务市场
    • 服务扩展
    • 框架版本说明
  • 开源版框架介绍
    • 开源版本部署
      • 部署总体介绍
      • Docker环境安装
      • Mysql安装
      • 框架源码部署(Linux/Mac)
      • 框架源码部署(Windows)
      • 框架Docker部署
      • 框架节点部署
      • 业务服务容器化
      • 框架K8SDocker 部署
      • 框架K8STARS 部署
      • 框架K8SFramework 部署(强烈推荐)
      • 框架更新及扩容
      • 调用链升级注意事项
      • TarsWeb-v3.0.3升级说明
    • 开源版管理平台
      • TarsWeb说明
      • web用户体系
      • web管理平台 API
  • 企业版本介绍
    • 企业版说明
    • 框架集群化机制
    • 框架单节点机制
    • 使用二进制包部署
    • 使用容器部署
    • 业务服务一主多备机制
    • 命令行控制终端
    • IP-LIST级联缓存机制
    • 多数据中心管理
    • 多网络支持
    • 第三方服务管理
    • 数据产生和管理机制
    • 密码重置
    • TarsPython介绍
  • 框架关键特性
    • 业务配置
    • 服务监控
    • 无损发布/重启
    • 调用链
    • IDC分组
    • 鉴权功能
  • TarsCPP
    • 编译
    • 快速开发入门
    • 使用指南
    • 开发规范
    • 服务线程说明文档
    • protobuf 协议支持文档
    • 第三方协议支持
    • HTTP1 支持
    • HTTP2 支持
    • TLS 通信支持
    • Push 功能说明
    • PushCallback 功能说明
    • Cookie 支持
    • 队列模式
    • 手动绑定
    • 性能数据
    • 2.x 版本变化
    • 3.x 版本变化
    • 协程版本说明
    • 基础类库说明
    • [案例]
      • 框架快速入门
      • Http 服务示例
  • TarsJava
    • 快速开始
    • 快速开发入门
    • [使用指南]
      • Tars 服务开发与上线
      • HTTP 服务开发与上线
      • 生成接口调用文件
    • [性能测试]
      • tars java 压测代码
  • TarsGo
    • 基本介绍
    • 快速开始
    • 使用指南
    • cmake 管理代码
    • pb2tarsgo
    • 性能数据
    • 使用示例
  • TarsPHP
    • 搭建 php 环境
    • 快速开发入门
    • [快速起步]
      • 搭建 HttpServer
      • 搭建 TimerServer
      • 搭建 TcpServer
      • 搭建 WebSocketServer
      • 弹幕活动实战
    • [框架简介]
      • 简介
      • tars-server
      • tars-client
      • tars-config
      • tars-deploy
      • tars-extension
      • tars-log
      • tars-monitor
      • tars-registry
      • tars-report
      • tars-utils
      • tars2php
    • [高阶应用]
      • PHP 的 Swoole 框架如何接入 Tars
      • 与 thinkphp 结合使用
      • 与 Swoft 结合使用
      • 与 Laravel 结合使用
      • 与 Yii2 结合使用
      • 持续集成方案
    • [其他]
      • 常见问题
      • 如何 Debug
      • changelog
      • 其他外部文档
  • Tars.js
    • 基本介绍
    • 脚手架
    • 快速开发入门
    • @tars/stream
    • @tars/rpc
    • @tars/logs
    • @tars/config
    • @tars/monitor
    • @tars/notify
    • @tars/utils
    • @tars/dyeing
    • @tars/node-agent
    • @tars/winston-tars
    • tars2node
  • K8SFramework
    • [安装和使用说明]
      • 介绍
      • 特性
      • 安装
      • 升级
      • 云原生运维
      • 管理平台
      • 证书
    • [开发环境构建]
      • Dockerfile 说明
      • 服务发布流程说明
      • 制作基础编译镜像
      • 制作业务服务镜像
      • 制作 Helm 包
      • 发布业务镜像到 K8S 集群
      • 服务发布示例
      • 如何调试业务服务
  • 服务扩展
    • 云告警
    • 接口及压测工具
    • 网关服务
    • dcache缓存服务
    • 发送邮件服务
    • 一致性存储服务
    • 一致性存储web管理平台
    • 唯一计数服务
  • 常见问题
    • 安装常见问题
    • Issues
    • Issues-tarscpp
    • Issues-tarsjava
    • Issues-tarsgo
    • Issues-tarsphp
  • 开源合作
    • TarsFramework 项目 Git 合作规范
  • 直播视频
    • B 站 TARS 培训系列课程
  • 相关文章
    • TARS 技术文章
  • 其它资源分享
    • 下载
    • Tars 介绍.pptx
    • TarsPHP 解密.pdf
    • TarsJava 本地调试.pdf
    • 微服务在腾讯的业务实践.pptx
Powered by GitBook
On this page
  • 目录
  • 1. Tars 语言
  • 1.1. 接口文件
  • 1.2. 词法规则
  • 1.3. 基本类型
  • 1.4. 复杂类型
  • 1.5. 接口
  • 1.6. 名字空间
  • 1.7. 引用
  • 2. Tars 协议
  • 2.1. 数据编码
  • 2.2. 消息格式

Was this helpful?

  1. 基础介绍

基础通信协议 Tars

Previous基础概念Next统一通信协议 Tup

Last updated 1 year ago

Was this helpful?

目录

1. Tars 语言

1.1. 接口文件

Tars 语言是一种类 c++标识符的语言,用于生成具体的服务接口文件

Tars 文件是 Tars 框架中客户端和服务端的通信接口,通过 Tars 的映射实现远程对象调用

Tars 文件的扩展名必须以.tars 为扩展名

对于结构定义,可以支持扩展字段,即可以增加字段而不影响原有结构的解析,可以在存储/协议等地方单独使用

大小写敏感

1.2. 词法规则

1.2.1. 注释

采用 c++的注释规范。

//表示注释一行,/**/表示注释范围中的所有代码。

1.2.2. 关键字

void,struct,bool,byte,short,int,double,float,long,string,vector,map,key,routekey,module,interface,out,require,optional,false,true,enum,const

1.2.3. 标识符

所有标识符不能带有'tars_’符号,且必须以字母开头,同时不能和关键字冲突。

1.3. 基本类型

支持的基本类型包括以下:

void :只能在函数的返回值表示

bool :布尔类型,映射到 tars::Bool

byte :有符号字符,映射到 tars::Char

short :有符号短整型,映射到 tars::Short

int :有符号整型,映射到 tars::Int32

long :有符号长整型,映射到 tars::Int64

float :映射到 tars::Float

double :映射到 tars::Double

string :映射到 std::string,java:String

unsigned byte :无符号字符,c++映射到 unsigend char 其它版本 tars::Short

unsigned short:无符号短整形 c++映射到 unsigned short 其它版本 tars::Int32

Unsigned int:无符号整形 c++映射到 unsigned int 其它版本 tars::Int64

1.4. 复杂类型

1.4.1. 枚举

枚举类型的定义如下:

enum TE
{
    E1,
    E2,
    E3
};

说明:

  • 枚举类型支持在指定枚举变量的值,例如支持:E1 = 1 这种定义方式;

  • 第一个定义的枚举类型值为 0,这里 E1 的值为 0;

  • 枚举类型在 tars 文件定义后,通过 tars2cpp 生成以后,除了会生成相应的 enum 定义之外,会生成 etos 和 stoe 函数,将枚举值转换成字符串,以及将字符串转换成枚举值,在代码调试时会非常方便。

  • 建议在 c++的 tars 文件中,所有接口都以 int 返回,且返回值在 tars 文件中以枚举来定义。

1.4.2. 常量

Tars 文件中可以定义常量,例如:

const int a = 0;

const string s = “abc”;

说明:

  • 由于 map,vector 没有描述常量的值,因此不支持 map,vector 的定义;

1.4.3. 结构

结构定义如下:

struct Test
{
    0  require  string s;
    1  optional int  i = 23;
};

key[Test, s, i];

说明:

  • 第一列数字表示该字段的标识(tag),无论结构增减字段,该字段的值都不变,必须和相应的字段对应;

  • Tag 的值必须要>=0 且<=255;

  • require 表示该字段必选;

  • optional 表示该字段可选;

  • 对于 optional 字段,可以有一个缺省值,缺省值在编码时默认不打包;

key 说明:

  • 表示结构的小于比较符号,缺省时 Struct 是没有小于操作的,如果定义了 key,则生成小于比较符。

key 详细说明:

  • key[Struct, member…]:

  • Struct:表示结构的名称

  • Member:表示该结构的成员变量,可以有多个;

  • 生成的小于比较操作符,按照 key 中成员变量定义的顺序进行优先<比较;

  • 生成小于比较操作符以后,该结构就可以作为 map 的 key;

其他说明:

  • 在 Tars 的 c++语言中,对于结构而言,提供两个成员函数用于直接打印出结构的内容,可以用于调试和记录日志:

  • ostream& display(ostream& _os, int _level=0):直接打印结构的详细内容,主要用于调试;

  • ostream& displaySimple(ostream& _os, int _level=0):所有成员变量自动按照顺序以|分隔打印出来,用于记录日志;

1.4.4. 序列

序列用 vector 来定义,如下:

vector<int> vi;

1.4.5. 字典

字典用 map 来定义,如下:

map<int, string> m;

说明:

  • 对于 struct,通常不能作为 map 的 key,因此 struct 没有大小比较符号;

  • 如果需要 struct 能够作为 map 的 key,需要用 less 定义 struct 中成员的比较顺序;

1.4.7 嵌套

任何 struct,map,vector 都可以嵌套;

1.5. 接口

接口定义如下,例如:

interface Demo
{
    int get(out vector<map<int, string>> v);

    int set(vector<map<int, string>> v);
};

说明:

  • 表示输出参数

  • 接口定义后,通过自动代码生成工具 (如:tars2cpp)会生成同步接口和异步接口等代码

1.6. 名字空间

所有的 struct,interface 必须在名字空间中,例如:

module MemCache
{
    struct Key
    {
        0 require string s;
    };

    struct Value
    {
        0 require string s;
    };

    interface MemCacheI
    {
        int get(Key k, out Value v);

        int set(Key k, Value v);
    };
};

说明:

  • 名字空间不能嵌套;

  • 可以引用其他名字空间,例如:Demo1::Key

1.7. 引用

一个 tars 文件可以 include 另外一个 tars 文件, 只需要在头部如下引用其他文件即可: #include "other.tars"

即可引用其他 tars 文件中的结构体了

2. Tars 协议

2.1. 数据编码

2.1.1. 基本结构

每一个数据由两个部分组成,如下图:

| 头信息 | 实际数据 |

而其中头信息包括以下几个部分:

| Type(4 bits) | Tag 1(4 bits) | Tag 2(1 byte) |

Tag 2 是可选的,当 Tag 的值不超过 14 时,只需要用 Tag 1 就可以表示;当 Tag 的值超过 14 而小于 256 时,Tag 1 固定为 15,而用 Tag 2 表示 Tag 的值。Tag 不允许大于 255。

Type 表示类型,用 4 个二进制位表示,取值范围是 0~15,用来标识该数据的类型。不同类型的数据,其后紧跟着的实际数据的长度和格式都是不一样的,详见一下的类型表。

Tag 由 Tag 1 和 Tag 2 一起表示。取值范围是 0~255,即该数据在结构中的字段 ID,用来区分不同的字段。

2.1.2. 编码类型表

注意,这里的类型与 tars 文件定义的类型是两个不同的概念,这里的类型只是标识数据存储的类型,而不是数据定义的类型。

取值
类型
备注

0

int1

紧跟 1 个字节整型数据

1

int2

紧跟 2 个字节整型数据

2

int4

紧跟 4 个字节整型数据

3

int8

紧跟 8 个字节整型数据

4

float

紧跟 4 个字节浮点型数据

5

double

紧跟 8 个字节浮点型数据

6

String1

紧跟 1 个字节长度,再跟内容

7

String4

紧跟 4 个字节长度,再跟内容

8

Map

紧跟一个整型数据表示 Map 的大小,再跟[key, value]对列表

9

List

紧跟一个整型数据表示 List 的大小,再跟元素列表

10

自定义结构开始

自定义结构开始标志

11

自定义结构结束

自定义结构结束标志,Tag 为 0

12

数字 0

表示数字 0,后面不跟数据

13

SimpleList

简单列表(目前用在 byte 数组),紧跟一个类型字段(目前只支持 byte),紧跟一个整型数据表示长度,再跟 byte 数据

2.1.3. 各类型详细描述

1.基本类型(包括 int1、int2、int4、int8、float、double)

头信息后紧跟数值数据。char、bool 也被看作整型。所有的整型数据之间不做区分,也就是说一个 short 的值可以赋值给一个 int。

2.数字 0

头信息后不跟数据,表示数值 0。所有基本类型的 0 值都可以这样来表示。

这是考虑到数字 0 出现的概率比较大,所以单独提一个类型,以节省空间。

3.字符串(包括 String1、String4)

String1 跟一个字节的长度(该长度数据不包括头信息),接着紧跟内容。

String4 与之类似。

4.Map

紧跟一个整形数据(包括头信息)表示 Map 的大小,然后紧跟[Key 数据(Tag 为 0),Value 数据(Tag 为 1)]对列表。

5.List

紧跟一个整形数据(包括头信息)表示 List 的大小,然后紧跟元素列表(Tag 为 0)

6.自定义结构开始

自定义结构开始标志,后面紧跟字段数据,字段按照 tag 升序顺序排列

7.自定义结构结束

自定义结构结束标志,Tag 为 0

2.1.4 对象持久化

对于自定义结构的持久化,由开始标志与结束标志来标识。

比如如下结构定义:

struct TestInfo
{
    1  require  int    ii  = 34;
    2  optional string s   = "abc";
};

struct TestInfo2
{
    1  require TestInfo  t;
    2  require int       a = 12345;
};

其中,默认的 TestInfo2 结构编码后结果为:

2.2. 消息格式

TUP 底层协议完全采用 Tars 定义,与 Tars 的底层数据包定义一致,其中 require 的字段为 TUP 必须的字段,optional 为访问 Tars 服务时额外需要用到的字段。

2.2.1. 请求包

//请求包体
struct RequestPacket
{
    1  require short        iVersion;         //版本号
    2  optional byte        cPacketType;      //包类型
    3  optional int         iMessageType;     //消息类型
    4  require int          iRequestId;       //请求ID
    5  require string       sServantName;     //servant名字
    6  require string       sFuncName;        //函数名称
    7  require vector<byte> sBuffer;          //二进制buffer
    8  optional int         iTimeout;         //超时时间(毫秒)
    9  optional map<string, string> context;  //业务上下文
    10 optional map<string, string> status;   //框架协议上下文
};

2.2.2. 响应包

//响应包体
struct ResponsePacket
{
    1 require short         iVersion;       //版本号
    2 optional byte         cPacketType;    //包类型
    3 require int           iRequestId;     //请求ID
    4 optional int          iMessageType;   //消息类型
    5 optional int          iRet;           //返回值
    6 require vector<byte>  sBuffer;        //二进制流
    7 optional map<string, string> status;  //协议上下文
    8 optional string       sResultDesc;    //结果描述
};

//返回值
const int TAFSERVERSUCCESS       = 0;       //服务器端处理成功
const int TAFSERVERDECODEERR     = -1;      //服务器端解码异常
const int TAFSERVERENCODEERR     = -2;      //服务器端编码异常
const int TAFSERVERNOFUNCERR     = -3;      //服务器端没有该函数
const int TAFSERVERNOSERVANTERR  = -4;      //服务器端没有该Servant对象
const int TAFSERVERRESETGRID     = -5;      //服务器端灰度状态不一致
const int TAFSERVERQUEUETIMEOUT  = -6;      //服务器队列超过限制
const int TAFASYNCCALLTIMEOUT    = -7;      //异步调用超时
const int TAFINVOKETIMEOUT       = -7;      //调用超时
const int TAFPROXYCONNECTERR     = -8;      //proxy链接异常
const int TAFSERVEROVERLOAD      = -9;      //服务器端超负载,超过队列长度
const int TAFADAPTERNULL         = -10;     //客户端选路为空,服务不存在或者所有服务down掉了
const int TAFINVOKEBYINVALIDESET = -11;     //客户端按set规则调用非法
const int TAFCLIENTDECODEERR     = -12;     //客户端解码异常
const int TAFSERVERUNKNOWNERR    = -99;     //服务器端位置异常
Tars 语言
Tars 协议
tars