lua是一个巴西人设计的小巧的脚本语言,它的设计目的是为了能够嵌入到应用程序中,从而为应用程序提供灵活的扩展和定制功能。

作为web开发工程师,我们平时主要使用的开发语言是php。这个语言提供了对html模版的强大的处理能力,也提供了十分丰富的函数库及扩展,非常的适合web开发使用。那么lua是如何进入到我们的视线中的呢?在这里我先说下我在开发一个web产品时,会优先考虑的几个问题:

如何保证服务的稳定性,即如何防止白屏、50x错误的发生。

如何提高页面的响应速度,即让用户感觉页面打开足够快。

那么在用php解决这几个问题时,是否够用呢?答案在我看来是否定的,为什么这么说呢?请听我分别道来:

php在处理服务稳定性时的不足

先简单说下由php导致的服务异常原因:

php语法错误、运行时的异常都会导致500错误,这在用户端浏览器就会显示出白屏。

在使用nginx + php-cgi这种组合提供动态web服务时,当后台cgi进程挂掉或数量不够用时,即会产生502错误;当php执行时遭遇阻塞(如连db时,db压力过大),而在nginx中配置的超时时间到达后,通常会产生504错误。

这几种异常本身都是由于php导致的,当然不能靠php去解决。

webserver如nginx提供了如error_page这种用于处理当服务产生异常时的后续处理机制,为了不让用户看到白屏或错误页面,我们可以定时对正常服务时的页面做一个快照,当遇到服务异常时,就给用户这个历史快照看。

但这样做也有个局限性:当你提供服务的页面很多时,又或是需要根据请求的参数做一些逻辑上的处理时,显然就很难做到了。

你也许会说,我可以写nginx配置,让它分析请求参数,再做相应的逻辑处理。但是这样做的话,想想看你的nginx配置会有多么的复杂,多么的难以维护,而且就算你这样做,也不能解决所有的问题。比如说我有个接口要输出json字符串,或是其它别的格式,你总不能说我再去写个nginx扩展让它支持json吧。

所以,在提高服务的稳定性方面,我们的需求是:

能用到webserver提供的错误处理机制。

能方便的处理请求参数,做需要的逻辑处理。

php在提高用户响应速度方面的不足

php是一个阻塞式顺序执行的脚本语言,虽然支持多进程执行,但这种模式并不适合使用在并发量很高的web服务中。

想像如果一个请求的处理过程中,你需要调用到多处外部资源或服务(db、rest接口),那么你的处理速度就要依赖于这些外部服务,而且是一个一个顺序处理的,它们越多,处理就越慢。

php的multi_curl可以用来并发请求这些外部的rest服务,但这样做的话,依旧需要等全部的请求都处理完成,才能返回给用户。换句话说,如果某个外部服务很慢,那么用户看到页面打开依旧会很慢。

也可以选择把页面分块,让慢的部分用js异步请求加载。但这样做的话,会增加服务器的访问量,每增加一块,访问量会增大一倍。

所以,在提高页面的响应速度方面,我们的需求是:

耗时慢的服务能够做到异步加载,服务端每完成一部分的计算,就让页面展示这部分。

不能过大的增加服务器的压力。

nginx-lua模块

最终,我们找到了nginx-lua?模块。这个模块会在每个nginx的worker_process中启动一个lua解释器,在nginx处理http请求的11个阶段中,你可以在其中的多个阶段用lua代码处理请求。

这二者的结合,给我们的web开发带来了新的思路。下面我就来说下导航目前是如何使用它来解决问题的。

解决服务稳定性

这里的思路很简单,我们会在error_page指令被执行后,用lua代码来接受参数,处理逻辑部分,最终会返回前端和用php处理看起来一致的内容。部分代码如下:

nginx_conf:

location ~* ^/api/.+/.+$ {

error_page 500 502 503 504 =200 @jump_to_error_page_api;

rewrite ^/api/(.+)/(.+)$ /index.php?_c=$1&_a=$2 break;

root /home/ligang/demo/src/api/;

fastcgi_pass 127.0.0.1:9000;

include fastcgi.conf;

fastcgi_connect_timeout 5s;

fastcgi_send_timeout 5s;

fastcgi_read_timeout 5s;

fastcgi_intercept_errors on;

}

