Nginx 最新版本已经支持 传输层端口转发 和负载均衡 stream 模块。使用stream模块在编译nginx时需要添加–with-stream参数。 1、什么叫加权轮询? 加权轮询是指nginx照配置权重来分发給上游服务器请求。让不同服务器按照配置来承担压力。假设有a,b,c服务器,轮询权重按如下配置,则在7次请求中a服务器会接受请求1次,b服务器会接受请求2次,c服务器会接受请求4次。
upstream cluster { server a weight=1; server b weight=2; server c weight=4; }
2、加权轮询算法nginx源码 这里仅列出加权轮询算法的核心代码、
static ngx_stream_upstream_rr_peer_t *
ngx_stream_upstream_get_peer(ngx_stream_upstream_rr_peer_data_t *rrp)
{
for (peer = rrp->peers->peer, i = 0;
peer;
peer = peer->next, i++)
{
peer->current_weight += peer->effective_weight;
total += peer->effective_weight;
if (best == NULL || peer->current_weight > best->current_weight) {
best = peer;
p = i;
}
}
best->current_weight -= total;
return best;
}
3、gdb调试nginx加权轮询源码 这里使用gdb 调试客户端连接请求时 nginx加权轮询的过程。 nginx 配置如下
worker_processes 1; events { worker_connections 1024; } stream { upstream bitbucket-ssh { server localhost:9001; server 120.48.9.1:9001; } server { listen 9000; proxy_pass bitbucket-ssh; } }
gdb启动nginx(关于gdb调试nginx后续单独发链接) 我们这里配置了两个服务器 ,权重参数未配置(默认所有服务器相等)。nginx监听端口设置为9000。 b ngx_stream_proxy_module.c:696 在 这个文件的696行设置断点。 进程数配置为1。也就是一个master进程。一个worker进程。接受客户端连接肯定是在woker进程中处理的。所以set fllow-fork-mode child 将gdb设置为跟踪子进程。  r 命令开始运行nginx程序。下图可以看到nginx已经启动了。接下来就是使用客户端连接服务器。  我们使用tcp客户端测试工具连接nginx。  点击打开 开始连接nginx服务的9000端口。  上图 可以看到 命中了设置的断点。 但是我设置的断点并不在加权轮询的函数内。所以在单步跟踪几次进入加权轮询函数如下图。  下图给出所有的调用堆栈。也就是客户端开始连接nginx后epoll_wait 返回,子进程也就被唤醒开始处理客户端的连接请求,然后就是下面的堆栈了。具体逻辑流程后续也打算发文总结。  我们打印一下peer这个结构 也可以看到我们配置的服务器信息 。一个是本机localhost;一个是120.48.9.1 ,都是9001端口。 
|