高并发环境搭建nginx+lua+redis

 

高并发环境搭建nginx+lua+redis

 

一、安装环境 2

1.1、安装Lua解释器 2

1.2、安装nginx 2

1.2.1、下载nginx开发插件ngx_devel_kit 2

1.2.2、下载nginx的lua模块lua-nginx-module 2

1.2.3、安装nginx 2

1.3、安装redis 3

1.3.1、redis下载安装 3

1.3.2、安装lua-resty-redis 4

1.3.3、连接redis连接池 4

1.4、整合运行 6

1.4.1、修改nginx配置文件 6

1.4.2、编写lua执行脚本 6

二、高并发优化 7

2.1调整文件访问数量相关参数 7

2.2调整Socket连接相关参数 7

三、压力测试 9

3.1压力测试工具 9

3.2测试效果 9

 

 

一、安装环境

1.1、安装Lua解释器

cd /usr/local/src

wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz

tar  -xvf   LuaJIT-2.0.2.tar.gz

cd  LuaJIT-2.0.2

make && make install

 

默认lib 以及驱动文件路径是/usr/local/lib 和  /usr/local/include/luajit-2.0

export LUAJIT_LIB=/usr/local/lib

export LUAJIT_INC=/usr/local/include/luajit-2.0

 

1.2、安装nginx

1.2.1、下载nginx开发插件ngx_devel_kit

cd /usr/local/src

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz

tar  -xvf   v0.3.0.tar.gz    **包名好奇怪

 

1.2.2、下载nginx的lua模块lua-nginx-module

cd /usr/local/src

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz

tar  -xvf   v0.10.9rc7.tar.gz     **包名。。。

1.2.3、安装nginx

cd /usr/local/src

wget http://nginx.org/download/nginx-1.12.1.tar.gz 

tar  -xvf  nginx-1.12.1.tar.gz

cd nginx-1.12.1

 

 

./configure --prefix=/usr/local/nginx \

--with-http_ssl_module   \

--with-pcre=/usr/local/src/pcre-8.40 \

--with-zlib=/usr/local/src/zlib-1.2.11 \

--with-openssl=/usr/local/src/openssl-1.0.2l \

--with-http_stub_status_module \

--add-module=/usr/local/src/ngx_devel_kit-0.3.0 \

--add-module=/usr/local/src/lua-nginx-module-0.10.9rc7   

 

make && make install

 

其中http_stub_status_module 是状态监控模块

安装nginx之前确保已经安装依赖包openssl、zlib、pcre下载解压到相应位置

 

如果提示下面错误,应该是 lua-nginx-module和OpenSSL 1.1.0不兼容,换成OpenSSL 1.0.2就好了,

/usr/local/src/lua-nginx-module-0.10.10/src/ngx_http_lua_module.c:1022:37: error: passing argument 2 of ‘SSL_CTX_sess_set_get_cb’ from incompatible pointer type [-Werror]

 

运行nginx

/usr/local/nginx/sbin/nginx

如果提示下面错误,表示找不到libluajit-5.1.so.2库

error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory

解决方法:

ln -s  /usr/local/lib/libluajit-5.1.so.2  /lib64/libluajit-5.1.so.2

 

1.3、安装redis

1.3.1、redis下载安装

cd /usr/local/src

wget http://download.redis.io/releases/redis-4.0.1.tar.gz

tar xzf redis-4.0.1.tar.gz

cd redis-4.0.1

make

 

编译完成后,在src目录下,有四个文件redis-server、redis-benchmark、redis-cli和redis.conf,然后拷贝到一个目录下。

 

mkdir /usr/local/redis

cp /usr/local/src/redis-4.0.1/src/redis-server /usr/local/redis

cp /usr/local/src/redis-4.0.1/src/redis-benchmark /usr/local/redis

cp /usr/local/src/redis-4.0.1/src/redis-cli /usr/local/redis

cp /usr/local/src/redis-4.0.1/redis.conf /usr/local/redis

 

设置密码

修改redis.conf,将# requirepass foobared前面的#号去掉并设置密码;

启动redis服务端

    /usr/local/redis/redis-server  redis.conf &

加&表示后台启动

启动redis客户端

    /usr/local/redis/redis-cli  -h 127.0.0.1  -p 6379   -a yourpassword

 

1.3.2、安装lua-resty-redis

从https://github.com/openresty/lua-resty-redis.git下载lua-resty-redis-master后解压

将lib包安装到lua库

cd /usr/local/src/lua-resty-redis-master

make && make install

安装完成之后在/usr/local/lib/lua/resty里面会有redis.lua

 

1.3.3、连接redis连接池

在/usr/local/lib/lua添加redisUtil.lua,代码如下

 

local redis = require "resty/redis"

 

local log = ngx.log

local ERR = ngx.ERR

local setmetatable = setmetatable

 

local _M = {

 

}

 

local mt = { __index = _M }

 

local function errlog(...)

    log(ERR, "Redis: ", ...)

end

 

