

本文分享,旨在使读者朋友通过实践了解如何在Openresty中使用脚本语言Lua自定义或定制化自己的文件服务、缓存服务、DB服务等。
一、构建文件存储服务
1.upload.lua
local upload = require "resty.upload"local cjson = require "cjson"local chunk_size = 4096local form, err = upload:new(chunk_size)if not form thenngx.log(ngx.ERR, "failed to new upload: ", err)ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)endform:set_timeout(1000)-- 字符串 split 分割string.split = function(s, p)local rt= {}string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )return rtend-- 支持字符串前后 trimstring.trim = function(s)return (s:gsub("^%s*(.-)%s*$", "%1"))end-- 文件保存的根路径local saveRootPath = "/usr/local/openresty/nginx/upload/"-- 保存的文件对象local fileToSave--文件是否成功保存local ret_save = falsewhile true dolocal typ, res, err = form:read()if not typ thenngx.say("failed to read: ", err)returnendif typ == "header" then-- 开始读取 http header-- 解析出本次上传的文件名local key = res[1]local value = res[2]if key == "Content-Disposition" then-- 解析出本次上传的文件名-- form-data; name="testFileName"; filename="testfile.txt"local kvlist = string.split(value, ';')for _, kv in ipairs(kvlist) dolocal seg = string.trim(kv)if seg:find("filename") thenlocal kvfile = string.split(seg, "=")local filename = string.sub(kvfile[2], 2, -2)if filename thenfileToSave = io.open(saveRootPath .. filename, "w+")if not fileToSave thenngx.say("failed to open file ", filename)returnendbreakendendendendelseif typ == "body" then-- 开始读取 http bodyif fileToSave thenfileToSave:write(res)endelseif typ == "part_end" then-- 文件写结束,关闭文件if fileToSave thenfileToSave:close()fileToSave = nilendret_save = trueelseif typ == "eof" then-- 文件读取结束breakelsengx.log(ngx.INFO, "do other things")endendif ret_save thenngx.say("save file ok")end
2.配置
location upload_file {client_max_body_size 10m;content_by_lua_file usr/local/openresty/nginx/upload.lua;}location download {autoindex on;autoindex_localtime on;alias usr/local/openresty/nginx/upload;}
二、缓存控制
1.cache.lua
local redis = require "resty.redis"local red = redis:new()local resty_lock = require "resty.lock"local ngx_cache = ngx.shared.ngx_cachefunction set_to_cache(key, value, exptime)if not exptime thenexptime = 0endlocal succ, err, forcible = ngx_cache:set(key, value, exptime)return succendfunction get_from_cache(key)local ngx_cache = ngx.shared.ngx_cache;local value = ngx_cache:get(key)if not value then -- cache misslocal lock = resty_lock:new("cache_lock")local elapsed, err = lock:lock(key)if not elapsed thenreturn fail("failed to acquire the lock: ", err)endvalue = get_from_redis(key)if not value thenlocal ok, err = lock:unlock()if not ok thenreturn fail("failed to unlock: ", err)endngx.say("no value found")returnendlocal ok, err = ngx_cache:set(key, value, 1)if not ok thenlocal ok, err = lock:unlock()if not ok thenreturn fail("failed to unlock: ", err)endreturn faile("failed to update ngx_cache: ", err)endlocal ok, err = lock:unlock()if not ok thenreturn faile("failed to unlock: ", err)endreturn valueendngx.say("get from cache.")return valueendfunction get_from_redis(key)red:set_timeout(1000)local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("failed to connect: ", err)returnendlocal res, err = red:get(key)if not res thenngx.say("failed to get doy: ", err)return ngx.nullendngx.say("get from redis.")return resendfunction set_to_redis(key, value)red:set_timeout(1000)local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("failed to connect: ", err)returnendlocal ok, err = red:set(key, value)if not ok thenngx.say("failed to set to redis: ", err)returnendreturn okendset_to_redis('key', "Lua And Openrestry")local rs = get_from_cache('key')ngx.say(rs)
2.配置
location cache {content_by_lua_file usr/local/openresty/nginx/cache.lua;}
三、数据库操作
1.mysql.lua
local request_method = ngx.var.request_methodlocal cjson = require("cjson")local mysql = require("resty.mysql")local quote = ngx.quote_sql_strlocal db,err = mysql:new()local function close_db(db)if not db thenreturnenddb:close()endif not dbthennax.say("new mysql error",err)endlocal args = nillocal username = nillocal pwd = nilif "GET" == request_methodthenargs = ngx.req.get_uri_args()elseif "POST" == ngx.request_methodthenngx.req.read_body()args = ngx.req.get_post_args()endusername = tostring(args["username"])pwd = tostring(args["pwd"])if username == nil thenngx.say("username not nil")returnelseif username == '' thenngx.say("username not nil")returnelseif pwd == nil thenngx.say("password not nil")return;elseif pwd == '' thenngx.say("password not nil")return;enddb:set_timeout(1000)local props = {host = "xxxx.com",port = 3306,database = "xxxx",user = "xxxx",password = "xxxx"}local res, err, errno, sqlstate = db:connect(props)if not res thenngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)return close_db(db)endlocal select_name = "select username from users where username="..quote(username)res, err, errno, sqlstate = db:query(select_name)if not res thenngx.exec("/view/404.html")return close_db(db)endlocal result = {}result.success = true;result.info = "login success"ngx.say(cjson.encode(result))
2.配置
location mysql {access_by_lua_file usr/local/openresty/nginx/mysql.lua;}
文章转载自youcongtech,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




