日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenResty简介及学习笔记

發布時間:2024/2/28 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenResty简介及学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OpenResty簡介及學習筆記

  • 摘要
  • 簡介
  • 一、OpenResty綜述
  • 二、指令說明:
    • *_by_lua
    • *_by_lua_block {lua_script}
    • *_by_lua_file
  • 三、登陸驗證
    • IP防火墻
    • 操作頭信息檢測
    • 登陸緩存
    • 過濾參數
  • 四、輸出過濾
    • header_filter_by_lua*
    • body_filter_by_lua*
  • 五、Redis

摘要

OpenResty系列文章之一。

前些日子做的一些研究,期間收獲了一些對web后臺應用的理解,nginx運行機理的部分理解。

本篇包括簡介、部分模塊的介紹。

簡介

OpenResty?(也稱為?ngx_openresty)是一個全功能的 Web 應用服務器。它打包了標準的?Nginx 核心,很多的常用的第三方模塊,以及它們的大多數依賴項。

通過眾多進行良好設計的 Nginx 模塊,OpenResty 有效地把 Nginx 服務器轉變為一個強大的 Web 應用服務器,基于它開發人員可以使用Lua 編程語言對 Nginx 核心以及現有的各種Nginx C 模塊進行腳本編程,構建出可以處理一萬以上并發請求的極端高性能的 Web 應用。

OpenResty 致力于將你的服務器端應用完全運行于 Nginx 服務器中,充分利用 Nginx 的事件模型來進行非阻塞 I/O 通信。不僅僅是和 HTTP 客戶端間的網絡通信是非阻塞的,與MySQL、PostgreSQL、Memcached、以及 Redis 等眾多遠方后端之間的網絡通信也是非阻塞的。

因為 OpenResty 軟件包的維護者也是其中打包的許多 Nginx 模塊的作者,所以 OpenResty 可以確保所包含的所有組件可以可靠地協同工作。

作者簡介:

agentzh,本名章亦春,現任 CloudFare 系統工程師,主要是 Nginx 和 OpenResty 開發,是一名快樂的程序員,現定居美國舊金山。曾經在北京的時候供職于 Yahoo!中國以及淘寶(阿里巴巴)。

教程:agentzh 的 Nginx 教程

其他內容可以參看:?OpenResty簡介,OpenResty 作者章亦春訪談實錄

一、OpenResty綜述

?

?

?

?

OpenResty?通過 Lua 擴展 NGINX 實現的可伸縮的 Web 平臺


先扔三個網站:

?

首先,OpenResty官網!

還有Github:OpenResty

為數不多的書籍:OpenResty最佳實踐(Lua語言入門也可以全靠它)

下圖給出的是Lua Nginx Module中各指令的執行順序

  • set_by_lua: 流程分支處理判斷變量初始化
  • rewrite_by_lua: 轉發、重定向、緩存等功能(例如特定請求代理到外網)
  • access_by_lua: IP 準入、接口權限等情況集中處理(例如配合 iptable 完成簡單防火墻)
  • content_by_lua: 內容生成
  • header_filter_by_lua: 應答 HTTP 過濾處理(例如添加頭部信息)
  • body_filter_by_lua: 應答 BODY 過濾處理(例如完成應答內容統一成大寫)
  • log_by_lua: 會話完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機器)

實際上我們只使用其中一個階段 content_by_lua,也可以完成所有的處理。但這樣做,會讓我們的代碼比較臃腫,越到后期越發難以維護。把我們的邏輯放在不同階段,分工明確,代碼獨立,后期發力可以有很多有意思的玩法。

二、指令說明:

*_by_lua < lua-script-str >

無后綴的指令,后加字符串型的lua程序。

如:

  • location / {
  • default_type text/html;
  • content_by_lua '
  • ngx.say("<p>hello, world</p>")
  • ';
  • }

nginx

*_by_lua_block {lua_script}

有block后綴,可以直接跟lua程序段。

如:

  • location / {
  • content_by_lua_block{
  • local test = 'Hello,world'
  • ngx.say(test)
  • }
  • }

*_by_lua_file < path-to-lua-script-file >

file后綴跟lua文件路徑

如:

  • location ~ ^/api/([-_a-zA-Z0-9/]+) {
  • # 準入階段完成參數驗證
  • access_by_lua_file lua/access_check.lua;
  • ?
  • #內容生成階段
  • content_by_lua_file lua/$1.lua;
  • ?
  • }

nginx

三、登陸驗證

在access_by_lua*中集中進行一些權限認證,防止惡意ip、非法行為進入到服務器中。

  • location / {
  • access_by_lua_block{
  • ngx.exit(ngx.HTTP_FORBIDDEN)
  • }
  • content_by_lua_block{
  • --內容生產階段
  • }
  • }

IP防火墻

OpenResty最佳實踐提到:禁止某些終端訪問

上面文檔下方推薦第三方包:Github,Lua-resty-iputils

操作頭信息檢測

通過access_by_lua*可以對請求進行過濾,比如可以在這里檢查有沒有帶authorization頭部信息,若沒有帶可以用ngx.exit()直接退出。

登陸緩存

Github:?lua-resty-jwt模塊進行jwt校驗

結合lua-resty-jwt和lua-resty-redis甚至可以將服務器登陸緩存移植到nginx上。

過濾參數

還未嘗試。

防止 SQL 注入

四、輸出過濾

通常是header_filter_by_lua*與body_filter_by_lua*配合實現。

【文檔來源官方】:

注意下列API函數現在還不能在set_by_lua*、header_filter_by_lua*、body_filter_by_lua*、log_by_lua*四個環境中使用:

  • 輸出API 函數 (e.g., ngx.say and ngx.send_headers)
  • 控制API 函數 (e.g., ngx.redirect and ngx.exec)
  • 子請求API 函數 (e.g., ngx.location.capture and ngx.location.capture_multi)
  • Cosocket API 函數 (e.g., ngx.socket.tcp and ngx.req.socket).

header_filter_by_lua*

使用Lua代碼在lua塊中定義輸出頭信息。

example1:

  • location / {
  • proxy_pass http://mybackend;
  • header_filter_by_lua 'ngx.header.Foo = "blah"';
  • }

nginx

example2:

  • header_filter_by_lua_block {
  • ngx.header["content-length"] = nil
  • }

body_filter_by_lua*

參考:

談談 OpenResty 中的 body_filter_by_lua*

輸入數據塊chunks要經過ngx.arg1?(Lua 字符串)的過濾,"eof"標志指示響應體數據流的末端通過ngx.arg2?(Lua bollean值)顯示。

這個情景下,"eof"標志就是主請求的last_buf或子請求的?last_in_chain。"eof" == "true" 表示此次nginx請求的響應結束了。

由于響應體可能會分多塊發送,body_filter_by_lua*可能會被多次調用。詳細機理參考上面文獻有提到。

  • location /t {
  • echo hello world;
  • echo hiya globe;
  • ?
  • body_filter_by_lua '
  • ......
  • ';
  • }

nginx

比如上面,body_filter_by_lua*首次調用時ngx.arg1?的值只是hello world,不包括下面的hiya globe。

我驗證了一下:

  • location = /test_bf {
  • echo hello world;
  • echo this;
  • echo is;
  • echo world;
  • header_filter_by_lua_block {
  • ngx.header.content_length = nil
  • }
  • body_filter_by_lua_block {
  • if string.match(ngx.arg[1], "this") then
  • ngx.arg[2] = true
  • ngx.arg[1] = "end"
  • return
  • end
  • }
  • }

上述location發送四塊數據,匹配到this便設置"eof"不再發送下去了。

  • $ curl

結果:

  • $ hello world
  • $ end

要點:

①?ngx.arg[2] = true設置新的"eof"標志使截斷響應,設置"eof"依舊是有效的響應。

②?ngx.arg[1] = "end"修改ngx.arg[1]?的值,即為修改輸出響應。而當需要替換一些信息,僅需一行代碼即可實現。

  • ngx.arg[1] = ngx.re.gsub(ngx.arg[1], "o", "*")

上文也提到。上述即為將所有 ' o ' 字符替換為 ' * ' 字符

若該location作為其他location的子請求,而作為子請求不想被過濾數據。需要通過ngx.is_subrequest判斷。

  • body_filter_by_lua_block {
  • if ngx.arg[1] and not ngx.is_subrequest then
  • ......
  • end
  • }

nginx

還有一點,如果在body_filter_by_lua*中的Lua代碼會修改響應體的長度,這就需要去把Content-Length的響應頭去除掉。我之前測試與前端聯調時,就是發現body過濾必須要字符數相同才會顯示,很頭疼不知道什么原因。其實只要去掉這個頭就行了。

  • location = / {
  • proxy_pass ......
  • header_filter_by_lua_block {
  • ngx.header.content_length = nil
  • }
  • body_filter_by_lua_block {
  • ngx.arg[1] = ngx.re.gsub(ngx.arg[1], "o", "**")
  • }
  • }

五、Redis

官方github:lua-resty-redis

OpenResty最佳實踐:訪問有授權驗證的 Redis

官方包封裝了一些Redis的方法,使用起來還是挺舒適的。

本文鏈接:https://blog.maozhiting.com/post/openresty_notes.html

--?EOF?--

作者?毛毛?發表于?2017-11-05 15:11:55?,并被添加「?OpenResty?」標簽 ,最后修改于?2017-11-05 15:47:30

總結

以上是生活随笔為你收集整理的OpenResty简介及学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。