function _M.exec(self, func)

 

    local red = redis:new()

    red:set_timeout(self.timeout)

 

    local ok, err = red:connect(self.host, self.port)

    if not ok then

        errlog("Cannot connect, host: " .. self.host .. ", port: " .. self.port)

        return nil, err

    end

 

    if self.password ~= '' then

         -- 请注意这里 auth 的调用过程

            local count

            count, err = red:get_reused_times()

            if 0 == count then

                ok, err = red:auth(self.password)

                if not ok then

                    ngx.say("failed to auth: ", err)

                    return

                end

           elseif err then

                ngx.say("failed to get reused times: ", err)

                return

          end

    end

 

    red:select(self.database)

 

    local res, err = func(red)

    if res then

        local ok, err = red:set_keepalive(self.max_idle_time, self.pool_size)

        if not ok then

            red:close()

        end

    end

    return res, err

end

 

function _M.new(opts)

    local config = opts or {}

    local self = {

        host = config.host or "127.0.0.1",

    password = config.password or '',

        port = config.port or 6379,

        timeout = config.timeout or 5000,

        database = config.database or 0,

        max_idle_time = config.max_idle_time or 60000,

        pool_size = config.pool_size or 1000

    }

    return setmetatable(self, mt)

end

 

return _M

 

1.4、整合运行

1.4.1、修改nginx配置文件

http内添加 lua_package_path "/usr/local/lib/lua/?.lua";

 

server 内添加

location /lua/test {

    default_type 'text/plain';

    content_by_lua_file conf/lua/redisController.lua;

}

1.4.2、编写lua执行脚本

在/usr/local/nginx/conf/lua添加redisController.lua,代码如下

 

local redisUtil = require "redisUtil"

local red = redisUtil.new({host = "127.0.0.1",password="yourpassword"})

local res, err = red:exec(

    function(red)

        return red:get("key1")

    end

)

ngx.say(res);

 

测试效果

curl http://127.0.0.1/lua/test

返回结果:

    helloworld   

**测试之前先往redis里set数据set key1 helloworld

 

二、高并发优化

2.1调整文件访问数量相关参数

修改操作系统参数

    ulimit -n 50000

修改nginx.conf

    worker_rlimit_nofile 50000;             #每个子进程允许打开的文件数

 

2.2调整Socket连接相关参数

修改操作系统参数

vi /etc/sysctl.conf 新增或者修改

net.core.somaxconn = 50000     #最大连接:somaxconn

net.ipv4.tcp_tw_recycle = 1      #加快tcp回收

net.ipv4.tcp_tw_reuse = 1        #空tcp回收

net.ipv4.tcp_syncookies = 0      #去除洪水攻击抵御

让sysctl.conf生效

sysctl -p

修改nginx.conf

worker_connections 50000             #每个子进程允许打开的连接数

keepalive_timeout 0                   #连接的保持时间

 

优化完成后的nginx.conf文件如下

 

#user  nobody;

worker_processes  1;

worker_rlimit_nofile 50000;

 

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

 

#pid        logs/nginx.pid;

 

events {

    worker_connections  50000;

}

 

http {

    include       mime.types;

    default_type  application/octet-stream;

 

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';

 

    #access_log  logs/access.log  main;

 

    lua_package_path "/usr/local/lib/lua/?.lua";

    sendfile        on;

    #tcp_nopush     on;

 

    keepalive_timeout  0;

    #keepalive_timeout  65;

 

    #gzip  on;

 

    server {

        listen       80;

        server_name  localhost;

 

        #charset koi8-r;

 

        #access_log  logs/host.access.log  main;

 

        

        location /lua/get/test {

            default_type 'text/plain';

            content_by_lua_file conf/lua/redisController.lua;

        }

 

location /status {

            stub_status on;

            access_log   off;

        }

 

 

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

    }

}

三、压力测试

3.1压力测试工具

apache,自带ab工具;

也可以独立安装:

ab运行需要依赖apr-util包,安装命令为: 

yum install apr-util 

安装ab

cd /usr/local

mkdir ab

cd ab

yum install yum-utils.noarch

yumdownloader httpd-tools*

rpm2cpio httpd-*.rpm | cpio -idmv

解开后就能得到独立的 ab可执行文件了。

操作完成后 将会产生一个 usr 目录 ab工具就在这个usr 目录下的bin目录中

3.2测试效果

发生20万个请求,并发20000

/usr/local/ab/usr/bin/ab -n 200000 -c 20000 http://127.0.0.1/lua/test

测试结果:

Server Software:        nginx/1.12.1

Server Hostname:        127.0.0.1

Server Port:            80

 

Document Path:          /lua/test

Document Length:        6 bytes

 

Concurrency Level:      20000

Time taken for tests:   23.136 seconds

Complete requests:      200000

Failed requests:        0

Write errors:           0

Total transferred:      29600000 bytes

HTML transferred:       1200000 bytes

Requests per second:    8644.45 [#/sec] (mean)

Time per request:       2313.624 [ms] (mean)

Time per request:       0.116 [ms] (mean, across all concurrent requests)

Transfer rate:          1249.39 [Kbytes/sec] received

 

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        0  537 1687.5      2   15048

Processing:    16   69 192.4     43    6447

Waiting:        1   67 192.4     41    6445

Total:         18  605 1713.2     46   15898

 

Percentage of the requests served within a certain time (ms)

  50%     46

  66%     48

  75%     52

  80%   1046

  90%   1240

  95%   3060

  98%   7063

  99%   7077

 100%  15898 (longest request)

 

 

出错请求为0

90%的请求在1.3秒内完成

 

 

 

 

 

 

你可能感兴趣的:(nginx)