Que se passe-t-il en cas de conflit entre les règles Lua et la configuration NGINX ?
API7.ai
October 13, 2022
1. Le nom et le langage d'OpenResty
Q : Je n'ai pas compris l'origine du nom OpenResty jusqu'à présent. De plus, OpenResty prend son envol avec le langage Lua, alors pourquoi pas avec d'autres langages de script ? Par exemple, Shell, etc.
R : OpenResty a commencé comme un projet d'entreprise de Yahoo!, qui a débuté en octobre 2007. Le nom "Open" a été tiré d'OpenAPI, et "Resty" a été tiré de rest API. Initialement, OpenResty n'était pas destiné à être un serveur web et une plateforme de développement, mais une application comme un site web.
Lorsqu'OpenResty a été open-sourcé il y a plus de dix ans, très peu de langages prenaient en charge le non-blocage synchrone. Même aujourd'hui, peu de langages back-end peuvent atteindre ce niveau de performance avec OpenResty. Actuellement, de plus en plus de développeurs utilisent OpenResty dans les passerelles API et les WAF logiciels, ce qui est un choix naturel pour les développeurs.
Quant au langage, OpenResty n'est pas le seul projet à intégrer d'autres langages de développement dans NGINX. Par exemple, NGINX intègre officiellement JS ; il existe également des projets open source qui intègrent PHP dans NGINX.
En général, le choix du langage à exploiter est basé sur des facteurs tels que la concurrence, le JIT et la popularité du langage. Pour OpenResty, en 2007, Lua était effectivement le meilleur choix. OpenResty a fait un détour en choisissant perl plutôt que Lua dans ses premières versions.
2. La priorité des règles de configuration
Q : Lorsque les règles Lua dans OpenResty entrent en conflit avec le fichier de configuration NGINX, par exemple, NGINX configure des règles de réécriture, et en même temps fait référence à rewrite_by_lua_file, quelle est alors la priorité de ces deux règles ?
R : En fait, cela dépend de la manière dont la règle de réécriture NGINX est écrite, qu'il s'agisse d'un break
ou d'un last
, comme indiqué dans la documentation officielle d'OpenResty, avec un exemple de code :
location /foo {
rewrite ^ /bar;
rewrite_by_lua 'ngx.exit(503)';
}
location /bar {
...
}
Dans cette configuration de l'exemple de code, ngx.exit(503)
ne sera pas exécuté.
Cependant, si vous l'écrivez comme suit, ngx.exit(503)
sera exécuté.
rewrite ^ /bar break.
Cependant, je recommande d'utiliser OpenResty pour la réécriture plutôt que la configuration NGINX. Pour éviter cette ambiguïté, une grande partie de la configuration NGINX est relativement obscure et nécessite de consulter la documentation pour la comprendre à plusieurs reprises.
3. Pourquoi mon code génère-t-il une erreur ?
Q : Dans la fonction table de l'extension LuaJIT, pourquoi les deux lignes de code suivantes génèrent-elles une erreur "module not found" lorsqu'elles sont exécutées par LuaJIT ? J'utilise la version 2.0.5 de LuaJIT.
local new_tab = require('table.new')
# ou
require('table.clear')
# L'exécution générera une erreur
luajit: table_luajit.lua:1: module 'table.new' not found:
R : Ces deux lignes de code nécessitent la version 2.1 de LuaJIT pour fonctionner, comme documenté ici : https://github.com/LuaJIT/LuaJIT/blob/v2.1/doc/extensions.html#L218, vous pouvez en savoir plus.
Comme nous l'avons mentionné, vous devez être particulièrement attentif lors de l'utilisation d'OpenResty, qui nécessite une version spécifique de LuaJIT pour fonctionner correctement. OpenResty est basé sur la branche LuaJIT 2.1 et a apporté de nombreuses extensions à LuaJIT.
Ainsi, lors de l'exécution du code dans cette colonne, veuillez vous souvenir d'utiliser l'installation officielle d'OpenResty. Si vous ajoutez le lua-nginx-module
pour compiler sur NGINX, vous rencontrerez encore de nombreux problèmes !
4. Confusion concernant les valeurs nulles
Q : Certaines choses déroutantes que j'ai rencontrées sont ngx.null
, nil
, null
, et ""
. Lorsque j'ai cherché sur le web, j'ai vu que quelqu'un disait que null
est une définition de ngx.null
. Lorsque Redis renvoie un résultat, il détermine souvent si le résultat renvoyé est nul ou non, alors à quelle valeur est-il comparé lors de cette détermination ? Y a-t-il d'autres pièges concernant l'utilisation de ces valeurs ? Je ne comprends pas clairement ces valeurs.
R : Avant de répondre à votre question, je vous suggère d'utiliser le code suivant pour trouver une clé dans lua-resty-redis
.
local res, err = red:get("dog")
Cela est dû au fait que le nil de Lua ne peut pas être utilisé comme valeur de table, donc OpenResty introduit ngx.null
comme valeur nulle dans la table.
Nous pouvons imprimer ngx.null
et son type avec le code suivant.
# imprimer ngx.null
$ resty -e 'print(ngx.null)'
null
# Imprimer le type
$ resty -e 'print(type(ngx.null))'
userdata
Comme vous pouvez le voir, ngx.null
n'est pas nil
, mais est de type userdata
.
De plus, il existe de nombreuses valeurs nulles dans OpenResty, telles que cjson.null
, cdata``:NULL
, etc., dont je parlerai plus tard.
Les seules valeurs fausses dans OpenResty sont nil
et false
. Donc, lorsque vous écrivez du code comme if not res then
, vous devez être prudent, et il est préférable de le changer en if res ~= nil and res ~= false then
, avec quelque chose comme ça, et avec une couverture de cas de test correspondante.
5. Qu'est-ce exactement qu'une passerelle API ?
Q : Qu'est-ce que la passerelle API mentionnée dans l'article ? Et NGINX, Tomcat, Apache, et d'autres serveurs web ?
R : Une passerelle API est une passerelle utilisée pour gérer de manière unifiée les services. Par exemple, le paiement, la connexion utilisateur, etc., sont tous des services fournis sous forme d'API, et ils ont tous besoin d'une passerelle pour effectuer une sécurité et une authentification unifiées.
La passerelle API peut remplacer les traditionnels NGINX, Apache pour gérer le trafic nord-sud, mais aussi dans l'environnement des microservices pour gérer le trafic est-ouest, c'est un middleware plus proche des métiers, plutôt qu'un serveur Web de base.
Pour plus d'informations sur l'introduction et la mise en œuvre de la passerelle API, veuillez vous référer à Apache APISIX ; Apache APISIX est basé sur l'implémentation d'OpenResty.