评分 0, 满分 5 星
0 票

0.参加了北京2016 phpcon  大会,见到了鸟哥,韩天峰等大牛,php7性能提升 挺赞的

1.关注和学习ngx_lua,参加 深圳OpenRestyCon2016,收获很多,很有活力的社区,遗憾没能第二次见到春哥,在2015年在广州见过春哥
2. app接口一套 ,流量还较少,有个业务做了分表以及sql优化,有个业务上了https,其他都是运营活动需求,修了一堆bug
3.学习ngx_lua 做了总结笔记 ,写写案例,性能很赞 很喜欢
4.人生新篇章,结婚摆酒了,更加努力

评分 0, 满分 5 星
0 票
  1. http, 可以通过 init_by_lua 加载公共函数,比如 lua-resty-core.
  2. server selection,listen,server_name.
  3. post read, ngx_realip.
  4. server rewrite, set, rewrite, return, set_by_lua.
  5. server rewrite tail, rewrite_by_lua.
  6. server access, allow, deny.
  7. server access tail, access_by_lua.
  8. server try_files.
  9. location:
    1. prefix strings 遵循 最长子串匹配原则
    2. regular expressions 遵循 先定义优先匹配原则
    3. location = {exact_url} 精准匹配
    4. location ~ {case-sensitive regex} 区分大小写
    5. location ~* {case-insensitive regex} 不区分大小写
    6. location ^~ {prefix_string_if_any} 一旦字符匹配成功,就不再正则匹配
    7. 尽量不要 if,换用 try_files
    8. -f 检测文件是否存在,-d 目录,-e 文件/目录/符号链接,-x 可执行文件
  10. location rewrite, set, rewrite, return, set_by_lua.
  11. location rewrite tail, rewrite_by_lua.
  12. preaccess, degradation, limit_zone, limit req, ngx_realip.
  13. location access, allow, deny, auth_basic.
  14. location access tail, access_by_lua.
  15. content, ngx_echo, proxy_pass, content_by_lua.
    1. 请求具体处理阶段,只能有一个 内容处理程序(content handler)
    2. 多个 echo 可以共存,因为同属于 ngx_echo 模块,但 ngx_lua 限制只能有一个 content_by_lua.
    3. ngx_echo 的 echo_before_body/echo_after_body 可以和其他模块共存
    4. 如果没有 ngx_echo, proxy_pass, content_lua 这些 content handler,Nginx 会根据 URL 将请求映射到静态资源服务模块,依次是 ngx_index, ngx_autoindex, ngx_static.
    5. ngx_index/ngx_autoindex 处理以 / 结尾的请求,ngx_static 正好相反。
  16. output header filter, more_set_headers 输出 Headers.
  17. output filter echo_before_body, echo_after_body, body_filter_by_lua.
  18. log, access_log, error_log, log_by_lua.
  19. post action.

评分 0, 满分 5 星
0 票

ngx_lua:

  1. 快,和 nginx 简直绝配,尤其是分执行阶段进行操作
  2. 同步方式写异步非阻塞,相比 Node.js 回调,代码体验好
  3. 但还不够好,欠缺在开发效率,社区丰富程度,我们这些使用者也有责任
  4. Lua 语言非常棒,简单高效,但相较于其他语言这些年进步太慢
  5. LuaJIT 让性能爆表,但只兼容到 Lua 5.1,见过很多因为用错版本而引发错误。原开发者不再继续维护,转有 CloudFlare 接手,后续有一定不确定性 via
  6. nginScript 现在和 ngx_lua 完全没有可比性,未来很难说,毕竟有官方支持,加上 js 一统江湖的趋势
  7. nginx 本身主要处理 HTTP 业务,适用范围相对有限,不过现在有了 TCP Proxy,后面想象力也会很大。

Go:

  1. 静态语言
  2. 学院派看 Go 语言的设计有很多缺陷,但从工程的角度,简单,规范,标准库丰富
  3. 开发效率高,自测性能在 ngx_lua 70% 左右,大多数情况下完全够用
  4. goroutine + channel,同步方式写异步
  5. 方便的工具链,go fmt/doc/test/pprof
  6. 跨平台编译,单二进制文件,部署方便
  7. 虽然有 go get,但一开始没有原生包管理是很大的失败,现在社区已经分裂出 godep/govender/nut/gb/glide/gopkg.in 等等

 

 

评分 0, 满分 5 星
0 票

为了在 Lua 里处理可变参数,我们可能会写下面这样的代码:

local function args(...)
if next({...}) then
for _, v in ipairs{...} do
print(v)
end
else
print("empty var")
end
end

增强后的函数为:

local function args(...)
if next({...}) then
-- get the count of the params
for i = 1, select('#', ...) do
-- select the param
local param = select(i, ...)
print(param)
end
else
print("empty var")
end
end

args(10, nil, 30)

args(10, 20, 30)
咋一看,貌似没什么问题,但是当传入 args(10, nil, 30) 时,发现并不符合我们的预期。原因就在于 ipairs 遍历的 table 必须是一个序列。序列的数字索引必须连续。table 中间包括 nil,这样的 table 就不是序列,例如:a={10, nil, 30} 它不是序列,因为它的数字索引是 1 3 不是连续的, 所以它不是序列。为了处理这个问题,就要引入 select 了。

调用 select 时,需要传入一个 selector 和变长参数。如果 selector 为数字 n, 那么 select 返回它的第 n 个可变实参,否则只能为字符串 #, 这样 select 会返回变长参数的总数。

评分 0, 满分 5 星
0 票

export Foo=bar

env Foo;
...
location = /t {
content_by_lua_block { ngx.say(os.getenv("Foo")) }
}

评分 0, 满分 5 星
0 票

重点推荐

这里的看完,基本的概念和使用都会了。

PPT

视频

其他教程

https://github.com/torhve/LuaWeb

社区

资源集合

 
 
 

评分 0, 满分 5 星
0 票

做一个正确的性能测试并不容易,有不少需要注意的地方。下面是 Mio 的性能测试步骤,请大家参考指正。

系统设置

关闭 SELinux

如果你是 CentOS/RedHat 系列的操作系统,建议你关闭 SELinux,不然可能会遇到不少诡异的权限问题。

通过这个命令查看 SELinux 是否开启:

$ sestatus
SELinux status: disabled

如果是开启的,通过这个方法来临时关闭:

$ setenforce 0

同时修改 /etc/selinux/config 文件来永久关闭,将 SELINUX=enforcing 改为 SELINUX=disabled

最大打开文件数

$ cat /proc/sys/fs/file-nr
3984 0 3255296

第三个数字 3255296 就是当前系统的全局最大打开文件数。

如果你的机器中这个数字比较小,请修改为 100w 以上或者更多。 通过修改 /etc/sysctl.conf 文件来实现:

fs.file-max = 1020000
net.ipv4.ip_conntrack_max = 1020000
net.ipv4.netfilter.ip_conntrack_max = 1020000

需要重启系统服务来生效:

sudo sysctl -p /etc/sysctl.conf

进程限制

修改每一个进程可以打开文件数的限制,也就是 ulimit,这样子查看当前的限制:

$ ulimit -n
1024

临时修改的方法:

$ ulimit -n 1024000

永久修改,编辑 /etc/security/limits.conf, 增加:

* hard nofile 1024000
* soft nofile 1024000

星号代表的是所有用户。

测试是否支持到 C1000K

别着急,我们先用工具测试下,看我们这样子修改后,是否可以支持 C1000K。

这里有一个开源的工具,来自 SSDB 的作者:https://github.com/ideawu/c1000k

使用方法非常简单,启动一个服务端和客户端,来测试连接,具体见这个项目的说明。

修改 NGINX 参数

以上面的配置文件为例,有几个注意点:

  • 新增 OpenResty 的用户,这里取名为 nginx。这样可以保证基于 OpenResty 的程序不会干坏事儿,也不会被想干坏事儿的人利用。比如利用它来执行系统命令什么的。
  • NGINX 的工作进程设置为 4 个。我的测试环境是 24 核,我需要压测工具让每一个 NGINX 工作进程都跑满 CPU,所以我设置的并不高。在你的生成环境中,一般会设置为和 CPU 核数相同的值。
  • 设置 CPU 亲缘性,防止 CPU 资源使用不均衡。
  • 调整每个NGINX worker 的连接数限制。

    其中第二点和第三点,在 NGINX 1.9.10 以后的版本中可以自动完成,如下面所示:

    worker_processes auto;
    worker_cpu_affinity auto;

压测前的检查

压测前,你需要简单的用 curl 检查下 Mio的各个接口是否正常工作,比如:

curl -i http://127.0.0.1/hello
curl -i http://127.0.0.1:9090/status
curl -i http://127.0.0.1:9090/summary

不仅要看返回值,更要看 logs/error.log 是否有日志记录。

一般来说都是权限的问题。比如 NGINX 的用户没有代码目录的权限,你需要用 chown 来解决。特别注意的是,chmod 777这样的命令过于粗暴,也有安全隐患,最好不要使用。

有时候,你关闭了 SELinux,也通过 chown 设置了正确的用户,还是报错,提示权限问题。这个时候不要像无头苍蝇一样胡乱尝试,你应该:

su nginx

切换到这个用户下,试试具体的问题。有时候是因为某个代码目录 没有执行权限, 你需要 chmod +x 来解决。

比如 /root/Mio/gateway 目录,你可能有 /root/Mio 目录的执行权限,却没有 /root 目录的执行权限。你可以 chmod +x 来解决,也可以换到其他目录来解决。

开始测试

这里我们选用 wrk 来进行压力测试,我们的目的是要让 NGINX worker 满载,而简单的 ab 可能做不到这一点。

wrk -t50 -c100 -d60s http://127.0.0.1/hello

wrk 这几个参数含义是,使用 50 个线程,100 个 http 并发连接,持续 60 秒的压力测试。

在我的测试环境中(24 核,32G内存,4个 NGINX worker),单纯的hello 接口,压力测试结果是:

加入 Mio 的统计代码后,压力测试结果是:

性能下降了 33% 左右。注意这个是和空跑的逻辑做的对比,也就是最坏的情况。 如果加了业务逻辑,比如查询下数据库、做几次字符串操作,那么对性能的影响就很低了。

 

评分 0, 满分 5 星
0 票

 

评分 0, 满分 5 星
0 票

浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象。在lua里,自然就是table了。另外lua 没有传引用的概念,对于table或function或string等可以理解为拷贝了表的地址然后返回,并不会引起表的深拷贝。下面这段片段引用自luawiki: