aFlex脚本入门

aFlex脚本入门


对于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在当前事件中的变量值 。对于 这个链接来说,”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

 

  待续
-----------------------------------
aFlex脚本入门
https://blog.51cto.com/u_15127592/4195511

posted @ 2023-10-15 11:54  .dier  阅读(39)  评论(0编辑  收藏  举报