TAF 入门源码学习总结

2021-08-03 14:56:08 浏览数 (1)

作者:邓永强

导语

TAF 是分布式基于 epoll 的多线程非阻塞的高性能且支持同步、异步、单向调用 RPC 框架。框架将网络线程和业务线程隔离,并通过队列和管道实现网络线程和业务线程间通信。框架维护网络连接,实现客户端和服务端远程调用和本地调用基本一样,用户只需关注业务逻辑。框架支持多种语言开发,集高可用,高性能,高并发,高效率等优秀特性。

1 TAF 简介

TAF(Total Application Framework)框架整体划分为五层结构,运营、平台、通信框架、公共库、协议层。框架将网络线程和业务线程隔离,通过消息管道和队列实现业务线程(应用层)和网络线程(传输层)间通信,业务侧只需关注业务逻辑开发。框架协议层使用适宜传输且与语言无关的JCE、WUP协议;提供了完善的公共库;传输层提供完善网络通信机制,包括RPC(单向/同步/异步),过载保护;平台层提供统一管理,负载均衡,容错等机制;运营层前端集发布,监控,自动配置等。

1.1框架比较

目前主要基于taf和基于appPlatform框架的后台开发,因此对两个框架有浅显的了解和学习。两个框架都是RPC通信,taf框架是基于epoll的多线程非阻塞RPC框架,而appPlatform是基于多进程,主要应用于电商形式的后台框架。

2 服务端

2.1 服务端启动过程

服务需要继承taf基类Application, 调用框架main函数,解析服务端配置文件加载到服务端,然后初始客户端通讯器,初始化服务端并创建_epollServer对象,并绑定到AdminAdapter,然后adapters绑定IP和Port,启动业务线程。调用框架waitForShutdown()创建网络线程并监听端口,然后启动网络线程,完成服务启动。

TAF启动过程概述:

1、业务系统服务g_app.main()调用框架Application::main()完成以下过程:

1)调用parseConfig(),解析TAF服务模板内容配置,包括client和server的locator,超时,log,心跳等。

2)调用initializeClient(),初始化客户端通信器_communicator

3)调用initializeServer(),初始化taf基础配置

a. 初始化ServerConfig结构体

b. _epollServer = new TC_EpollServer()

c. 初始化日志服务代理,配置中心代理,信息中心代理,Node代理,管理对象。

d.创建Socket,AdminAdapter给网络线程绑定Socket,并设置连接数,超时,队列等。

4)调用bindAdapter(),线程绑定adapters和端口

5)回调Servant的initialize()方法,业务初始化

6)遍历vector<TC_EpollServer::BindAdapterPtr>,并创建线程组HandleGroup()

7)调用_epollServer->startHandle(),启动业务处理线程组

8)调用epollServer ->createEpoll(),网络线程创建Epoller对象

2、业务系统服务g_app.waitForShutdown() 调用Application::waitForShutdown()完成以下过程:

1)调用_epollServer->waitForShutdown()完成:

a. 遍历线程组,并依次调用start()启动

b. 创建Epoll对象,并监听socket事件

c. 如果有请求调用accept()接收请求信息,如果有关闭请求调用stopThread(),遍历网络线程HandleGroup(),调用join结束网络线程。

2)服务线程结束,调用destroyApp(),析构业务申请资源。

2.2 服务端分析

2.1.1 基础类图

业务服务系统需继承TAF框架Application类初始化服务端基础配置,并创建TC_EpollServer类对象,在Epoll类中创建网络线程类NetThread和BindAdapter,并把线程和adapter绑定。

2.1.2 调用方式

TAF是多线程基于Epoll的RPC框架,主要实现网络线程和业务线程隔离,框架实现底层网络线程,框架维护网络连接队列,数据接收队列,数据发送队列,通过pipe实现网络线程和业务线程间通信,业务侧只需要考虑业务线程处理业务逻辑,很大程度提升业务开发效率。如下图所示:

TAF基于Epoll实现单向、同步、异步的远程RPC通信方式。客户端和服务端调用方式如图所示。客户端首先通过stringtoProxy(obj)方式上报taf主控并获取到当前活跃的服务端IP和端口,然后客户端可以发送连接请求与服务端通信。服务端每台机器需要安装node,node不断上报心跳等信息到taf主控,并通过patch实现主控控制服务节点。如下图所示:

2.1.3 业务线程

1、taf服务提供业务处理线程类Handle,并由HandleGroup统一管理。HandleGroup相当于业务处理线程池。有请求则把请求回调到Servant的onDispatch()方法并分发给业务线程处理,同步调用直接将处理结果写入到消息对列,网络线程取出消息对列数据返回调用方。

每个Servant存在一个BindAdapter()实例,负责统一管理Servant的信息。当服务端接收到客户端的请求,网络线程把请求放到BindAdapter()的消息队列。并唤醒HandleGroup锁,Handle线程从消息对列取出消息。

2.1.4 网络线程

1 、遍历连接长时间无数据,主动关闭并删除链接。

2 、等待epoll消息,事件到来处理epoll消息。

1)连接请求

客户端连接events,建立连接,框架选择网络线程处理连接列表,再把socket加入epoll事件的处理列表,调用accep接收数据

2)停止请求

break到外层,调用stopThread通知线程

3)控制通知:

a .关闭通知,则调用stopThread关闭并删除此连接;

b .发送通知,将网络线程缓存发送,避免关闭网络线程导致数据丢失。

4)数据请求:

a .如果socket收到数据,调用insertRecvQueue()

b .如果缓存有处理结果待发送,发送处理结果给客户端。

c .更新连接表超时时间。

0 人点赞