Skip to content

Apache Traffic Server 源代码分析

Notifications You must be signed in to change notification settings

zengxiaobai/atsinternals

This branch is 31 commits behind oknet/atsinternals:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

aa631cf · Feb 1, 2019
Feb 1, 2019
May 12, 2018
Jun 5, 2017
Aug 30, 2016
Jan 9, 2019
Jan 23, 2019
Sep 4, 2017
May 9, 2016
Sep 4, 2017

Repository files navigation

权利保留

对本项目内容的任何转发和引用,请注明本项目地址:http://github.com/oknet/atsinternals

Apache Traffic Server 源代码分析

本项目主要是我对Apache Traffic Server 6.0(以下简称ATS)源代码的分析结果。

是我对其内部实现,架构设计的个人认识,受限于个人能力,可能有理解、分析不到位的情况。

部分内容是直接将ATS源码中的注释直接翻译过来的,可能有些不通顺,可以对照源码理解阅读。

由于 ATS 6.0 的变化比较大,所以如果您在使用/参照的源代码不是6.0版本,请翻阅官方git仓库中的源代码变化,以帮助理解。

联系作者

如果对内容有不理解,或者认为有错误,可以在github直接留言给我。

源代码目录结构

ATS的源代码由多个部分构成,分别设立独立的目录以区分:

  • iocore
    • 实现各种底层的I/O交互
    • 包含了多个子系统(subsystem)
  • proxy

IOCORE

在IOCore内包含了多个子系统,每个子系统使用独立的目录来区隔:

  • EventSystem
    • 提供基本的事件系统,用以实现延续(Continuation)编程模式的基础组件
  • Net
    • 提供基本的网络操作,TCP,UDP,OOB,Polling等网络I/O操作
  • DNS
    • 提供DNS解析服务
  • HostDB
    • 提供DNS解析结果的缓存/查询服务
  • AIO
    • 提供磁盘I/O操作
  • Cache
    • 提供缓存服务
  • Cluster
    • 提供集群服务

另外 Utils 目录是公共部分,不是一个子系统。

在每个子系统内,有两种类型的头文件前缀:

  • I_xxxx.h
    • 对外提供接口的定义,I表示Interface
    • 可以 include I_xxxx.h,但是不可以 include P_xxxx.h
  • P_xxxx.h
    • 在子系统内部使用的定义,P表示Private
    • 可以 include I_xxxx.h,也可以 include P_xxxx.h

EventSystem子系统

主要包含Interface基础类型的定义:

  • Continuation
  • Action
  • Thread
  • Processor
  • ProxyMutex
  • IOBufferData
  • IOBufferBlock
  • IOBufferReader
  • MIOBuffer
  • MIOBufferAccessor
  • VIO

主要包含Interface扩展类型的定义

  • VConnection <- Continuation
  • Event <- Action
  • EThread <- Thread
  • EventProcessor <- Processor

可以看到EventSystem子系统基本上都是Interface类型的定义,这是因为它是延续(Continuation)编程模式的基础组件。

Net子系统

主要包含Interface定义:

  • NetVCOptions
  • NetVConnection <- VConnection
  • NetProcessor <- Processor
  • SessionAccept <- Continuation
  • UDPConnection <- Continuation
  • UDPPacket
  • UDPNetProcessor <- Processor

主要包含Private基础定义:

  • PollDescriptor
  • PollCont <- Continuation
  • Connection
  • Server <- Connection
  • NetState

TCP 相关:

  • UnixNetVConnection <- NetVConnection
  • NetHandler <- Continuation
  • NetAccept <- Continuation
  • UnixNetProcessor <- NetProcessor

SSL 相关:

  • SSLNetVConnection <- UnixNetVConnection
  • SSLNetAccept <- NetAccept
  • SSLNetProcessor <- UnixNetProcessor
  • SSLSessionID
  • SSLNextProtocolAccept <- SessionAccept
  • SSLNextProtocolTrampoline <- Continuation
  • SSLNextProtocolSet

