traffic server文件目錄

功能:

         Trafficserver的主要功能是緩存,固然你也能夠用它來作純粹的反向代理(像一般用nginx那樣)。一般切入一個龐大的系統的最好方式是看如何使用,使用traffic server的主要入口有兩個:配置文件和插件。全部使用者都須要配置文件,高級使用者則須要插件。css

traffic支持大規模的集羣處理,不一樣於nginx的單點(須要ospf均衡鏈路來作冗餘),全部的配置文件能夠作到改動一個通知所有。程序根據功能劃分爲不一樣的幾個子程序,有服務運行時使用的程序,也有管理使用的。詳細見下文。html

[root@controller trafficserver]# tree -L 3 bin/ etc/ var/
bin/
├── traffic_cop
├── traffic_crashlog
├── traffic_ctl
├── traffic_layout
├── traffic_line
├── traffic_logcat
├── traffic_logstats
├── traffic_manager
├── traffic_sac
├── trafficserver
├── traffic_server
├── traffic_top
├── traffic_via
├── tspush
├── tstop -> traffic_top
└── tsxs
etc/
└── trafficserver
    ├── body_factory
    │   └── default
    ├── cache.config
    ├── cache.config_1
    ├── cluster.config
    ├── cluster.config_1
    ├── congestion.config
    ├── congestion.config_1
    ├── hosting.config
    ├── hosting.config_1
    ├── icp.config
    ├── icp.config_1
    ├── ip_allow.config
    ├── ip_allow.config_1
    ├── log_hosts.config
    ├── log_hosts.config_1
    ├── logs_xml.config
    ├── logs_xml.config_1
    ├── parent.config
    ├── parent.config_1
    ├── plugin.config
    ├── plugin.config_1
    ├── prefetch.config
    ├── prefetch.config_1
    ├── proxy.pac
    ├── proxy.pac_1
    ├── records.config
    ├── records.config_1
    ├── remap.config
    ├── remap.config_1
    ├── remap.config_2
    ├── snapshots
    ├── socks.config
    ├── socks.config_1
    ├── splitdns.config
    ├── splitdns.config_1
    ├── ssl_multicert.config
    ├── ssl_multicert.config_1
    ├── stats.config.xml
    ├── stats.config.xml_1
    ├── storage.config
    ├── storage.config_1
    ├── storage.config_2
    ├── trafficserver-release
    ├── update.config
    ├── update.config_1
    ├── vaddrs.config
    ├── vaddrs.config_1
    ├── volume.config
    └── volume.config_1
var/
├── log
│   └── trafficserver
│       ├── access.log_controller.19691231.19h00m00s-20171201.00h00m04s.old
│       ├── access.log_controller.20171201.00h35m04s-20171201.02h00m02s.old
│       ├── diags.log
│       ├── error.log
│       ├── manager.log
│       ├── squid.blog
│       ├── squid.blog_controller.19691231.19h00m00s-20171201.00h00m04s.old
│       ├── traffic.out
│       ├── traffic_server.stderr
│       └── traffic_server.stdout
└── trafficserver
    ├── cache.db
    ├── cop.lock
    ├── eventapi.sock
    ├── host.db
    ├── hostdb.config
    ├── manager.lock
    ├── mgmtapi.sock
    ├── processerver.sock
    ├── records.snap
    ├── server.lock
    └── stats.snap

配置文件:

l  緩存Cache.configlinux

n  上游拉取數據擁塞控制:congestion.confignginx

n  緩存分割與上游分配:hosting.configgolang

n  劃分不一樣種類的緩存類型(與hosting.config配合能夠實現不一樣種的數據緩存安排)算法

n  定義上游的peer:Icp.configapache

n  定義可使用cache的白名單:ip_allow.config編程

n  緩存能夠定義多級,定義級別的配置:parent.config後端

n  緩存持久化:storage.configapi

l  Log配置

n  將不一樣上游的log放到不一樣的log文件中:log_hosts.config

n  定義不一樣的log格式:logs_xml.config

l  插件管理plugins.config

l  主程序可調整參數:records.config

l  代理:

n  請求和響應的url修改配置:remap.config

l  域名解析:splitdns.config

l  安全:配置多個ssl證書:ssl_multicert.config

插件系統:

         標準的面向過程作插件的過程。一個HTTP有個處理流程,包括request頭部處理(你能夠改url),dns查詢(你能夠決定去哪一個後臺獲取數據)、從後臺或緩存拉取數據、返回內容等。只要是http請求,這個流程就是固定的。所以插件系統就是在這些流程上註冊回調函數。這裏的回調函數還不是直接調用,還會傳遞一個event事件參數,用於表示在當前的鉤子上發生的事情,使plugin能夠更好的處理。

         除了被調用,trafficserver還要提供調用方法。這裏提供的調用方式可不是通常意義上的函數調用,而是相似遠程過程調用。插件經過將本身要被執行的代碼(action)發送給server(就連發送都是要指明ip地址和端口的),而後經過查詢server返回的接口來得到action執行的狀態。這裏的action就是traffic server裏面的協程概念,整個過程相似golang的go func(){}()關鍵字操做。

         除了這種遠程調用,不少函數插件也是能夠直接調用的。

協程:

         Trafficserver的超高併發天然須要協程的概念(ng也是)。Traffic server本身實現的協程叫作continuation,結構體用TSCont表示。

         一個TSCont表明一個異步執行的代碼塊,這個代碼塊擁有本身的執行狀態,而且能夠被

         協程是用戶空間管理的線程,也就是說調度算法是在用戶空間的程序中實現的。能夠保存程序執行的狀態,能夠在某時刻拉出來執行。多個協程在一個操做系統的線程上執行,或者是M個協程在N個線程上執行。如此帶來的好處是能夠任性的阻塞,沒必要擔憂資源的浪費問題。因此協程本質上也是一種應對阻塞調用的方式。其餘的重要思想還有異步。貌似操做系統更傾向於異步,而不是傾向於協程。

         Trafficserver底層大量基於異步,但向上提供的併發卻大量基於協程的概念。

插件類型:

內容變換

         內容變換是修改request的內容或者response的內容。因爲內容是變長的,因此traffic server定義了vconnection(結構體TSVConn)和vio。Vconnection表明從一個buffer到另外一個buffer的鏈接,通過這個鏈接的數據能夠根據鏈接指定的變化方法變化。這也就是內容變換的本質。本質上TSVConn是一個continuation,因此也具有協continuation具有的數據通知能力。

         而VIO是VConnection兩端。一個input一個output,因爲能夠多個vconnection串行,因此一個vconnection的output vio就能夠另外一個vconnection的input。Vconnection的本質是變換,VIO的本質是內存buffer。

其餘協議插件

         這個就比較底層了。通常的插件都是服務於http協議的,你也能夠直接跳過http協議支持別的協議,或者是支持http之上的其餘協議。課件traffic server對其網絡基礎結構的信心。

插件提升:

         每一個插件都必須包含voidTSPluginInit(int argc, const char *argv[])函數,熟悉C的很容易理解,固定的名字和參數對應着固定的符號表符號,當插件被加載的時候,主程序能夠直接按照這個符號表去執行就行了,這就是入口。

1.        向主程序註冊插件:TSPluginRegister。能夠不註冊,主要是爲了兼容性

2.        向某個全局鉤子位置添加鉤子回調:TSHttpHookAdd

a)        註冊的鉤子能夠是全局的也多是trasaction、session相關的。若是是transaction相關的,經過TSHttpTxn txnp = (TSHttpTxn)edata;得到transaction的指針。使用TSHttpTxnHookAdd函數添加transactionhook。

b)        若是是session相關的,使用TSHttpSsnHookAdd進行註冊。Plugin中得到session的方法變爲TSHttpSsn ssion = (TSHttpSsn)edata;

 

插件容許發起網絡鏈接,使用TSNetConnect()發起只鏈接traffic server的http鏈接,TSHttpConnect()發起向任意地址的http鏈接。

cache系統:

         使用ats無非就是反向代理和緩存兩種,其中緩存是ats最重要的功能。要想理解ats的cache架構,理解幾個關鍵字和概念就行了。

         還有就是ats的cache能夠組成集羣,有兩種方式:一種是配置共享的,一種是統一緩存的。配置共享的只是保證各個節點的配置是同樣的,各個節點的cache仍是各自緩存(重複是確定有的),而統一緩存則是互相協做的,在多個節點之間排序緩存的,在本機找不到會自動去隔壁拉數據。

         ats在使用磁盤的時候不使用文件概念,因此能夠直接使用裸盤(若是你使用文件,也只有一個大文件),ats會本身安排對磁盤的使用方式和數據的組織。

概念:

         代理:Http請求並不必定要所有從server獲取,能夠在靠近用戶的機房緩存。尤爲是圖片視頻等資源,這個緩存過程叫作代理。

         新鮮度:代理必需要保證緩存的數據是當前最新的,如何與上游的服務器確認是一個專門的話題。HTTP協議自己有提供一些頭部來控制緩存新鮮度。例如max-age、last-modified、expires、date等。ats根據這些頭部和用戶的配置計算一個對象的新鮮度,決定是否要,何時去server段拉取(快要過時的時候去拉取叫fuzz Revalidation)。

         緩存控制:能夠控制有的不緩存、當上遊服務器出現擁塞的時候中止拉取、同一個url緩存不一樣的版本。

         緩存層級:cache自己也是能夠分層的,就像CPU的一級緩存、二級緩存的概念。在ats中這個概念叫作parent,每一個cache能夠有sibling也能夠有parent,cache在本地查不到,或者在本地的集羣查不到,就能夠去parent去查,parent查不到再回源到後臺server查詢。這些緩存之間還可使用ICP協議(緩存控制協議)查查詢parent或者sibling中的緩存狀態,以便更新本身的緩存。

關鍵字:

l  裸盤:ats的cache支持硬件存儲,不但支持文件系統的文件,還支持裸盤。裸盤支持在linux中有被移除的可能,由於直接訪問磁盤能夠經過O_DIRECT替代。裸盤其實就是不使用文件系統的磁盤,因爲沒有文件系統天然也沒有文件的概念。在內核中是直接走sd驅動,電梯層,到scsi到磁盤的,不須要走文件系統層和緩存層。O_DIRECT也是同樣。

l  cache span:一塊連續的物理存儲空間,通常是一個磁盤。

l  cache volumn:一個邏輯和業務上的存儲空間,能夠橫跨多個cache span。這就像lvm橫跨多個物理磁盤劃分的邏輯分區。

l  cache strip:位於cache span(volumn)上的一條一條的存儲帶。數據都是組織在cache strip中。

l  cache ID、cache key:cache key惟一的標示一個緩存對象,通常以url表示,cache ID則是從cache key計算得來的128位的MD5值。

l  directory:在cache strip中的數據是由directory組織的。一個cache strip中有多個directory,每一個directory中有多個條目。每個directory都對應一個cache,由cache id索引。但directory只是cache的一個索引,經過directory能夠找到cache在磁盤中的信息和實體。而全部的directory都是加載到內存的,因此若是一次cache查詢結果是miss,就不須要磁盤(經過url計算獲得cache id,可是查詢內存發現該cache id沒有對應directory),就能夠返回。因此directory的存在讓miss過程加速,可是若是找到了directory,每個cache查詢都須要接下來讀取磁盤。值得注意的是,內存中只有directory,不包含實體,而且directory的大小是固定的,磁盤大下也是固定的,只要程序啓動就會盡量多的建立最多的directory,因此程序運行的過程當中ats的內存需求是不會增長的(由於能夠支持的緩存數是固定的,每條緩存在內存中的記錄大小也是固定的)。

l  segment、bucket: 並非strip下面就是並排的一片directory,這些directory也是組織的。4個directory是一個bucket,多個bucket是一個segment。在每一個strip的頭部都有一個空閒列表,裏面是每一個segment的directory空閒列表,也就是說又多少個segment在strip的頭部就有多少個列表。事實上,cache ID定位的並非directory,而是bucket,strip的free list也不包含每一個bucket的第一個directory,而是順序的包含第4個、第3個、第2個。如此,來了一個cache object的cache ID(128位),就能夠定位到某個bucket,而後查看該bucket的第一個directory是否是used,若是used說明整個bucket都滿了(只有後面3個都用完了纔會用第1個),這個cache object就添加失敗了。不然就會順序的從4/3/2/1開始使用。因此,綜上能夠看出,bucket其實是一個哈希桶,用來出來哈希函數的碰撞狀況,只給出了4個,說明只能處理4個cache ID一致的狀況。因此segment和bucket這兩種組織結構的引入,是爲了解決管理問題。

l  content:咱們知道directory只是元數據,是要常駐內存的,存儲了cache的索引。因此能夠根據directory判斷一個cache是否存在。若是發現了對應的directory,就得去取directory對應的cache的真實內容,這個內容就是放在content裏的,位置由directory指明。directory的數目是動態計算出來的,總大小除以平均一個對象的大小就能夠得到,平均一個對象的大小能夠經過proxy.config.cache.min_average_object_size進行設置,從而控制directory的數目。content的大小是動態的,也是有限的,因此當content滿的時候會自動從開頭開始覆蓋。可是並不會更新directory。直到下一次讀取到directory的時候纔會發現內容不存在,從而更新directory。這裏能夠帶來的一個問題是,經過查看directory的統計值獲得的結果是不許確的,而且一旦跑滿數據量一直滿的。

l  fragment:因爲ats的並行性,不可能一會兒存儲太多的連續數據。因此大文件必然要分片(不然併發的來不少大文件緩存請求將沒法應對)。咱們知道directory裏面會指出數據再content中的位置,這裏指出的只是該cache的第一個fragment,在這個fragment的頭部又不少信息,包括其餘的fragment到哪裏去找,還包括其餘的同名版本的存儲directory(例如同一個url的png、jpg版本)

