7

Tars框架进阶

 3 years ago
source link: https://www.lanindex.com/tars%e6%a1%86%e6%9e%b6%e8%bf%9b%e9%98%b6%e4%bd%bf%e7%94%a8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Tars框架进阶

2017/11/28 · Leave a comment

总结Tars中一些重要的原理与使用方式,内容可能会有部分内容与官方docs重合,但绝对不会是官方docs的搬运。

本文适合已经可以自行安装好Tars,并且使用过一段时间Tars,对其有一些基本感知的人阅读。当然,同时也欢迎Tars新鸟、老鸟来交流。

Tars中一些重要的概念

Tars核心点有四个:

  • 一套服务器框架(特点:高稳定性、高可用性、高性能);
  • 十分方便的内建RPC机制(特点:开发使用简单方便);
  • 丰富的公用库(特点:封装了大部分常用方法,易于使用);
  • 服务治理平台(功能:服务部署、发布、配置、监控、调度管理、容灾);

Tars中的客户端:

这是一个比较容易混淆的概念,Tars是一个服务器框架,这里的客户端只是对调用接口者一种统称:

  • Tars里的客户端,做个比喻:有两个Tars Server – ServerA与ServerB,ServerA需要调用ServerB提供的接口获取信息,那么此时ServerA看做成客户端,ServerB看做成服务端;

在Tars内部,对于客户端,提供了四种调用服务端方式:

  • 同步阻塞,官方有样例,代码结构最简单;
  • 异步非阻塞,官方有样例,需要自己继承CallBack实现;
  • Future/Promise,官方无样例,异步代码同步化;
  • Coroutine,官方无样例,在配置里面[OpenCoroutine]默认是关闭的;

一句经验之谈:Tars的客户端一般是属于被服务端“利用”的状态,即在服务端的代码中利用上述四种方式调用其他Tars服务端的接口(隐藏了客户端的概念)。

所以,仅仅只是使用Tars,我们不必纠结客户端的概念,只需要知道它大概是一个什么角色即可,若是想要深入源码去剖析、学习Tars原理就必须得要区分清楚。

需要注意是:Tars客户端支持多线程,可在[运维管理]->[模版管理]->[编辑tars.default]中的<client>标签下面加入netthread = n修改客户端线程的数量(默认值是1)。

每个客户端线程下面会持有m个异步处理线程,异步处理线程主要是处理上述接口调用方式后三种的调用结果,其值可以在[服务列表]->[编辑]->[异步线程数]输入框里面修改线程数量。

为什么需要知道这些设置?因为根据这些设置,再结合机器资源与自己要实现的业务属性,可以定制化自己需要的线程数,达到资源利用最优!

Tars中的服务端:

在Tars中,具体的业务服务都从Servant继承实现,一个Tars节点可以拥有多个不同的Servant,这些Servant可以根据需要自主的选择Tars/非Tars协议,Tcp/Udp协议。

推荐的做法是:Tars内部之间的服务提供可以选择Tars协议 + Tcp(在同一IDC基本网络耗时在1-2ms);对外非Tars提供服务选择非Tars协议 + Tcp/Udp

需要注意是:Tars的Udp是原生的,若想实现Udp的有序和可靠,且不修改Tars源码,可以选择嵌入KCP

Tars服务端也支持多线程,可在[管理Servant]->[编辑]->[线程数]输入框里面修改线程数量。

Tars客户端使用

抽象一个场景:Tars应用Lan,其中一个服务名字叫TestServer,该服务提供业务接口的Servant叫TestServant,提供Hello()这个接口,这个服务有n个节点。

现在在同样的应用Lan里面,有一个Tars服务作为客户端想调用Hello()接口:

TestServantPrx testPrx = Application::getCommunicator()->stringToProxy<TestServantPrx>("Lan.TestServer.TestServant");
//这个方法会自动找到有效节点进行轮询调用
testPrx->Hello();
//可以获得刚才调用节点的IP、PORT相关信息
//const TC_Endpoint ep = testPrx->tars_invoke_endpoint();

