zoukankan      html  css  js  c++  java
  • 浅谈 OpenResty

    一.前言

    我们都知道Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。为了开发人员方便,所以接下来我们要介绍一种整合了Nginx和lua的框架,那就是OpenResty,它帮我们实现了可以用lua的规范开发,实现各种业务,并且帮我们弄清楚各个模块的编译顺序。关于OpenResty,我想大家应该不再陌生,随着系统架构的不断升级、优化,OpenResty在被广泛的应用。

    二.OpenResty运行原理

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

    ps. 协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过代码来完成协程的切换,任何时刻只有一个协程程序在运行。并且这个在运行的协程只有明确被要求挂起时才会被挂起。

    原理图如下:

    三.OpenResty的优势

    首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。

    借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。

    而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒杀、动态服务、单品页、列表页等都在使用Nginx+Lua架构,其他公司如淘宝、去哪儿网等。

    四.Nginx和lua的简介

    1. Nginx:

    (1) Nginx的优点

    • 轻量级同样起web 服务比apache占用更少内存及资源 

    • 抗并发nginx 处理请求异步非阻塞而apache 则阻塞型高并发下nginx 能保持低资源低消耗高性能 

    • 高度模块化设计编写模块相对简单 

    • 社区活跃各种高性能模块出品迅速啊

    (2) Nginx为什么性能高,占用内存少

    众所周知,nginx性能高,而nginx的高性能与其架构是分不开的。在这里,我们简单粗略的介绍一下nginx的架构。

    • 首先,nginx采用的是多进程模式,好处是什么呢?首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低风险。

    • Nginx是采用异步非阻塞的方式去处理请求的,什么是异步非阻塞呢?其实就是当一个线程调用出现等待的io之类的情况时,而不是阻塞在这里,而是去处理别的事情,等io准备好了,然后再去执行,具体的我就不在这里和大家描述了。

    2. lua:

    (1) Lua 是一个小巧的脚本语言。作者是巴西人。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能

    (2) Lua的特点:

    • Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,Ini等文件格式,并且更容易理解和维护。

    • Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

    五.OpenResty的安装

    上面我门对OpenResty进行了简单的介绍,运行原理的说明,还有Nginx、Lua优点的介绍,是为了更好的让大家理解。让大家知道用这个的好处,接下来我简单的介绍一下OpenResty的安装和搭建一个简单的限流的例子,这是为了让大家明白,除了上面说的好处,它到底能够做什么。

    OpenResty的安装:

    (1) 需要事先安装一下所需的插件

    1
    yum install readline-devel pcre-devel openssl-devel

    (2) 下载ngx_openresty-1.7.7.2.tar.gz并解压 

    1
    wget http://openresty.org/download/ngx_openresty-1.7.7.2.tar.gz

    (3) 安装LuaJIT

    1
    2
    3
    cd bundle/LuaJIT-2.1-20150120/
    make clean && make && make install
    ln -sf luajit-2.1.0-alpha /usr/local/bin/luajit

    (4) 下载ngx_cache_purge模块,该模块用于清理nginx缓存

    1
    wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz

    (5) 下载nginx_upstream_check_module模块,该模块用于ustream健康检查

    1
    wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/v0.3.0.tar.gz

    (6) 安装ngx_openresty

    1
    2
    3
    4
    5
    6
    7
    8
    9
    cd /usr/servers/ngx_openresty-1.7.7.2
    ./configure 
    --prefix=/usr/servers 
    --with-http_realip_module  
    --with-pcre  
    --with-luajit 
    --add-module=./bundle/ngx_cache_purge-2.3/ 
    --add-module=./bundle/nginx_upstream_check_module-0.3.0/ -j2
    make && make install

    (7) 到/usr/servers目录下,会发现多出来了如下目录,说明安装成功

    (8) 启动nginx:/usr/servers/nginx/sbin/nginx(其实我们可以配置好系统的环境变量,配置好后就可以直接数据nginx命令了)

    六.防刷(黑白名单)简单例子的搭建

    1. 首先我们先可以在/usr/servers/nginx/conf/ 目录下创建我们自己的一个简单的lua文件,就叫做example.lua好了。

    输入如下命令,我们就可以创建一个example.conf文件,或者我们可以cp nginx.conf  example.conf 或者mkdir example.conf

    2. 接下来我们需要编辑nginx.conf这个启动配置的文件了

    ok,我们进入到编辑界面,接下来我们需要将我们的example.conf文件给引入进来,在nginx.conf的http体里添加一下命令:include example.conf

    nginx.conf 的具体内容如下:

    其中大家可以看到用红线框框的是自己项目文件的引入和lua模块的引入。

    3. 接下来我们可以在example.conf文件中写我们的逻辑实现了

    4. 我们可以看到,在example.conf中的server里面配置多个location,而location中嵌入了content_by_lua_file  /usr/example/lua/redis_black_limit.lua,从这可以看出在content阶段嵌入了lua脚本,进行了内容的响应,在这里,我们进去看看相应的代码是如何来处理的:

    这是一个防刷的demo,从中我们可以看出,我是更具ip,从redis里面取值,然后通过请求ip的匹配,来做到防刷的功能,除此之外,这里有一个语句,我们的注意到,那就是require,这就相当于我们的类加载器,class.forname,从而做到加载进来lua的模块。

    5. 除此之外,还简单的做了一个设置黑名单和取消黑名单的功能,用来充当我们以后的管理中心,具体逻辑写在set_black.lua和cancel.lua中,然后在lua.conf中配置好url,具体如下图所示:

    在lua.conf中server体里加入一下代码:

    接下来我们需要写set_black.lua和cancel.lua文件,文件内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    v  set_black.lua:
    local redis =require "resty.redis"
    local cache =redis.new()
    cache:set_timeout(6000)
    local ok,err=cache.connect(cache,'192.168.150.61',6379)
    if not ok then
            ngx.say("failed to connect:",err)
            return
    end
    local ip = ngx.var.remote_addr
    cache:set("user:"..ip..":block",1)
    ngx.say("user:"..ip..":block".."设置黑名单成功")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    v  cancel_black.lua:
    local redis =require "resty.redis"
    local cache =redis.new()
    cache:set_timeout(6000)
    local ok,err=cache.connect(cache,'192.168.150.61',6379)
    if not ok then
            ngx.say("failed to connect:",err)
            return
    end
    local ip = ngx.var.remote_addr
    cache:expire("user:"..ip..":block",0)
    ngx.say("user:"..ip..":block".."移除黑名单")

    7. 效果

    做好了以上配置,我们可以开始先设置好黑名单,然后访问请求,返回的结果是被黑名单了,然后再取消黑名单,再访问请求,显示访问成功,具体结果如下图。

    七.总结

    上文简单的介绍一些OpenResty,以及搭建了一个简单的应用,目的是想让大家对这个框架有一个大体的了解。随着架构的升级,我们会慢慢的把一些不太复杂的业务可以移到nginx层,从而提高我们的吞吐量,解决一些性能上的瓶颈。例如在nginx这一层做简单的限流、黑白名单,缓存之类的业务复杂性不是太强的工作,从而增加我们的吞吐率,也可以再nginx这一层过滤掉一些垃圾流量,从而让tomcat层只需要更加专注于业务。

    参考文档:https://blog.csdn.net/forezp/article/details/78616856

  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/baizhanshi/p/10113650.html
Copyright © 2011-2022 走看看