打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
iRules 101
userphoto

2012.06.03

关注
iRules有一个常常被忽视的特点是能够在执行任务时使用动态变量,这可以有助于编写一些有趣的iRules ,但如果你在程序运行时没有在当前配置中定义其中一些变量,它也可以给你带来运行时麻烦。本章技术技巧将说明如何从HTTP请求中找出输入内容,并使用它做为向哪个pool发送数据的标准,同时,使用TCL语言的catch命令维护系统运行的错误的捕捉。
 
The "pool" command

The pool command is used to assign a connection to a specified pool name (and optionally a specific pool member).  The syntax for the pool command is:
Pool 命令
pool命令用于指定连接到一个指定的pool名字(和随意的一个特有的pool member)。
Pool命令的语法规则是:
pool <pool_name>
指定发送流量到pool。
pool <pool_name> ?member <addr> ?<port>??
指定直接发送流量到pool member。

很多时候,我们的iRules是这样写的(使用pool名字进行编码) 

when HTTP_REQUEST {switch -glob [HTTP::uri] {"*.gif" -"*.jpg" -"*.png" {pool images_pool}"*.asp" {pool ms_app_pool}"*.jsp" {pool java_app_pool}}}
当iRules建立时,pool命令会被系统进行语法检查并且确认,pool是照字面意思命名,所以保存逻辑将会确认特定的pool是否存在于配置中。如果不存在,将会出现一个保存错误,因此你在保存iRule前必须先配置pools。在这种情况下,没有运行时执行异常会发生(除非你必须把创建好的iRule里关联的Pool 移除)。
 
但是,假设您想要建立可以随着时间推移扩展的一种更加动态的解决方案。在此示例中,假设您想要客户端来确定将流量发送到那些Pool. 这可能是服务器指定一个在HTTP cookie中的Pool名称 ,或者是一个简单的在URI上附加的GET参数。我们在这个将使用后一种场景举例。
For this example, we'll define the following GET parameters that can control pool direction.
pool=name

So an example URI could be
http://somedomain.com/somefile.ext?param1=val1&pool=pool_name&pararm2=val2...

We will interrogate the URI's GET parameters in search of the "pool" parameter, extract the pool_name value and use that variable as the argument in the pool command.  For newer versions of BIG-IP, one could use the URI::query command to extract values, but this implementation should work all the way back to BIG-IP v9.0.
在这个例子里,我们将定义以下的GET参数来控制Pool分配。
pool=name

这样一个完整的URI例子可能是这样的:
http://somedomain.com/somefile.ext?param1=val1&pool=pool_name&pararm2=val2...

我们将询问URI的GET参数来寻找“pool”参数,提取出Pool名称,并使用这个变量作为pool命令的参数。在BIG-IP新的版本里,我们可以使用的URI::query 查询命令来提取参数, 但这一功能应当返回去在BIGIP V9.0所有的版本里实现。

 

when HTTP_REQUEST {set namevals [split [HTTP::query] "&"]set pool_name ""for {set i 0} {$i < [llength $namevals]} {incr i} {set params [split [lindex $namevals $i] "="]set name [lindex $params 0]set val [lindex $params 1]switch $name {"pool" {set pool_name $val}}}if { "" ne $pool_name } {pool $pool_name}}

 这样部署会出现什么问题?如果在配置中已经包含有$ pool_name变量所代表的Pool,则不会有任何错误。那如果在配置中不存在这个Pool会发生什么?答案是,你将会得到一个运行时错误并且当前的连接将会被中断。这不是一个理想的解决方案,简单使用的catch命令可避免运行时连接中断,并允许请求持续进行发送到默认pool。

Catch命令的语法如下:


catch script ?varName?
 
Cache 命令可用于避免在放弃命令解释时的错误。Cache命令通过递归方式来调用TCL的编译器来执行脚本, 并且通常在返回时不产生错误,无论在执行脚本时会发生任何错误。
 
如果脚本执行出现了一个错误,Catech捡回返回一个非0的整数值来对应脚本执行的异常返回代码。TCL 定义了脚本正常执行的返回代码为零(0), 或者TCL_OK。TCL也定义了四个异常返回代码:1(TCL_ERROR), 2 (TCL_RETURN), 3 (TCL_BREAK)和4 (TCL_CONTINUE). 脚本执行错误对应返回代码TCL_ERROR。其他的异常返回代码返回return, break和continue命令, 同时定义一些其他的特殊情况。 TCL包可以同时定义新的命令和其他整数值来作为返回代码,并且脚本执行的返回代码命令和返回代码可以不是在标准的TCL定义的五种类型中。

如果给出了varName参数,那么它值将会是脚本执行的结果值。当从脚本返回代码是1 ( TCL_ERROR ) ,则存储在varName里的值会是一个错误信息。当从脚本返回的代码是0 ( TCL_OK ) ,则存放在resultVarNamede 值就代表着脚本的返回值


解决方案

下面的一个iRule和上面的iRule实现同样的功能,除了它使用了在动态Pool指定时的异常处理机制。

 

when HTTP_REQUEST {set namevals [split [HTTP::query] "&"]set pool_name ""for {set i 0} {$i < [llength $namevals]} {incr i} {set params [split [lindex $namevals $i] "="]set name [lindex $params 0]set val [lindex $params 1]switch $name {"pool" {set pool_name $val}}}if { "" ne $pool_name } {if { [catch { pool $pool_name } ] } {log local0. "ERROR: Attempting to assign traffic to non-existant pool $pool_name"pool default_pool}}}
现在,控制连接被定向到那个Pool完全决定于请求的URI。只有在极少的情况下,当你的应用逻辑改变在网络配置改变之前发生,连接将会被fallback到default pool中的服务器上,同时,可以记录下中错误到系统log中以供后续的分析。
结论
使用动态变量,可以极大地提高你在使用iRule命令时的灵活性,Catch 命令可以被用于包含任何使用动态变量的iRule命令并且捕获到运行时的错误。事实上,如果你需要,你可以嵌套使用Catch命令来实现一个多层的异常处理解决方案,但把这个解决方案留到了将来的文章中。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
DL之Attention:基于ClutteredMNIST手写数字图片数据集分别利用CNN_Init、ST_CNN算法(CNN+SpatialTransformer)实现多分类预测
网站数据统计分析中的日志收集原理及其实现
如何快速进行策略扫描?
后处理TCL脚本语言:命令、脚本文件、值
SecureCRT使用技巧 2010/10/10工具, 网络技术标签:tool, 优化 说明:如果您在阅读中产生疑问,请与文档维护人联系。如果您发现有更好的新的功能,请直接在修订上增加,并把修订后的文
Tcl / Tk 大全
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服