这次调用默认是按轮询的,tars也提供了hash方式的调用,保证相同key,会调用相同的active节点(这里隐含的重点是会自动屏蔽掉inactive的节点):

TestServantPrx testPrx = Application::getCommunicator()->stringToProxy<TestServantPrx>("Lan.TestServer.TestServant");
testPrx->tars_hash(0)->Hello();
testPrx->tars_consistent_hash(0)->Hello();

也可以指定节点调用,前提你需要知道它的协议,IP,PORT:

TestServantPrx testPrx = Application::getCommunicator()->stringToProxy<TestServantPrx>("Lan.TestServer.TestServant@tcp -h 10.120.129.226 -p 20001");

获得对应TestServer所有节点的IP列表:

TestServantPrx testPrx = Application::getCommunicator()->stringToProxy<TestServantPrx>("Lan.TestServer.TestServant");
vector<EndpointInfo> actives;   //有效节点列表
vector<EndpointInfo> inactives; //失效节点列表
testPrx->tars_endpointsAll(actives, inactives);
vector<EndpointInfo>::const_iterator it = actives.begin();
for ( ; it != actives.end(); it++) {
const EndpointInfo &ep = *it;
//ep里面包含了协议、IP、PORT等等信息
}

Tars服务端一些方法

场景和客户端相同,我们想获取当前TestServant节点的协议、IP、PORT等信息:

//需要在TestServant的子类里调用
TC_EpollServer *e = getHandle()->getEpollServer();
const TC_Endpoint ep = e->getBindAdapter(ServerConfig::Application + "." + ServerConfig::ServerName + ".TestServantAdapter")->getEndpoint();
//ep里面包含了协议、IP、PORT等等信息

获得当前SET相关信息

if (tars::ClientConfig::SetOpen && !tars::ClientConfig::SetDivision.empty()) {
vector<string> set = TC_Common::sepstr<string>(tars::ClientConfig::SetDivision, ".");
//set[0]-Set名  set[1]-Set区域   set[2]-Set组
}

怎么看待Tars服务端协议接口?

Tars所有的接口都是socket在TCP/UDP应用层的封装,不论你用的什么语言,Java,C++,PHP……只要有socket存在的地方Tars接口就可以被调用。所以任何系统任何语言只要通过socket按照特定的协议格式都可以与Tars服务进行连接。具体原理与步骤可以参考官方的文档:TUP

现在Tars加入了接口鉴权,不好评价这个功能,我觉得Tars最需要的是一个易扩展的前置验证,就是在进入www.yourtars.com:8080的时候需要验证身份才可以进入,临时的方案可以使用resin自带的验证功能,缺点是不太利于集中管理权限。当然也可以自己在Tars管理页面前面套一层验证管理,这个成熟方案比较多,没什么特别要求的话大家选取合适和喜欢就好。

Tars的缺点

说了这么多Tars的亮点,下面也谈谈个人觉得Tars不太妥的地方。

一台服务器(物理机、虚拟机、云主机)不能部署同应用的同种Server

比如我都轻量级的微服务,AServer我想要部署4个进程,那么必须分布在4个不同的服务器上。资源有一定的浪费,好处是提高了服务可用性。

部署对于Tars新手门槛略高

虽然现在官方在推直接部署好的Tars云服务器,然后也有民间制作的docker,但是原生的安装步骤边边角角的坑实在太多了,尤其是对于linux不太熟悉的人。

小BUG依旧很多

Tars服务自带的配置文件框无法拉大,adminRegistry线程过多(官方已经修复),Tars自带服务QueryxxxServer的coredump(官方已经修复)……虽然都是不影响核心业务的小问题,总之还是需要不断的完善,不断的有人趟坑。

文档不全,缺少核心社区

官方文档很多都是早期腾讯内部就已存在的,开源以来更新的文档屈指可数,个人觉得少了几处比较关键的:客户端Future/Promise与Coroutine的使用样例、服务扩/缩容原理与注意事项、核心线程的协作关系;社区就不用说了,Tars群基本都是伸手党,官方少了一点带头作用。

最后希望Tars能越来越好!

(全文结束)

转载文章请注明出处:漫漫路 - lanindex.com


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK