---
title: "Drei häufig verwendete Lua Resty-Bibliotheken in OpenResty - API7.ai"
description: "Lassen Sie uns die häufig verwendeten Lua Resty-Bibliotheken in OpenResty kennenlernen: `lua-resty-ngxvar`, `lua-rapidjson` und `lua-resty-worker-events`."
url: "https://api7.ai/de/learning-center/openresty/lua-resty-libraries-in-openresty"
---

# Drei häufig verwendete Lua Resty-Bibliotheken in OpenResty

API7.ai

January 13, 2023

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

Das Erlernen von Programmiersprachen und Plattformen ist oft eine Frage des Verständnisses der Standard- und Drittanbieter-Bibliotheken und nicht der Syntax selbst. Nachdem wir die API und Leistungsoptimierungstechniken gelernt haben, müssen wir die Verwendung verschiedener `lua-resty`-Bibliotheken erlernen, um unsere OpenResty-Fähigkeiten auf mehr Szenarien auszudehnen.

## Wo findet man die `lua-resty`-Bibliothek?

Im Vergleich zu PHP, Python und JavaScript sind die aktuellen Standard- und Drittanbieter-Bibliotheken von OpenResty noch relativ spärlich, und es ist nicht einfach, die richtigen `lua-resty`-Bibliotheken zu finden. Hier sind jedoch zwei empfohlene Quellen, die Ihnen helfen, sie schneller zu finden.