location @jump_to_error_page_api {

lua_code_cache on;

set $prj_home " /home/ligang/demo";

content_by_lua_file /home/ligang/demo/src/glue/error_page_api.lua;

}

这里大家看到,当请求出现50x错误时,会跳到location jump_to_error_page_api中,在这里面,content_by_lua_file指令会在content处理阶段启动指定好的lua脚本(这里是error_page_api.lua)来处理请求。我们再看下lua脚本中都做了什么:

lua示例代码:

ngx.header['Content-Type'] = 'text/html'

prj_home = ngx.var.prj_home

request_args = ngx.req.get_uri_args()

local controller = request_args['_c']

local action = request_args['_a']

if 'demo' == controller

then

processErrorPageApiDemo(action)

else

ngx.print('invalid controller')

end

......

这里大家可以看到,我们可以在lua脚本中接受请求参数,做和php一样的逻辑,最终输出前端需要的正确的内容。

目前这套机制我们已经用在我们这边的一个重要用户页面上,目前都没有收到用户反馈说页面打不开,出现错误页这种,效果很是明显。

提高用户页面的响应速度

上面提到的解决响应速度的几个需求,我们的思路是引入bigpipe的处理机制。关于bigpipe本文不做讲解,大家可以自行google。这个项目目前尚处于实验阶段,但我们已经实现了一个简单的demo:

nginx_conf:

location = /index.php {

content_by_lua_file /home/ligang/demo/src/glue/bigpipe_index.lua;

}

这里指定请求index.php会用bigpipe_index.lua处理。

lua代码:

-- for header

ngx.header.content_type = 'text/html';

