Lua学习笔记 目录 Lua学习笔记 1 需求 2 选型 2 Python 2 Lua 3 分析 4 环境 4 下载所需依赖 4 环境配置 4 代码 5 代码结构以下 5 Monster.java 5 LuaDemo.java 7 MyMonsterThread.java 8 LuaTest.java 9 demo.lua 13 问题 18 总结 19 需求 在游戏开发过程当中,因为须要支持不一样的手机平台,如winPhone、android、iphone等,这样,一套游戏逻辑就须要从新开发屡次,而这部分游戏逻辑是与平台无关的,能够单独实现,若是这部分逻辑提炼出来,嵌入到不一样的语言中,将会使得维护起来更加方便; 另外,服务器后台在处理游戏逻辑的时候,一样会出现游戏逻辑常常出现变化的状况,好比任务系统的更新等,这样,若是游戏逻辑直接写到code中,会形成每次更新都须要重启服务的状况,咱们但愿实现热更新,尤为是业务逻辑模块方面的变化,当出现多服的状况下,这部分的更新会更麻烦; 还有就是游戏设计师与程序员沟通的问题,当设计师设计出一套场景后,须要程序员去实现才能看到具体的结果,沟通费时费力还不必定达到预期的效果,若是出现一种脚本语言使得设计师不须要依赖程序员便可独立设计并表现出游戏场景,同时设计师与程序员都熟悉这种脚本语言,则对双方都受益。 选型 市面上出现的适合于游戏开发的脚本语言主要有Python与Lua,由于这两种脚本语言均可以直接调用C++功能(虽然我是一个java程序员,但不得不认可,绝大部分的好玩的大型游戏都是基于C++实现的),事实上,这两种脚本语言的兼容性与扩展性都很是好(均可以集成到Java中) 关于Python与Lua的对比(http://lua-users.org/wiki/LuaVersusPython) Python 扩展模块更加完善。含有大量的有用的函数库,很是利于线下工做,如做为工具脚本。另外还有大量的教程。 经过附加模块可实现极为出色的多维数组数值计算能力(我的认为在作机器学习算法等数学模型应用中可能会更合适),严格的说,Lua并无数组的概念,全部的数据结构都是以table形式存储的。 自带ctypes数据类型。能够访问动态连接库(.so文件或.dll文件),无需对C进行扩展。、 支持远程调试。 Lua有一个简约的不能再简单的语法,这点上与Python没有较大差异。 Python对string与list作了较大层度的扩展,我建议若是想要在Lua中更有成效,就去使用扩展库 Python对Unicode编码的支持更好些 Python对空白字符敏感 Python内置了按位操做,Lua可经过扩展库实现 Python具备错误检测能力,而在这方面,Lua更易出错 Python有更为详细的初学者文档,目前尚缺少对Lua介绍的入门教程 Lua Lua比Python小巧的多,python22.dll 824KB,而一个基本的lua引擎仅在100KB如下 占用内存更少 看起来没有任何的指针使用 编译器与解释器执行起来更快 在脚本与C语言中,仅用少许的"胶水代码"便可实现较为优雅且简单的API交互 不适用能够获得复杂而易出错对象的引用计数 Lua以做为一门配置语言开始,在须要建立与配置文件的时候(尤为是在游戏中),他是很是了不得的 Lua有一个很是漂亮且简单强大的语法,与Python相比,能够用更少的代码 Lua有一个小巧简单稳定的代码库,若是须要,查看与修改很容易,但可能文档不如Python完善 Lua不多有扩展组件使之更易为一个专门的须要作绑定,Python则须要众多的模块 Lua支持多线程操做,多个解释器能够同存于一个进程中,每个解释器均可以在本身的线程中独立运行,所以,Lua更适合在多线程程序中嵌入 Lua对空白字符不敏感 Lua支持多线程开箱即用,可在一个单独的线程或进程中有多个解释器,而Python不支持多线程,多线程能够访问解释器,但须要每一个线程都必须持有全局锁 分析 经过以上分析,在作独立的运行程序或脚本时候,采用Python是一个不错的选择(如线下分析等任务),而做为脚本嵌入到另一种语言中,更推荐使用Lua 环境 下载所需依赖 Win32: Win64 : 其余环境:下载地址:http://www.keplerproject.org/luajava/index.html#download 源码以及文档: 教程: 环境配置 将luajava-1.1.dll加入到jre的bin目录下 将luajava-1.1.jar引入到工程的环境变量中 下载lua的eclipse插件Lua Development Tools 如需单独调试Lua,则须要单独安装LuaForWindows 编译器 代码 代码结构以下 Monster.java package com.chilijoy.bean; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; /******************************************************************************* * * Monster.java Created on 2014年7月28日 * * Author: linfenliang * * Description: * * Version: 1.0 ******************************************************************************/ public class Monster { private String race;//种族 private int defense;//防护值 private int attack;//攻击值 private int life;//生命值 public String getRace() { return race; } public void setRace(String race) { this.race = race; } public int getDefense() { return defense; } public void setDefense(int defense) { this.defense = defense; } public int getAttack() { return attack; } public void setAttack(int attack) { this.attack = attack; } public int getLife() { return life; } public void setLife(int life) { this.life = life; } @Override public String toString() { return ReflectionToStringBuilder.toString(this); } } LuaDemo.java package com.chilijoy.lua; import java.io.File; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /******************************************************************************* * * LuaDemo.java Created on 2014年7月28日 * * Author: linfenliang * * Description: * * Version: 1.0 ******************************************************************************/ public class LuaDemo { public static final String luaPath = "." + File.separator + "conf" + File.separator ; public static void main(String[] args) { ExecutorService service = Executors.newSingleThreadExecutor(); for(int i=0;i<500000;i++){ service.execute(new MyMonsterThread()); } service.shutdown(); } } MyMonsterThread.java package com.chilijoy.lua; import java.io.File; import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFactory; import com.chilijoy.bean.Monster; /******************************************************************************* * * MyMonster.java Created on 2014年7月28日 * * Author: linfenliang * * Description:设计存在屡次打开关闭问题,弃用 * * Version: 1.0 ******************************************************************************/ public class MyMonsterThread extends Thread { static final String luaPath = "." + File.separator + "conf" + File.separator + demo.lua"; @Override public void run() { LuaState lua = null; try { Monster m = new Monster(); // System.out.println("monster_before:" + m); lua = LuaStateFactory.newLuaState(); lua.openLibs(); lua.LdoFile(luaPath); lua.getField(LuaState.LUA_GLOBALSINDEX, "create"); // lua.pushObjectValue(monster); lua.pushJavaObject(m); lua.call(1, 0); // System.out.println("monster_after:" + m); } catch (Exception e) { e.printStackTrace(); } finally { if (lua != null) { lua.close(); } System.out.println(this.getName()); } } } LuaTest.java package com.chilejoy.lua; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.Assert; import org.junit.Test; import org.keplerproject.luajava.LuaException; import org.keplerproject.luajava.LuaObject; import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFactory; import com.chilijoy.bean.Monster; import com.chilijoy.lua.LuaDemo; import com.chilijoy.lua.MyMonsterThread; /******************************************************************************* * LuaTest.java Created on 2014年7月28日 * Author: linfenliang * Description: * Version: 1.0 ******************************************************************************/ public class LuaTest { static final int cycleTimes = 1000; @Test public void test() throws LuaException { System.out.println("-------input object test-------"); LuaState lua = null; Monster m = new Monster(); System.out.println("monster_before:" + m); lua = LuaStateFactory.newLuaState(); lua.openLibs(); lua.LdoFile(LuaDemo.luaPath + "demo.lua"); lua.getField(LuaState.LUA_GLOBALSINDEX, "create"); // lua.pushObjectValue(monster); lua.pushJavaObject(m); lua.call(1, 1);//传入一个参数,传出1个参数 lua.setField(LuaState.LUA_GLOBALSINDEX, "monster"); LuaObject obj = lua.getLuaObject("monster"); System.out.println("monster_lua:"+obj.getObject()); System.out.println("monster_after:" + m); Assert.assertEquals(obj.getObject(), m); lua.close(); } @Test public void testHelloWorld(){ System.out.println("-------hello ,world test-------"); LuaState lua = LuaStateFactory.newLuaState(); lua.openLibs(); lua.LdoFile(LuaDemo.luaPath + "demo.lua"); lua.getField(LuaState.LUA_GLOBALSINDEX, "hello"); lua.call(0, 0); lua.close(); } @Test public void calculateTest(){ System.out.println("--------calculate---------"); LuaState lua = null; lua = LuaStateFactory.newLuaState(); lua.openLibs(); lua.LdoFile(LuaDemo.luaPath + "demo.lua"); lua.getField(LuaState.LUA_GLOBALSINDEX, "calculate"); lua.pushNumber(3); lua.pushNumber(5); lua.pushNumber(8); lua.call(3, 1); // lua.setField(LuaState.LUA_GLOBALSINDEX, "result"); // LuaObject obj = lua.getLuaObject("result"); LuaObject obj = lua.getLuaObject(1); System.out.println("calculate result:"+obj.getNumber()); lua.close(); } @Test public void multipleReturnValueTest(){ System.out.println("--------multipleReturnValue---------"); LuaState lua = null; lua = LuaStateFactory.newLuaState(); lua.openLibs(); lua.LdoFile(LuaDemo.luaPath + "demo.lua"); lua.getField(LuaState.LUA_GLOBALSINDEX, "getValues"); lua.pushNumber(3); lua.pushNumber(5); lua.pushNumber(8); lua.call(3, 3); for(int i=1;i<=3;i++){ LuaObject o1 = lua.getLuaObject(i); System.out.println("获取第"+i+"个返回值:"+o1.getNumber()); } lua.close(); } @Test public void nestedFuncTest(){ System.out.println("------------nestedFunc-----------"); LuaState state = LuaStateFactory.newLuaState(); state.openLibs(); state.LdoFile(LuaDemo.luaPath+"demo.lua"); state.getField(LuaState.LUA_GLOBALSINDEX, "nestedFunc"); state.pushNumber(3); state.pushNumber(5); state.pushNumber(8); state.call(3, 1); LuaObject obj = state.getLuaObject(1); System.out.println("nestedFunc 返回值:"+obj.getNumber()); state.close(); } @Test public void cycleTest(){ System.out.println("--------cycle(for(){}) ---------"); LuaState state = LuaStateFactory.newLuaState(); state.openLibs(); state.LdoFile(LuaDemo.luaPath + "demo.lua"); double a,b,c; for(int i=0;i<cycleTimes;i++){ a= Math.random(); b = Math.random(); c = Math.random(); state.getField(LuaState.LUA_GLOBALSINDEX, "calculate"); state.pushNumber(a); state.pushNumber(b); state.pushNumber(c); state.call(3, 1); // state.setField(LuaState.LUA_GLOBALSINDEX, "result"); // LuaObject obj = state.getLuaObject("result"); LuaObject obj = state.getLuaObject(1); state.pop(1); System.out.println(String.format(" a=%6f,b=%6f,c=%6f sum=>%6f", a,b,c,obj.getNumber())); } state.close(); } // @Test public void concurrentTest() throws InterruptedException { System.out.println("--------concurrent ---------"); ExecutorService service = Executors.newFixedThreadPool(5); for(int i=0;i<cycleTimes;i++){ service.execute(new MyMonsterThread()); } Thread.sleep(5000); service.shutdown(); } // @Test public void concurrentSingleThreadTest() throws InterruptedException { System.out.println("--------concurrentSingleThread ---------"); ExecutorService service = Executors.newSingleThreadExecutor(); for(int i=0;i<cycleTimes;i++){ service.execute(new MyMonsterThread()); } service.shutdown(); } @Test public void testFunc() throws InterruptedException{ System.out.println("-----------testFunc-----------"); LuaState state = LuaStateFactory.newLuaState(); state.openLibs(); state.LdoFile(LuaDemo.luaPath+"demo.lua"); state.getField(LuaState.LUA_GLOBALSINDEX, "testFunc"); state.call(0, 0); state.close(); // System.out.println(Math.toRadians(30)); // System.out.println(Math.sin(Math.toRadians(30))); } } demo.lua --对monster赋值(传入对象,返回对象) function create(monster) monster:setRace("the first demo") monster:setDefense(10) att = monster:getAttack() print("monster.attack=>"..att) monster:setAttack(10-att) monster:setLife(100) print("create monster !"); return monster end --打印输出测试 function hello() print("Hello World from Lua !"); end --数值计算结果输出 function calculate(a,b,c) return a+b+c end --多返回值测试 function getValues(a,b,c) return a,b,c end --函数嵌套调用 function nestedFunc(a,b,c) printFunc() return calculate(a,b,c) end function printFunc() print("提供给nestedFunc 函数调用的打印函数 !"); end function testFunc() print("------LUA-----testFunc--------START-----") a=1 b="123" c={4,5,6} d=hello print(type(a))--打印数据类型 print(type(b)) print(type(c)) print(type(d)) print(_VERSION)--_VERSION 打印LUA版本 print( a, b,c, d)--多个返回值输出 --多行数据 reservedWords =[[Lua reserved words are: and, break, do, else, elseif,end, false, for, function, if, in, local, nil, not, or,repeat, return, then, true, until, while]] print(reservedWords) --多个变量赋值 a1,a2,a3=1,"2_",3 print(a1,a2,a3) --数据互换 b1,b2=3,5 print(b1,b2) b1,b2=b2,b1 print(b1,b2) a,b,c,d,e = 1, 1.123, 1E9, -123, .0008 print("a="..a, "b="..b, "c="..c, "d="..d, "e="..e) --字符串链接用 .. 取代"+"\ io.write("io.write writes to stdout but without new line.") io.write(" Use an empty print to write a single new line.") print() a={} -- {} empty table b={1,2,3} c={"a","b","c"} print(a,b,c) -- tables 不能被直接打印 ---------测试object格式数据---------------- user={} user.username="linfenliang" user.password="123456" user.age=26 user.isMan=true if(user.age>20) then print(user.username ,"is more than 20 years old!") elseif(user.age>10) then print(user.username, "maybe a student") else print(user.username, "is just a little boy ") end if(user.username=="linfenliang") then print("yes,I am linfenliang !") else print("sorry,you got the wrong guy!") end print(user.username,user.password,user.age,user.isMan) judge(user) print "------LUA-----testFunc --------END -----" --也可不添加括号 end --若是 age==26,则address为 shanghai,不然为 not in shanghai function judge(user) user.address = (user.age==26) and "I am in Shanghai" or "I am not in Shanghai" print(user.address) while(user.age~=30) do user.age=user.age+1 io.write(" My age is growing ..."..user.age) end print() repeat user.age=user.age-1 print(" I am beginning young "..user.age) until user.age==26 -- 从1到4依次打印 for a=1,4 do print(a) end print() -- 从1到6,每次增加3 for a=1,6,3 do print(a) end print() --pairs 迭代table元素 for key,value in pairs({12,8,9,7}) do print(key,value) end arr = {1,2,3,"four","five",6} for k,v in pairs(arr) do print(k,v) end a=0 while true do a=a+1 if a==10 then break end end print("循环累加:"..a) --全局变量与局部变量测试 sayHello() print(word_a,word_b) --字符串格式化测试 io.write(string.format("hello,now is %s, I am %s, I am %s",os.date(),"linfenliang","a good man!\n")) --数学公式测试 print(math.sqrt(81),math.pi,math.sin(0.5235987755982988)) --字符串操做 --string.byte, string.char, string.dump, string.find, string.format, --string.gfind, string.gsub, string.len, string.lower, string.match, --string.rep, string.reverse, string.sub, string.upper print(string.reverse("abcdefg"),string.rep("abcd",5),string.find("abcdeadvdsrerdv","dv")) --table测试 t = {1} table.insert(t,2) table.insert(t,3) table.sort(t,function(v1,v2) return v1>v2 end) print("table t==>"..table.concat(t,":")) table.insert(t,"iii") --输出 for k,v in ipairs(t) do print(k,v) end --Lua IO 操做 -- IO 函数: -- io.close , io.flush, io.input, io.lines, io.open, io.output, io.popen, -- io.read, io.stderr, io.stdin, io.stdout, io.tmpfile, io.type, io.write, -- file:close, file:flush, file:lines ,file:read, -- file:seek, file:setvbuf, file:write print(io.open("E://demo.lua","r")) --os.clock, os.date, os.difftime, os.execute, os.exit, os.getenv, --os.remove, os.rename, os.setlocale, os.time, os.tmpname print(os.date()) dofile("E://demo.lua") str_01 = "print(\"Hello,this function is load from String!\")" loadstring(str_01)() math.randomseed(os.time()) a = math.random(10,20) b = math.random(10,20) c = math.random(10,20) d = math.random(10,20) e = math.random(10,20) f = math.random(10,20) print(a,b,c,d,e,f) end word_a = "hello" --测试本地变量与全局变量 function sayHello() local word_a = "nihao" word_b = "I am good" print(word_a,word_b) end 问题 1、在作并发测试时,发现若是屡次建立关闭 LuaState,会出现异常,甚至会致使JVM崩溃,分析缘由可能为加载编译器与执行器占用内存过大致使,可是我将JVM内存参数改成512MB仍是会出现这个问题,仍是有疑问。 总结 一直没有找到一个比较典型的使用案例,《Lua游戏开发实践指南》有些例子,还在研究。
Lua 调用自定义C模块 这是《Lua程序设计》中提到的,可是想成功执行,对于初学Lua的确没那么简单。这里涉及如何如何生成一个动态连接库so文件;Lua5.2中导出函数从LuaL_register变成了LuaL_newlib。对于具体的细节有待深刻。这里的模块名是hello_lib, Lua解释器会根据名字找到对应的模块,然后执行其中的 luaopen_XXX方法。 Lua程序设计(第2版)中文 PDF http://www.linuxidc.com/Linux/2013-03/81833.htm 代码: #include <math.h> #include <lua5.2/lua.h> #include <lua5.2/lauxlib.h> #include <lua5.2/lualib.h> static int hello_sin(lua_State *L){ double d = luaL_checknumber(L, 1); lua_pushnumber(L, sin(d)); return 1; } static const struct luaL_Reg hello_lib[] = { {"hello_sin" , hello_sin}, {NULL, NULL} }; int luaopen_hello_lib(lua_State *L){ luaL_newlib(L, hello_lib); //luaL_register(L, "hello_lib",hello_lib); // lua 5.1 return 1; } 在Lua中调用: local hello = require "hello_lib" print(hello.hello_sin(1)) 执行过程和结果: Lua 调用自定义C模块 Lua 语言 15 分钟快速入门 http://www.linuxidc.com/Linux/2013-06/86582.htm Lua程序设计(第二版)阅读笔记 http://www.linuxidc.com/Linux/2013-03/81834.htm NetBSD 将支持用 Lua 脚本开发内核组件 http://www.linuxidc.com/Linux/2013-02/79527.htm CentOS 编译安装 Lua LuaSocket http://www.linuxidc.com/Linux/2011-08/41105.htm
lua读写redis的环境部署 个人lua环境是5.2版本,而对应的lua redis接口都是基于5.1的。因此首先先安装 1. compact5.1 这个安装没什么好说的,搜到官方网站,下载便可。而后copy对应lua文件到lua对应的安装库路径 我这里是/usr/local/lib/lua/5.2/ 2. 安装luasocke, 这个接口是实现了lua基本的网络请求接口。这个安装麻烦一点,对应的参考http://blog.csdn.net/shiningstarpxx/article/details/12911569 3. 安装redis-lua-git, 把对应的src目录下的lua文件拷到对应的库路径便可。 测试下面的代码,若是成功了就说明安装成功 local redis = require 'redis' local myclient = redis.connect('127.0.0.1', 6379) response = myclient:ping() print( response ) myclient:set("10000", "Hello World"); value = http://blog.csdn.net/shiningstarpxx/article/details/myclient:get("10000") print(value)
hello world 增长nginx配置: location /hello { default_type text/html; content_by_lua ' ngx.say("<p>hello, world</p>") ngx.say(tostring(ngx.var.remote_addr),"<br/>") ngx.say(tostring(ngx.var.arg_name),"<br/>") '; } 这样就可使用nginx开发动态接口了。 niginx的其余参数: 很是多的扩展和使用方法 https://github.com/chaoslawful/lua-nginx-module 3,链接数据库redis local mysql = require "resty.mysql" local memcached = require "resty.memcached" local function query_mysql() local db = mysql:new() db:connect{ host = "127.0.0.1", port = 3306, database = "test", user = "monty", password = "mypass" } local res, err, errno, sqlstate = db:query("select * from cats order by id asc") db:set_keepalive(0, 100) ngx.say("mysql done: ", cjson.encode(res)) end local function query_memcached() local memc = memcached:new() memc:connect("127.0.0.1", 11211) local res, err = memc:get("some_key") ngx.say("memcached done: ", res) end ngx.thread.spawn(query_mysql) -- create thread 1 ngx.thread.spawn(query_memcached) -- create thread 2
几行lua代码计算http包总长度 --帮助理解一下lua里的字符串模式和捕获的使用 --计算HTTP包总长度 local i, j = pMsg:find("\r\n\r\n") if(i ~= nil and pkgsize == 0) then --字符串模式匹配加捕获,j是HTTP头的长度 pkgsize = j + tonumber(pMsg:match("Content%-Length: (%d+)")) end
标签: 杂谈 |
在搭建环境以前,确定要一个Lua的解释器之类的东西,这些东西从哪里来?html
1.直接编译文件java
(1)http://www.lua.org/download.html下载新版本的Luapython
(2)解压进入etc/mysql
C:\Documents and Settings\Administrator>cd /d f:lua_study/lua-5.1.4/etc
(3)执行 luavs.batlinux
F:\lua_study\lua-5.1.4\etc>luavs.bat
(4)src目录下生成动态库等等文件,不过我在编译的时候出现了好多问题,就使用的下面的方法android
2.使用LuaForWindowsios
Lua for Windows 为 Windows 系统下提供了 Lua 脚本语言的开发和运行环境,不少东西配套好了。nginx
直接像python同样安装一下,安装时把SciTe编辑器也选择上,像头文件,库什么的都直接放好了。git
推荐这种方法程序员
3.SciTe编辑器
是一个体积小巧的文本编辑器,在安装LuaForWindows能够选择安装,而且把那个黑底色选择上更有感受一点。
4.下载地址
http://code.google.com/p/luaforwindows/
或者
http://luaforge.net/frs/?group_id=377
蓝蚂蚁软件工做室的一个做品,用着感受不错,用这个也是至关的方便,最主要的是它有vc番茄同样的提示
下载地址:http://www.blueantstudio.net
先下载 基础安装包,再下载安装Lua开发包
print("hello lua...")
SciTe编辑器中:
1.加入外部的头和库
VS2008-工具-选项-VC++目录中,把LuaForWindows安装下的头文件和库文件加到目录,运行文件在安装LuaForWindows的时候加入了环境变量,能够不用加了。
2.第一个工程
新建一个vc的命令行工程,写一个Lua脚本,用C++调用。
脚本:environment_test.lua
function ShowPrint()
print( "this is my cpp code call..." )
end
C++工程:Lua_c_evn
//注释:这段代码是参考网上文章照猫画虎出来的,只是来验证环境正确。
1: //-------------------------------------------------
2: //说明:Lua环境测试
3: //时间:2011-7-28
4: //环境:vs2008
5: //-------------------------------------------------
6: #include "stdafx.h"
7: #include <iostream>
8:
9: extern "C" {
10: #include <lua.h>
11: #include <lualib.h>
12: #include <lua.hpp>
13: }
14:
15: #pragma comment(lib,"lua5.1.lib")
16:
17: int _tmain(int argc, _TCHAR* argv[])
18: {
19: lua_State *L = lua_open(); //
20: luaL_openlibs(L); //加载 .lib 文件
21:
22: // 加载脚本文件,须要放在程序目录
23: luaL_loadfile( L, "environment_test.lua" );
24: lua_resume( L, 0 );
25:
26: // 调用函数
27: lua_getglobal( L, "ShowPrint" );
28: if( lua_resume( L, 0 ) )
29: {
30: printf( "%s/n", lua_tostring( L, 1) );
31: }
32:
33: // 调用结束
34: lua_close(L);
35:
36: std::system("pause");
37:
38: return 0;
39: }
40:
41:
直接运行,结果
OK,环境配置看来是正确了,以后,就开始真正的Lua之旅了。
全部文章您均可以任意转载,修改,演绎,但请保持完整性并留个大妈般的出处,不要误导他人
本文出处(熊哥)
http://pppboy.blog.163.com/blog/static/30203796201162811730972/
引用申明
http://blog.csdn.net/kingsollyu/article/details/6613468
http://blog.csdn.net/kun1234567/article/details/1929815
http://baike.baidu.com/view/1207529.htm
2013-09-10 17:25:05 发表评论
Rewrite phase.
Access phase.
Content phase.
详细的步骤:
1.init_by_lua 上下文http ngx启动时执行 2. set_by_lua 上下文 server, server if, location, location if 3.rewrite_by_lua 上下文 http, server, location, location if 4.access_by_lua 上下文 http, server, location, location if 5.content_by_lua 上下文 location, location if 6.header_filter_by_lua 上下文 http, server, location, location if 7.body_filter_by_lua 上下文 http, server, location, location if 8.log_by_lua 上下文 http, server, location, location if
我们再过滤post、get请求或者是触发了某个access、rewrite,若是发现恶意和违规的侵入的话,能够发邮件报警,好让咱们第一时间收到邮件的信息。
location = /smtp { default_type "text/plain"; content_by_lua ' local smtp = require("socket.smtp") local from = "<ruifengyunceshi@163.com>" local rcpt = {"",} local mesgt = { headers = { to = "", -- 收件人 subject = "This is Mail Title" }, body = "This is Mail Content." } local r, e = smtp.send{ server="smtp.163.com", user="", password="", from = from, rcpt = rcpt, source = smtp.message(mesgt) } if not r then ngx.say(e) else ngx.say("send ok!") end '; }
lua这东西挺怪的,他的双引号和单引号是有很大区别的,我到如今也没搞明白,啥区别,反正用双引号就对了。。。有事error.log报错的话,改为单引号试试。。
好点的方法是 先在lua的环境中跑一边,ok后,在放到ngx_lua里面。
Lua有丰富的接口的方案,不仅是给别人提供的接口,还有他本身访问别的接口所用的模块。
若是你的同事那边已经有个高性能的socket接口,那你就别麻烦他改为rest模式了。毕竟socket对socket速度很快的。
location /cosocket { default_type "text/plain"; content_by_lua ' local sock = ngx.socket.tcp() sock:settimeout(1000) local ok, err = sock:connect("127.0.0.1", 12000) if not ok then ngx.say("failed to connect: ", err) return end local bytes, err = sock:send("flush_all") ngx.say(bytes,err) if not bytes then ngx.say("failed to send query: ", err) return end local line, err = sock:receive() if not line then ngx.say("failed to receive a line: ", err) return end ngx.say("result: ", line) '; } } }
对于给别人的mysql查询,给帐号密码不合适,和一个小权限的帐号密码也不合适。
这种状况,咱们要是求高性能的话,能够用lua配置cjson作成rest接口。
location /select2 { content_by_lua ' local mysql = require "resty.mysql" local db,err = mysql:new() if not db then ngx.say("failed to instantiate mysql: ",err) return end db:set_timeout(1000) local ok,err,errno,sqlstate = db:connect{ host = "127.0.0.1", port = 3306, database = "niubi", user = "ruifengyun", password = "", max_package_size = 1024 } if not ok then ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate) return end ngx.say("connected to mysql.") res,err,errno,sqlstate = db:query("select username,password from users where id="..ngx.var.arg_id) if not res then ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".") return end local cjson = require "cjson" ngx.say("result: “,cjson.encode(res)) '; }
我们既然知道了 lua的强大之处, 能够从lua里面搞负载均衡。
往redis里面 扔两个key 好比 web1 8.8.8.111 web2 8.8.8.222
server { listen 80; server_name _; server_name_in_redirect off; port_in_redirect off; root /root/html; location / { set $upstream ""; rewrite_by_lua ' local routes = _G.routes -- setup routes cache if empty if routes == nil then routes = {} ngx.log(ngx.ALERT, "Route cache is empty.") end -- try cached route first local route = routes[ngx.var.http_host] if route == nil then local redis = require "redis" local client = redis.connect("localhost", 6379) route = client:get(ngx.var.http_host) end if route ~= nil then ngx.var.upstream = route routes[ngx.var.http_host] = route _G.routes = routes else ngx.exit(ngx.HTTP_NOT_FOUND) end '; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; proxy_connect_timeout 10; proxy_send_timeout 30; proxy_read_timeout 30; proxy_pass http://$upstream; } }
用lua 对cookie的控制
header_filter_by_lua ' t = {} if ngx.var.http_cookie then s = ngx.var.http_cookie for k, v in string.gmatch(s, "(%w+)=([%w%/%.=_-]+)") do t[k] = v end end p = ngx.req.get_uri_args() if not t.uid and p.uid then expires = ngx.cookie_time(4523969511) ngx.header["Set-Cookie"] = {"uid=" .. p.uid .."; expires=" .. expires .. "; end ';