`

转载:HAProxy 研究笔记 -- rules 实现

阅读更多

转载:HAProxy 研究笔记 -- rules 实现 

原文链接:http://blog.chinaunix.net/uid-10167808-id-3775567.html

 

  • 作者:Godbach <nylzhaowei@gmail.com>
  • Blog:  http://godbach.blog.chinaunix.net  
  • 微博:weibo.com/godbach
  • 日期:Jun 25, 2013
  • 本文可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接。
  • ----


本文研究 haproxy-1.5-dev17 中 rules 的相关实现。

 

  • 1. ACL
  • 2. rule 的组成
  • 3. rule 的执行
  • 4. rule 的种类

1. ACL

如果要实现功能丰富的 rules,需要有配套的 ACL 机制。

ACL 的格式如下:

acl <aclname> <criterion> [flags] [operator] <value> ...

haproxy 中 ACL 数据结构的定义:

/* The acl will be linked to from the proxy where it is declared */
struct acl {
	struct list list;           /* chaining */
	char *name;		    /* acl name */
	struct list expr;	    /* list of acl_exprs */
	int cache_idx;              /* ACL index in cache */
	unsigned int requires;      /* or'ed bit mask of all acl_expr's ACL_USE_* */
};

其中:

  • name: ACL 的名字
  • expr: ACL 定义的表达式。就是定义的 ACL 名字后面的表达式。这是一个链表结构。因此,可以定义多条表达式不同但是名字相同的 ACL。这样,多个表达式都属于同一个 ACL。
  • requires: 所有表达式中关键字对应的作用域(该关键字可以用在什么场合)的集合

函数 parse_acl() 负责解析定义好的 ACL:

  • 查找 ACL 的名字,如果不存在的话,则 alloc 一个新的 acl 结构
  • 通过调用 parse_acl_expr() 对表达式进行解析,并返回 struct acl_expr 结构
    • ACL 中的表达式应该只有一个 kw
    • 查找该关键字,必须是已经注册好的。并返回该关键字注册时的数据结构 struct acl_expr
    • alloc 一个 struct acl_expr 结构体,记录下返回的 kw 的数据结构,并作成员的初始化
    • 调用对应 kw 的 parse 方法,将解析的结果保存在 struct acl_pattern 结构体中,并将该结构体加入到 expr->patterns 的链表中
  • 将解析到的表达式插入到 acl 中的 expr 链表中

总结: 一个 ACL 包含一到多个表达式。每个表达式包含一个 kw及一到多个 pattern。

2. rule 的组成

这里简要描述 rule 与 acl 之间的逻辑关系:

  • rule 应该是 action + condition 组成
    • 有些动作自身可能也需要记录一些信息。不同的 rule 对应动作的信息可能不同,比如 reqirep 等
    • block rules 的动作比较单一, condition 满足之后处理结果均相同
  • condition,完成 rule 检测的判断条件 对应数据结构: struct acl_cond
            struct acl_cond {
            	struct list list;           /* Some specific tests may use multiple conditions */
            	struct list suites;         /* list of acl_term_suites */
            	int pol;                    /* polarity: ACL_COND_IF / ACL_COND_UNLESS */
            	unsigned int requires;      /* or'ed bit mask of all acl's ACL_USE_* */
            	const char *file;           /* config file where the condition is declared */
            	int line;                   /* line in the config file where the condition is declared */
            };
            
    
  • condition 包含多个 ACL 组。组的分割逻辑是逻辑或(|| 或者 or),即 struct list suites 的成员,组的数据结构 struct acl_term_suite
        struct acl_term_suite {
        	struct list list;           /* chaining of term suites */
        	struct list terms;          /* list of acl_terms */
        };
    
    • 该数据结构可以包含多个 ACL,以及每个 ACL 可能的一个取反标识 '!'
    • 所有表达式中相邻的 ACL 且其逻辑关系为逻辑与(&&) 的构成一个 ACL 组
      • 比如 if acl1 !acl2 or acl3 acl4,则构成两个 acl_term_suite,分别是 acl1 !acl2 和 acl3 acl4
      • 每个 ACL 及其可能的取反标记对应的数据结构: struct acl_term
            struct acl_term {
            	struct list list;           /* chaining */
            	struct acl *acl;            /* acl pointed to by this term */
            	int neg;                    /* 1 if the ACL result must be negated */
            };
        
    • 一个 ACL 包含多个 expr

3. rule 的执行

概括起来很简单,执行判断条件。符合条件,然后执行对应动作。

下面是 rspadd 的示例代码:

	/* add response headers from the rule sets in the same order */
	list_for_each_entry(wl, &rule_set->rsp_add, list) {
		if (txn->status < 200)
			break;
		if (wl->cond) {
			int ret = acl_exec_cond(wl->cond, px, t, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
			ret = acl_pass(ret);
			if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
				ret = !ret;
			if (!ret)
				continue;
		}
		if (unlikely(http_header_add_tail(&txn->rsp, &txn->hdr_idx, wl->s) < 0))
			goto return_bad_resp;
	}

对于同一个种类的 rules,执行逻辑如下:

  • 主要遍历 rule,调用 acl_exec_cond 执行该 rule 的检测条件。该检测结果只给出匹配与否。
    • 逐个遍历 cond 上的 ACL 组,即cond->suites。任一 suite 匹配成功,则认为匹配成功
    • 同一个 ACL 组上,遍历所有 suite->terms (ACL + 取反逻辑)。任意一个 ACL 匹配失败,则跳到下一个 ACL 组继续匹配。同一组全部 ACL 匹配成功,则认为该 ACL 组匹配
      • 同一个 ACL 上的匹配,则是逐一遍历 ACL 的 expr。只要任意一个 expr 匹配成功,则认为该 ACL 匹配成功
  • 结合 condition 中的条件 if/unless,确定最终匹配结果
  • 如果匹配则执行对应的 action,否则检测下一条规则。

4. rule 的种类

从 proxy 结构体可以看出 rule 的种类

struct proxy {
	...
	struct list acl;                        /* ACL declared on this proxy */
	struct list http_req_rules;		/* HTTP request rules: allow/deny/http-auth */
	struct list block_cond;                 /* early blocking conditions (chained) */
	struct list redirect_rules;             /* content redirecting rules (chained) */
	struct list switching_rules;            /* content switching rules (chained) */
	struct list persist_rules;		/* 'force-persist' and 'ignore-persist' rules (chained) */
	struct list sticking_rules;             /* content sticking rules (chained) */
	struct list storersp_rules;             /* content store response rules (chained) */
	struct list server_rules;               /* server switching rules (chained) */
	struct {                                /* TCP request processing */
		unsigned int inspect_delay;     /* inspection delay */
		struct list inspect_rules;      /* inspection rules */
		struct list l4_rules;           /* layer4 rules */
	} tcp_req;
	struct {                                /* TCP request processing */
		unsigned int inspect_delay;     /* inspection delay */
		struct list inspect_rules;      /* inspection rules */
	} tcp_rep;
    ...
}

其中, 函数 http_process_req_common 中处理的规则如下:

http_process_req_common
{
    ... 
    1. process block rules
    ...
    2. process http req rules
    ...
    3. execute regular exp if any
    ...
    4. req add
    ...
    5. process redirect rules
    ...
}


这里没有详细的介绍各种具体用途的 rules。随后具体分析代码的时候总结一下再加上。

分享到:
评论

相关推荐

    rh-haproxy18-haproxy-1.8.24-3.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    netty-codec-haproxy-4.1.74.Final-API文档-中文版.zip

    赠送jar包:netty-codec-haproxy-4.1.74.Final.jar; 赠送原API文档:netty-codec-haproxy-4.1.74.Final-javadoc.jar; 赠送源代码:netty-codec-haproxy-4.1.74.Final-sources.jar; 赠送Maven依赖信息文件:netty-...

    haproxy-2.3.2-win64

    总的来说,haproxy-2.3.2-win64是Windows环境中实现高可用、高性能网络服务的重要工具,尤其适用于需要在Windows服务器集群中进行负载均衡和反向代理的场景。结合Cygwin64的特性,它为开发者提供了更广阔的平台选择...

    netty-codec-haproxy-4.1.73.Final-API文档-中英对照版.zip

    赠送jar包:netty-codec-haproxy-4.1.73.Final.jar; 赠送原API文档:netty-codec-haproxy-4.1.73.Final-javadoc.jar; 赠送源代码:netty-codec-haproxy-4.1.73.Final-sources.jar; 赠送Maven依赖信息文件:netty-...

    haproxy-1.5.18-9.el7_9.1.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    haproxy-1.8.23-1.el7.x86_64.rpm haproxy 1.8.23 rpm包

    haproxy-1.8.23 RPM包 for Centos7 rpm -ivh 安装即可,软件目录:/usr/local/haproxy-1.8.23 配置文件: /etc/haproxy/haproxy.cfg 可通过 systemctl 来进行 start 、stop 、restart 可通过 systemctl enable...

    netty-codec-haproxy-4.1.74.Final-API文档-中英对照版.zip

    赠送jar包:netty-codec-haproxy-4.1.74.Final.jar; 赠送原API文档:netty-codec-haproxy-4.1.74.Final-javadoc.jar; 赠送源代码:netty-codec-haproxy-4.1.74.Final-sources.jar; 赠送Maven依赖信息文件:netty-...

    haproxy-1.5.18-1.el6.x86_64.rpm

    新手练习 haproxy-1.5.18-1.el6.x86_64.rpm

    haproxy-windows-master.zip

    标题中的"haproxy-windows-master.zip"是一个包含haproxy Windows版本的压缩包,通常包含了haproxy的源代码、编译好的二进制文件和其他必要的依赖库。这个压缩包可能用于在Windows环境中搭建和配置haproxy。 描述中...

    netty-codec-haproxy-4.1.73.Final-API文档-中文版.zip

    赠送jar包:netty-codec-haproxy-4.1.73.Final.jar; 赠送原API文档:netty-codec-haproxy-4.1.73.Final-javadoc.jar; 赠送源代码:netty-codec-haproxy-4.1.73.Final-sources.jar; 赠送Maven依赖信息文件:netty-...

    rh-haproxy18-haproxy-syspaths-1.8.4-1.el7.x86_64.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    haproxy-ansible-源码.rar

    总的来说,"haproxy-ansible-源码.rar"提供的源码旨在帮助用户利用Ansible实现HAProxy的自动化部署和管理,简化运维工作,提高效率,同时确保服务的稳定性和可靠性。通过理解和使用这些源码,你可以更好地掌握...

    Windows Haproxy-2.0.2--20190725.rar(Windows Haproxy 最新版

    根据百度的上文档将目前最新版的Haproxy2.0.2打包成Windows下可执行的Haproxy.exe 最新版支持动态的ssl证书,经过测试以该Windows 下的版本已经可以支持。如果你觉得好用,劳烦给个好评。谢谢

    HAProxy-2-RPM-builder:最新HAProxy 2.3(CentOS 7)的RPM构建器

    HAProxy 2.3(CentOS 7)的RPM构建器 以普通用户的身份在构建框中执行以下步骤: sudo yum -y groupinstall 'Development Tools'cd /optsudo git clone ...2-RPM-builder建造:没有Lua: sudo make使用Lua: sudo make ...

    haproxy-1.5.18-9.el7.x86_64.rpm

    离线安装包,亲测可用

    haproxy-1.9-dev8.tar.gz

    haproxy-1.9-dev8是haproxy的一个开发版本,这标志着它是1.9系列中的一个预发布版本,可能包含新特性、改进和bug修复。 在haproxy-1.9-dev8.tar.gz这个压缩包中,用户可以获取haproxy的源代码,以便在自己的系统上...

    rh-haproxy18-haproxy-syspaths-1.8.4-2.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    haproxy-1.4.18.tar.gz

    haproxy-1.4.18是haproxy的一个稳定版本,发布于2011年,虽然现在已经有了更新的版本,但1.4系列因其稳定性仍被许多系统所采用。 haproxy的主要功能包括: 1. **负载均衡**:haproxy可以根据多种算法(如轮询、...

    haproxy-2.3.1.tar.gz

    在解压`haproxy-2.3.1`文件后,你会看到源代码和其他相关文件,包括文档、示例配置等。安装通常涉及编译源码、配置和启动服务。具体步骤如下: 1. **编译安装**:使用`configure`脚本进行配置,然后运行`make`和`...

    haproxy-2.8.0.tar.gz 二进制安装包,解压放置服务运行即可

    haproxy-2.8.0.tar.gz 是一个用于Linux环境的Haproxy二进制安装包,适用于CentOS 7.9操作系统。Haproxy是一款高性能、高可用的负载均衡器,它能够处理大量的网络连接,广泛应用于Web服务器集群的流量管理和故障切换...

Global site tag (gtag.js) - Google Analytics