Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >TarsGo支持Protocol Buffer

TarsGo支持Protocol Buffer

原创
作者头像
陈明杰
修改于 2018-10-10 10:22:37
修改于 2018-10-10 10:22:37
2.8K00
代码可运行
举报
文章被收录于专栏:TarsTars
运行总次数:0
代码可运行

Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架TAF(Total Application Framework),目前支持C++,Java,PHP,Nodejs,Golang语言。该框架为用户提供了涉及到开发、运维、以及测试的一整套解决方案,帮助一个产品或者服务快速开发、部署、测试、上线。 它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。目前该框架在腾讯内部,各大核心业务都在使用,颇受欢迎,基于该框架部署运行的服务节点规模达到上万个。

Tars 于2017年4月开源,并于2018年6月加入Linux 基金会,项目地址 https://github.com/TarsCloud

TarsGo 是Tars 的Go语言实现版本, 于2018年9月开源, 项目地址 https://github.com/TarsCloud/TarsGo

Tars协议是一种类c++标识符的语言,用于生成具体的服务接口文件,Tars文件是Tars框架中客户端和服务端的通信接口,通过Tars的映射实现远程对象调用。 Tars 协议是和语言无关,基于IDL接口描述语言的二进制编码协议。

详见 TarsProtocol

Protocol Buffers (简称 PB )是 Google 的一种数据交换的格式,它独立于语言,独立于平台,最早公布于 2008年7月。随着微服务架构的发展及自身的优异表现,ProtoBuf 可用于诸如网络传输、配置文件、数据存储等诸多领域,目前在互联网上有着大量应用。

PB协议是单独的协议,如果要支持RPC,可以定义service字段,并且基于protoc-gen-go 的grpc 插件生成相应的grpc编码。

以下面的 proto 文件为例

代码语言:go
AI代码解释
复制
syntax = "proto3";
package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

使用protoc生成相应的接口代码,以Go语言为例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protoc --go_out=plugins=grpc:. helloworld.proto

如果对于现有已使用grpc,使用proto,想转换成tars协议的用户而言,需要将上面的proto文件翻译成Tars文件。对于Tars而言,Tars是编写tars文件,然后用相应的工具tars2xxx, 比如tars2go生成相应的接口代码。上面的proto文件翻译成tars文件是:

代码语言:c++
AI代码解释
复制
module helloworld{
    struct HelloRequest {
        1 require string name ;
    };
    struct HelloReply {
        1 require string message ;
    };

    interface Greeter
    {
        int SayHello(HelloRequest req, out HelloReply resp);
    };
}

然后调用tars2go生成 相应的tarsgo接口:

代码语言:go
AI代码解释
复制
tars2go --outdir ./ helloworld.tars

这种翻译会比较繁琐,而且容易出错。 为此我们决定编写插件支持proto直接生成tars的rpc逻辑。

有两种方案,一种是写protoc插件,直接读取protoc解析proto文件的二进制流,对service相应的字段进行解析,以便生成相应的rpc逻辑,其他交由protoc-gen-go处理

另外一种是直接编写protoc-gen-go的插件,类似gRPC插件,

这里决定采用方案2 。

protoc-gen-go 并没有插件编写的相关说明,但protoc-gen-go的代码逻辑里面是预留了插件编写的规范的,参照grpc,主要有 grpc/grpc.go 和一个导致插件包的link_grpc.go 。 这里我们编写 tarsrpc/tarsrpc.go 和 link_tarsrpc.go

代码逻辑基本上就是继承 generator.Generator,注册插件, 获取相应的service,method,和method的input和output,再调用P方法将要生成的代码输出即可

代码语言:go
AI代码解释
复制
func init() {
	generator.RegisterPlugin(new(tarsrpc))
}

// tarsrpc is an implementation of the Go protocol buffer compiler's
// plugin architecture.  It generates bindings for tars rpc support.
type tarsrpc struct {
	gen *generator.Generator
}

func (t *tarsrpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) {
	originServiceName := service.GetName()
	serviceName := upperFirstLatter(originServiceName)
	t.P("// This following code was generated by tarsrpc")
	t.P(fmt.Sprintf("// Gernerated from %s", file.GetName()))
	t.P(fmt.Sprintf(`type  %s struct {
		s model.Servant
	}
	`, serviceName))
	t.P()
... ...
}   

这里主要是生成 service 转成相应的interface,然后interface里面有定义的rpc method, 用户可以实现自己真正业务逻辑的method,其余的都是tars相应的发包收包逻辑。Tars的请求包体:

代码语言:go
AI代码解释
复制
type RequestPacket struct {
	IVersion     int16             `json:"iVersion"`
	CPacketType  int8              `json:"cPacketType"`
	IMessageType int32             `json:"iMessageType"`
	IRequestId   int32             `json:"iRequestId"`
	SServantName string            `json:"sServantName"`
	SFuncName    string            `json:"sFuncName"`
	SBuffer      []uint8           `json:"sBuffer"`
	ITimeout     int32             `json:"iTimeout"`
	Context      map[string]string `json:"context"`
	Status       map[string]string `json:"status"`
}

我们只需要将rpc method的名字,放入RequestPacket 的SFuncName ,然后将请求参数调用proto的Marshal序列化后放到 SBuffer。

而对于回包,Tars的回包结构体:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type ResponsePacket struct {
	IVersion     int16             `json:"iVersion"`
	CPacketType  int8              `json:"cPacketType"`
	IRequestId   int32             `json:"iRequestId"`
	IMessageType int32             `json:"iMessageType"`
	IRet         int32             `json:"iRet"`
	SBuffer      []uint8           `json:"sBuffer"`
	Status       map[string]string `json:"status"`
	SResultDesc  string            `json:"sResultDesc"`
	Context      map[string]string `json:"context"`
}

同样,我们只需要将返回的结果,调用Marshal 将请求放入 SBuffer ,其他逻辑和tars保持一致。

编写完插件,就可以通过和grpc生成代码相同的方式,将proto 文件转化成tars的接口文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protoc --go_out=plugins=tarsrpc:. helloworld.proto

下面是简单的服务端例子

代码语言:go
AI代码解释
复制
package main

import (
    "github.com/TarsCloud/TarsGo/tars"
    "helloworld" //上面工具生成的package
)

type GreeterImp  struct {
}

func (imp *GreeterImp) SayHello(input helloworld.HelloRequest)(output helloworld.HelloReply, err error) {
    output.Message = "hello" +  input.GetName() 
    return output, nil 
}

func main() { //Init servant

    imp := new(GreeterImp)                                    //New Imp
    app := new(helloworld.Greeter)                            //New init the A JCE
    cfg := tars.GetServerConfig()                              //Get Config File Object
    app.AddServant(imp, cfg.App+"."+cfg.Server+".GreeterTestObj") //Register Servant
    tars.Run()
}

简单的客户端调用例子

代码语言:go
AI代码解释
复制
package main

import (
    "fmt"
    "github.com/TarsCloud/TarsGo/tars"
    "helloworld"
)

func main() {
    comm := tars.NewCommunicator()
    obj := fmt.Sprintf("StressTest.HelloPbServer.GreeterTestObj@tcp -h 127.0.0.1  -p 10014  -t 60000")
    app := new(helloworld.Greeter)
    comm.StringToProxy(obj, app)
    input := helloworld.HelloRequest{Name: "sandyskies"}
    output, err := app.SayHello(input)
    if err != nil {
        fmt.Println("err: ", err)
    }   
    fmt.Println("result is:", output.Message)
}

