OpenResty搭建

作者: 懒眉 | 来源:发表于2019-03-15 16:06 被阅读157次

    OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。


    下载安装

    以下操作指令摘抄自OpenResty官网,不做赘述。

    sudo yum -y install yum-utils
    sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
    sudo yum -y install openresty
    sudo yum -y install openresty-resty
    

    安装完成之后,我们进入OpenResty所在目录

    cd /usr/local/openresty
    ll
    
    测试用例
    • 创建测试用lua文件
    cd /usr/local/openresty/lualib
    mkdir test
    cd test
    vim test.lua
    
    --用于接收前端数据的对象
    local args=nil
    --获取前端的请求方式 并获取传递的参数   
    local request_method = ngx.var.request_method
    --判断是get请求还是post请求并分别拿出相应的数据
    if"GET" == request_method then
            args = ngx.req.get_uri_args()
    elseif "POST" == request_method then
            ngx.req.read_body()
            args = ngx.req.get_post_args()
            --兼容请求使用post请求,但是传参以get方式传造成的无法获取到数据的bug
            if (args == nil or args.data == null) then
                    args = ngx.req.get_uri_args()
            end
    end
    
    --获取前端传递的name值
    local name = args.name
    --响应前端
    ngx.say("linux hello:"..name)
    
    • 配置nginx
      openresty内置nginx,使用openresty需要使用它内部的nginx。
    cd /usr/local/openresty/nginx/conf
    vim nginx.conf
    
    

    最终测试配置为

    #user  nobody;
    worker_processes  2;
    events {
      use epoll;
        worker_connections 150000;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        gzip  on;
        server {
            listen       80;
            server_name  localhost;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
            location / {
                root   html;
                index  index.html index.htm;
            }
            location /luatest
            {
                default_type text/html;
                content_by_lua_file /usr/local/openresty/lualib/test/test.lua;
            }       
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    }
    
    AB压力测试
    安装httpd-tools
    yum -y install httpd-tools
    

    试一把1w并发,10w请求


    提示Too many open files (24)打开的文件太多了
    查看允许打开的文件数
    ulimit -a
    修改允许打开的文件数
    ulimit -n 204800
    

    继续试1w并发,10w请求,出现apr_socket_recv: Connection reset by peer (104)问题

    apr_socket_recv这个是操作系统内核的一个参数,在高并发的情况下,内核会认为系统受到了SYN flood(一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式)攻击,导致未完成退出测试,所以在应用服务武器上设置下这个参数为0禁用系统保护
    进入管理配置文件
    vim /etc/sysctl.conf 
    #添加如下一行
    net.ipv4.tcp_syncookies = 0
    #保存退出后执行
    sysctl -p
    
    扩展(未测试)
    net.ipv4.tcp_syncookies = 0  
    #此参数是为了防止洪水攻击的,但对于大并发系统,要禁用此设置
    net.ipv4.tcp_max_syn_backlog
    #参数决定了SYN_RECV状态队列的数量,一般默认值为512或者1024,即超过这个数量,系统将不再接受新的TCP连接请求,一定程度上可以防止系统资源耗尽。可根据情况增加该值以接受更多的连接请求。
    net.ipv4.tcp_tw_recycle
    #参数决定是否加速TIME_WAIT的sockets的回收,默认为0。
    net.ipv4.tcp_tw_reuse
    #参数决定是否可将TIME_WAIT状态的sockets用于新的TCP连接,默认为0。
    net.ipv4.tcp_max_tw_buckets
    
    

    好了,现在可以正常测试了

    • 1w并发10w请求
    ab -c 10000 -n 100000 127.0.0.1/luatest
    

    结果:

    #服务器信息,ip,端口
    Server Software:        openresty/1.13.6.2
    Server Hostname:        127.0.0.1
    Server Port:            80
    #文档/接口,响应数据大小
    Document Path:          /luatest
    Document Length:        541 bytes
    #压力测试的结果报表
    #并发请求数
    Concurrency Level:      10000
    #测试耗时
    Time taken for tests:   11.361 seconds
    #完成请求数
    Complete requests:      100000
    #失败请求数
    Failed requests:        9
       (Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
    Write errors:           0
    Non-2xx responses:      100000
    #总网络传输量
    Total transferred:      73096724 bytes
    #HTML内容传输量
    HTML transferred:       54096922 bytes
    #吞吐量,平均每秒处理请求数
    Requests per second:    8801.77 [#/sec] (mean)
    #前端请求平均时间
    Time per request:       1136.135 [ms] (mean)
    #服务平均处理请求的时间
    Time per request:       0.114 [ms] (mean, across all concurrent requests)
    #网络传输速度。对于大文件的请求测试,这个值很容易成为系统瓶颈所在。
    Transfer rate:          6283.01 [Kbytes/sec] received
    #时间消耗报表针对请求平均等待时间`Time per request`的细化分析,只是了解
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0  304 884.1     14    7055
    Processing:     3   35  65.5     23   11029
    Waiting:        0   29  63.4     18   11029
    Total:          6  339 902.2     36   11226
    #请求时间分布,50%的请求在36毫秒内处理完毕。90%的请求在1077毫秒内处理完毕,最长响应时间为11226毫秒
    Percentage of the requests served within a certain time (ms)
      50%     36
      66%     61
      75%    101
      80%    171
      90%   1077
      95%   1197
      98%   3160
      99%   3235
     100%  11226 (longest request)
    
    

    提取部分参数稍微总结下:
    吞吐量(每秒处理的请求数):8801.77
    验证:吞吐量(8801.77) * 测试耗时 (11.361) 约等于10W
    用户平均等待时间:1136.135
    服务器平均处理时间:0.114
    验证:由于服务器并发量为1W,那用户前端响应时间,应该接近服务器平均处理时间 * 1w,0.114*10000=1140,1136.135约等于1140
    90%的请求在1077ms内完成,最长的请求耗时11226毫秒。
    网络传输速度:6283.01kb

    • 2w并发10w请求
    ab -c 20000 -n 100000 127.0.0.1/luatest
    

    这里简单分析标出重要数据


    image.png
    总结

    这里主要测试openresty(实际上是nginx)平台的并发能力,用于测试的电脑,为2核4G的笔记本,2W的并发没有什么压力,可惜AB测试有上限,不太方便做极限测试。
    简单来说,OpenResty提供了一种Nginx处理请求,lua脚本处理逻辑(操作MySQL,Redis等)的一种平台响应模式。我们知道Lua 是一种轻量小巧的脚本语言,用标准C语言编写。它的执行效率无疑比java高的多。
    特点

    1. 充分利用Nginx的并发能力和lua的执行效率,分担了Tomcat等Web应用服务器的压力。
    2. lua属于脚本语言,更新版本只需要更新修改Lua脚本之后,重启Nginx即可完成更新发布。
    3. 不适合开发复杂业务逻辑
      适用
    4. 高并发,高频率调用的,并且主要目的用于获取数据的接口适用lua编写(比如首页的展示数据)。
    5. 请求过滤拦截(商城秒杀,商品完了之后的请求拦截)

    参考

    OpenResty®
    Apache ab性能测试结果分析

    相关文章

      网友评论

        本文标题:OpenResty搭建

        本文链接:https://www.haomeiwen.com/subject/lxdlmqtx.html