l  SPDY:用戶與同一個IP的http通訊,不管是否是同一個網站,都複用一個tcp鏈接。這在大部分狀況下是沒用的,可是在用戶使用的代理的時候就用戶大了。由於用戶的全部http請求都是發到代理去的,使用這個協議能夠一成天都只使用一個tcp鏈接跑http,每一個網戰的http流只是tcp流裏面的一個stream。這對提供代理效率和減輕代理和客戶端負擔有很大的提升。

集羣

         多個cache能夠配置爲集羣,完整的集羣模式包含配置文件統一,和節點數據的交互。集羣中的每一個節點的配置文件是同樣的,因此配置文件中不要出現本機的IP。在配置爲集羣模式後(這個須要每臺機器單獨配置),對任何一個節點的配置修改會被自動的同步到其餘節點。同步配置使用多播,交換數據使用單播。

源代碼與架構:

核心代碼在iocore裏面,iocore裏面按照大功能分爲了以下的幾個模塊。

         這就要從trafficserver的架構提及了。這幾個目錄幾乎就是traffic server的關鍵字:異步(aio)、緩存(cache)、集羣支持(cluster)、域名解析(dns)、事件系統(eventsysytem)、上游配置(hostdb)、網絡(net)。

網絡與nginx的對比:http://www.cnblogs.com/liushaodong/archive/2013/02/26/2933535.html

         除了提供核心程序功能,程序須要入口,入口通常是一個啓動server的主程序和若干的管理程序,管理程序都在cmd目錄下,每個目錄是一個管理程序:

         主程序位於proxy目錄下的Main.cc(.cc後綴的是C++文件的glibc後綴表示)。

經常使用命令

 主程序名稱是traffic_server,  

traffic_manager:爲traffic_ctl提供服務

traffic_cop:獨立的監控程序,監控traffic_server和traffic_manager的職責和內存交換空間使用狀況,發現異常重啓進程。

traffic_crashlog:由traffic_server進程啓動,在traffic_server崩潰的時候打印一個崩潰報告到log目錄。

traffic_ctl:在線配置一些traffic_server能夠配置的參數

traffic_logcat:將trafficserver的二進制log文件轉變成可讀的ASCII log

traffic_logstats:trafficserver的log分析工具

traffic_via:能夠配置proxy.config.http.insert_request_via_str、proxy.config.http.insert_response_via_str兩個參數使得全部的數據的http頭部都攜帶VIA信息(表示cache狀態,能夠看出是從哪裏拿來的),wget這個文件就會在http頭部看到這個信息,而這個信息是被traffic server編碼過的,使用traffic_via命令能夠將這個信息解碼就能夠看到緩存的獲取路徑。

traffic_sac:standalonecollator。日誌收集器,用在traffic server集羣中。能夠用來收集各個節點的日誌集中到本機進行處理。一個節點能夠不安裝traffic server,只安裝sac能夠發揮更大的日誌能力。

tspush:不須要用戶請求能夠直接使用這個命令將內容投遞到traffic server的cache中,使用這個命令須要打開proxy.config.http.push_method_enabled 選項

tsxs:插件編譯程序。用來編譯和安裝插件。

traffic_top:一個方便的查看當前trafficserver內部狀態的程序。要編譯這個必需要有libncurses5-dev庫,不然會靜悄悄不安裝。

架構

         Trafficserver雖然大部分狀況跑在linux上,可是倒是跨平臺的。通常的操做系統都提供了網絡訪問的方式,可是並無提供大量併發網絡訪問的方式(或許往後操做系統的API能夠直接提供這個功能),因此處理大量併發須要程序本身來(有的編程語言內部封裝了這部分邏輯,例如golang,就省了程序的事了)。目前處理這個問題的最經常使用辦法就是上層抽象協程。

         除了網絡訪問,操做系統通常也不提供特別易用的事件系統、dns系統、緩存系統、集羣系統等接口。然而這些都是traffic server核心功能所要依賴的底層服務。Traffic server的應對辦法是將這些服務封裝,主要邏輯所有基於封裝的服務,而不是操做系統的API(這裏就不得不說操做系統和glibc的API不與時俱進了。。。還得別人還得本身搞)。

HTTP事務流程:

         必需要理解的是trafficserver是個程序,主要的業務是無數的transaction,每一個transaction都是一個用戶的http鏈接處理,不只包含了用戶的tcp鏈接,還包含了traffic server與後端的通訊和本地操做等。一個transaction只是用戶一個tcp鏈接上執行的一次事務,還有一個session概念,是一個client和server之間tcp概念上的鏈接。一個session能夠包括不少個transaction。對用戶來講,一個request和response是一個transaction。

相關文章
相關標籤/搜索