Socks 相关:

  • SocksEntry <- Continuation

UDP 相关:

  • UDPIOEvent <- Event
  • UDPConnectionInternal <- UDPConnection
  • UnixUDPConnection <- UDPConnectionInternal
  • UDPPacketInternal <- UDPPacket
  • PacketQueue
  • UDPQueue
  • UDPNetHandler <- Continuation

可以看到Net子系统已经开始区分Interface和Private类型的定义了,对于Private类型的定义,应该仅仅在Net子系统内部直接使用。

注意:由于ATS的代码由社区的许多开发者功能开发,因此在编写代码时可能打破了上面这种逻辑,所以在阅读代码时不必过于纠结。

NetVConnection的继承关系

早期,这非常的久远,作为ATS开源的前身,Inktomi Cache Server 是支持Windows操作系统的,从现在ATS的代码里仍然能看到一些被注释掉的代码,使用的一些类的名字以NT开头,而且可以找到与其对应的以Unix开头的类定义。

因此对于 NetVConnection 的继承类 UnixNetVConnection:

  • 可以大胆猜测存在 NTNetVConnection 也是 NetVConnection 的继承类
  • 然后我们看到,NetVConnection的定义是出现在I_NetVConnection.h中的,所以NetVConnection是对外提供的Interface
  • 而UnixNetVConnection的定义是出现在P_UnixNetVConnection.h中的,所以UnixNetVConnection则是只在Net子系统内使用
  • 然后再看所有头文件名称内包含Unix关键字的,都是以P_开头的

因此我们可以得出下面的结论:

  • NetVConnection 是Net子系统对外部提供的Interface,所有可以供外部调用的方法都需要放在其中以虚方法来定义
  • UnixNetVConnection 和 NTNetVConnection 则在不同的平台,使用不同的实现方式,重新定义基类NetVConnection的虚方法
  • 以此来实现NetVConnection对多操作系统平台的支持
  • 而外部系统无需关心NetVConnection的具体底层实现是UnixNetVConnection还是NTNetVConnection

建立在对上述继承关系的理解之上,然后再来看一下SSLNetVConnection:

  • SSLNetVConnection是继承自UnixNetVConnection的
  • SSLNetVConnection的定义没有包含Unix或NT关键字
  • 实现SSLNetVConnection的 *.h 和 *.cc 文件名也没有包含Unix或NT关键字
  • 但是所有头文件名称内包含SSL关键字的,都是以P_开头的

可以大胆猜测SSLNetVConnection的实现是通过宏定义来区分的:

  • 在Unix操作系统,SSLNetVConnection继承自UnixNetVConnection
  • 在WinNT操作系统,SSLNetVConnection继承自NTNetVConnection

但是后来NT部分的代码被砍掉了,所以现在看到的继承关系就是:

  • NetVConnection
    • UnixNetVConnection
      • SSLNetVConnection

但是在实现中,并未提供一个方法,让Net子系统的用户能够知道一个NetVConnection具体是什么类型,因此在proxy目录中看到大量的代码直接引用了UnixNetVConnection和SSLNetVConnection类型的动态转换来判断一个NetVConnection是什么类型。

由于SSL层的实现是建立在使用OpenSSL库的基础上,而且在实际的业务逻辑实现的时候,同样要设置一些SSL的属性,因此SSLNetVConnection需要提供一些Interface给Net子系统的用户,但是SSLNetVConnection的这些方法并没有在NetVConnection中进行定义,这里大概是因为SSLNetVConnection与NetVConnection中间还隔着UnixNetVConnection,有些不方便,而又有一些丑陋吧。

因此,Net子系统的用户在使用SSL相关的功能时,都需要将NetVConnection动态转换为SSLNetVConnection类型才可以进行调用,这些都打破了原有系统的良好设计。

注:上述分析由于包含大量猜测,只是本人个人理解。

About

Apache Traffic Server 源代码分析

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published