ngx_http_lua_module - Sematkan kekuatan Lua ke Server HTTP Nginx.
Modul ini adalah komponen inti OpenResty. Jika Anda menggunakan modul ini, pada dasarnya Anda menggunakan OpenResty :)
Modul ini tidak didistribusikan dengan sumber Nginx. Lihat petunjuk instalasi.
Produksi siap.
Dokumen ini menjelaskan ngx_lua v0.10.25, yang dirilis pada 19 Juni 2023.
Video YouTube "Contoh HTTP Hello World dengan OpenResty/Lua"
Video YouTube "Tulis Modul Lua Anda Sendiri di Aplikasi OpenResty/Nginx"
Video YouTube "Demo Utilitas Baris Perintah OpenResty yang terbaru"
Video YouTube "Mengukur Waktu Eksekusi Kode Lua dengan Benar di OpenResty"
Video YouTube "Kompilasi terlebih dahulu Modul Lua ke dalam Bytecode LuaJIT untuk Mempercepat Startup OpenResty"
Anda dipersilakan untuk berlangganan saluran YouTube resmi kami, OpenResty.
Kembali ke Daftar Isi
# set search paths for pure Lua external libraries (';;' is the default path):
lua_package_path '/foo/bar/?.lua;/blah/?.lua;;' ;
# set search paths for Lua external libraries written in C (can also use ';;'):
lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;' ;
server {
location /lua_content {
# MIME type determined by default_type:
default_type 'text/plain' ;
content_by_lua_block {
ngx.say('Hello,world!')
}
}
location /nginx_var {
# MIME type determined by default_type:
default_type 'text/plain' ;
# try access /nginx_var?a=hello,world
content_by_lua_block {
ngx.say(ngx.var.arg_a)
}
}
location = /request_body {
client_max_body_size 50k ;
client_body_buffer_size 50k ;
content_by_lua_block {
ngx.req.read_body() -- explicitly read the req body
local data = ngx.req.get_body_data()
if data then
ngx.say(" body data: ")
ngx.print(data)
return
end
-- body may get buffered in a temp file:
local file = ngx.req.get_body_file()
if file then
ngx.say(" body is in file ", file)
else
ngx.say(" no body found ")
end
}
}
# transparent non-blocking I/O in Lua via subrequests
# (well, a better way is to use cosockets)
location = /lua {
# MIME type determined by default_type:
default_type 'text/plain';
content_by_lua_block {
local res = ngx.location.capture(" /some_other_location ")
if res then
ngx.say(" status: ", res.status)
ngx.say(" body: ")
ngx.print(res.body)
end
}
}
location = /foo {
rewrite_by_lua_block {
res = ngx.location.capture(" /memc ",
{ args = { cmd = " incr ", key = ngx.var.uri } }
)
}
proxy_pass http://blah.blah.com;
}
location = /mixed {
rewrite_by_lua_file /path/to/rewrite.lua;
access_by_lua_file /path/to/access.lua;
content_by_lua_file /path/to/content.lua;
}
# use nginx var in code path
# CAUTION: contents in nginx var must be carefully filtered,
# otherwise there'll be great security risk!
location ~ ^/app/([-_a-zA-Z0-9/]+) {
set $path $1 ;
content_by_lua_file /path/to/lua/app/root/ $path .lua;
}
location / {
client_max_body_size 100k;
client_body_buffer_size 100k;
access_by_lua_block {
-- check the client IP address is in our black list
if ngx.var.remote_addr == " 132.5.72.3 " then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
-- check if the URI contains bad words
if ngx.var.uri and
string.match(ngx.var.request_body, " evil ")
then
return ngx.redirect(" /terms_of_use.html ")
end
-- tests passed
}
# proxy_pass/fastcgi_pass/etc settings
}
}
Kembali ke Daftar Isi
Modul ini menyematkan LuaJIT 2.0/2.1 ke Nginx. Ini adalah komponen inti OpenResty. Jika Anda menggunakan modul ini, pada dasarnya Anda menggunakan OpenResty.
Sejak versi v0.10.16
modul ini, juru bahasa Lua standar (juga dikenal sebagai "PUC-Rio Lua") tidak lagi didukung. Dokumen ini secara bergantian menggunakan istilah "Lua" dan "LuaJIT" untuk merujuk pada juru bahasa LuaJIT.
Dengan memanfaatkan subpermintaan Nginx, modul ini memungkinkan integrasi thread Lua yang kuat (dikenal sebagai Lua "coroutine") ke dalam model kejadian Nginx.
Berbeda dengan mod_lua Apache dan mod_magnet Lighttpd, kode Lua yang dieksekusi menggunakan modul ini dapat 100% non-blocking pada lalu lintas jaringan selama Nginx API untuk Lua yang disediakan oleh modul ini digunakan untuk menangani permintaan ke layanan upstream seperti MySQL, PostgreSQL, Memcached , Redis, atau layanan web HTTP hulu.
Setidaknya pustaka Lua dan modul Nginx berikut dapat digunakan dengan modul ini:
Hampir semua modul Nginx dapat digunakan dengan modul ngx_lua ini melalui ngx.location.capture atau ngx.location.capture_multi tetapi disarankan untuk menggunakan pustaka lua-resty-*
tersebut daripada membuat subpermintaan untuk mengakses modul upstream Nginx karena yang pertama biasanya jauh lebih fleksibel dan hemat memori.
Penerjemah Lua (juga dikenal sebagai "Lua State" atau "LuaJIT VM instance") dibagikan ke seluruh permintaan dalam satu proses pekerja Nginx untuk meminimalkan penggunaan memori. Konteks permintaan dipisahkan menggunakan coroutine Lua yang ringan.
Modul Lua yang dimuat tetap ada di tingkat proses pekerja Nginx sehingga menghasilkan jejak memori yang kecil di Lua bahkan ketika berada di bawah beban berat.
Modul ini dicolokkan ke subsistem "http" Nginx sehingga hanya dapat menggunakan protokol komunikasi hilir dalam keluarga HTTP (HTTP 0.9/1.0/1.1/2.0, WebSockets, dll...). Jika Anda ingin melakukan komunikasi TCP umum dengan klien hilir, maka Anda harus menggunakan modul ngx_stream_lua, yang menawarkan API Lua yang kompatibel.
Kembali ke Daftar Isi
Sekadar beberapa nama:
Kemungkinannya tidak terbatas karena modul ini memungkinkan menyatukan berbagai elemen dalam Nginx serta memperlihatkan kekuatan bahasa Lua kepada pengguna. Modul ini memberikan fleksibilitas penuh dalam pembuatan skrip sekaligus menawarkan tingkat kinerja yang sebanding dengan program bahasa C asli baik dalam hal waktu CPU maupun jejak memori berkat LuaJIT 2.x.
Implementasi bahasa skrip lainnya biasanya kesulitan untuk menyamai tingkat kinerja ini.
Kembali ke Daftar Isi
Versi terbaru modul ini kompatibel dengan versi Nginx berikut:
Inti Nginx yang lebih lama dari 1.6.0 (eksklusif) tidak didukung.
Kembali ke Daftar Isi
Sangat disarankan untuk menggunakan rilis OpenResty yang menggabungkan Nginx, ngx_lua (modul ini), LuaJIT, serta modul pendamping Nginx dan pustaka Lua yang kuat lainnya.
Tidak disarankan untuk membuat modul ini sendiri dengan Nginx karena sulit untuk menyiapkannya dengan tepat.
Perhatikan bahwa rilis resmi Nginx, LuaJIT, dan OpenSSL memiliki berbagai keterbatasan dan bug yang sudah berlangsung lama yang dapat menyebabkan beberapa fitur modul ini dinonaktifkan, tidak berfungsi dengan baik, atau berjalan lebih lambat. Rilis resmi OpenResty direkomendasikan karena menggabungkan fork LuaJIT 2.1 OpenResty yang dioptimalkan dan patch Nginx/OpenSSL.
Alternatifnya, ngx_lua dapat dikompilasi secara manual ke dalam Nginx:
Bangun sumber dengan modul ini:
wget ' https://openresty.org/download/nginx-1.19.3.tar.gz '
tar -xzvf nginx-1.19.3.tar.gz
cd nginx-1.19.3/
# tell nginx's build system where to find LuaJIT 2.0:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
# tell nginx's build system where to find LuaJIT 2.1:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.1
# Here we assume Nginx is to be installed under /opt/nginx/.
./configure --prefix=/opt/nginx
--with-ld-opt= " -Wl,-rpath,/path/to/luajit/lib "
--add-module=/path/to/ngx_devel_kit
--add-module=/path/to/lua-nginx-module
# Note that you may also want to add `./configure` options which are used in your
# current nginx build.
# You can get usually those options using command nginx -V
# you can change the parallelism number 2 below to fit the number of spare CPU cores in your
# machine.
make -j2
make install
# Note that this version of lug-nginx-module not allow to set `lua_load_resty_core off;` any more.
# So, you have to install `lua-resty-core` and `lua-resty-lrucache` manually as below.
cd lua-resty-core
make install PREFIX=/opt/nginx
cd lua-resty-lrucache
make install PREFIX=/opt/nginx
# add necessary `lua_package_path` directive to `nginx.conf`, in the http context
lua_package_path " /opt/nginx/lib/lua/?.lua;; " ;
Kembali ke Daftar Isi
Mulai dari NGINX 1.9.11, Anda juga dapat mengkompilasi modul ini sebagai modul dinamis, dengan menggunakan opsi --add-dynamic-module=PATH
alih-alih --add-module=PATH
pada baris perintah ./configure
di atas. Dan kemudian Anda dapat secara eksplisit memuat modul di nginx.conf
Anda melalui direktif load_module, misalnya,
load_module /path/to/modules/ndk_http_module.so; # assuming NDK is built as a dynamic module too
load_module /path/to/modules/ngx_http_lua_module.so;
Kembali ke Daftar Isi
Saat membangun modul ini melalui OpenResty atau dengan inti Nginx, Anda dapat menentukan makro C berikut melalui opsi kompiler C:
NGX_LUA_USE_ASSERT
Jika ditentukan, akan mengaktifkan pernyataan dalam basis kode ngx_lua C. Direkomendasikan untuk debugging atau pengujian build. Ini dapat menimbulkan beberapa overhead runtime (kecil) saat diaktifkan. Makro ini pertama kali diperkenalkan pada rilis v0.9.10
.NGX_LUA_ABORT_AT_PANIC
Ketika VM LuaJIT panik, ngx_lua akan menginstruksikan proses pekerja nginx saat ini untuk berhenti dengan baik secara default. Dengan menentukan makro C ini, ngx_lua akan segera membatalkan proses pekerja nginx saat ini (yang biasanya menghasilkan file dump inti). Opsi ini berguna untuk men-debug kepanikan VM. Opsi ini pertama kali diperkenalkan pada rilis v0.9.8
. Untuk mengaktifkan satu atau lebih makro ini, cukup berikan opsi compiler C tambahan ke skrip ./configure
Nginx atau OpenResty. Misalnya,
./configure --with-cc-opt="-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC"
Kembali ke Daftar Isi
Kembali ke Daftar Isi
Milis openresty-en ditujukan untuk penutur bahasa Inggris.
Kembali ke Daftar Isi
Milis terbuka ditujukan untuk penutur bahasa Mandarin.
Kembali ke Daftar Isi
Repositori kode proyek ini dihosting di GitHub di openresty/lua-nginx-module.
Kembali ke Daftar Isi
Silakan kirimkan laporan bug, daftar keinginan, atau patch paling lambat
Kembali ke Daftar Isi
Tonton video YouTube "Mengukur Waktu Eksekusi Kode Lua dengan Benar di OpenResty"
Sejak rilis v0.5.0rc32
, semua arahan konfigurasi *_by_lua_file
(seperti content_by_lua_file) mendukung pemuatan file bytecode mentah LuaJIT 2.0/2.1 secara langsung:
/path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc
Opsi -bg
dapat digunakan untuk memasukkan informasi debug dalam file bytecode LuaJIT:
/path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.ljbc
Silakan merujuk ke dokumentasi resmi LuaJIT pada opsi -b
untuk lebih jelasnya:
https://luajit.org/running.html#opt_b
Perhatikan bahwa file bytecode yang dihasilkan oleh LuaJIT 2.1 tidak kompatibel dengan LuaJIT 2.0, dan sebaliknya. Dukungan untuk bytecode LuaJIT 2.1 pertama kali ditambahkan di ngx_lua v0.9.3.
Upaya untuk memuat file bytecode Lua 5.1 standar ke dalam instance ngx_lua yang ditautkan ke LuaJIT 2.0/2.1 (atau sebaliknya) akan menghasilkan pesan kesalahan Nginx seperti di bawah ini:
[error] 13909#0: *1 failed to load Lua inlined code: bad byte-code header in /path/to/test_file.luac
Memuat file bytecode melalui primitif Lua seperti require
dan dofile
harus selalu berfungsi seperti yang diharapkan.
Kembali ke Daftar Isi
Jika Anda ingin mengakses variabel lingkungan sistem, katakanlah, foo
, di Lua melalui API Lua standar os.getenv, maka Anda juga harus mencantumkan nama variabel lingkungan ini di file nginx.conf
Anda melalui direktif env. Misalnya,
env foo;
Kembali ke Daftar Isi
Protokol HTTP 1.0 tidak mendukung keluaran terpotong dan memerlukan header Content-Length
eksplisit ketika isi respons tidak kosong untuk mendukung HTTP 1.0 tetap hidup. Jadi ketika permintaan HTTP 1.0 dibuat dan direktif lua_http10_buffering on
, ngx_lua akan menyangga output dari panggilan ngx.say dan ngx.print dan juga menunda pengiriman header respons hingga semua output isi respons diterima. Pada saat itu ngx_lua dapat menghitung panjang total isi dan membuat header Content-Length
yang tepat untuk kembali ke klien HTTP 1.0. Namun, jika header respon Content-Length
diatur dalam kode Lua yang sedang berjalan, buffering ini akan dinonaktifkan bahkan jika direktif lua_http10_buffering on
.
Untuk respons keluaran streaming yang besar, penting untuk menonaktifkan direktif lua_http10_buffering untuk meminimalkan penggunaan memori.
Perhatikan bahwa alat benchmark HTTP umum seperti ab
dan http_load
mengeluarkan permintaan HTTP 1.0 secara default. Untuk memaksa curl
mengirim permintaan HTTP 1.0, gunakan opsi -0
.
Kembali ke Daftar Isi
Dengan LuaJIT 2.x, dimungkinkan untuk menghubungkan bytecode modul Lua murni secara statis ke dalam executable Nginx.
Anda dapat menggunakan luajit
yang dapat dieksekusi untuk mengkompilasi file modul .lua
Lua ke file objek .o
yang berisi data bytecode yang diekspor, dan kemudian menautkan file .o
secara langsung di build Nginx Anda.
Di bawah ini adalah contoh sepele untuk menunjukkan hal ini. Anggaplah kita mempunyai file .lua
berikut bernama foo.lua
:
-- foo.lua
local _M = {}
function _M . go ()
print ( " Hello from foo " )
end
return _M
Dan kemudian kami mengkompilasi file .lua
ini menjadi file foo.o
:
/path/to/luajit/bin/luajit -bg foo.lua foo.o
Yang penting di sini adalah nama file .lua
, yang menentukan bagaimana Anda menggunakan modul ini nanti di Lua land. Nama file foo.o
tidak penting sama sekali kecuali ekstensi file .o
(yang memberi tahu luajit
format output apa yang digunakan). Jika Anda ingin menghapus informasi debug Lua dari bytecode yang dihasilkan, Anda cukup menentukan opsi -b
di atas alih-alih -bg
.
Kemudian saat membuat Nginx atau OpenResty, teruskan opsi --with-ld-opt="foo.o"
ke skrip ./configure
:
./configure --with-ld-opt= " /path/to/foo.o " ...
Terakhir, Anda dapat melakukan hal berikut pada kode Lua apa pun yang dijalankan oleh ngx_lua:
local foo = require " foo "
foo . go ()
Dan potongan kode ini tidak lagi bergantung pada file foo.lua
eksternal karena sudah dikompilasi ke dalam executable nginx
.
Jika Anda ingin menggunakan titik pada nama modul Lua ketika memanggil require
, seperti pada
local foo = require " resty.foo "
maka Anda perlu mengganti nama file foo.lua
menjadi resty_foo.lua
sebelum mengkompilasinya menjadi file .o
dengan utilitas baris perintah luajit
.
Penting untuk menggunakan versi LuaJIT yang sama persis saat mengkompilasi file .lua
ke file .o
seperti membuat nginx + ngx_lua. Hal ini karena format bytecode LuaJIT mungkin tidak kompatibel antara versi LuaJIT yang berbeda. Ketika format bytecode tidak kompatibel, Anda akan melihat kesalahan runtime Lua yang mengatakan bahwa modul Lua tidak ditemukan.
Bila Anda memiliki beberapa file .lua
untuk dikompilasi dan ditautkan, cukup tentukan file .o
-nya secara bersamaan dalam nilai opsi --with-ld-opt
. Misalnya,
./configure --with-ld-opt= " /path/to/foo.o /path/to/bar.o " ...
Jika Anda memiliki terlalu banyak file .o
, mungkin tidak mungkin untuk memberi nama semuanya dalam satu perintah. Dalam hal ini, Anda dapat membuat perpustakaan statis (atau arsip) untuk file .o
Anda, seperti pada
ar rcus libmyluafiles.a * .o
maka Anda dapat menautkan arsip myluafiles
secara keseluruhan ke executable nginx Anda:
./configure
--with-ld-opt= " -L/path/to/lib -Wl,--whole-archive -lmyluafiles -Wl,--no-whole-archive "
di mana /path/to/lib
adalah jalur direktori yang berisi file libmyluafiles.a
. Perlu dicatat bahwa opsi linker --whole-archive
diperlukan di sini karena jika tidak, arsip kita akan dilewati karena tidak ada simbol dalam arsip kita yang disebutkan di bagian utama nginx yang dapat dieksekusi.
Kembali ke Daftar Isi
Untuk berbagi data secara global di antara semua permintaan yang ditangani oleh proses pekerja Nginx yang sama, enkapsulasi data bersama ke dalam modul Lua, gunakan require
bawaan Lua untuk mengimpor modul, dan kemudian memanipulasi data bersama di Lua. Ini berfungsi karena modul Lua yang diperlukan dimuat hanya sekali dan semua coroutine akan berbagi salinan modul yang sama (baik kode maupun datanya).
Perhatikan bahwa penggunaan variabel Lua global sangat tidak disarankan , karena dapat menyebabkan kondisi balapan yang tidak terduga antara permintaan yang bersamaan.
Berikut adalah contoh kecil tentang berbagi data dalam pekerja Nginx melalui modul Lua:
-- mydata.lua
local _M = {}
local data = {
dog = 3 ,
cat = 4 ,
pig = 5 ,
}
function _M . get_age ( name )
return data [ name ]
end
return _M
dan kemudian mengaksesnya dari nginx.conf
:
location /lua {
content_by_lua_block {
local mydata = require "mydata"
ngx.say(mydata.get_age("dog"))
}
}
Modul mydata
dalam contoh ini hanya akan dimuat dan dijalankan pada permintaan pertama ke lokasi /lua
, dan semua permintaan berikutnya ke proses pekerja Nginx yang sama akan menggunakan instance modul yang dimuat ulang serta salinan data yang sama di itu, hingga sinyal HUP
dikirim ke proses master Nginx untuk memaksa memuat ulang. Teknik berbagi data ini penting untuk aplikasi Lua berkinerja tinggi berdasarkan modul ini.
Perhatikan bahwa pembagian data ini dilakukan berdasarkan per pekerja dan bukan berdasarkan per server . Artinya, ketika ada beberapa proses pekerja Nginx di bawah master Nginx, pembagian data tidak dapat melewati batas proses di antara para pekerja tersebut.
Biasanya disarankan untuk membagikan data hanya-baca dengan cara ini. Anda juga dapat berbagi data yang dapat diubah di antara semua permintaan bersamaan dari setiap proses pekerja Nginx selama tidak ada operasi I/O yang tidak memblokir (termasuk ngx.sleep) di tengah perhitungan Anda. Selama Anda tidak mengembalikan kendali ke loop peristiwa Nginx dan penjadwal thread ringan ngx_lua (bahkan secara implisit), tidak akan pernah ada kondisi balapan apa pun di antaranya. Oleh karena itu, selalu berhati-hatilah saat Anda ingin membagikan data yang dapat diubah di tingkat pekerja. Pengoptimalan buggy dapat dengan mudah menyebabkan kondisi balapan yang sulit di-debug saat memuat.
Jika berbagi data di seluruh server diperlukan, gunakan satu atau beberapa pendekatan berikut:
memcached
, redis
, MySQL
atau PostgreSQL
. Rilis resmi OpenResty hadir dengan serangkaian modul pendamping Nginx dan pustaka Lua yang menyediakan antarmuka dengan mekanisme penyimpanan data ini.Kembali ke Daftar Isi
Kembali ke Daftar Isi
Metode tcpsock:connect mungkin menunjukkan success
meskipun terjadi kegagalan koneksi seperti kesalahan Connection Refused
.
Namun, upaya selanjutnya untuk memanipulasi objek cosocket akan gagal dan mengembalikan pesan status kesalahan aktual yang dihasilkan oleh operasi koneksi yang gagal.
Masalah ini disebabkan oleh keterbatasan model kejadian Nginx dan tampaknya hanya memengaruhi Mac OS X.
Kembali ke Daftar Isi
dofile
Lua dan require
bawaannya saat ini diimplementasikan sebagai fungsi C di LuaJIT 2.0/2.1, jika file Lua dimuat oleh dofile
atau require
akan memanggil ngx.location.capture*, ngx.exec, ngx.exit, atau fungsi API lainnya yang memerlukan hasil dalam cakupan tingkat atas berkas Lua, maka kesalahan Lua "mencoba menghasilkan melintasi batas panggilan-C" akan dimunculkan. Untuk menghindari hal ini, letakkan panggilan-panggilan ini yang memerlukan penyerahan ke dalam fungsi-fungsi Lua Anda sendiri di dalam berkas Lua dan bukannya lingkup berkas tingkat atas.Kembali ke Daftar Isi
Kehati-hatian harus diberikan saat mengimpor modul, dan formulir ini harus digunakan:
local xxx = require ( ' xxx ' )
alih-alih formulir lama yang tidak digunakan lagi:
require ( ' xxx ' )
Inilah alasannya: berdasarkan desain, lingkungan global memiliki masa hidup yang sama persis dengan penangan permintaan Nginx yang terkait dengannya. Setiap penangan permintaan memiliki kumpulan variabel global Lua sendiri dan itulah gagasan isolasi permintaan. Modul Lua sebenarnya dimuat oleh penangan permintaan Nginx pertama dan di-cache oleh require()
bawaan dalam tabel package.loaded
untuk referensi nanti, dan module()
bawaan yang digunakan oleh beberapa modul Lua memiliki efek samping pengaturan variabel global ke tabel modul yang dimuat. Namun variabel global ini akan dihapus pada akhir penangan permintaan, dan setiap penangan permintaan berikutnya memiliki lingkungan globalnya sendiri (bersih). Jadi seseorang akan mendapatkan pengecualian Lua untuk mengakses nilai nil
.
Penggunaan variabel global Lua umumnya tidak disarankan dalam konteks ngx_lua karena:
Oleh karena itu sangat disarankan untuk selalu mendeklarasikannya dalam lingkup lokal yang sesuai.
-- Avoid
foo = 123
-- Recommended
local foo = 123
-- Avoid
function foo () return 123 end
-- Recommended
local function foo () return 123 end
Untuk menemukan semua contoh variabel global Lua dalam kode Lua Anda, jalankan alat lua-releng di semua file sumber .lua
:
$ lua-releng
Checking use of Lua global variables in file lib/foo/bar.lua ...
1 [1489] SETGLOBAL 7 -1 ; contains
55 [1506] GETGLOBAL 7 -3 ; setvar
3 [1545] GETGLOBAL 3 -4 ; varexpand
Outputnya mengatakan bahwa baris 1489 dari file lib/foo/bar.lua
menulis ke variabel global bernama contains
, baris 1506 membaca dari variabel global setvar
, dan baris 1545 membaca global varexpand
.
Alat ini akan menjamin bahwa variabel lokal dalam fungsi modul Lua semuanya dideklarasikan dengan kata kunci local
, jika tidak, pengecualian waktu proses akan dilempar. Ini mencegah kondisi balapan yang tidak diinginkan saat mengakses variabel tersebut. Lihat Berbagi Data dalam Nginx Worker untuk mengetahui alasan dibalik hal ini.
Kembali ke Daftar Isi
Direktif ngx.location.capture dan ngx.location.capture_multi tidak dapat menangkap lokasi yang menyertakan direktif add_before_body, add_after_body, auth_request, echo_location, echo_location_async, echo_subrequest, atau echo_subrequest_async.
location /foo {
content_by_lua_block {
res = ngx.location.capture( "/bar" )
}
}
location /bar {
echo_location /blah;
}
location /blah {
echo "Success!" ;
}
$ curl -i http://example.com/foo
tidak akan berfungsi seperti yang diharapkan.
Kembali ke Daftar Isi
Karena keterbatasan internal pada inti Nginx, API cosocket dinonaktifkan dalam konteks berikut: set_by_lua*, log_by_lua*, header_filter_by_lua*, dan body_filter_by_lua.
Cosocket saat ini juga dinonaktifkan dalam konteks arahan init_by_lua* dan init_worker_by_lua* tetapi kami dapat menambahkan dukungan untuk konteks ini di masa mendatang karena tidak ada batasan pada inti Nginx (atau batasan tersebut mungkin dapat diatasi).
Namun, terdapat solusi ketika konteks asli tidak perlu menunggu hasil cosocket. Artinya, membuat pengatur waktu tanpa penundaan melalui API ngx.timer.at dan melakukan hasil cosocket di pengendali pengatur waktu, yang berjalan secara asinkron sesuai dengan konteks asli pembuatan pengatur waktu.
Kembali ke Daftar Isi
CATATAN Setelah rilis v0.9.17
, kesalahan ini bisa dihindari dengan menggunakan arahan konfigurasi *_by_lua_block {}
.
Urutan PCRE seperti d
, s
, atau w
, memerlukan perhatian khusus karena dalam literal string, karakter garis miring terbalik, , dihilangkan oleh parser bahasa Lua dan parser file konfigurasi Nginx sebelum diproses jika tidak dalam a
*_by_lua_block {}
direktif. Jadi cuplikan berikut tidak akan berfungsi seperti yang diharapkan:
# nginx.conf
? location /test {
? content_by_lua '
? local regex = "d+" -- THIS IS WRONG OUTSIDE OF A *_by_lua_block DIRECTIVE
? local m = ngx.re.match("hello, 1234", regex)
? if m then ngx.say(m[0]) else ngx.say("not matched!") end
? ' ;
? }
# evaluates to "not matched!"
Untuk menghindari hal ini, keluarkan dua kali garis miring terbalik:
# nginx.conf
location /test {
content_by_lua '
local regex = "\\d+"
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
Di sini, \\d+
dipreteli menjadi \d+
oleh parser file konfigurasi Nginx dan selanjutnya dipreteli menjadi d+
oleh parser bahasa Lua sebelum dijalankan.
Alternatifnya, pola regex dapat disajikan sebagai string literal Lua yang diberi tanda kurung panjang dengan membungkusnya dalam "tanda kurung panjang", [[...]]
, dalam hal ini garis miring terbalik hanya perlu di-escape sekali untuk pengurai file konfigurasi Nginx.
# nginx.conf
location /test {
content_by_lua '
local regex = [[\d+]]
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
Di sini, [[\d+]]
dihilangkan menjadi [[d+]]
oleh parser file konfigurasi Nginx dan ini diproses dengan benar.
Perhatikan bahwa tanda kurung panjang yang lebih panjang, [=[...]=]
, mungkin diperlukan jika pola regex berisi urutan [...]
. Formulir [=[...]=]
dapat digunakan sebagai formulir default jika diinginkan.
# nginx.conf
location /test {
content_by_lua '
local regex = [=[[0-9]+]=]
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
Pendekatan alternatif untuk keluar dari rangkaian PCRE adalah dengan memastikan bahwa kode Lua ditempatkan di file skrip eksternal dan dieksekusi menggunakan berbagai direktif *_by_lua_file
. Dengan pendekatan ini, garis miring terbalik hanya dihilangkan oleh pengurai bahasa Lua dan oleh karena itu hanya perlu di-escape masing-masing satu kali.
-- test.lua
local regex = " \ d+ "
local m = ngx . re . match ( " hello, 1234 " , regex )
if m then ngx . say ( m [ 0 ]) else ngx . say ( " not matched! " ) end
-- evaluates to "1234"
Di dalam file skrip eksternal, urutan PCRE yang disajikan sebagai literal string Lua yang diberi tanda kurung panjang tidak memerlukan modifikasi.
-- test.lua
local regex = [[ d+ ]]
local m = ngx . re . match ( " hello, 1234 " , regex )
if m then ngx . say ( m [ 0 ]) else ngx . say ( " not matched! " ) end
-- evaluates to "1234"
Seperti disebutkan sebelumnya, urutan PCRE yang disajikan dalam direktif *_by_lua_block {}
(tersedia setelah rilis v0.9.17
) tidak memerlukan modifikasi.
# nginx.conf
location /test {
content_by_lua_block {
local regex = [[d+]]
local m = ngx.re.match( "hello, 1234" , regex)
if m then ngx.say(m[0]) else ngx.say( "not matched!" ) end
}
}
# evaluates to "1234"
CATATAN Anda dianjurkan untuk menggunakan by_lua_file
ketika kode Lua sangat panjang.
Kembali ke Daftar Isi
Mencampur SSI dengan ngx_lua dalam permintaan Nginx yang sama tidak didukung sama sekali. Cukup gunakan ngx_lua secara eksklusif. Segala sesuatu yang dapat Anda lakukan dengan SSI tetap dapat dilakukan di atas ngx_lua dan akan lebih efisien bila menggunakan ngx_lua.
Kembali ke Daftar Isi
Lua API tertentu yang disediakan oleh ngx_lua belum berfungsi dalam mode SPDY Nginx: ngx.location.capture, ngx.location.capture_multi, dan ngx.req.socket.
Kembali ke Daftar Isi
Nginx dapat menghentikan permintaan lebih awal dengan (setidaknya):
Artinya fase yang biasanya berjalan dilewati, seperti fase penulisan ulang atau akses. Ini juga berarti bahwa fase selanjutnya yang dijalankan, misalnya log_by_lua, tidak akan memiliki akses ke informasi yang biasanya diatur dalam fase tersebut.
Kembali ke Daftar Isi
bsdrecv
.ngx_hash_t
untuk mengoptimalkan proses pencarian header bawaan untuk ngx.req.set_header, dan lain-lain.ignore_resp_headers
, ignore_resp_body
, dan ignore_resp
ke metode ngx.location.capture dan ngx.location.capture_multi, untuk memungkinkan penyesuaian kinerja mikro di sisi pengguna.stat
mirip dengan mod_lua.Kembali ke Daftar Isi
Perubahan yang dilakukan pada setiap rilis modul ini tercantum dalam log perubahan bundel OpenResty:
https://openresty.org/#Changes
Kembali ke Daftar Isi
Dependensi berikut diperlukan untuk menjalankan rangkaian pengujian:
Versi Nginx >= 1.4.2
Modul Perl:
Modul Nginx:
Urutan penambahan modul-modul ini selama konfigurasi penting karena, misalnya, posisi modul filter apa pun dalam rantai pemfilteran menentukan hasil akhir. Urutan penambahan yang benar ditunjukkan di atas.
Perpustakaan Lua pihak ketiga:
Aplikasi: