TAF 入门源码学习总结

作者:邓永强

导语

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 .更新连接表超时时间。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jimoer

Java设计模式学习记录-状态模式

状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题。状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象...

571
来自专栏服务端思维

分布式锁不是控制并发幂等的方式

之前,我们探讨过幂等机制的实现方案,今天我们再来探讨下分布式锁是不是控制并发幂等的方式? 可能由于客户端的重复提交产生多份相同的数据,也可能因为服务端的重试机制...

762
来自专栏Java技术

基于TCP和HTTP协议的RPC简单实现

(1)RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网...

593
来自专栏架构师之路

1分钟了解Leader-Follower线程模型

上图就是L/F多线程模型的状态变迁图,共6个关键点: (1)线程有3种状态:领导leading,处理processing,追随following (2)假设共N...

3465
来自专栏Jerry的SAP技术分享

Netweaver工作进程的内存限制 VS CloudFoundry应用的内存限制

一个会话进程能够在堆上申请的内存大小上限, 在事务码RZ11里查看参数abap/heap_area_dia:

1834
来自专栏iOS 开发杂谈

iOS多线程之一:基本概念

进程:就是一个正在执行的程序。 线程:是执行程序最基本的单元,它有自己栈和寄存器。

531
来自专栏木可大大

Spring Boot 2.0深度实践之核心技术篇

第1章 系列总览 总览 Spring Boot 2.0 深度实践系列课程的整体议程,包括 Spring Boot 三大核心特性(组件自动装配、嵌入式Web容&#...

2133
来自专栏移动端开发

Swift2.0 函数学习笔记

最近又有点忙,忙着找工作,忙着适应这个新环境。现在好了,上班两周周了,也适应过来了,又有时间安安静静的就行我们前面的学习了。今天这篇笔记,记录的就是函数的使用。...

1816
来自专栏小灰灰

熔断Hystrix使用尝鲜

熔断Hystrix使用尝鲜 当服务有较多外部依赖时,如果其中某个服务的不可用,导致整个集群会受到影响(比如超时,导致大量的请求被阻塞,从而导致外部请求无法进来)...

3059
来自专栏程序猿DD

Spring Cloud构建微服务架构:消息驱动的微服务(入门)【Dalston版】

之前在写Spring Boot基础教程的时候写过一篇《Spring Boot中使用RabbitMQ》。在该文中,我们通过简单的配置和注解就能实现向RabbitM...

2317

扫码关注云+社区