nginx四层反向代理分析

1 反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,
此时代理服务器对外就表现为一个反向代理服务器。


2 nginx反向代理
首先看配置,nginx反向代理是一个核心模块。基本配置如下。
tcp {
    timeout 10s; //会话超时时间
    proxy_read_timeout 10s;//会话读超时时间
    proxy_send_timeout 10s; //会话写超时时间
    upstream proxy_name {
#       # simple round-robin
        server localhost:1935;#需要代理的端口//代理服务配置,最终落地的服务器
#check interval=3000 rise=2 fall=5 timeout=3000;
#check interval=3000 rise=2 fall=5timeout=1000
#check interval=3000 rise=2 fall=5timeout=1000
#check_http_send "GET /HTTP/1.0\r\n\r\n";
#check_http_expect_alive http_2xxhttp_3xx;
    }
    server {
        listen 8085; #代理8888端口   
        proxy_pass proxy_name;//对应上面的 upstream
    }
}


3 nginx反向代理编译运行
https://github.com/yaoweibin/nginx_tcp_proxy_module
解压后,到nginx目录下打补丁。
执行命令
patch -p1 < ./nginx_tcp_proxy_module-master/tcp.patch


配置编译
 ./configure --prefix=/home/nginx/   --with-openssl=/data/nginx/openssl-1.0.1t --with-stream  --add-module=/data/nginx/nginx_tcp_proxy_module-master
make && make install


4 代码分析
 (1)反向代理初始化
主要是解析到监听的端口,将监听端口添加到nginx网络框架中,并设置对应的回调函数
入口函数:ngx_tcp.c ngx_tcp_block()
ngx_tcp_optimize_servers()监听配置的端口
ls->handler = ngx_tcp_init_connection; 设置事件回调
ngx_tcp_upstream_init() tcp反向代理初始化,连接到对端,也就是配置中的server
这里可以配置域名,nginx启动的时候会解析域名,并得到ip列表。
ngx_tcp_upstream_get_round_robin_peer() 连接对端的时候,通过round robin算法获取一个连接ip。
连接成功后为对端的连接设置读写事件回调:
c->write->handler = ngx_tcp_upstream_handler;
        c->read->handler = ngx_tcp_upstream_handler;


ngx_tcp_upstream_check_broken_connection()每次会话上有新的请求的时候,判断连接的状态。

  (2) 反向代理数据透传
ngx_tcp_proxy_handler()回调函数
    if (c == s->connection)
{
        if (ev->write) {
            recv_action = "client write: proxying and reading from upstream";
            send_action = "client write: proxying and sending to client";
            src = pctx->upstream->connection;
            dst = c;
            b = pctx->buffer;
            write_bytes = &s->bytes_write;
        } else {
            recv_action = "client read: proxying and reading from client";
            send_action = "client read: proxying and sending to upstream";
            src = c;
            dst = pctx->upstream->connection;
            b = s->buffer;
            read_bytes = &s->bytes_read;
        }
   
else 
{
        if (ev->write) {
            recv_action = "upstream write: proxying and reading from client";
            send_action = "upstream write: proxying and sending to upstream";
            src = s->connection;
            dst = c;
            b = s->buffer;
            read_bytes = &s->bytes_read;
        } else {
            recv_action = "upstream read: proxying and reading from upstream";
            send_action = "upstream read: proxying and sending to client";
            src = c;
            dst = s->connection;
            b = pctx->buffer;
            write_bytes = &s->bytes_write;
        }
    }


通过时间源和类型,设置本次透传的源和目标。从而进行数据转发。





你可能感兴趣的:(nginx)