OpenResty实现缓存前移

OpenResty

简介

OpenResty 是一个nginx和它的各种三方模块的一个打包而成的软件平台。最重要的一点是它将lua/luajit打包了进来,使得我们可以使用lua脚本来进行web的开发。有了lua,我们可以借助于nginx的异步非阻塞的功能,达到使用 lua 异步并发访问后端的 MySQL, PostgreSQL, Memcached, Redis等等服务。特别是特有的 ngx.location.capture_multi 功能让人印象深刻,其可以达到极大的减少浏览器的http连接数量,并且可以异步并发的访问后台 Java/PHP/Python 等等接口。OpenResty 架构的web可以轻松超越Node.js的性能,并且对后端语言没有限制,你可以使用Java/PHP/Python等等各种语言。OpenResty(nginx+lua)可以替代node.js的前端渲染的功能。
Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中,实现了 OpenResty 这个高性能服务端解决方案。

OpenResty运行原理

Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。在OpenResty中,每个 woker 使用一个 LuaVM,当请求被分配到 woker 时,将在这个 LuaVM 里创建一个 coroutine(协程)。协程之间数据隔离,每个协程具有独立的全局变量_G。

协程(Coroutine)

协程类似一种多线程,与多线程的区别有: 

1. 协程并非os线程,所以创建、切换开销比线程相对要小。 

2. 协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。

3. 多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。 

4. 由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。 

5. 多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。 

Nginx的每个Worker进程都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力。

Lua

简介
Lua 是一个小巧的脚本语言。作者是巴西人。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
特点
1: Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,Ini等文件格式,并且更容易理解和维护。
2: Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

实验操作

安装OpenResty

1:本实验是为了与上篇博客中的实验做对比,基于上边的实验:PHP—memcache
2:关闭之前的nginx服务,因为我们要安装可以代替普通nginx的openresty
nginx -s stop
3:下载opneresty-1.13.6.1.tar.gz
tar zxf opneresty-1.13.6.1.tar.gz
cd opneresty-1.13.6.1
在这里插入图片描述
4:源码编译安装(三部曲)
(1):./configure --prefix=/usr/local/openresty --with-http_ssl_module --with-http_stub_status_module --user=nginx --group=nginx --with-threads --with-file-aio
在这里插入图片描述
(2):gmake
在这里插入图片描述
(3):gmake install
在这里插入图片描述

相关配置

1:cd /usr/local/openresty/nginx/conf/
vim nginx.conf
修改后的文件内容如下:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  65535;       #
}


http {
    upstream memcache {
    server localhost:11211;
    keepalive 512;
        }
#upstream属于handler,只是他不产生自己的内容,而是通过请求后端服务器得到内容,所以才称为upstream(上游)。请求并取得响应内容的整个过
#程已经被封装到nginx内部,所以upstream模块只需要开发若干回调函数,完成构造请求和解析响应等具体的工作。
# nginx将memcache缓存前移,客户端请求到来,先查看memcache缓存
    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;

    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 / {
            root   html;
            index  index.php index.html index.htm;
        }

        location /memc {
        internal;
        memc_connect_timeout 100ms;
        memc_send_timeout 100ms;
        memc_read_timeout 100ms;
        set $memc_key $query_string;
        set $memc_exptime 300;
        memc_pass memcache;
        }
#所有请求都通过请求这个location来操作 memcache,memc-nginx-module存取memcache是基于http method语义的,
#使用http的GET方法表示get、PUT方法表示set、这里我们将/memc设为internal表示只接受内部访问
#不接收外部http请求,这是为了安全考虑,当然如果需要通过http协议开放外部访问,可以去掉internal然后使用deny和allow指令控制权限。比较重要的是memckey这个变量,它表示以什么作为key,
#这里我们直接使用Nginx内置的query_string来作为key,$memc_exptime表示缓存失效时间,以秒记。
#这里统一设为300(5分钟),在实际应用中可以根据具体情况为不同的内容设置不同的过期时间。
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            set $key   $uri$args;
            srcache_fetch GET /memc $key;
            srcache_store PUT /memc $key;
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
        }
#为“~ \.php$”这个location配置了缓存,这表示所有以“.php”结尾的请求都会结果被缓存,当然这里只是示例需要,实际中一般不会这么配,而是为特定需要缓存的location配置缓存

#后面的内容不用修改

2:检测语法错误,因为是重新编译的,所以需要使用绝对路径,与之前的nginx区别开
/usr/local/openresty/nginx/sbin/nginx -t
/usr/local/openresty/nginx/sbin/nginx ##打开
在这里插入图片描述
3:将之前nginx默认发布目录中的.php文件复制到现在重新编译的nginx(openresty)的默认发布目录中
cd /usr/local/openresty/nginx/html/
cp /usr/local/nginx/html/example.php .
cp /usr/local/nginx/html/index.php .
在这里插入图片描述

测试

本次测试结果与上一篇博客最后的测试结果进行对比
1:本次实验测试:
在真机中
ab -c 10 -n 1000 http://172.25.66.1/example.php
在这里插入图片描述
查看处理情况,从下图可以看出,本次处理是由openresty服务所处理的
在这里插入图片描述
从图中可以看出,openresty服务所处理的1000次web请求,失败0个,错误0个,每秒钟处理次数为8700次
2:我们再来看看上篇博客中使用nginx服务处理同样为1000次请求的结果
在这里插入图片描述
可以看到nginx服务处理1000次请求,虽然同样是失败0次错误0次,但是它每秒只能处理1874次请求,所以,明显可以看出,openresty服务在web应用上的性能远远高于nginx,可以达到nginx的三四倍!!!

猜你喜欢

转载自blog.csdn.net/gd0306/article/details/84636651