openresty 教程(openresty实战视频)
openresty 教程,原文标题:使用OpenResty搭建DataEase视频服务器。编者注:本文为知乎博主万梓良的原创文章。原文链接:
openresty 教程,原文标题:使用OpenResty搭建DataEase视频服务器。
编者注:本文为知乎博主万梓良的原创文章。
原文链接:https://zhuanlan.zhihu.com/p/490108585。
DataEase是飞致云公司旗下的一款开源数据可视化分析工具,初代产品是在2021年6月份正式发布的。我是在从这款产品v1.4版本的时候入坑的,被它的功能所深深吸引,从此每月都紧跟产品的每月更新迭代。
之后DataEase v1.5版本更新了支持视频组件的功能,能够支持MP4格式和WebM格式的视频,刚好我公司想在制作的仪表板上播放公司的宣传视频,而DataEase的视频组件是通过直接嵌入视频链接的形式。具体如下图所示:

因此,公司内部想使用视频组件就需要搭建自己的视频文件服务器了。传统的文件服务器有很多,比如 Apache、Nginx等,不过这种方式搭建的文件服务器存在一个共性的问题,就是用户想要上传文件只能连接到服务器上,将文件上传到指定的目录。
这就需要将文件服务器的用户名/密码提供给所有需要使用到该文件服务器的人。这样操作一方面使用起来不是很便捷,特别是对业务人员来说,还需要去学习Linux的相关知识;另一方面,服务器用户名/密码的大量披露也会带来相应的安全隐患。
除此之外,也可以单独开发一套文件上传系统,但是带来的人力成本比较高,领导觉得性价比不高不予同意。
基于以上种种原因,公司希望能够搭建一个无需过多额外开发,且可以通过浏览器上传文件的文件服务器。带着这样的问题,我在网上一通搜索,发现了OpenResty。
OpenResty是一个基于Nginx与lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。OpenResty可用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。
OpenResty通过汇聚各种设计精良的Nginx模块,从而将Nginx有效地变成一个强大的通用Web应用平台。这样,Web开发人员和系统工程师可以使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。
安装步骤
接下来我来演示一下使用OpenResty搭建DataEase视频服务器的具体步骤。
■ 安装OpenResty
官方提供了OpenResty的Docker镜像,执行以下命令获取最新的Docker镜像:
docker pull openresty/openresty
镜像拉取完成后,执行以下命令启动容器:
docker run -itd --name openresty -p 80:80 openresty/openresty:latest
容器启动完成后,访问IP,若出现如下页面,则说明启动成功:

■ 设置OpenResty
接着来调整OpenResty的基础配置,使其先成为一个普通的文件服务器。由于OpenResty镜像未内置vi/vim等编辑器,所以我们需要先在外部进行配置文件的编写,再将配置文件拷贝至容器内部。
配置文件如下所示:
autoindex on;# 显示目录autoindex_exact_size on;# 显示文件大小autoindex_localtime on;# 显示文件时间server { listen 80 ; charset utf-8; root /data/; location / { }}
将配置文件保存为default.conf ,执行以下命令拷贝到容器内部:
docker cp default.conf openresty:/etc/nginx/conf.d
接着重启容器:
docker restart openresty
重启完成后进入容器,创建我们配置文件中写的 /data 目录:
docker exec -it openresty bashmkdir /data
接着打开浏览器,访问 http://IP ,看下效果:

接着我们拷贝任意文件至容器内的 /data 目录,看下效果:
docker cp default.conf openresty:/data

可以看到,文件名称、上传时间、大小等已经在我们的浏览器中展示出来了。至此,基础的文件服务器就搭建完成了。
■ 设置页面文件上传
接下来我们来编写lua脚本,实现页面文件上传,并且展示上传进度的功能。
首先是页面嵌入脚本:
vi inject.lua-- ignore *.html filesif ngx.var.uri:match(".html$") then return "</body>"endlocal inject_div = [[<div id="upload-inject"><link rel="stylesheet" href="/code/iview.css"><script src="/code/vue.min.js"></script><script src="/code/iview.min.js"></script><style>a {color: -webkit-link}</style><div id="app-upload"><upload multiple type="drag" :action="uploadUrl" :on-success="success" :before-upload="beforeUpload"> <div style="padding: 20px 0"> <icon type="ios-cloud-upload" size="52" style="color: #3399ff"></icon> <p>点击或拖拽文件上传</p> </div></upload></div><script>new Vue({ el: '#app-upload', data: { uploadUrl: '' }, mounted() { this.uploadApi = '/_upload' }, methods: { beforeUpload: function() { this.uploadUrl = this.uploadApi window.location.pathname let promise = new Promise((resolve) => { this.$nextTick(function () { resolve(true); }) }) return promise }, success: function(){ console.log("success"); location.reload(); } }})</script><div></body>]]return inject_div
然后是上传文件脚本:
vi upload.lualocal upload = require "resty.upload"local cjson = require "cjson"local chunk_size = 4096local home = "/data"local form, err = upload:new(chunk_size)if not form then ngx.log(ngx.ERR, "failed to new upload: ", err) ngx.exit(500)endform:set_timeout(1000) -- 1 seclocal function getsubdir(uri) return uri:gsub("^/_upload", "")endlocal function split(s, delimiter) result = {}; for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match); end return result;endlocal function strip(s) char = "%s" return string.match(s, "^" .. char .. "*(.-)" .. char .. "*$") or sendlocal function startswith(line, s) return line:find("^" .. s) ~= nilendlocal function getfilename(line) items = split(line, ";") for i, item in ipairs(items) do item = strip(item) if startswith(item, "filename") then name = split(item, "=") return name[2]:sub(2, -2) end end return ""endlocal filename = ""local subdir = getsubdir(ngx.var.uri)local filewhile true do local typ, res, err = form:read() if not typ then ngx.say("failed to read: ", err) ngx.exit(500) end if typ == "header" then if res[1] == "Content-Disposition" then filename = getfilename(res[2]) if filename == "" then ngx.say("filename not found") ngx.exit(400) end local path = home .. subdir .. "/" .. filename file = assert(io.open(path, "w ")) if not file then ngx.say("open " .. path .. " failed") ngx.exit(500) end end elseif typ == "body" then if file then file:write(res) end elseif typ == "part_end" then if file then file:close() file = nil end elseif typ == "eof" then break endendngx.header.content_type = "text/html"ngx.say("<p>upload success</p>")ngx.flush(true)
除此之外,我还引用了一些外部的CSS、JavaScript、Fonts文件,文件的分享地址如下。有需要可以自行下载:
链接:
https://pan.baidu.com/share/init?surl=FWt3HeY8Xy0OuZ6VJbeGiw
密码:up1j
我将这些文件拷贝至OpenResty容器内部:
docker cp code/ openresty:/
接着调整我们的default.conf文件,同样拷贝至容器内部:
vi default.confautoindex on;# 显示目录autoindex_exact_size on;# 显示文件大小autoindex_localtime on;# 显示文件时间server { listen 80 ; charset utf-8; root /data/; location /code/ { alias /code/; } location / { sub_filter_once on; set_by_lua_file $inject_div_before_body /code/inject.lua; sub_filter '</body>' $inject_div_before_body; } location ~ ^/_upload { client_max_body_size 4000m; content_by_lua_file /code/upload.lua; }}docker cp default.conf openresty:/etc/nginx/conf.d
再次访问 http://IP :

页面拖拽文件上传:


至此,可以通过浏览器上传文件的文件服务器便制作完成了。接下来,我们就可以复制视频链接,并且在仪表板上播放视频了。
最终效果




现在,一个简单、页面拖拽即可完成视频上传的文件服务器就此完成了。搭配上人人可用的开源数据可视化分析平台DataEase,完美解决了公司的需求!
注:文中的lua脚本参考了GitHub上大佬的代码,仓库地址如下:/http://github.com/yangbinnnn/ngx-upload-web。我在其基础上做了文件上传目录优化、上传完成自动刷新、本地化第三方组件等功能。
本文《openresty 教程(openresty实战视频)》由网赚联盟( wangzhuan.org.cn )整理或原创,感谢您的阅读。随机文章
站长导航友情链接交换
搜素引擎算法
关键词排名优化
网站内容优化
SEO教程
友情链接交换
搜素引擎算法
百度搜索“网赚联盟”即可找到本站,微信搜索“小小课堂网”关注小小课堂网公众号。网赚联盟( wangzhuan.org.cn )欢迎用户投稿,发布者:FIT2CLOUD飞致云,文章版权归作者所有,投稿文章不代表网赚联盟立场,中二少年发布为网赚联盟原创文章,转载请注明出处:https://wangzhuan.org.cn/993283.html

微信扫一扫
支付宝扫一扫