Openresty(Lua+Nginx)实践
简介:
OpenResty(也称为 ngx_openresty)是一个全功能的 Web 应用服务器。它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。
OpenResty 致力于将你的服务器端应用完全运行于 Nginx 服务器中,充分利用 Nginx 的事件模型来进行非阻塞 I/O 通信。不仅仅是和 HTTP 客户端间的网络通信是非阻塞的,与MySQL、PostgreSQL、Memcached 以及 Redis 等众多远方后端之间的网络通信也是非阻塞的。
————章亦春
Lua基础数据类型
Lua表达式
Lua控制结构
Lua函数
函数调用的时候可以传参,形参(a,b)与实参(x,y)在使用上需要注意,在使用函数时实参若大于形参则多余的参数为nli(空)
- Local function test(a,b)
- local temp = a
- a = b
- b = temp
- print(a,b)
- end
- local x = "hello"
- local y = 20
- print(x, y)
- swap(x, y) --调用swap函数
- print(x, y) --调用swap函数后,x和y的值并没有交换
- -->output
- hello 20
- 20 hello
- hello 20
Openrsty连接redis连接池封装(connect,port)+auth 使用
- --这是大神们封装好的redis连接池,在配置中修改ip和端口即可 文件放到 Openresty/lualib/resty/redis_iresty.lua
- local redis_c = require "resty.redis"
- local ok, new_tab = pcall(require, "table.new")
- if not ok or type(new_tab) ~= "function" then
- new_tab = function (narr, nrec) return {} end
- end
- local _M = new_tab(0, 155)
- _M._VERSION = '0.01'
- local commands = {
- "append", "auth", "bgrewriteaof",
- "bgsave", "bitcount", "bitop",
- "blpop", "brpop",
- "brpoplpush", "client", "config",
- "dbsize",
- "debug", "decr", "decrby",
- "del", "discard", "dump",
- "echo",
- "eval", "exec", "exists",
- "expire", "expireat", "flushall",
- "flushdb", "get", "getbit",
- "getrange", "getset", "hdel",
- "hexists", "hget", "hgetall",
- "hincrby", "hincrbyfloat", "hkeys",
- "hlen",
- "hmget", "hmset", "hscan",
- "hset",
- "hsetnx", "hvals", "incr",
- "incrby", "incrbyfloat", "info",
- "keys",
- "lastsave", "lindex", "linsert",
- "llen", "lpop", "lpush",
- "lpushx", "lrange", "lrem",
- "lset", "ltrim", "mget",
- "migrate",
- "monitor", "move", "mset",
- "msetnx", "multi", "object",
- "persist", "pexpire", "pexpireat",
- "ping", "psetex", "psubscribe",
- "pttl",
- "publish", --[[ "punsubscribe", ]] "pubsub",
- "quit",
- "randomkey", "rename", "renamenx",
- "restore",
- "rpop", "rpoplpush", "rpush",
- "rpushx", "sadd", "save",
- "scan", "scard", "script",
- "sdiff", "sdiffstore",
- "select", "set", "setbit",
- "setex", "setnx", "setrange",
- "shutdown", "sinter", "sinterstore",
- "sismember", "slaveof", "slowlog",
- "smembers", "smove", "sort",
- "spop", "srandmember", "srem",
- "sscan",
- "strlen", --[[ "subscribe", ]] "sunion",
- "sunionstore", "sync", "time",
- "ttl",
- "type", --[[ "unsubscribe", ]] "unwatch",
- "watch", "zadd", "zcard",
- "zcount", "zincrby", "zinterstore",
- "zrange", "zrangebyscore", "zrank",
- "zrem", "zremrangebyrank", "zremrangebyscore",
- "zrevrange", "zrevrangebyscore", "zrevrank",
- "zscan",
- "zscore", "zunionstore", "evalsha"
- }
- local mt = { __index = _M }
- local function is_redis_null( res )
- if type(res) == "table" then
- for k,v in pairs(res) do
- if v ~= ngx.null then
- return false
- end
- end
- return true
- elseif res == ngx.null then
- return true
- elseif res == nil then
- return true
- end
- return false
- end
- -- change connect address as you need
- function _M.connect_mod( self, redis )
- redis:set_timeout(self.timeout)
- return redis:connect("1.1.1.1", 6379)
- end
- function _M.set_keepalive_mod( redis )
- -- put it into the connection pool of size 100, with 60 seconds max idle time
- return redis:set_keepalive(60000, 1000)
- end
- function _M.init_pipeline( self )
- self._reqs = {}
- end
- function _M.commit_pipeline( self )
- local reqs = self._reqs
- if nil == reqs or 0 == #reqs then
- return {}, "no pipeline"
- else
- self._reqs = nil
- end
- local redis, err = redis_c:new()
- if not redis then
- return nil, err
- end
- local ok, err = self:connect_mod(redis)
- if not ok then
- return {}, err
- end
- redis:init_pipeline()
- for _, vals in ipairs(reqs) do
- local fun = redis[vals[1]]
- table.remove(vals , 1)
- fun(redis, unpack(vals))
- end
- local results, err = redis:commit_pipeline()
- if not results or err then
- return {}, err
- end
- if is_redis_null(results) then
- results = {}
- ngx.log(ngx.WARN, "is null")
- end
- -- table.remove (results , 1)
- self.set_keepalive_mod(redis)
- for i,value in ipairs(results) do
- if is_redis_null(value) then
- results[i] = nil
- end
- end
- return results, err
- end
- function _M.subscribe( self, channel )
- local redis, err = redis_c:new()
- if not redis then
- return nil, err
- end
- local ok, err = self:connect_mod(redis)
- if not ok or err then
- return nil, err
- end
- local res, err = redis:subscribe(channel)
- if not res then
- return nil, err
- end
- res, err = redis:read_reply()
- if not res then
- return nil, err
- end
- redis:unsubscribe(channel)
- self.set_keepalive_mod(redis)
- return res, err
- end
- local function do_command(self, cmd, ... )
- if self._reqs then
- table.insert(self._reqs, {cmd, ...})
- return
- end
- local redis, err = redis_c:new()
- if not redis then
- return nil, err
- end
- local ok, err = self:connect_mod(redis)
- if not ok or err then
- return nil, err
- end
- local fun = redis[cmd]
- local result, err = fun(redis, ...)
- if not result or err then
- -- ngx.log(ngx.ERR, "pipeline result:", result, " err:", err)
- return nil, err
- end
- if is_redis_null(result) then
- result = nil
- end
- self.set_keepalive_mod(redis)
- return result, err
- end
- for i = 1, #commands do
- local cmd = commands[i]
- _M[cmd] =
- function (self, ...)
- return do_command(self, cmd, ...)
- end
- end
- function _M.new(self, opts)
- opts = opts or {}
- local timeout = (opts.timeout and opts.timeout * 1000) or 1000
- local db_index= opts.db_index or 0
- return setmetatable({
- timeout = timeout,
- db_index = db_index,
- _reqs = nil }, mt)
- end
- return _M
我的调用,生成uuid后存储到redis里 :
- ngx.req.read_body()
- local args= ngx.req.get_uri_args()
- for k,v in pairs(args) do
- local mac = v
- ngx.say(mac)
- end
- function guid()
- local seed={'e','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
- local tb={}
- for i=1,32 do
- table.insert(tb,seed[math.random(1,16)])
- end
- local sid=table.concat(tb)
- return string.format('%s-%s-%s-%s-%s',
- string.sub(sid,1,8),
- string.sub(sid,9,12),
- string.sub(sid,13,16),
- string.sub(sid,17,20),
- string.sub(sid,21,32)
- )
- end
- --print('execute_time='..tostring(os.clock()-start_time))
- local redis = require "resty.redis_iresty"
- local red = redis:new()
- redis:auth("password")
- local s=0
- --local start_time=os.clock()
- while s<50 do
- s=s+1
- local uuid = guid()
- local ok, err = redis:hset("lbs",uuid,"1")
- if not ok then
- ngx.say("failed to set dog: ", err)
- return
- end
- ngx.say(s,uuid)
- end
认为Openresty完全可以替代nginx
Openresty(Lua+Nginx)实践的更多相关文章
- 【原创】大叔经验分享(77)openresty(nginx+lua)发http请求
openresty(nginx+lua)发http请求 利用location+proxy_pass间接实现 location ^~ /test/http { internal; proxy_pass ...
- openresty(nginx+lua)初识
1.新增项目配置文件: vim /usr/example/example1.conf --将以下内容加入example1.conf server { listen 80; server_name _; ...
- openresty+lua在反向代理服务中的玩法
openresty+lua在反向代理服务中的玩法 phith0n · 2015/06/02 10:35 0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了 ...
- openresty+lua+kafka方案与Tomcat接口并发度对比分析
1.openresty+lua+kafka 1.1 openresty+lua+kafka方案 之前的项目基于nginx反向代理后转发到Tomcat的API接口进行业务处理,然后将json数据打入ka ...
- Openresty+Lua+Kafka实现日志实时采集
简介 在很多数据采集场景下,Flume作为一个高性能采集日志的工具,相信大家都知道它.许多人想起Flume这个组件能联想到的大多数都是Flume跟Kafka相结合进行日志的采集,这种方案有很多他的优点 ...
- Openresty Lua协程调度机制
写在前面 OpenResty(后面简称:OR)是一个基于Nginx和Lua的高性能Web平台,它内部集成大量的Lua API以及第三方模块,可以利用它快速搭建支持高并发.极具动态性和扩展性的Web应用 ...
- OpenResty Lua钩子调用完整流程
前面一篇文章介绍了Openresty Lua协程调度机制,主要关心的是核心调度函数run_thread()内部发生的事情,而对于外部的事情我们并没有涉及.本篇作为其姊妹篇,准备补上剩余的部分.本篇将通 ...
- openresty + lua 1、openresty 连接 mysql,实现 crud
最近开发一个项目,公司使用的是 openresty + lua,所以就研究了 openresty + lua.介绍的话,我就不多说了,网上太多了. 写这个博客主要是记录一下,在学习的过程中遇到的一些坑 ...
- 用lua nginx module搭建一个二维码
用lua nginx module搭建一个二维码(qr code)生成器 作者 vinoca 發布於 2014年10月31日 如果有VPS,或者开源的路由器,安装一个nginx,添加lua-nginx ...
- linux环境中,openssl升级及openresty中nginx基于新版本openssl重新编译
需求说明: 最近在对系统进行安全扫描的时候,出现了openssl版本的问题,建议对openssl版本进行升级,在此记录下升级过程. 环境说明: 操作系统:RHEL 6.6 升级操作过程: 1.下载最新 ...
随机推荐
- Visual Studio 2012 编译错误【error C4996: 'scanf': This function or variable may be unsafe. 】的解决方案
在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...
- JS-移动端判断上拉和下滑
一.手指触屏,利用touchstart和touchend计算前后滑动距离,判断是上拉还是下滑. 二.js中距离:pageY.clientY.offsetY的区别: offsetY:相对于父节点的偏移距 ...
- 【LeetCode3】Longest Substring Without Repeating Characters★★
题目描述: 解题思路: 借用网上大神的思想:the basic idea is, keep a hashmap which stores the characters in string as key ...
- css学习之LInk & import
一.用link加载外部样式表 1.放置位置:放在head元素中 2.样式表中只能包含样式规则,不能包含其他标记语言.如出现了标记,会导致其中一部分或全部被忽略. 3.type = 'text/css' ...
- 基于Verilog的CRC-CCITT校验
由于笔者在自己设计CRC模块时遇到很多问题,在网上并未找到一篇具有实际指导意义的文章,在经过多次仿真修改再仿真之后得到了正确的结果,故愿意在本文中为大家提供整个设计流程供大家快速完成设计.本文章主要针 ...
- SparkSQL与Hive的整合
其他的配置hive基本配置就不记录了!! 1. 拷贝$HIVE_HOME/conf/hive-site.xml $SPARK_HOME/conf/2. 在$SPARK_HOME/conf/目录中,修改 ...
- JavaWeb基础—过滤器Filter
一.概念 JavaWeb三大组件之一(组件都有一个特性,需要在web.xml中配置) 过滤器:会在一组资源(jsp servlet等)的前面执行,可以让请求得到目标资源,也可以终止请求,不再继续 也就 ...
- 20155301 滕树晨linux基础——linux进程间通信(IPC)机制总结
20155301 滕树晨linux基础--linux进程间通信(IPC)机制总结 共享内存 共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,由IPC为进程创建的一个特殊地址范围,它将出现在 ...
- java中package import区别
他们两个是互逆过程package freedom.bean;将你这个类放在了/freedom/bean/这个文件夹下面要使用的话import freedom.bean.*;导入这个类
- JavaWeb总结(三)
什么是Servelt - 是运行在Web服务器或应用服务器上的Java程序 - 在Web上创建动态内容的有效而强大的解决方案 - 由容器来管理生命周期与Web服务器交互 Servlet规范的组成 Ja ...