nginx openresty 快速入门指南,


目录
  • 一、什么是openresty?
  • 二、openresty编译安装
    • 1. 编译安装命令
      • 1.1 编译完成后路径
      • 1.2 常用编译选项解释
    • 2. nginx配置文件配置
      • 2.1 nginx.conf模板
    • 3. nginx常见配置
    • 三、OpenResty工作原理
      • OpenResty工作原理
        • OpenResty处理请求流程
          • Nginx架构 的 好处
            • ngx_lua
              • ngx_lua模块的原理
                • 协程
                  • NIO编程(同步阻塞与同步非阻塞详解)
                  • 四、工作遇坑细节总结
                    • inlude相对路径、lua相对路径问题
                      • access_log 和 error_log有什么区别

                      一、什么是openresty?

                      官网: https://openresty.org/cn/

                      OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其**内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。**用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

                      总结:openresty 内部已经帮你集成了许多依赖项,编译时只需要–with-xxx 激活这些依赖模块。

                      二、openresty编译安装

                      官网参考: https://openresty.org/cn/installation.html

                      安装路径 选择 /usr/local/openresty,如果不配置安装路径,默认安装路径即 /usr/local/openresty
                      因为公司准生产 使用的是 1.9.15.1

                      单纯编译openresty比较简单,openresty强大在很多第三方拓展模块,你需要提前下载好这些模块源码,在配置 openresty编译选项时,把这些模块加进来。当然openrest以及集成大量模块,直接可以使用–with-xxx编译加入这些模块。

                      1. 编译安装命令

                      相关命令如下:

                      tar -zxvf openresty-1.13.6.2.tar.gz
                      ## --with-http_ssl_module依赖openssl
                      yum install openssl openssl-devel
                      export INSTALL_DIR=/usr/local/openresty
                      ./configure --prefix=${INSTALL_DIR} --sbin-path=${INSTALL_DIR}/nginx/sbin/nginx --conf-path=${INSTALL_DIR}/nginx/conf/nginx.conf --pid-path=${INSTALL_DIR}/nginx/logs/nginx.pid --lock-path=${INSTALL_DIR}/nginx/logs/nginx.lock --user=root --group=root --with-luajit --without-http_redis2_module --with-http_iconv_module --with-stream --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_auth_request_module --with-pcre --with-pcre-jit --with-debug --with-http_v2_module
                      gmake
                      gmake install

                      1.1 编译完成后路径

                      安装完成后,nginx命令路径为
                      /usr/local/openresty/nginx/sbin/nginx
                      配置文件路径
                      /usr/local/openresty/nginx/conf/nginx.conf
                      /usr/local/openresty/nginx/conf/http_vhost/.conf
                      /usr/local/openresty/nginx/conf/http_upstream/.conf

                      # nginx重载
                      /usr/local/openresty/nginx/sbin/nginx -s reload

                      1.2 常用编译选项解释

                      • –with-stream

                      ngx_stream_core_module模块自1.9.0版开始提供。默认情况下不构建此模块,应使用–with-stream 配置参数启用它。用来实现四层协议的转发、代理或者负载均衡等。stream 模块用于一般的 TCP 代理和负载均衡。

                      • –with-http_ssl_module

                      Nginx虚拟主机、Nginx模块的安装使用(加密模块–with-http_ssl_module)
                      参考URL: https://www.jb51.net/article/91933.htm

                      报错: SSL moudules require the OpenSSL library
                      解决,执行

                      yum -y install openssl openssl-devel
                      • –with-http_realip_module

                      这个模块主要功能就是 在nginx访问日志中去除代理IP,显示客户的真实IP。作用呢,一般就是统计客户地域或写个统计脚本看有没有流量攻击。

                      然后nginx.conf中
                      在这里加上"http_x_forwarded_for"’ 段,获取真实IP用的 log_format main ’

                      HTTP模块,不要在server中用,要在HTTP区用。这样就是全局使用。

                      –with-http_v2_module
                      支持http2协议。

                      2. nginx配置文件配置

                      ## 复制配置好的nginx.conf到conf目录 ${INSTALL_DIR}为你前面定义的安装目录
                      cp -rf nginx.conf ${INSTALL_DIR}/nginx/conf/
                      # 修改nginx.conf中的工作线程数为CPU核数
                      CPU_NUM=`cat /proc/cpuinfo | grep processor|wc -l | awk -F' ' '{print $NF}' | sed -n '$p'`
                      sed -i "s/^worker_processes.*/worker_processes ${CPU_NUM};/g" ${INSTALL_DIR}/nginx/conf/nginx.conf

                      创建nginx日志目录(你的nginx.conf中配置的,这里创建好目录)

                      # create nginx logs dirtory
                      mkdir -p /home/logs/nginx

                      2.1 nginx.conf模板

                      # nginx的工作进程运行时的身份,也就是进程文件的属主和属组属性,如果在源码安装时configure配置已经指定用户和组,这里可以注释掉
                      #user  root;
                      # 定义nginx的工作进程的数量,一般为CPU核数或核数的倍数,该参数与并发量有关
                      worker_processes 4;
                      #worker_cpu_affinity 0001 0010 0100 1000;
                      # 错误日志的位置
                      error_log  /home/logs/nginx/error.log  error;
                      # nginx的master进程的pid存储文件
                      pid        /usr/local/openresty/nginx/logs/nginx.pid;
                      worker_rlimit_nofile 307200;
                      events {
                          use epoll;
                           # 每一个工作进程可以接收的请求连接数,一般与系统的进程可以打开的文件描述符数量相同,
                          worker_connections 51200;
                      }
                      #流模块
                      stream {
                          include tcp_vhost/*.conf;
                          include tcp_upstream/*.conf;
                      }
                      http {
                          # mime.types文件含有nginx支持的媒体类型,include可以加载该文件
                          include    mime.types;
                          include    fastcgi.conf;
                          # 访问日志的格式,可以自定义
                          log_format main     '$remote_addr $host $remote_user [$time_local] "$request" '
                                              '$status $body_bytes_sent "$http_referer" '
                                              '"$http_user_agent" "$http_x_forwarded_for" "$upstream_response_time" "$upstream_addr" "$upstream_status" "$request_time"';
                           # 指定访问日志的位置和格式main
                          access_log off;
                          client_header_buffer_size 64k; 
                          large_client_header_buffers 8 64k;
                          client_max_body_size 500m;
                          proxy_next_upstream error timeout invalid_header http_502 http_504;
                          # 调用系统的方法传输文件,速度更快,
                          sendfile     on;
                          tcp_nopush   on;
                          keepalive_requests 10000;
                          keepalive_timeout 10;
                          ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
                           # 隐藏nginx版本号,不再浏览显示
                          server_tokens off;
                          include http_vhost/*.conf;
                          include http_upstream/*.conf;
                          lua_package_path 'lua/?.lua;../lua/?.lua;/usr/local/openresty/nginx/conf/lua/?.lua;/usr/local/openresty/lualib/?.lua;;';
                      }

                      注意: 配置文件中的相对路径,是当前nginx.conf同级目录,注意理解。

                      比如

                      include http_vhost/*.conf;
                      include http_upstream/*.conf;

                      对应路径为
                      /usr/local/openresty/nginx/conf/http_vhost
                      /usr/local/openresty/nginx/conf/http_upstream

                      3. nginx常见配置

                      Nginx常用配置有这一篇就够了
                      参考URL: https://www.jb51.net/article/50899.htm

                      一个站点配置多个域名

                      server {
                      listen 80;
                      server_name aaa.cn bbb.cn;
                      }

                      server_name 后跟多个域名即可,多个域名之间用空格分隔

                      nginx配置中location匹配规则

                      nginx配置中location匹配规则详解
                      参考URL: https://www.jb51.net/article/182472.htm

                      nginx官方文档给出location语法如下:

                      location [=|~|~*|^~] uri { … }

                      其中,方括号中的四种标识符是可选项,用来改变请求字符串和uri的匹配方式。uri是待匹配的请求字符串,可以是不包含正则的字符串,这种模式被称为**“标准的uri";也可以包含正则,这种模式被称为"正则uri"**。

                      • location = /uri

                      = 开头表示精确匹配。

                      • location ^~ /uri

                      ^~ 开头对URL路径进行前缀匹配,并且在正则之前

                      • location ~ 正则表达式

                      ~开头表示区分大小写的正则匹配

                      • location ~*正则表达式

                      ~*开头表示不区分大小写的正则匹配

                      • location /uri

                      不带任何修饰符,也表示前缀匹配,但是在正则匹配之后

                      • location /

                      通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default

                      如果匹配规则以^开头,就是匹配以指定字符串开头的路径,如果没有就是匹配url中的内容是否包含指定字符串
                      如果匹配规则以$结尾,就是匹配以指定字符串结尾的路径

                      多个location配置的情况下匹配顺序为(当有匹配成功时候,停止匹配,按当前匹配规则处理请求):

                      优先匹配 =
                      其次匹配 ^~
                      按照文件中的匹配顺序执行
                      最后匹配 /
                      普通匹配(最长字符匹配)

                      总结为: (location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)

                      三、OpenResty工作原理

                      OpenResty工作原理

                      Nginx采用的是master-worker模型,也就是一个master进程管理多个worker进程,基本的事件处理都放在worker进程中,master进程负责全局初始化以及对worker进行的管理。

                      OpenResty中,每个worker进程使用一个LuaVM,当请求被分配到worker时,将在这个LuaVM中创建一个coroutine协程,协程之间数据隔离,每个协程都具有独立的全局变量。


                      Nginx设计为主进程和多个工作进程的工作模式,每个进程是单线程来处理多个连接,每个工作进程采用了非阻塞I/O来处理多个连接,从而减少线程上下文切换,从而实现高性能、高并发。因此,生产环境中会通过将CPU绑定给Nginx工作进程,从而提升性能。

                      OpenResty处理请求流程

                      Nginx会把一个请求分成不同阶段,第三方模块可以根据自己的行为,挂在到不同阶段中以达到自身目的。OpenResty采用了同样的特性,不同阶段有着不同的处理行为。

                      Nginx架构 的 好处

                      Nginx采用多进程模式,对于每个worker进程都是独立的,因此不需要加锁,所以节省了锁带来的性能开销。采用独立的进程的好处在于worker进程之间相互不会影响,当一个进程退出后,其他进程依然工作,以保证服务不会终端。

                      Nginx采用异步非堵塞的方式去处理请求,异步非堵塞就是当一个线程调用出现阻塞而等待时,其他线程可以去处理其他任务。

                      ngx_lua

                      ngx_lua是将Lua嵌入Nginx,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求。Lua内建协程,可以很好的将异步回调转换成顺序调用的形式。ngx_lua在Lua中进行的IO操作都会委托给Nginx的事件模型,从而实现非阻塞调用。开发者可以采用串行的方式编写程序,ngx_lua会自动的在进行阻塞的IO操作中终端,保存上下文,然后将IO操作委托给Nginx事件处理机制,在IO操作完成后,ngx_lua会恢复上下文,程序继续执行,这些操作都是对用户程序透明的。

                      每个Nginx的worker进程持有一个Lua解释器或LuaJIT实例,这个worker处理的所有请求共享这个实例每个请求的context上下文会被Lua轻量级的协程分隔,从而保证各个请求时独立的。

                      ngx_lua模块的原理

                      • 每个工作进程worker创建一个Lua虚拟机(LuaVM),工作进程worker内部协议共享VM。
                      • -每个Nginx I/O原语封装后注入Lua虚拟机,并允许Lua代码直接访问。
                      • 每个外部请求都由一个Lua协程处理,协程之间数据隔离。
                      • Lua代码调用I/O操作等异步时,会挂起当前协程,而不阻塞工作机进程。
                      • I/O等异步操作完成时,还原相关协程相关协议的上下文,并继续运行。

                      协程

                      协程,又称微线程,纤程。英文名Coroutine。

                      协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。

                      子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。

                      所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。

                      子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

                      协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

                      注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。

                      Java语言里面解决并发问题靠的就是多线程,但线程是个重量级对象,不能频繁创建和销毁,且线程切换成本也很高,为了解决这个问题,java采用了线程池。Java没有官方的协程支持,不过有一些库可以支持,如:Quasar。而一些其他语言本身就支持协程,如:go就内置支持协程。

                      所谓的协程,可以理解为是一种轻量级的线程,它与线程的主要区别在于

                      a. 线程切换的过程是由系统内核完成,切换的过程中会进入到内核态。而协程则完全工作在用户态。

                      b. 线程是否发生切换是由操作系统决定的(抢占式调度),工作线程本身没有决定权。而协程的切换是需要工作协程主动放弃CPU,这样调度器才能让另外一个协程继续运行。

                      NIO编程(同步阻塞与同步非阻塞详解)

                      NIO编程(同步阻塞与同步非阻塞详解)
                      参考URL: https://www.jb51.net/article/131810.htm

                      • BIO与NIO

                      IO为同步阻塞形式,NIO为同步非阻塞形式,NIO并没有实现异步,在JDK1.7后升级NIO库包,支持异步非阻塞模型NIO2.0(AIO)

                      • BIO(同步阻塞式IO)

                      同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

                      • NIO(同步非阻塞式IO)

                      同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理

                      • AIO(异步非阻塞式IO)

                      异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

                      • 什么是阻塞?

                      应用程序在获取网络数据的时候,如果网络传输数据很慢,就会**一直等待,**直到传输完毕为止。

                      • 什么是非阻塞?

                      应用程序直接可以获取已经准备就绪好的数据,无需等待。

                      同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪;或者采用轮训的策略实时检查数据的就绪状态,如果就绪则获取数据.

                      异步时,则所有的IO读写操作交给操作系统,与我们的应用程序没有直接关系,我们程序不需要关系IO读写,当操作系统完成了IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据极即可。

                      四、工作遇坑细节总结

                      inlude相对路径、lua相对路径问题

                      比如nginx启动如下:

                      /home/she/openresty/nginx/sbin/nginx -c /home/she/openresty/nginx/conf/nginx.conf

                      如下则配置中的include 指的就是当前配置nginx.conf所在的路径,即
                      /home/she/openresty/nginx/conf/http_vhost/*.conf

                              include http_vhost/*.conf;
                              include http_upstream/*.conf;

                      假如其中一个conf有配置如下: 那么这里的conf/lua/access_check.lua 是哪个路径呢?从刚才的经验来看,配置中写的相对路径都是相关该配置当前的路径

                              location ~* /api/auth/([-_a-zA-Z0-9/]+) {
                                  access_by_lua_file conf/lua/access_check.lua;
                              }

                      工作中,竟然发现 /home/she/openresty/nginx/conf/lua/access_check.lua 修改打印一直打不出来?

                      猜测思考:openresty找lua脚本位置,应该有一个配置查找路径有优先级。
                      经过百度,果然有配置项,lua_package_path可以配置openresty的文件寻址路径

                              lua_package_path 'lua/?.lua;../lua/?.lua;/opt/openresty/nginx/conf/lua/?.lua;/opt/openresty/nginx/conf/lua/dialer/?.lua;;';

                      经过测试,配置生效。

                      access_log 和 error_log有什么区别

                      日志-nginx的access_log与error_log
                      参考URL:https://www.jb51.net/server/298054hhs.htm

                      • access_log 访问日志

                      access_log为访问日志,记录所有对apache服务器进行请求的访问,它的位置和内容由CustomLog指令控制,LogFormat指令可以用来简化该日志的内容和格式。

                      • error_log 错误日志

                      error_log为错误日志,记录下任何错误的处理请求,它的位置和内容由ErrorLog指令控制,通常服务器出现什么错误,首先对它进行查阅**,是一个最重要的日志文件**。

                      总结:
                      error_log 我们可以配置日志等级,我们的lua中的ngx.log打印日志就是根据日志级别打印到该配置项配置的文件路径中。
                      每个service配置项中,都可以配置自己的 access_log和error_log。从而每个服务看自己的access_log和error_log。

                      到此这篇关于nginx openresty 快速入门指南的文章就介绍到这了,更多相关nginx openresty内容请搜索PHP之友以前的文章或继续浏览下面的相关文章希望大家以后多多支持PHP之友!

                      您可能感兴趣的文章:
                      • Nginx结合Openresty通过Lua+Redis实现动态封禁IP
                      • 安装OpenResty(Nginx仓库)
                      • 强大的 Web 应⽤服务器OpenResty安装(Nginx仓库)
                      • 在Debian11上安装Openresty服务(Nginx+Lua)的详细教程
                      • Nginx/Openresty中启用http2支持的方法教程
                      • openresty中使用lua-nginx创建socket实例

                      相关内容