前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开源代码TarsGo-v1.0.0源码分析之transport

开源代码TarsGo-v1.0.0源码分析之transport

作者头像
月牙寂道长
发布2019-07-02 14:11:34
9750
发布2019-07-02 14:11:34
举报
文章被收录于专栏:月牙寂月牙寂

版权声明:本文为作者原创,如需转载请通知本人,并标明出处和作者。擅自转载的,保留追究其侵权的权利。golang群:570992072。qq 29185807 个人公众号:月牙寂道长 公众号微信号yueyajidaozhang https://cloud.tencent.com/developer/article/1454555

本人微信公众号文章链接:https://mp.weixin.qq.com/s/wNULJpEr9g3TlGAhD8JuKg

Tars是腾讯开源的一款微服务框架。在去年9月,腾讯宣布正式开源 Tars 的 Golang 版本TarsGo。

当TarGo开源的时候,就想对此开源代码进行学习。近期刚好有空,就看了看。说实话,本人并未使用Tars框架,本文只是对TarsGo源码进行分析。

Tars整体框架介绍,可以参考https://github.com/TarsCloud/Tars/blob/master/Introduction.md

还有文章:

腾讯 Tars 开源 Go 版本 Tars-Go,并发性能比 gRPC 高 5 倍

https://my.oschina.net/editorial-story/blog/2054185

关于TarsGo的介绍还有:

https://github.com/TarsCloud/TarsGo/blob/master/README.zh.md

源码地址:

https://github.com/TarsCloud/TarsGo

按照本人习惯,从低版本进行研究,此次源码分析定位v1.0.0版本

源码目录:

在Tarsgo中,有两个模块client和server

此图来源https://github.com/TarsCloud/Tars/blob/master/Introduction.md https://github.com/TarsCloud/Tars/blob/master/Introduction.md server服务运行后,会定期上报心跳到node,node然后把服务心跳信息上报到registry服务,由registry进行统一管理。 Client访问Server流程:client可以通过server的对象名Obj间接访问server,Client会从registry上拉取server的路由信息(如ip、port信息),然后根据具体的业务特性(同步或者异步,tcp或者udp方式)访问server(当然client也可以通过ip/port直接访问server)。 https://github.com/TarsCloud/Tars/blob/master/Introduction.md

在github.com/TarsCloud/TarsGo/tars/tools/Demo中有构建client和server,这将是源码开始的第一步。

transport

在此之前,有一个底层模块很独立,会优先分析

transport模块,是一个完全独立的模块,其中有底层的tarclient和tarserver模块。

在github.com/TarsCloud/TarsGo/tars/transport/examples中有两个很简单的案例

tarsclient

那么直接看源码github.com/TarsCloud/TarsGo/tars/transport/tarsclient.go

tarsclient是底层通信层,包括链接部分,以及提供了协议接口。

TarsClientProtocol是TarsClient唯一对外的接口,通过此接口,使得TarsClient模块完全独立。这样的模块设计,是非常值得推荐的。

此interface,提供两个方法:Recv,ParsePackage。

TarsClient,其中最重要的两个成员为:

cp:TarsClient对外提供的接口,这个是具体的协议处理部分

conn:是具体的链接

connection,其实很简单的结构体。主要是封装了net.conn

初始化,最重要的有:

参数cp(TarsClientProtocol),这个是协议处理部分,由外部构建传入。

52:tc.conn:构建了一个链接结构体

对于TarsClient有两个操作,send和recv

Send

58:调用了tc.conn的reConnect操作

61:将要发送的reg传送到tc.sendQueue中

160:加锁,防止并发

161:判断标志位isClosed

163:构建net.Dial,这个代码应该很熟悉了

175:设置标志位isClosed

176:开启recv协程

177:开启send协程

send协程,在reconnet中开启的

75:设置了一个ticker,定时器

79:从TarsClient的sendQueue中取出数据到req中

80-89:获取定时器信号,然后检测TarsClient的标志位isClosed。如果已经关闭则会在87行return。

