• 使用Nginx+Lua代理Hadoop HA


    一、Hadoop HAWeb页面访问

    Hadoop开启HA后,会同时存在两个Master组件提供服务,其中正在使用的组件称为Active,另一个作为备份称为Standby,例如HDFS的NameNode、YARN 的ResourceManager。HDFS的web页面只有通过Active的NameNode才能正常访问,同样地,YARN的web页面也只有通过Active的ResouceManager才能正常访问。

     

     

    (1) HDFS HA的Web访问

     

    正常使用Nginx的proxy_pass代理单一的Web服务地址时非常简单(参考博文最简反向代理配置),而面对Hadoop HA这样的多Web服务地址时就会有点麻烦。

     

     

    (2) HDFS HA的Web代理

     

    虽然Nginx的upstream支持配置多个Web地址,默认会随机将Web请求随机转发到任意一个Web地址,只有某个web地址被认为不可达后,才会被Nginx列入黑名单。而Hadoop HA的Active和Standby节点都是一直服务的,只是同一个时刻,最多只有一个节点的Web访问是有效的,这就要求Nginx对upstream中的Web地址更细致地检查,而非粗略地判断是否可达。

    二、Nginxupstream健康检查

     

    对upstream的地址有效性检查称为健康检查。通过定期的调用检查逻辑,对upstream配置的Web地址进行标记,不健康的Web地址会被临时列入黑名单内,直到该地址被标记为健康状态时,才会有新的Web请求转发到该地址上。

    (1)Nginx本身对upstream的健康检查支持并不强大,做不到对检查逻辑的自由定制。

    (2)开源项目nginx_upstream_check_module以Nginx补丁的方式扩展了Nginx的upstream语法,支持自定义HTTP请求的方式检查Web服务的健康状态。但在实际使用过程中,遇到一个很不方便的地方。

    upstream resourcemanagers {
    
        server 192.168.0.1:8084;
    
        server 192.168.0.2:8084;
    
        check interval=30000 rise=1 fall=3 timeout=5000 type=http;
    
        check_http_send "HEAD / HTTP/1.0
    
    ";
    
        check_http_expect_alive http_3xx;
    
        keepalive 2000;
    
    }

    nginx_upstream_check_module使用check命令定义健康检查的基本属性,使用check_http_send自定义HTTP请求,check_http_expect_alive定义期望的健康状态HTTP code。这里使用http_3xx是该模块定义的内置匹配语法,表示以3开头的HTTP code。想必大家已经想到,这种定义方式是无法精确区分301、302、307报文的。当然正常情况下,3xx的报文应该是同类型的报文,不需要如此精确的区分,但是不巧的是Hadoop2.7.2版本的Active ResourceManager和Standby ResourceManager分别返回的是302和307报文!

    (3)以上两种方案并不是解决Nginx upstream健康检查的完美方案,真正完美的方案是OpenRestylua-resty-upstream-healthcheck。OpenResty内置了大量的Lua库,可以自由扩展、定制Nginx的功能。其中healthcheck.lua模块用于upstream的健康检查。

    不过我希望在Nginx的基础上只扩展upstream健康检查的功能,而非用OpenResty代替Nginx,因此需要使用Nginx的lua-upstream-nginx-module模块。

    三、编译安装扩展Nginx

     

    (1)由于lua-upstream-nginx-module是使用Lua脚本对Nginx进行扩展,因此必须安装Lua解释器。LuaJIT是Lua语言的即时编译器,效率更高。

    $ wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
    
    $ tar zxvf LuaJIT-2.0.4.tar.gz
    
    $ cd LuaJIT-2.0.4
    
    $ make
    
    $ make install
    
    $ export LUAJIT_LIB=/usr/local/lib
    
    $ export LUAJIT_INC=/usr/local/include/luajit-2.0
    
    $ rm /usr/local/lib/libluajit-5.1.so*
    
    $ cd ..

    导出环境变量LUAJIT_LIB和LUAJIT_INC是为了后续编译lua-nginx-module模块使用。删除libluajit的所有动态链接库是为了保证后续编译时是静态链接,否则默认为动态链接。

    (2)准备好Lua环境后,接下来下载Nginx的Lua模块lua-nginx-module、Nginx开发包ngx_devel_kit、Nginx upstreamLua模块lua-upstream-nginx-modulepcre库openssl库Nginx源码。解压后的文件列表如下:

    ./lua-nginx-module-0.10.5
    
    ./lua-upstream-nginx-module-0.05
    
    ./nginx-1.10.1
    
    ./ngx_devel_kit-0.3.0
    
    ./openssl-OpenSSL_1_0_1t
    
    ./pcre-8.38

     

    执行命令编译Nginx:

    $ cd nginx-1.10.1
    
    $ ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=root --group=root --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_v2_module --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-pcre=../pcre-8.38 --with-openssl=../openssl-OpenSSL_1_0_1t --add-module=../ngx_devel_kit-0.3.0 --add-module=../lua-nginx-module-0.10.5 --add-module=../lua-upstream-nginx-module-0.05
    
    $ make && make install

     

    (3) 安装完毕后,Nginx的配置文件为/etc/nginx/nginx.conf,可执行文件为/usr/sbin/nginx。执行Nginx启动命令:

    $ nginx

    访问http://127.0.0.1:8080即可看到Nginx主页。

    (4) 添加Lua测试链接,测试Lua模块是否正常工作。

    location /lua {
    
        set $test "hello, world.";
    
        content_by_lua '
    
            ngx.header.content_type = "text/plain";
    
            ngx.say(ngx.var.test);
    
        ';
    
    }

     

    更新Nginx配置:

    $ nginx -s reload

    访问http://127.0.0.1:8080/lua即可看到”hello,world.”。

    四、Nginx代理Hadoop HA

     

     

    (3) Nginx代理Hadoop HA

    虽然安装了lua-upstream-nginx-module模块,但是仍需要使用OpenResty的healthcheck.lua模块才能完成upstream的健康检查功能。

    (1) 下载最新版本的OpenResty代码。执行如下命令:

    make && make install
    
    ls /usr/local/openresty/lualib/resty/upstream/healthcheck.lua

    其中healthcheck.lua脚本就是我们需要的健康检查模块。

    (2) 配置nginx.conf:

    # upstream
    
    upstream resourcemanagers {
    
        server 192.168.0.1:8084;
    
        server 192.168.0.2:8084;
    
        keepalive 2000;
    
    }
    
    upstream namenodes {
    
        server 192.168.0.1:50070;
    
        server 192.168.0.2:50070;
    
        keepalive 2000;
    
    }
    
     
    
    # health check
    
    lua_package_path "/usr/local/openresty/lualib/?.lua;;";
    
    lua_shared_dict healthcheck 1m;
    
    lua_socket_log_errors off;
    
    init_worker_by_lua_block {
    
           local hc = require "resty.upstream.healthcheck"
    
           local ok, err = hc.spawn_checker {
    
               shm = "healthcheck",
    
               upstream = "resourcemanagers ",
    
               type = "http",
    
               http_req = "GET / HTTP/1.0
    
    ",
    
               interval = 2000,
    
               timeout = 5000,
    
               fall = 3,
    
               rise = 2,
    
               valid_statuses = {302},
    
               concurrency = 1,
    
           }
    
           if not ok then
    
               ngx.log(ngx.ERR, "=======> failed to spawn RM health checker: ", err)
    
               return
    
           end
    
           local ok, err = hc.spawn_checker {
    
               shm = "healthcheck",
    
               upstream = "namenodes ",
    
               type = "http",
    
               http_req = "GET /webhdfs/v1/?op=LISTSTATUS HTTP/1.0
    
    ",
    
               interval = 2000,
    
               timeout = 5000,
    
               fall = 3,
    
               rise = 2,
    
               valid_statuses = {200},
    
               concurrency = 1,
    
           }
    
           if not ok then
    
               ngx.log(ngx.ERR, "=======> failed to spawn NameNode health checker: ", err)
    
               return
    
           end
    
    }
    
     
    
    # proxy
    
    location /yarn/ {
    
        proxy_pass http://resourcemanagers/;
    
        # some sub_filter, rewrite config
    
    }
    
    location /hdfs/ {
    
        proxy_pass http://namenodes/;
    
        # some sub_filter, rewrite config
    
    }

     

    更新Nginx配置:

    $ nginx -s reload

    访问http://127.0.0.1:8080/hdfs或http://127.0.0.1:8080/yarn即可看到HDFS或YARN的Web页面。

    五、总结

    综上,使用Lua扩展Nginx的功能十分强大,且十分容易定制,这也是OpenResty的功能如此强大的原因。虽然OpenResty已经提供了lua-resty-upstream-healthcheck模块完成upstream的健康检查功能,不过我们仍在社区版的Nginx上亲自扩展了该功能。希望这篇文章能帮助大家快速的配置Nginx+Lua的环境,并方便地开发自己的Nginx扩展功能。

  • 相关阅读:
    C#几种截取字符串的方法小结
    KinSlideshow参数设置说明
    WinForm程序中两份mdf文件问题的解决
    全国省市数据库
    ASP.NET项目中使用CKEditor +CKFinder 实现上传图片
    mht文件无法打开的解决办法
    Non-parametric tests
    Plot transpant lines in Matleb 在Matlab中绘制透明线条
    Which HRV method to use: FFT or Autoregressive?
    SPM How-tos SPM预处理及统计分析指南
  • 原文地址:https://www.cnblogs.com/fanzhidongyzby/p/5621866.html
Copyright © 2020-2023  润新知