Skip to content

Tinywan/lua-nginx-redis

Repository files navigation

Markdown

开发过程记录

  • openresty 学习
    • luajit 执行文件默认安装路径:/opt/openresty/luajit/bin/luajit,这样我们直接可以这样运行一个Lua文件:luajit test.lua

      • luajit 运行测试案例:
      tinywan@tinywan:~/Lua$ luajit test.lua    
      The man name is Tinywan            
      The man name is Phalcon
      
    • lua-resty-redis 扩展

      • 代码引入:lua_package_path "/opt/openresty/nginx/lua/lua-resty-redis/lib/?.lua;;";
      • Lua脚本实现一个CDN的反向代理功能(智能查找CDN节点)
        • nginx.conf 配置信息
        http {
                lua_package_path "/opt/openresty/nginx/lua/lua-resty-redis/lib/?.lua;;";
                server {
                    listen 80;
                    server_name  localhost;
                    location ~ \/.+\/.+\.(m3u8|ts) {
                            if ($uri ~ \/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)(|-).*\.(m3u8|ts)) {
                                    set $app_name $1;
                                    set $a $2;
                            }
                            set $stream_id "";
                            default_type 'text/html';
                            rewrite_by_lua_file  /opt/openresty/nginx/lua/proxy_pass_cdn.lua;
                            proxy_connect_timeout       10;
                            proxy_send_timeout          30;
                            proxy_read_timeout          30;
                            proxy_pass                  $stream_id;
                    }
        
                }
        }
        
    • lua-resty-websocket 扩展

      • 代码引入:lua_package_path "/opt/openresty/nginx/lua/lua-resty-websocket/lib/?.lua;;";

      • Lua脚本实现一个websocket连接(测试成功,可上线)

        • nginx.conf 配置信息
        http {
                lua_package_path "/opt/openresty/nginx/lua/lua-resty-websocket/lib/?.lua;;";
                server {
                    listen 80 so_keepalive=2s:2s:8;  #为了防止半开TCP连接,最好在Nginx监听配置指令中启用TCP keepalive:
                    server_name  localhost;
                    location /ws {
                        lua_socket_log_errors off;
                        lua_check_client_abort on;
                        lua_code_cache off; # 建议测试的时候最好关闭缓存
                        content_by_lua_file /opt/openresty/nginx/conf/Lua/websocket.lua;
                    }
                }
        }
        

        websockt-lua

    • lua-cjson 扩展

      • 基本用法
        • nginx.conf
        location /cjson {
                content_by_lua_block {
                        local cjson = require "cjson"
        
                        local json = cjson.encode({
                                foo = "bar",
                                some_object = {},
                                some_array = cjson.empty_array
                        })
                        ngx.say(json)
                }
        }
        
        • curl 请求
        root@tinywan:/opt/openresty/nginx/conf# curl http://127.0.0.1/cjson
        {"some_object":{"tel":13669313112,"age":24},"name":"tinywan","some_array":[]}
        
      • lua对象到字符串、字符串到lua对象

Redis、Lua、Nginx一起工作事迹

Redis执行Lua脚本示例

Lua 基本语法


  • Hello, Lua!

    我们的第一个Redis Lua 脚本仅仅返回一个字符串,而不会去与redis 以任何有意义的方式交互

    local msg = "Hello, world!"
    return msg
    

    这是非常简单的,第一行代码定义了一个本地变量msg存储我们的信息, 第二行代码表示 从redis 服务端返回msg的值给客户端。 保存这个文件到Hello.lua,像这样去运行:

    www@iZ239kcyg8rZ:~/lua$ redis-cli EVAL "$(cat Hello.lua)" 0
    "Hello, world!"
    

    运行这段代码会打印"Hello,world!", EVAL在第一个参数是我们的lua脚本, 这我们用cat命令从文件中读取我们的脚本内容。第二个参数是这个脚本需要访问的Redis 的键的数字号。我们简单的 “Hello Script" 不会访问任何键,所以我们使用0

Lua知识


基本语法
  • redis.call() 与 redis.pcall()的区别

    • 他们唯一的区别是当redis命令执行结果返回错误时
    • redis.call()将返回给调用者一个错误.
    • redis.pcall()会将捕获的错误以Lua表的形式返回.
    • redis.call() 和 redis.pcall() 两个函数的参数可以是任意的 Redis 命令
  • Lua网络编程

Redis执行Lua脚本基本用法


  • 基本语法

    EVAL script numkeys key [key ...] arg [arg ...]
    
  • 通过lua脚本获取指定的key的List中的所有数据

        local key=KEYS[1]
        local list=redis.call("lrange",key,0,-1);
        return list;
    
  • 根据外面传过来的IDList 做“集合去重”的lua脚本逻辑:

        local result={};
        local myperson=KEYS[1];
        local nums=ARGV[1];
        
        local myresult =redis.call("hkeys",myperson);
        
        for i,v in ipairs(myresult) do
           local hval= redis.call("hget",myperson,v);
           redis.log(redis.LOG_WARNING,hval);
           if(tonumber(hval)<tonumber(nums)) then
              table.insert(result,1,v);
           end
        end
        
        return  result;
    
  • 在命令行输入以下命令

    git config --global credential.helper store
    

    这一步会在用户目录下的.gitconfig文件最后添加:

    [credential]
    helper = store
    
  • push 代码

    push你的代码 (git push), 这时会让你输入用户名和密码, 这一步输入的用户名密码会被记住, 下次再push代码时就不用输入用户名密码!这一步会在用户目录下生成文件.git-credential记录用户名密码的信息。

  • Markdown 的超级链接技术

    【1】需要链接的地址:

    ```
    [解决向github提交代码不用输入帐号密码](#githubpush)  
    ```
    

    【2】要链接到的地方:

    ``` 
    <a name="githubpush"/> 解决向github提交代码不用输入帐号密码
    ```
    

    通过【1】和【2】可以很完美的实现一个连接哦!

Lua 脚本

  • [1] Lua 实现简单封装

    man.lua

        local _name = "Tinywan"
        local man = {}
    
        function man.GetName()
            return _name
        end
    
        function man.SetName(name)
            _name = name    
        end
    
        return man 
    

    测试封装,test.lua

        local man = require('man')
        print("The man name is "..man.GetName())
        man.SetName("Phalcon")
        print("The man name is "..man.GetName())