Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7656418
  • 博文数量: 1770
  • 博客积分: 18684
  • 博客等级: 上将
  • 技术积分: 16357
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-02 10:28
个人简介

啥也没写

文章分类

全部博文(1770)

文章存档

2024年(15)

2023年(44)

2022年(39)

2021年(46)

2020年(43)

2019年(27)

2018年(44)

2017年(50)

2016年(47)

2015年(15)

2014年(21)

2013年(43)

2012年(143)

2011年(228)

2010年(263)

2009年(384)

2008年(246)

2007年(30)

2006年(38)

2005年(2)

2004年(1)

分类: LINUX

2009-04-20 09:18:25

看一个这样的架构:
squid<=>nginx<=>server(s)
前端使用squid做缓存,后端用多台服务器,但多台服务器间的SESSION不共享,为了做负载均衡,使用nginx的ip_hash来做,使得来源机器的会话是持续的。
于是便引起来了一个问题,使用nginx的ip_hash规则来做负载均衡时,得到的IP则始终是squid机器的IP,于是负载均衡便失效了。
同理,在使用nginx的ip_hash做负载均衡方案时也会存在这个问题,即realip的问题,nginx有一个realip的模块,但并没有解决ip_hash的realip的问题,因此当通过代理访问你的网站就会引起分布均的问题,这种情况在小范围的负载方案中会表现的尤为突出。
nginx中有一个ngx_http_request_t的数据结构,其中的x_forwarded_for存储的就是realip的信息(当然这是存在安全问题的).
typedef struct {
ngx_uint_t        hash;
ngx_str_t         key;
ngx_str_t         value;
u_char           *lowcase_key;
} ngx_table_elt_t;
value存储的就是realip的信息。
于是便实现了ip_hash使用realip来做负载均衡的方案:
为ngx_http_upstream_ip_hash_module.c这个文件添加一个函数用来获取realip.
static ngx_int_t ngx_http_upstream_realip(ngx_http_request_t *r);
函数的实现如下:
static ngx_int_t
ngx_http_upstream_realip(ngx_http_request_t *r)
{
    u_char                      *ip, *p;
    size_t                       len;
    in_addr_t                    addr;
    struct sockaddr_in          *sin;
    if (r->headers_in.x_forwarded_for == NULL) {
            return NGX_DECLINED;
    }
    len = r->headers_in.x_forwarded_for->value.len;
    ip = r->headers_in.x_forwarded_for->value.data;
    for (p = ip + len - 1; p > ip; p--) {
                if (*p == ' ' || *p == ',') {
                          p++;
                        len -= p - ip;
                        ip = p;
                        break;
                }
        }
    /*ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "realip: \"%s\"", ip);*/
    /* AF_INET only */
    sin = (struct sockaddr_in *) r->connection->sockaddr;
        addr = inet_addr((char *) ip);
    if (addr == INADDR_NONE) {
                return NGX_DECLINED;
        }
        p = ngx_palloc(r->connection->pool, len);
        if (p == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        ngx_memcpy(p, ip, len);
        sin->sin_addr.s_addr = addr;
        r->connection->addr_text.len = len;
        r->connection->addr_text.data = p;
    return NGX_DECLINED;
}
在函数ngx_http_upstream_init_ip_hash_peer中调用它来获取realip.
ngx_http_upstream_realip(r);
以上代码做过小的测试,能正常使用。 :)
阅读(4821) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

betsell82011-02-19 11:59:01

介绍说明:
    相信很多做过“皇冠投注系统出租或安装”的技术人员来说,会有一个很头痛的技术问题:那就是客户要求经常要求更换服务器(至少更换IP)。
    大部分情况都是直接把程序安装到新的服务器去,当然也包括导入和导出数据库等一系列工作。要是新服务器的配置环境遇到什么问题的话,恐怕需要花不长时间调试。
    和传统的端口映射软件不同之处在于:一般端口映射是tcp/ip层影射,而这个是http协议层的影射,以为着软件会识别http协议和进行http级的转换处理。(例如http包头里的地址信息将会被修改——达到转换目的)
    另外这个功能还可以避免被攻击的时候(例如CC攻击),直接关闭程序,而真实IP的服务器依然正常运行着。
    所以我们www.betsell.net为行业开发出了一款针对这个问题的小型软件(http映射),使用相当简单,具体请看使用说明。

使用说明: