【Nginx 归档整理】Openresty 实现数据文件上传数仓网关 2020.7.28

模块设计
    模块组成
        Nginx Web模块
        Shell脚本模块
    最终形体
        Openresty(Nginx+lua扩展+lua_upload库) + Shell(OS+HDFS+Hive+Impala)

设计思想
    Nginx Web模块
        采用 封装 lua 语言扩展完善的 Openresty 自带 upload 库
        Openresty 部署方式为 Docker 快速部署
            带来的问题: Docker 容器封装导致的 Shell 仅能调用 Docker 内服务 --> 无法调用 宿主机 Linux 部署的相关服务
                解决办法 -> 将原属于 连带 调用的 Shell 脚本 进行拆离 -> 宿主机 Linux Crontab 定时调用 Shell 脚本
        Web服务形式
            API: http://IP/hdfs_upload? 【default 未配置 域名/特殊端口 拦截】
            URI参数: tenant=&dbtable=&dt=&isclean= 【非必要参数 isclean, dt 支持 多个日期使用','分隔, 支持 tenant/dataone_tenant 自动切换顺带切换dt】
            POST参数: -F "file=@/Path/to/file"
                为什么既用 Get URI 又用 POST 为什么不直接 Post 传参即可?
                问题: -F 文件内容过大 占据 Body,而 Post 参数也在 Body 存储传输 导致 ngx.req.get_post_args() 无法解析
                    解决办法: 使用 URI 参数 通过 ngx.req.get_uri_args() 进行解析
            参数校验
                tenant: >0 <1000 数值
                dbtable: db只能为字母开头+'_'混合组成 db与table之间必须有'.' table由字母+数字+'_'组成 '.'之后必须以字母起头
                dt: 数值 8位 或者 非数值'ACTIVE'
                isclean: 非必要参数 只校验是否等于 "true" 其余输入默认 "false"
            OS
                创建 /tmp/upload/pending/ 下目录
                    目录名组成: tenant=?+dbtable=?+dt=?+isclean=?+20位随机数
                以文件流形式写入创建的目录下
                    创建 上传的同名文件
                上传结束标志文件 位于同级目录下
                    创建 _success 文件

    Shell脚本模块
    	查询同名进程,如果存在则不执行,不存在则执行本次Shell脚本
        扫描 /tmp/upload/pending 目录 所有文件目录
        如果扫描到 文件 且 同级目录下 存在 _success 文件 则执行 数仓操作
            判断 文件 / ZIP [ZIP 解压 并 定死 数仓操作目标为 ZIP 文件内容]
                HDFS 创建目录
                HDFS 文件上传
                Hive 建立分区
                    如果 路径中的tenant 类似 d999 则使用 dataone_tenant + dataone_dt
                    否则 使用 tenant dt
                Impala 刷新目标表

环境命令
    Docker重启
        docker exec -it cdp_nginx nginx -s reload
    Error日志
        tail -f /var/log/nginx/error.log
    Nginx日志
        vim /nginx/conf.d/default.conf
实现细节
    Nginx 配置文件
        location ^~ /hdfs_upload {
            content_by_lua_file /app/hdfs_upload.lua;   # Docker 挂载目录 实际目录位于其他位置
            lua_code_cache on;                          # 测试时设置为 off
            lua_need_request_body off;                  # 如果 on 则导致 file stream 读取失败
            client_max_body_size 1024m;                 # 文件内容过大导致 拒绝请求 client_body_buffer_size 128k
        }
    URI 配置
        /hdfs_upload?tenant=${tenant}|?dataone_tenant=${dataone_tenant}&dt=${dt}&dbtable=${db.table}&isclean=${clean}
    POST 配置
        -F "file=@/home/xxx/hdfs_load.sh" -X POST
    CURL 请求示例
        curl -F "file=@/home/xxx/hdfs_load.sh" -X POST "http://xx.xxx.x.xxx/hdfs_upload?tenant=999&dbtable=db.table&dt=20200724,ACTIVE&isclean=true"

注意[涵盖未实现]
    1.使用 dataone_tenant 作为参数传递,在创建分区时 dt 自动转为 dataone_dt
    2.上传的文件名 及 ZIP压缩包内文件名 禁止出现空格,如 " - 副本.csv"
    3.dt 支持多日期,以","隔开,如"dt=20200727,ACTIVE",不识别小写 active
    4.同一时刻只存在一个 sh hdfs_load.sh 进程 即不并行处理 /tmp/upload/pending 待处理文件 
    5.未对Spark新建表进行 Impala 元数据同步 "invalidate metadata db.table;",只 refresh table 报错无效 Impala不可见
    6.待优化 创建分区+刷新表 单个文件执行 -> 攒批处理


参考资源
    level 1 [实现参考主体]
        Openresty文件上传upload
            http://moguhu.com/article/detail?articleId=19
        Openresty官方upload test示例 [建议先完整实现一遍 Synopsis 以这个为基础糅合其他参考]
            https://github.com/openresty/lua-resty-upload

    level 2 [有效解决方案]
        post请求体过大导致ngx.req.get_post_args()取不到参数体的问题
            https://www.cnblogs.com/wangzhisdu/p/7771310.html

    level 3 [部分参考]
        Nginx + Lua搭建文件上传下载服务
            https://cloud.tencent.com/developer/article/1004880

    level 4 [感觉有用但没用到的]
        Openresty 最佳实践 [有时间可以详勘 -- 调研]
            https://moonbingbing.gitbooks.io/openresty-best-practices/content/
        lua 使用中遇到的坑总结
            https://www.cnblogs.com/zhuzi91/p/8392385.html
        lua-resty-upload模块实现图片上传
            https://github.com/shixinke/openresty-practices/blob/master/upload/upload.lua
        Nginx与Lua: 使用Nginx的upload模块打造文件上传服务
            https://cyrusin.github.io/2015/10/13/lua-20151013/
        使用openresty的lua-resty-upload实现文件上传 [带Github]
            http://www.shixinke.com/openresty/openresty-upload-file

    level 5 [Docker]
        openresty/openresty
            https://hub.docker.com/r/openresty/openresty/dockerfile
        使用 OpenResty Docker 镜像快速搭建 Web 服务器
            https://www.jianshu.com/p/6e15a4b3d838
        Docker下的OpenResty三部曲之一:极速体验
            https://blog.csdn.net/boling_cavalry/article/details/79290944
        Docker下的OpenResty三部曲之二:细说开发
            https://blog.csdn.net/boling_cavalry/article/details/79292356

    level 0 [基础知识]
        玩转 Nginx 之:使用 Lua 扩展 Nginx 功能
            https://my.oschina.net/leejun2005/blog/494248
        Nginx与Lua
            https://blog.huoding.com/2012/08/31/156
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值