ngx.say("

Test Bigpipe")

ngx.flush()

local capture = ngx.location.capture

local spawn = ngx.thread.spawn

local wait = ngx.thread.wait

local say = ngx.say

local function section_top()--{{{

ngx.say("

this is top section.

")

ngx.flush()

end--}}}

local function section_php(sleep) --{{{

local res = ngx.location.capture("/content.php?sleep="..sleep)

ngx.say(res.body)

ngx.flush()

end--}}}

-- for body

local threads = {

spawn(section_top), --这里处理没有延迟

spawn(section_php, "1"), --这里的处理逻辑会sleep1秒

spawn(section_php, "5"), --这里的处理逻辑会sleep4秒

}

for i=1, #threads do

ngx.say("

before wait

")

wait(threads[i])

end

ngx.say("

all contents are loaded

")

ngx.say("")

......

这里在处理请求时,大致逻辑如下:

首先会先吐出首屏html部分及部分html框架代码。

接下来会启动3个lua协程,在nginx-lua这个模块的调度下以异步非阻塞的模式并发的来处理3个外部请求。

这3个外部请求各自的延时不同,但是任何一部分处理完成,都会直接返回给前端用于展示。

通过这种方式,用户的页面响应速度得到了明显的提高,体验更好。

结束语

正如lua官方给出的定义所说,lua很小巧,非常的适合嵌入已有的应用程序中,从而补足现有系统的一些缺憾,并扩展出新的功能。对nginx-lua模块的使用,笔者也还在研究中,但我相信更好的使用它,能为我们现有的web开发打开一扇新的窗户,理解更深层次的知识。

参考资料

听我说完这些你有没有心动想用用看?那么在最后附上相关参考资料:

lua能解决php什么问题,我们能用lua做什么相关推荐

  1. Lua封装C++实践(二)—— C++调用Lua函数的封装

    在上篇博客中,记录了Lua与C/C++的基本交互,但是如果按照那样来使用的话,实在太麻烦了,所以我们开始进行封装.本篇博客主要记录C++调用Lua函数的封装. 封装目标 C++调用Lua,复杂的地方主 ...

  2. 记录:tolua错误之LuaException: cannot open tolua.lua: No such file or directory no file ‘./tolua.lua‘解决方案

    LuaException: cannot open tolua.lua: No such file or directory no file './tolua.lua' no file 'E:/uni ...

  3. 【Lua运行时热重载功能实现①】检测Lua文件发生变化

    这几天由于项目组需要一直在琢磨一个功能,就是如何在unity编辑器下不需要重启游戏就能让lua文件改动后立刻生效.如果能够实现这个功能,那会大幅提高开发效率.查了一圈,网上的结果都不太满意,要么只有理 ...

  4. Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解

    这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...

  5. Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本

    Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本 首先参考http://wiki.chumby.com/index.php?title=Lua&print ...

  6. lua ue_slua unreal分析(二)LuaActor与lua表互访

    相关文章: 南京周润发:slua unreal分析(一)LuaActor概览​zhuanlan.zhihu.com 南京周润发:slua unreal分析( 三)slua与GC​zhuanlan.zh ...

  7. ubuntu/wireshark --Lua: Error during loading: [string /usr/share/wireshark/init.lua]:45问题解决

    错误如下: 解决方案:修改init.lua 直接运行wireshark的话会报错: Lua: Error during loading: [string "/usr/share/wiresh ...

  8. lua打开浏览器并加载网页_使用Lua做Web开发

    Lua应用程序与框架 WSAPI 从Lua Web应用程序抽象Web主机服务器的API Xavante 提供WSAPI接口的Lua Web服务器 Orbit Orbit是Lua的MVC Web框架,完 ...

  9. lua游戏代码_在游戏中如何使用LUA脚本语言

    当你希望在你的游戏开始的时候读取一些信息,以配置你的游戏,这些信息通常都是放到一个文本文件中,在你的游戏启动的时候,你需要打开这个文件,然后解析字符串,找到所需要的信息. 或许你认为这样就足够了,为什 ...

  10. 【木头Cocos2d-x 026】Lua篇(第01章):让Lua和C++牵手

    [木头Cocos2d-x 026]Lua篇(第01章):让Lua和C++牵手 网上关于Lua的教程似乎还没有泛滥,最近刚好学习在Cocos2d-x使用Lua,当然了,我是写教程狂,我会分享我的学习心得 ...

最新文章

  1. 最烦人的正则表达式记忆口诀
  2. c++ 把数字和中文字符分开_C语言中的字符常量与变量
  3. SendKeys中特殊字符的键代码
  4. VTK:PolyData之TransformFilter
  5. linux下iptables讲解
  6. 列表嵌套字典,根据字典某一key排序
  7. Lecture 3 Divide and Conquer
  8. nodejs 获取内存,网络 ,连接 ,磁盘等等
  9. 基于JAVA+Servlet+JSP+MYSQL的学生选课系统
  10. WinAPI: SetTextJustification - 设置两端对齐
  11. 修改Eclipse的WorkSpace保持数[转载]
  12. SPOJ SUBST1 New Distinct Substrings(后缀数组 本质不同子串个数)题解
  13. 阿里最新分享Redis全套学习笔记PDF版,图文并茂,太详细了
  14. 安装informatic过程中的错误
  15. 本地组策略编辑器计算机配置,打开本地组策略编辑器|没有本地组策略编辑器...
  16. c语言速算24课程设计,C语言速算24数据结构课程设计.doc
  17. 安徽省淮南市谷歌卫星地图下载
  18. 编写程序,生成一种贯穿10*10字符数组(初始时全为字符'.')的“随机步法”。程序必须随机地从一个元素“走到”另一个元素,每次都向上、向下、向左或向右移动一个元素位置
  19. Linux下批量把GDK编码的文章转化为UTF-8编码的文章以及“iconv: 未知 xxx 处的非法输入序列”错误处理
  20. 数据库课程设计——学生信息管理系统

热门文章

  1. 计算机考研需要过英语六级吗,研究生毕业要过英语六级吗 研究生毕业对英语六级有要求吗...
  2. Effective Modern C++笔记汇总
  3. 计算机网络中rtd,一文了解Modern Standby与RTD3
  4. 网卡,交换机和路由器
  5. [openwrt] ubus实现进程间通信举例
  6. HCNE复习参考(上)
  7. 使用FlashPaper在线转换.doc为.swf
  8. DNS服务器常见的攻击方式
  9. PHP面试技巧——如何准备电话面试?
  10. 耐克官网一直显示无法连接服务器,nikeapp无法连接服务器是什么原因 nikeapp怎么抢鞋子...