---
title: "Tiga Library Lua Resty yang Sering Digunakan di OpenResty - API7.ai"
description: "Mari kita pelajari library Lua Resty yang umum digunakan di OpenResty: `lua-resty-ngxvar`, `lua-rapidjson`, dan `lua-resty-worker-events`."
url: "https://api7.ai/id/learning-center/openresty/lua-resty-libraries-in-openresty"
---

# Tiga Library Lua Resty yang Sering Digunakan di OpenResty

API7.ai

January 13, 2023

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

Mempelajari bahasa pemrograman dan platform seringkali merupakan masalah memahami pustaka standar dan pihak ketiga daripada sintaks itu sendiri. Setelah mempelajari API dan teknik optimasi kinerjanya, kita perlu mempelajari penggunaan berbagai pustaka `lua-resty` untuk memperluas kemampuan OpenResty kita ke lebih banyak skenario.

## Di mana menemukan pustaka `lua-resty`?

Dibandingkan dengan PHP, Python, dan JavaScript, pustaka standar dan pihak ketiga OpenResty saat ini masih relatif terbatas, dan menemukan pustaka `lua-resty` yang tepat tidaklah mudah. Namun, berikut adalah dua sumber yang direkomendasikan untuk membantu Anda menemukannya lebih cepat.

Rekomendasi pertama adalah repositori [`awesome-resty`](https://github.com/bungle/awesome-resty) yang dikelola oleh Aapo. Repositori ini mengorganisir pustaka terkait OpenResty berdasarkan kategori dan sangat lengkap, termasuk modul C NGINX, pustaka `lua-resty`, kerangka kerja web, pustaka routing, template, kerangka kerja pengujian, dll. Ini adalah pilihan utama Anda untuk sumber daya OpenResty.

Jika Anda tidak menemukan pustaka yang tepat di repositori Aapo, Anda juga dapat melihat `luarocks`, `topm`, atau GitHub. Mungkin ada beberapa pustaka yang belum lama dibuka sumbernya dan belum banyak mendapat perhatian.

Dalam artikel sebelumnya, kita telah mempelajari beberapa pustaka yang berguna seperti `lua-resty-mlcache`, `lua-resty-traffic`, `lua-resty-shell`, dll. Hari ini, dalam artikel terakhir dari bagian optimasi kinerja OpenResty, kita akan mengenal 3 pustaka periferal unik lainnya, semuanya merupakan kontribusi dari pengembang di komunitas.

## Peningkatan kinerja `ngx.var`

Pertama, mari kita lihat modul C: [`lua-var-nginx-module`](https://github.com/api7/lua-var-nginx-module). Seperti yang saya sebutkan sebelumnya, `ngx.var` adalah operasi yang relatif memakan kinerja. Oleh karena itu, dalam praktiknya, kita perlu menggunakan `ngx.ctx` sebagai lapisan cache.

Jadi, adakah cara untuk sepenuhnya menyelesaikan masalah kinerja `ngx.var`?

Modul C ini melakukan beberapa eksperimen dalam hal ini, dan hasilnya cukup menakjubkan, dengan peningkatan kinerja 5x dibandingkan `ngx.var`. Modul ini menggunakan pendekatan `FFI`, jadi Anda perlu mengompilasi OpenResty dengan opsi kompilasi berikut terlebih dahulu.

```
./configure --prefix=/opt/openresty \
         --add-module=/path/to/lua-var-nginx-module
```

Kemudian gunakan `luarocks` untuk menginstal pustaka lua dengan cara berikut:

```
luarocks install lua-resty-ngxvar
```

Metode yang dipanggil di sini juga sangat sederhana, hanya memerlukan satu baris fungsi `fetch`. Ini bekerja sama dengan `ngx.var.remote_addr` asli untuk mendapatkan alamat IP klien.

```
content_by_lua_block {
    local var = require("resty.ngxvar")
    ngx.say(var.fetch("remote_addr"))
}
```

Setelah memahami operasi dasar ini, Anda mungkin lebih penasaran tentang bagaimana modul ini mencapai peningkatan kinerja yang signifikan. Seperti yang selalu kita katakan, "tidak ada rahasia di depan kode sumber". Jadi mari kita cari tahu cara mengambil variabel `remote_addr`.

```
ngx_int_t
ngx_http_lua_var_ffi_remote_addr(ngx_http_request_t *r, ngx_str_t *remote_addr)
{
    remote_addr->len = r->connection->addr_text.len;
    remote_addr->data = r->connection->addr_text.data;

    return NGX_OK;
}
```

Setelah membaca kode ini, Anda akan melihat bahwa pendekatan Lua `FFI` ini sama dengan pendekatan `lua-resty-core`. Ini memiliki keuntungan yang jelas dengan menggunakan `FFI` untuk mendapatkan variabel secara langsung, melewati logika pencarian asli dari `ngx.var`. Kerugiannya jelas: menambahkan fungsi C dan panggilan `FFI` untuk setiap variabel yang ingin Anda dapatkan, yang memakan waktu dan tenaga.

Beberapa orang mungkin bertanya, "Mengapa saya mengatakan ini memakan waktu dan tenaga? Bukankah kode C di atas terlihat cukup substansial?" Mari kita lihat sumber dari beberapa baris kode ini, yang berasal dari `src/http/ngx_http_variables.c` dalam kode NGINX.

```
static ngx_int_t
ngx_http_variable_remote_addr(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
    v->len = r->connection->addr_text.len;
    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->data = r->connection->addr_text.data;

    return NGX_OK;
}
```

Setelah melihat kode sumber, misteri terungkap! `lua-var-nginx-module` adalah porter dari kode variabel NGINX, dengan pembungkus FFI di lapisan luar, dan dengan cara ini, modul ini mencapai optimasi kinerja. Ini adalah ide yang bagus dan arah yang baik untuk optimasi.

Ketika mempelajari pustaka atau alat, kita tidak boleh hanya berhenti pada tingkat operasi, tetapi juga bertanya mengapa kita melakukannya dan melihat kode sumbernya. Tentu saja, saya juga sangat mendorong Anda untuk berkontribusi kode untuk mendukung lebih banyak variabel NGINX.

## JSON Schema

Di sini saya memperkenalkan pustaka `lua-resty`: [`lua-rapidjson`](https://github.com/xpol/lua-rapidjson). Ini adalah pembungkus di sekitar `rapidjson`, pustaka JSON sumber terbuka milik Tencent, dan dikenal karena kinerjanya. Di sini, kita fokus pada perbedaan antara itu dan `cjson`: dukungan `JSON Schema`.

`JSON Schema` adalah standar umum yang memungkinkan kita untuk secara tepat mendeskripsikan format parameter dalam antarmuka dan bagaimana mereka harus divalidasi. Berikut adalah contoh sederhana:

```
"stringArray": {
    "type": "array",
    "items": { "type": "string" },
    "minItems": 1,
    "uniqueItems": true
}
```

JSON ini secara akurat mendeskripsikan bahwa parameter `stringArray` adalah tipe array string dan bahwa array tidak boleh kosong, dan elemen array tidak boleh duplikat.

`lua-rapidjson` memungkinkan kita untuk menggunakan JSON Schema di OpenResty, yang dapat membawa kemudahan besar dalam validasi antarmuka. Misalnya, untuk antarmuka batas hitungan yang dijelaskan sebelumnya, kita dapat menggunakan skema berikut untuk mendeskripsikannya:

```
local schema = {
    type = "object",
    properties = {
        count = {type = "integer", minimum = 0},
        time_window = {type = "integer",  minimum = 0},
        key = {type = "string", enum = {"remote_addr", "server_addr"}},
        rejected_code = {type = "integer", minimum = 200, maximum = 600},
    },
    additionalProperties = false,
    required = {"count", "time_window", "key", "rejected_code"},
}
```

Anda akan menemukan bahwa ini dapat menghasilkan dua manfaat yang sangat jelas:

1. Untuk front end, front end dapat langsung menggunakan kembali deskripsi skema ini untuk pengembangan halaman front end dan validasi parameter tanpa harus memikirkan back end.
2. Untuk back end, back end langsung menggunakan fungsi validasi skema `SchemaValidator` dari `lua-rapidjson` untuk menentukan legitimasi antarmuka, dan tidak perlu menulis kode tambahan.

## Komunikasi `Worker`

Terakhir, saya ingin membahas pustaka `lua-resty` yang memungkinkan komunikasi antar worker di OpenResty, di mana tidak ada mekanisme komunikasi langsung antar worker, yang menimbulkan banyak masalah. Mari kita bayangkan sebuah skenario:

> Sebuah layanan OpenResty memiliki 24 proses worker, dan ketika administrator memperbarui konfigurasi sistem melalui REST HTTP APIs, hanya satu `Worker` yang menerima pembaruan dari administrator dan menulis hasilnya ke database, memperbarui `shared dict` dan `lru cache` di dalam Worker-nya sendiri. Jadi, bagaimana 23 worker lainnya dapat diberitahu untuk memperbarui konfigurasi ini?

Sebuah mekanisme pemberitahuan di antara beberapa `Worker` diperlukan untuk menyelesaikan tugas di atas. Dalam kasus bahwa OpenResty tidak mendukungnya, kita harus menyelamatkan situasi dengan data `shared dict` yang dapat diakses oleh semua worker.

[`lua-resty-worker-events`](https://github.com/Kong/lua-resty-worker-events) adalah implementasi konkret dari ide ini. Ini mempertahankan nomor versi dalam `shared dict`, dan ketika pesan baru diterbitkan, itu menambahkan satu ke nomor versi dan memasukkan konten pesan ke dalam kamus dengan nomor versi sebagai `key`.

```
event_id, err = _dict:incr(KEY_LAST_ID, 1)
success, err = _dict:add(KEY_DATA .. tostring(event_id), json)
```

Juga, sebuah loop `polling` dengan interval default 1 detik dibuat di latar belakang menggunakan `ngx.timer` untuk terus memeriksa perubahan dalam nomor versi:

```
local event_id, err = get_event_id()
if event_id == _last_event then
    return "done"
end
```

Dengan cara ini, segera setelah pemberitahuan event baru ditemukan untuk diproses, konten pesan diambil dari `shared dict` berdasarkan nomor versi:

```
while _last_event < event_id do
    count = count + 1
    _last_event = _last_event + 1
    data, err = _dict:get(KEY_DATA..tostring(_last_event))
end
```

Secara keseluruhan, meskipun `lua-resty-worker-events` memiliki penundaan satu detik, itu masih mengimplementasikan mekanisme pemberitahuan event antar Worker.

Namun, dalam beberapa skenario real-time, seperti push pesan, kurangnya komunikasi langsung antara proses `Worker` di OpenResty dapat menyebabkan Anda beberapa masalah. Tidak ada solusi yang lebih baik untuk ini, tetapi jika Anda memiliki ide bagus, silakan diskusikan di Github. Banyak fitur OpenResty didorong oleh komunitas untuk membangun siklus ekologis yang baik.

## Ringkasan

Tiga pustaka yang kami perkenalkan hari ini unik dan membawa lebih banyak kemungkinan untuk aplikasi OpenResty. Terakhir, sebuah topik interaktif, apakah Anda menemukan pustaka menarik di sekitar OpenResty? Atau apa yang Anda temukan atau pertanyakan tentang pustaka yang disebutkan hari ini? Anda dipersilakan untuk mengirim artikel ini ke pengguna OpenResty di sekitar Anda untuk bertukar dan berkembang bersama.

Share article link

Share

Related Posts

[![OpenResty FAQ | Bagaimana OpenResty Digunakan dalam Praktik](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [OpenResty FAQ | Bagaimana OpenResty Digunakan dalam Praktik](https://api7.ai/learning-center/openresty/faq-5)

[![Bagian 3: Cara Membangun Microservices API Gateway Menggunakan OpenResty](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [Bagian 3: Cara Membangun Microservices API Gateway Menggunakan OpenResty](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [Di mana menemukan pustaka `lua-resty`?](#di-mana-menemukan-pustaka-lua-resty)
- [Peningkatan kinerja `ngx.var`](#peningkatan-kinerja-ngxvar)
- [JSON Schema](#json-schema)
- [Komunikasi `Worker`](#komunikasi-worker)
- [Ringkasan](#ringkasan)
