HAProxy是一个著名的High performance tcp/http负载均衡软件,和nginx相比,有如下特点

  • 专业负载均衡软件,有管理界面,
  • 敏感的health检查算法,
  • 各种权限控制策略,而nginx做负载均衡只适用于简单场景,
  • 原生就支持tcp代理,效率高,nginx需要安装第三方module

本文描述haproxy版本是1.4.23,和hash算法相关的有两个部分 打开 Lb_chash.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
static inline unsigned int chash_hash(unsigned int a)
{
	/* This function is one of Bob Jenkins' full avalanche hashing
	* functions, which when provides quite a good distribution for little
	* input variations. The result is quite suited to fit over a 32-bit
	* space with enough variations so that a randomly picked number falls
	* equally before any server position.
	* Check http://burtleburtle.net/bob/hash/integer.html for more info.
	*/
	a = (a+0x7ed55d16) + (a<<12);
	a = (a^0xc761c23c) ^ (a>>19);
	a = (a+0x165667b1) + (a<<5);
	a = (a+0xd3a2646c) ^ (a<<9);
	a = (a+0xfd7046c5) + (a<<3);
	a = (a^0xb55a4f09) ^ (a>>16);
	/* ensure values are better spread all around the tree by multiplying
	* by a large prime close to 3/4 of the tree.
	*/
	return a * 3221225473U;
}

这是给hash 桶取模,看看即可,无需修改 打开Backend.c,定位到函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
{
	unsigned long hash = 0;
	const char *p;
	const char *params;
	int plen;
	//....
	p += plen + 1;
	uri_len -= plen + 1;
	while (uri_len && *p != '&') {
		hash = *p + (hash << 6) + (hash << 16) - hash;
		uri_len--;
		p++;
	}
}

这一段就是hash的核心计算公式:如果你要替换haproxy的hash算法,修改这处代码即可;或者你要跳过haproxy直接访问后端server,也可以通过这个算法计算出url和后端server的对应表