protoc-gen-go 的插件放在 TarsGo/tars/tools/pb2tarsgo , 需要要求Protocol Buffer 3.6.0以上。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
TarsGo新版本发布,支持protobuf,zipkin和自定义插件
Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架,目前支持C++,Java,PHP,Nodejs,Golang语言。该框架为用户提供了涉及到开发、运维、以及测试的一整套解决方案,帮助一个产品或者服务快速开发、部署、测试、上线。 它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。目前该框架在腾讯内部,各大核心业务都在使用,颇受欢迎,基于该框架部署运行的服务节点规模达到上万个。 Tars 于2017年4月开源,并于2018年6月加入Linux 基金会。TarsGo 是Tars 的Go语言实现版本, 于2018年9月开源。 项目地址 https://github.com/TarsCloud/TarsGo ,欢迎star !
腾讯开源
2018/11/13
9410
基于spring-boot、grpc、zookeeper的分布式微服务架构
Protocol buffer 已经开源一段时间了,项目示例目前使用proto3版本,最新版本对一些定义做了简化,添加了一些新的特性,并且在语言支持上做了扩展。
WindWant
2020/09/11
1K0
基于spring-boot、grpc、zookeeper的分布式微服务架构
TarsGo新版本发布,支持protobuf,zipkin和自定义插件
Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架,目前支持C++、Java、PHP、Nodejs、Golang语言。该框架为用户提供了涉及到开发、运维、以及测试的一整套解决方案,帮助一个产品或者服务快速开发、部署、测试、上线。 它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。目前该框架在腾讯内部,各大核心业务都在使用,颇受欢迎,基于该框架部署运行的服务节点规模达到上万个。
TARS小助手
2018/11/13
1.1K0
TarsGo新版本发布,支持protobuf,zipkin和自定义插件
Protocol buffer使用配置
Protocol buffers 是一种语言无关、平台无关的可扩展机制或者说是数据交换格式,用于序列化结构化数据, 与 XML、JSON 相比,Protocol buffers 序列化后的码流更小、速度更快、操作更简单, 一般可用于(数据)通信协议、数据存储等
Johns
2022/09/22
1.2K0
C++中gRPC:从小白入门到大神精通
在当今分布式系统盛行的时代,高效的通信机制是构建健壮、可扩展软件的关键。gRPC作为一个高性能、开源的远程过程调用(RPC)框架,在C++开发领域中扮演着重要角色。无论是开发微服务架构,还是构建大规模分布式系统,掌握gRPC都能让你的开发工作事半功倍。接下来,让我们一起开启从gRPC小白到大神的学习之旅。
码事漫谈
2025/02/07
3620
C++中gRPC:从小白入门到大神精通
gRPC,爆赞
gRPC 这项技术真是太棒了,接口约束严格,性能还高,在 k8s 和很多微服务框架中都有应用。
AlwaysBeta
2021/10/12
1.2K0
Google 序列化神器 Protocol Buffer 学习指南
在现代软件开发中,数据的高效传输和存储是一个关键问题。Google 开发的 Protocol Buffer(简称 Protobuf)作为一种语言中立、平台无关、可扩展的机制,用于高效地序列化结构化数据。它比 XML 或 JSON 更加紧凑和高效,非常适合需要高性能和小体积的场景。
Michel_Rolle
2024/06/17
3.2K0
GRPC: 理解Protocol Buffers和gRPC的基本概念和使用方法
Protocol Buffers(简称protobuf)是由Google开发的一种灵活、高效的结构化数据序列化方法。它类似于XML或JSON,但具备更小、更快、更简单的特点。protobuf主要用于定义数据的结构,然后生成用于解析和序列化数据的代码。这些代码可以用于各种编程语言,如Java、C++、Python、Go等。
运维开发王义杰
2024/06/25
6610
GRPC: 理解Protocol Buffers和gRPC的基本概念和使用方法
RPC简介和grpc的使用
RPC(Remote Procedure Call)远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,简单的理解是一个节点请求另一个节点提供的服务。RPC只是一套协议,基于这套协议规范来实现的框架都可以称为 RPC 框架,比较典型的有 有阿里巴巴的 Dubbo、Google 的 gRPC、Facebook 的 Thrift 和 Twitter 的 Finagle 等。
onenewcode
2024/02/06
3150
API 网关 gRPC-Gateway V2 初探
我们都知道 gRPC 并不是万能的工具。在某些情况下,我们仍然想提供传统的 HTTP/JSON API。原因可能从保持向后兼容性到支持编程语言或 gRPC 无法很好地支持的客户端。但是仅仅为了公开 HTTP/JSON API 而编写另一个服务是一项非常耗时且乏味的任务。
我是阳明
2021/04/09
2.5K0
API 网关 gRPC-Gateway V2 初探
服务端测试实战之rpc协议(二)
在服务端测试(一)中详细了介绍了服务端测试中的策略和方法论,以及针对服务端测试中稳定性的测试,以及高并发下对服务的并发请求。不过在企业的应用中,除了REST API的接口,还有gRPC的协议,主要应用于金融以及货币交易等领域,当然不仅仅如此,gRPC协议是一个高性能,开源和通用的框架,主流的开发语言都提供了对应的API,如Java,Go,Python等语言。gRPC的协议是基于HTTP/2标准设计(REST API 基本是基于HTTP/1.1设计),可以处理双向流,单路复用等,这些特性在移动端的领域表现更加高效,而且更加节省空间,背后的技术团队是Google。
无涯WuYa
2021/05/06
8120
Go - 如何编写 ProtoBuf 插件(二)?
上篇文章《Go - 如何编写 ProtoBuf 插件 (一) 》,分享了使用 proto3 的 自定义选项 可以实现插件的编写,说到基于 MethodOptions 和 ServiceOptions 选项去实现 method 和 service 自定义设置拦截器。
新亮
2021/12/20
6100
gRPC cpp 框架快速上手
在gRPC框架中,运行在不同机器上的客户端应用可以直接调用服务器端上「提供的方法」,使得我们可以更容易的创建一个分布式系统。
Mculover666
2021/11/02
1.1K0
grpc-swift入门
不想看前面的屁话,要直接上代码的,请跳到「iOS App端如何实现和RPC服务器通信」章节
iOS Development
2022/06/12
1.3K0
grpc-swift入门
小白零基础--gRPC整合Kubernetes
上一篇,我们简单介绍了下mac下单节点Kubernetes的安装,今天我们乘热打铁,感受下grpc整合Kubernetes的魅力。好了Talk is cheap,Show me the graph 我们要做的是下面这么一个架构的小demo。
用户3904122
2022/06/29
1.3K1
小白零基础--gRPC整合Kubernetes
gRPC 在 Go 中的应用:一个初步探索
gRPC 是 Google 开发的一个高性能、开源的通用 RPC (Remote Procedure Call, 远程过程调用) 框架,其面向移动和 HTTP/2 设计,并且可以运行在任何环境中。它可以从任何应用程序中调用其他应用程序的方法,无论这些应用程序是在同一个主机上,还是分布在不同的主机上。gRPC 还为开发人员提供了简洁的服务定义框架,使得能够自动化生成客户端和服务器端的代码。
运维开发王义杰
2023/08/10
4260
gRPC 在 Go 中的应用:一个初步探索
Go - 关于 proto 文件的一点小思考?
ProtoBuf 是一套接口描述语言(IDL),通俗的讲是一种数据表达方式,也可以称为数据交换格式。
新亮
2021/11/29
3880
Grpc介绍 — ProToBuf基本使用
RPC(Remote Procedure Call)远程过程调用,关注笔者的同学应该知道之前笔者出过关于Thrift对应的问题,这次主要来说的是Google开源的Grpc,和Thrift有很大的区别Grpc是基于HTTP2.0并且依赖protobuf,为什么又推出关于grpc的文章呢?请大家继续往下看。
喵了个咪233
2019/05/26
1.6K0
Golang笔记 6.3 RPC 编程之 gRPC
先了解几个基本概念,https://grpc.io/docs/guides/concepts/
twowinter
2020/04/17
1.5K0
gRPC示例初探【实战笔记】
备注:Will try to greet world ...这条日志在Client端访问Server前打印;Greeting: Hello world 这条日志在Server返回给Client后打印。
瓜农老梁
2019/11/12
8340
gRPC示例初探【实战笔记】
相关推荐
TarsGo新版本发布,支持protobuf,zipkin和自定义插件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验