Die erste Empfehlung ist das von Aapo gepflegte Repository [`awesome-resty`](https://github.com/bungle/awesome-resty). Dieses Repository organisiert OpenResty-bezogene Bibliotheken nach Kategorien und ist allumfassend, einschließlich NGINX-C-Module, `lua-resty`-Bibliotheken, Web-Frameworks, Routing-Bibliotheken, Templates, Test-Frameworks usw. Es ist Ihre erste Wahl für OpenResty-Ressourcen.

Wenn Sie in Aapos Repository nicht die richtige Bibliothek finden, können Sie auch bei `luarocks`, `topm` oder GitHub nachschauen. Es könnte einige Bibliotheken geben, die noch nicht lange Open Source sind und nicht viel Aufmerksamkeit erhalten haben.

In den vorherigen Artikeln haben wir bereits einige nützliche Bibliotheken wie `lua-resty-mlcache`, `lua-resty-traffic`, `lua-resty-shell` usw. kennengelernt. Heute, im letzten Artikel des OpenResty-Leistungsoptimierungsabschnitts, lernen wir drei weitere einzigartige periphere Bibliotheken kennen, die alle von Entwicklern in der Community beigetragen wurden.

## Leistungsverbesserung von `ngx.var`

Zuerst schauen wir uns ein C-Modul an: [`lua-var-nginx-module`](https://github.com/api7/lua-var-nginx-module). Wie ich bereits erwähnt habe, ist `ngx.var` eine relativ leistungsintensive Operation. Daher müssen wir in der Praxis `ngx.ctx` als eine Ebene des Caches verwenden.

Gibt es also eine Möglichkeit, das Leistungsproblem von `ngx.var` vollständig zu lösen?

Dieses C-Modul hat in dieser Hinsicht einige Experimente durchgeführt, und die Ergebnisse sind bemerkenswert, mit einer 5-fachen Leistungssteigerung gegenüber `ngx.var`. Es verwendet den `FFI`-Ansatz, daher müssen Sie OpenResty zuerst mit der folgenden Kompilierungsoption kompilieren.

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

Dann installieren Sie die Lua-Bibliothek mit `luarocks` auf folgende Weise:

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

Die hier aufgerufene Methode ist ebenfalls sehr einfach und erfordert nur eine Zeile der `fetch`-Funktion. Sie funktioniert genauso wie das ursprüngliche `ngx.var.remote_addr`, um die IP-Adresse des Clients zu erhalten.

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

Nachdem Sie diese grundlegenden Operationen verstanden haben, sind Sie vielleicht neugieriger darauf, wie dieses Modul eine signifikante Leistungssteigerung erreicht. Wie wir immer sagen: "Vor dem Quellcode gibt es keine Geheimnisse". Lassen Sie uns also herausfinden, wie die `remote_addr`-Variable abgerufen wird.

```
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;
}
```

Nachdem Sie diesen Code gelesen haben, werden Sie sehen, dass dieser Lua-`FFI`-Ansatz dem Ansatz von `lua-resty-core` entspricht. Es hat den offensichtlichen Vorteil, dass `FFI` verwendet wird, um Variablen direkt zu erhalten und die ursprüngliche Suchlogik von `ngx.var` zu umgehen. Sein Nachteil ist offensichtlich: Das Hinzufügen von C-Funktionen und `FFI`-Aufrufen für jede Variable, die Sie erhalten möchten, ist zeit- und energieaufwendig.

Einige Leute mögen fragen: "Warum sage ich, dass dies zeit- und energieaufwendig ist? Sieht der obige C-Code nicht ziemlich substanziell aus?" Schauen wir uns die Quelle dieser Codezeilen an, die aus `src/http/ngx_http_variables.c` im NGINX-Code stammen.

```
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;
}
```

Nachdem Sie den Quellcode gesehen haben, ist das Geheimnis gelüftet! `lua-var-nginx-module` ist ein Portier des NGINX-Variablencodes, mit FFI-Wrapping in der äußeren Schicht, und auf diese Weise erreicht es Leistungsoptimierung. Dies ist eine gute Idee und eine gute Richtung für die Optimierung.

Wenn Sie eine Bibliothek oder ein Werkzeug lernen, dürfen Sie nicht nur auf der Ebene der Operation stehen bleiben, sondern müssen auch fragen, warum wir es tun, und den Quellcode betrachten. Natürlich ermutige ich Sie auch stark, Code beizutragen, um mehr NGINX-Variablen zu unterstützen.

## JSON Schema

Hier stelle ich eine `lua-resty`-Bibliothek vor: [`lua-rapidjson`](https://github.com/xpol/lua-rapidjson). Es ist ein Wrapper um `rapidjson`, die Open-Source-JSON-Bibliothek von Tencent, und ist für ihre Leistung bekannt. Hier konzentrieren wir uns auf den Unterschied zwischen ihr und `cjson`: `JSON Schema`-Unterstützung.

`JSON Schema` ist ein gängiger Standard, der es uns ermöglicht, das Format der Parameter in einer Schnittstelle genau zu beschreiben und wie sie validiert werden sollen. Hier ist ein einfaches Beispiel:

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

Dieses JSON beschreibt genau, dass der `stringArray`-Parameter ein String-Array ist und dass das Array nicht leer sein darf, noch können die Array-Elemente dupliziert werden.

`lua-rapidjson` ermöglicht es uns, JSON Schema in OpenResty zu verwenden, was der Schnittstellenvalidierung große Vorteile bringen kann. Zum Beispiel können wir für die zuvor beschriebene Limit-Count-Schnittstelle das folgende Schema verwenden:

```
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"},
}
```

Sie werden feststellen, dass dies zwei sehr offensichtliche Vorteile hat:

1. Für das Frontend kann das Frontend diese Schema-Beschreibung direkt für die Frontend-Seitenentwicklung und Parametervalidierung wiederverwenden, ohne sich um das Backend kümmern zu müssen.
2. Für das Backend verwendet das Backend direkt die Schema-Validierungsfunktion `SchemaValidator` von `lua-rapidjson`, um die Legitimität der Schnittstelle zu bestimmen, und es ist keine zusätzliche Code-Erstellung erforderlich.

## `Worker`-Kommunikation

Schließlich möchte ich über die `lua-resty`-Bibliothek sprechen, die die Kommunikation zwischen Workern in OpenResty ermöglicht, wo es keinen Mechanismus für die direkte Kommunikation zwischen Workern gibt, was viele Probleme verursacht. Stellen wir uns ein Szenario vor:

> Ein OpenResty-Dienst hat 24 Worker-Prozesse, und wenn der Administrator eine Konfiguration des Systems über die REST-HTTP-APIs aktualisiert, erhält nur ein `Worker` die Aktualisierung vom Administrator und schreibt das Ergebnis in die Datenbank, aktualisiert das `shared dict` und den `lru cache` innerhalb seines eigenen Workers. Wie können also die anderen 23 Worker benachrichtigt werden, diese Konfiguration zu aktualisieren?

Ein Benachrichtigungsmechanismus zwischen mehreren `Worker`s ist erforderlich, um die obige Aufgabe zu erfüllen. In dem Fall, dass OpenResty dies nicht unterstützt, müssen wir mit `shared dict`-Daten über Worker hinweg retten.

[`lua-resty-worker-events`](https://github.com/Kong/lua-resty-worker-events) ist eine konkrete Implementierung dieser Idee. Es verwaltet eine Versionsnummer in einem `shared dict`, und wenn eine neue Nachricht veröffentlicht wird, wird die Versionsnummer um eins erhöht und der Inhalt der Nachricht mit der Versionsnummer als `key` in das Wörterbuch gelegt.

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

Außerdem wird im Hintergrund eine `polling`-Schleife mit einem Standardintervall von 1 Sekunde mit `ngx.timer` erstellt, um ständig nach Änderungen in der Versionsnummer zu suchen:

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

Auf diese Weise wird, sobald eine neue Ereignisbenachrichtigung zur Verarbeitung gefunden wird, der Nachrichteninhalt basierend auf der Versionsnummer aus dem `shared dict` abgerufen:

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

Insgesamt hat `lua-resty-worker-events` zwar eine Verzögerung von einer Sekunde, implementiert aber dennoch einen Worker-zu-Worker-Ereignisbenachrichtigungsmechanismus.

In einigen Echtzeit-Szenarien, wie z.B. beim Nachrichten-Pushing, kann das Fehlen einer direkten Kommunikation zwischen `Worker`-Prozessen in OpenResty jedoch einige Probleme verursachen. Es gibt keine bessere Lösung dafür, aber wenn Sie gute Ideen haben, diskutieren Sie diese bitte auf Github. Viele Funktionen von OpenResty werden von der Community angetrieben, um einen virtuellen ökologischen Kreislauf aufzubauen.

## Zusammenfassung

Die drei Bibliotheken, die wir heute vorgestellt haben, sind einzigartig und eröffnen mehr Möglichkeiten für OpenResty-Anwendungen. Zum Schluss ein interaktives Thema: Haben Sie interessante Bibliotheken rund um OpenResty gefunden? Oder was finden oder fragen Sie sich über die heute erwähnten Bibliotheken? Sie sind herzlich eingeladen, diesen Artikel an die OpenResty-Benutzer in Ihrer Umgebung zu senden, um gemeinsam auszutauschen und Fortschritte zu machen.

Share article link

Share

Related Posts

[![OpenResty FAQ | Wie OpenResty in der Praxis eingesetzt wird](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 | Wie OpenResty in der Praxis eingesetzt wird](https://api7.ai/learning-center/openresty/faq-5)

[![Teil 3: Wie man ein Microservices API Gateway mit OpenResty erstellt](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)

## [Teil 3: Wie man ein Microservices API Gateway mit OpenResty erstellt](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [Wo findet man die `lua-resty`-Bibliothek?](#wo-findet-man-die-lua-resty-bibliothek)
- [Leistungsverbesserung von `ngx.var`](#leistungsverbesserung-von-ngxvar)
- [JSON Schema](#json-schema)
- [`Worker`-Kommunikation](#worker-kommunikation)
- [Zusammenfassung](#zusammenfassung)