定时器的这种操作,是一种常规的协程自销毁操作。

96:将读取的req通过conn发送出去。

recv

115:从conn中Read数据

134:将读取的数据,不断的append到currBuffer中

136:cp则就是TarsClientProtocol,将读取到的数据,进行协议解析

145:将解析过的数据,开启一个TarsClientProtocol的Recv协程,传入其中处理。

136和145就是TarsClientProtocol接口的两个处理地方。

小结:TarsClient的代码流程还是很简单的,模块设计也很简单,对外的接口TarsClientProtocol也是非常的合理。

tarsserver

有client,就有server

github.com/TarsCloud/TarsGo/tars/transport/tarsserver.go

server也有一个协议接口,TarsProtoCol,这里有三个方法

Invoke:数据处理部分

ParsePackage:协议解析部分

InvokeTimeout:处理超时

对于server,还有一个接口,就是底层监听,是udp还是tcp。

Listen:监听

Handle:处理部分

初始化,其中最重要的是svr(TarsProtocol)

72:获取到handle

76:则调用了handle

这里提供了两个协议,tcp和udp,是根据配置中设定来初始化。

先看下invoke,这个将在tcp或udp handle中调用。

97:handleTimeout==0的情况,应该是忽略超时。调用了TarsProtocol中的Invoke操作

99-103:开启了一个协程,来调用Invoke

104-108:有一个定时器,来判断是否超时。若超时了,则调用TarsProtocol中的InvokeTimeout操作。

server的操作还未结束,继续看看udphandler

github.com/TarsCloud/TarsGo/tars/transport/udphandler.go

里面存储了TarsServer

udphandler的listen,不解释了

udphandler的Handle接口

32:读取数据

43-48:开启了一个协程,调用了tarsServer的invoke函数。按理来说,应该是要做协议解析,再处理的。看后面的注释:no need to check package。这个应该是协议的规定

小结:udphandle比较简单

tcphandle

tcphandle相对比udphandle要复杂一些。

github.com/TarsCloud/TarsGo/tars/transport/tcphandler.go

最重要的还是ts(TarsServer)

tcp的listen,不做解释

tcp的Handle,分为三部分

43-47:开启了worker,这里有多个work处理

50:tcp的accept

59-67:对每个conn,都开启了一个协程。在65行,调用了recv操作

96:读取数据

112:将读取的数据,append到currBuffer中

114:调用了TarsProtocol的协议解析函数ParsePackage

122-124:若开启了多个worker的话,则将数据发送到jobs中

126-131:若没有开启多个worker的话,则开启一个协程,调用TarsServer的invoke。

woker的处理,就是从jobs中读取数据,然后调用TarsServer的invoke处理数据。

小结:

tcphandle相对比udphandle多了一个worker的操作,另外也多了协议解析。

现在来看案例

helloserver

目录github.com/TarsCloud/TarsGo/tars/transport/examples/helloserver

github.com/TarsCloud/TarsGo/tars/transport/examples/helloserver/server.go

构建了一个TarsProtocol的接口,MyServer

Invoke:填充了hello

ParsePackage:对包解析,并做了一些防御性操作

InvokeTimeout:超时处理

46:proto:tcp

57:构建了TarsServer

58:开启Server

github.com/TarsCloud/TarsGo/tars/transport/examples/helloserver/client.go

构建了一个TarsClientProtocol接口,Myclient

Recv:接收数据的处理部分

ParsePackage:数据协议解析

45:proto:tcp

51:构建了TarsClient

57:调用TarsClient send发送数据

总结:

transport是整个tarsgo的底层部分,其模块设计简单,并且独立。是整个tarsgo架构的底层模块。

由于文章篇幅问题,本文只做transport的分析。后续还有更多的源码分析。

龚浩华

月牙寂道长

qq:29185807

2019年05月28日

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年06月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 腾讯 Tars 开源 Go 版本 Tars-Go,并发性能比 gRPC 高 5 倍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档