aFlex腳本入門


aFlex腳本入門

來源:http://blog.51cto.com/virtualadc/599194

來源:http://blog.51cto.com/virtualadc/624219

 

對於A10的aFelx腳本,相信很多人都知道,甚至用過,但是實際上很多工程師在各種項目中的使用可能都是按照模板進行修改,雖然能ok,但是卻缺乏對aFelx腳本本質上的了解,所以在用戶實際場景與腳本應用場景不完全一致的時候,就會碰到問題,不知如何修改。而更多的技術人員或者用戶更是知其然,不知其所以然,這樣一來,其實未必真的理解aFlex的工作原理,以及到底aFlex能做些什么事。本篇文章的目的是以我自己的理解對aFlex的一些基本原理,功能及典型案例進行簡單的分析,讓大家能夠相對深入的了解aFlex,從而能更加充分的發揮aFlex這柄利器。

 

當我們在A10上建立一個virtual server的時候,可能主要包含如下幾個因素:

1、VIP(當然包含具體的協議及端口)

2、server-group(當然包含具體的server、負載均衡算法、健康狀態檢測)

3、會話保持

 

      正常的負載均衡流程如下:

1、client發起對VIP的請求,命中該VIP上的某個協議端口,從而命中某個virtual server

2、A10考察該請求命中的virtual server,找到和該virtual server關聯的server-group,從而了解到對該server-group中的server的負載均衡算法

3、如果該virtual server建立了會話保持,且該請求滿足會話保持的條件,則直接將請求轉發到特定的server;如果未滿足會話保持的條件,則按照server-group的負載均衡算法進行請求的分發。

 

aFlex無法單獨生效,必須綁定在virtual server上,可以在以上3步流程的第一步之后介入,改變正常的流程行為,從而達到根據客戶應用進行定制行為的目的。

 

一個完整的aFlex會包含3個組成部分:

1、Events(事件)      aFlex生效的事件上下文環境

2、operators(操作)   在該事件上下文環境中需要滿足的條件

3、commands(命令)  滿足指定條件以后進行的行為

 

這3個部分之間的關系,簡單來說,可以理解如下:

 

當發生某個事件的時候{

    { [如果滿足某個條件]}  {

執行某個命令}

}

 

所以要清楚的了解aFlex能做什么,只需要分別了解events、operators、commands的詳細內容即可。

 

   以下依次介紹events、operators、commands這3個組成部分。

1、events

events是aFlex被觸發的先決條件,重要程度不言而喻,從aFlex支持的events種類和數量就能看出aFlex的作用范圍

 

aFlex的events主要分為4個大類:

a、Global  b、IP,TCP,UDP  C、HTTP  D、SSL

(這里插入介紹2個很重要的概念,clientside,serverside。對於一個正常的應用流程而言,client向server發起請求,經過A10建立連接的過程,可以分為3個部分:

1、client向A10的VIP發起連接請求,通過TCP 3次握手,client和A10之間建立了連接,這個時候A10還未和server建立TCP連接。隨后client發送一個數據請求。

2、client發送一個數據請求到達A10之后,A10會向與server通過TCP 3次握手建立連接,然后A10會通過負載均衡算法選擇一台合適的server,並對數據請求進行一定的修改,隨后將數據請求發送到一台合適的server上,這個時候server會進行響應,且響應的數據包會返回到A10上。

3、A10接受到server響應數據之后,會進行適當的修改,然后把請求發送回client

 

在以上3個過程中,我們定義client與A10之間的交互都屬於clientside,server與A10之間的交互都屬於serverside,之所以在介紹events之前插入這段介紹,是因為一些events可以同時使用在clientside和serverside兩個部分,而雖然是相同的events,但是在這2個部分中,一些相同變量卻可以分別表達出不同的含義,這在后面篇幅中會介紹)

 

這里我們着重以b和c為例說明,因為這兩類events是使用頻率最高的。

在b類中,events有如下內容:

1、CLIENT_ACCEPTED

當client與A10建立了一個連接的時候觸發

2、CLIENT_DATA

當client與A10建立了連接之后並收到一個新的數據應答且連接狀態處於collect status的時候觸發

3、LB_FAILED

當AX設備不能為client發出的請求選擇一個合適的real server進行分發的時候,比如所有的server健康狀態檢測的結果都是down的時候或者所有server的連接上線都已經達到的時候觸發

4、LB_SELECTED

當AX已經為client的請求選擇了一個pool member的時候觸發

5、CLIENT_CLOSED

當一個clientside端連接關閉的時候觸發

6、SERVER_CLOSED

當一個serverside段連接關閉的時候觸發

7、SERVER_CONNECTED

當AX設備和目標server建立了連接的時候觸發

8、SERVER_DATA

當AX設備從目標server接收到一個新數據且連接處於hold status時候觸發

 

在c類events中,events有如下內容:

1、HTTP_REQUEST

當AX設備完整的接收並解析出client的http request header時候觸發

2、HTTP_RESPONSE

當AX設備從server的response中解析出了所有狀態碼以及header信息的時候觸發

3、HTTP_RESPONSE_CONTINUE

當AX設備從server接收到狀態碼 100 continue的response時候觸發

4、HTTP_REQUEST_DATA

當連接請求接收到一個新的http內容數據的時候觸發

5、HTTP_RESPONSE_DATA

當AX從response中接收到新的http內容數據的時候觸發

6、HTTP_REQUEST_SEND

在一個request被發送往server之前立即觸發

 

前面第一部分介紹了aFlex一些基本概念,包括aFlex的3個主要組成部分、以及第一個組成部分events的主要類別的介紹,還記得我們前面那個簡單的示意圖嗎?

當發生某個事件的時候{

    { [如果滿足某個條件]}  {

執行某個命令}

}

Events可以表示當發生某個事件的時候,Operators和一些特定的command(這些特定的command一般是用來獲取報文里特定位置的內容,比如IP地址,TCP端口號,http內容等)連接在一起表示如果滿足某個條件,而command(這里的command和前面提到的特定command有所區別,主要是用來進行一些特定的動作)則表示執行某個命令。

 

第二部分我們會介紹aFlex的第二個組成部分Operators

在開始之前我們先看一個aFlex腳本的經典例子:

 

when HTTP_REQUEST {

if { [HTTP::uri] ends_with ".gif" } {

pool gif_pool

} elseif { [HTTP::uri] ends_with ".jpg" } {

pool jpg_pool }

在上面這個典型的例子中,紅色部分的when HTTP_REQUEST{}即是events,表達的意思為當AX的VIP上收到一個完整的http request的時候觸發該aFlex腳本;兩行藍色的if { [HTTP::uri] ends_with ".gif" }和elseif { [HTTP::uri] ends_with ".jpg" }分別表示當http鏈接的URI部分以”.gif”結尾以及當http鏈接的URI部分以”.jpg結尾”這兩種情況的時候滿足該條條件;棕色的兩行{pool gif_pool}

和{pool jpg_pool }分別表示滿足各自的條件以后執行的command(選擇某個對應的服務器組)

 

這里需要普及幾個常識:

A、::  表示從屬關系,例如HTTP::uri,表示uri是從屬於HTTP類

B、“”  雙引號里的內容表示里面為字符串變量,不帶雙引號的變量為數值變量

C、[]  表示里面為一個command ,[command]表示這個command在當前事件中的變量值 。對於www.sina.com.cn/bbs 這個鏈接來說,”HTTP::uri:[HTTP::uri]”這個字符串,顯示出來的內容為”HTTP::uri :/bbs” 

1、Operators

Operators其實很簡單,說穿了就是一些邏輯關系符號,和一些特定的command一起使用,表達滿足某個或者某些條件。 

第一類:關系符號

1、Contains  包含

使用方式: (string1) contains (string2)

例如:

if  { [TCP::payload] contains "XYZ" } {

pool xyz_servers

}

    假如TCP數據內容中包含字符串XYZ時,選擇服務器組xyz_servers 

2、ends_with  以特定字符串結束

使用方式:  (string1) ends_with (string2)

例如:

if { [HTTP::uri] ends_with ".gif" } {

pool gif_pool

}

假如http鏈接中的URI是以.gif結尾時,選擇服務器組gif_pool 

3、equals  等於

使用方式:  string1 ends_with strig2

例如:

when CLIENT_ACCEPTED{

if { [IP::addr [IP::client_addr] equals 192.168.0.0/16] } {

pool 192.168_pool

}

}

假如客戶端IP地址等於192.168.0.0/16網段中的IP,則選擇服務器組192.168_pool 

4、matches  匹配(只限於字符串變量)

使用方式 :  (string1) matches (string2)

例如:

if { [HTTP::uri] matches {*\\aol\\[a-z].html} } {

pool aol_pool

}

假如http鏈接的URI匹配字符串*\\aol\\[a-z].html,則選擇服務器組aol_pool

 

5、matches_regex 匹配表達式,也可以匹配字符串變量,和matches類似 

6、starts_with 以特定字符串開始

使用方式:(string1) starts_with (string2)

例如:

if { [HTTP::uri] starts_with "/news" } {

pool news_pool

}

假如http鏈接的URI是以/news開始的,則選擇服務器組news_pool

 

  第二類:邏輯符號

1、and 同時滿足兩個條件

使用方式:<value1> and <value2>

例如:

if { ([HTTP::uri] starts_with "/abc") and ([HTTP::host] equals "www.company.com") } {

pool pool1

}

假如http鏈接的URI是以/abc開頭,並且http鏈接的host等於www.company.com,則選擇服務器組pool1

 

2、not 非某個條件

使用方式:not <value2>

例如: 

if { not ([HTTP::uri] starts_with "/abc") } {

pool pool1

}

       假如http鏈接的URI不是以/abc開頭的,則選擇服務器組pool1

 

3、or  或者,兩者滿足其一

  使用方式:<value1> or <value2>

  例如:

              if { ([HTTP::uri] starts_with "/abc") or ([HTTP::uri] starts_with

                      "/cde") } {

pool pool1

}

     假如http鏈接的URI是以/abc開頭或者以/cde開頭的,則選擇服務器組pool1

 

  待續

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM