OpenResty的部署与使用

OpenResty是什么

  • OpenResty是什么,官网是这样介绍的:html

    经过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台nginx

    的确,OpenResty能够简单的理解为Nginx + Lua,经过Lua库引入数据库访问能力,真正的让Nginx向搭建可以处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关这一目标迈出了重要的一步git

OpenResty的配置

  • OpenResty的配置能够分为2类
    • lua脚本
    • Nginx配置文件
  • 下面列举几个常见场景的Nginx配置

静态文件(页面)服务器配置

server {
    listen 80;
    # 以dvclab.com做为主网站域名,彻底匹配
    server_name ${hostname};
    rewrite ^(.*)$  https://${hostname}$1 permanent;
}

server {
    listen       443;
    server_name  ${hostname};

    # ssl证书文件位置(常见证书文件格式为:crt/pem)
    ssl_certificate      /etc/nginx/ssl/${hostname}.pem;
       
    # ssl证书key位置
    ssl_certificate_key  /etc/nginx/ssl/${hostname}.key;
  
    ssl_session_timeout  10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers  on;

    root        /etc/nginx/dist;
    index index.html index.htm;
}
复制代码
  • 将静态页面文件放到OpenResty容器内的/etc/nginx/dist内便可,后续会使用Docker Compose的yaml配置文件作路径映射

通常反向代理

server {
    listen 80;
    server_name ${hostname};
    rewrite ^(.*)$  https://${hostname}$1 permanent;
}

server {
    listen          443 ssl;
    server_name     ${hostname};

    # ssl证书文件位置(常见证书文件格式为:crt/pem)
    ssl_certificate      /etc/nginx/ssl/auth-cert.pem;
    
    # ssl证书key位置
    ssl_certificate_key  /etc/nginx/ssl/auth-cert.key;
    ssl_session_timeout  10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers  on;

    location / {
    
         proxy_set_header  Host  $host;
         proxy_set_header  X-Forwarded-Proto $scheme;
         proxy_set_header  X-Forwarded-For $host;
         proxy_set_header  Upgrade $http_upgrade;
         proxy_set_header  Connection 'Upgrade';
    		 proxy_http_version 1.1;
         proxy_set_header  X-Real-IP $remote_addr;
         
         proxy_pass    http://${target}/;
    }
}
复制代码
  • ${target}就是反向代理的目标服务器地址或域名,注意不要丢掉后边的/

动态路由设置

  • 大体的请求-相应流程以下

image-20210314234123950

  • 需求说明:根据请求参数动态转发到不一样的服务器、端口,好比hostname/users/1/info/2 转发到hosname1:9200hostname/users/3/info/4转发到hostname2:8080

在/opt/openresty/lua/目录下建立 split.luagithub

echo ' --[[ 拆分字符串 e.g. /a/b/c table[1] a table[2] b table[3] c --]] function split(str, pat) local t = {} local fpat = "(.-)" .. pat local last_end = 1 local s, e, cap = str:find(fpat, 1) while s do if s ~= 1 or cap ~= "" then table.insert(t, cap) end last_end = e + 1 s, e, cap = str:find(fpat, last_end) end if last_end <= #str then cap = str:sub(last_end) table.insert(t, cap) end return t end function split_path(str) return split(str, '[\\/]+') end ' > /opt/openresty/lua/split.lua
复制代码

在/opt/openresty/lua/目录下建立 query_redis.luaredis

