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

參考

相關文章
相關標籤/搜索