echo ' -- redis结果解析,导入redis.parser脚本 local parser = require "redis.parser" -- ngx.var.uri只包含路径参数,不包含主机与端口 -- 调用worker启动时引入的lua脚本中提供的函数 local parameters = split_path(ngx.var.uri) -- 访问的是根路径 if(#parameters == 0) then ngx.exit(ngx.HTTP_FORBIDDEN) end -- 拆分出查询参数 user_id = parameters[2] container_id = parameters[4] ngx.log(ngx.EMERG, "user_id--->", user_id) ngx.log(ngx.EMERG, "container_id--->", container_id) -- 组合参数 key = "DYNA" id = user_id .. "_" .. container_id -- 向redis查询 res = ngx.location.capture( "/redis", { args = { key = key, id = id } } ) -- 查询失败 if res.status ~= 200 then ngx.log(ngx.ERR, "redis server returned bad status: ", res.status) ngx.exit(res.status) end -- 结果为空 if not res.body then ngx.log(ngx.ERR, "redis returned empty body") ngx.exit(500) end -- raw tcp response from redis server -- 共2条返回因此应该使用parse_replies(res.body, 2) -- OK -- 172.17.144.4:8080 ngx.log(ngx.EMERG, "raw response ----->", res.body) local results = parser.parse_replies(res.body, 2) for i, result in ipairs(results) do if i == 2 then server = result[1] typ = result[2] end end -- 检查结果类型 if typ ~= parser.BULK_REPLY or not server then ngx.exit(500) end -- 返回value为空 if server == "" then server = "default.com" end ngx.var.target = server ngx.log(ngx.EMERG, "key--->", key) ngx.log(ngx.EMERG, "id--->", id) ngx.log(ngx.EMERG, "service--->", server) '   > /opt/openresty/lua/query_redis.lua
复制代码
  • 上述的lua脚本中,假设Redis存储着以DYNA为key的hash表,hash表的key是由用户请求中解析出的user_id和container_id使用_组合而成,对应的value就是要转发到的目标target

在/opt/openresty/conf.d/目录下建立dynamicRouter.confdocker

echo ' # 启用主进程后,在每次Nginx工做进程启动时运行指定的Lua代码 init_worker_by_lua_file /usr/local/openresty/nginx/lua/split.lua; server { listen 443; server_name ${hostname}; # redis交互库是openresty的内置的库 location = /redis { # Specifies that a given location can only be used for internal requests internal; redis2_query auth ${redis_password}; # 解析请求参数 set_unescape_uri $id $arg_id; set_unescape_uri $key $arg_key; # 执行redis查询请求 redis2_query hget $key $id; # 查询请求转发到指定的redis_server redis2_pass redis:6379; } location / { # 设置一个内嵌脚本的共享变量 set $target ''; # 引入内嵌脚本 access_by_lua_file /usr/local/openresty/nginx/lua/query_redis.lua; resolver 8.8.8.8; # 进行请求转发(反向代理) proxy_set_header Host $host; proxy_set_header X-Forwarded-For $host; # 若是客户端请求升级,将代理WebSocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'Upgrade'; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; # 最后的斜杠勿丢 proxy_pass http://$target/; } } > /opt/openresty/conf.d/dynamicRouter.conf 复制代码
  • ${redis_password}是redis访问的密码

动态路由的使用

  • 在部署OpenResty服务后,就能够经过读写Redis的方式来实现动态路由转发了shell

  • 在shell命令行使用 docker exec命令结合redis-cli便可完成动态配置,举例以下:数据库

    • 目的:将 /users/ u s e r i d / c o n t a i n e r s / {user_id}**/containers/** {container_id} 映射到 h o s t : {host}**:** {port}bash

      docker exec -it or-redis /bin/bash
      redis-cli --askpass
      # 输入redis密码
      hset DYNA ${user_id}_${container_id} ${host}:${port}
      复制代码
      • 注意: h o s t : {host}**:** {port} 不加最后的/;不用加协议头,默认是HTTP,一样也支持WebSocket的协议升级
  • 或者使用Redis-Java API 接口完成动态路由的设置服务器

OpenResty的安装部署

  • 本文章使用docker-compose进行OpneResty的安装部署

Docker Compose的安装

sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 增长可执行权限
sudo chmod +x /usr/local/bin/docker-compose
复制代码
  • 具体的最新的版本,能够去Docker官网查看

Docker Compose 部署OpenResty服务

echo 'version: "3" services: redis: image: redis restart: always volumes: - /opt/redis/redis.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf ports: - "61379:6379" container_name: or-redis openresty: image: openresty/openresty restart: always depends_on: - redis container_name: openresty volumes: - /opt/openresty/ssl/:/etc/nginx/ssl/ - /opt/openresty/conf.d/:/etc/nginx/conf.d/ - /opt/openresty/lua/:/usr/local/openresty/nginx/lua/ - /opt/static/:/etc/nginx/dist/ ports: - "443:443" - "80:80" ' > /etc/openresty/openresty.yaml

docker-compose -f /opt/openresty.yaml up -d
复制代码
  • /opt/openresty/ssl/ 目录是用来放域名的HTTPS证书的,固然也可使用更方便的Let's Encrypt服务,可参考使用lua-resty-auto-ssl

参考

相关文章
相关标签/搜索