Nginx ne démarre pas avec l'hôte introuvable en amont
J'utilise nginx proxy et de tenir les connexions persistantes aux serveurs lointains pour moi.
J'ai configuré environ 15 blocs de semblable à cet exemple:
upstream rinu-test {
server test.rinu.test:443;
keepalive 20;
}
server {
listen 80;
server_name test.rinu.test;
location /{
proxy_pass https://rinu-test;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
}
}
Le problème est que si le nom d'hôte ne peut pas être résolu dans un ou plusieurs des upstream
blocs, nginx ne (re)commencer. Je ne peux pas utiliser des adresses ip statiques, soit, certains de ces hôtes explicitement dit de ne pas le faire parce que les IPs va changer. Toutes les autres solutions que j'ai vu ce message d'erreur dit de se débarrasser de upstream
et tout faire dans le location
bloc. Qu'il pas possible ici, car keepalive
est uniquement disponible sous upstream
.
Je peut temporairement se permettre de perdre un serveur, mais pas tous 15.
Edit:
S'avère nginx n'est pas adapté pour ce cas d'utilisation. Une alternative backend (en amont) de la directive keepalive proxy doit être utilisé. Une coutume Node.js l'alternative est dans ma réponse. Jusqu'à présent, je n'ai pas trouvé d'autres alternatives qui fonctionnent réellement.
- Il y a deux choses que vous pouvez essayer. Changement
proxy_pass https://rinu-test;
àproxy_pass $proxyurl;
et avant que vous pouvez définir la variableset $proxyurl $scheme://$host$request_uri
Et la prochaine est d'essayer d'utiliser la variable dans l'amont, je n'ai pas testé la 2ème option et ne peut pas vérifier encore. Mais l'utilisation d'une variable dansproxy_pass
désactive la mise en cache dns dans nginx - L'utilisation de proxy sans l'amont est inutile. Les Variables ne peuvent pas être utilisés en amont.
- Je voulais vous pourriez essayer quelque chose comme
proxy_pass https://rinu-test$request_uri;
- Comment explorer HAProxy au lieu de nginx pour cela? Si vous utilisez des amonts ensuite ce cas d'utilisation ne peuvent pas être manipulés par défaut
- J'ai essayé de HAProxy mais il ne fonctionne pas. Il n'proxy, mais n'a pas garder les connexions ouvertes ou a omis de les réutiliser.
- Il devrait avoir keep-alive activé par défaut? stackoverflow.com/questions/46966813/...
- C'est la théorie, oui, mais je suppose que cela ne fonctionne que sur le frontal de côté. Mon test a clairement montré qu'il ne fonctionne pas sur le backend de côté. J'ai essayé toutes les options, a passé 4 heures sur elle.
Vous devez vous connecter pour publier un commentaire.
Les versions antérieures de nginx (avant 1.1.4), qui a déjà alimenté un grand nombre des sites les plus visités dans le monde (et certains continuent de le faire encore aujourd'hui, si le serveur les en-têtes sont pour le croire), n'a même pas le soutien
keepalive
sur leen amont
côté, car il n'y a que très peu d'intérêt pour le faire dans les centres de données paramètre, sauf si vous avez un non-trivial de latence entre vos différents hôtes; voir https://serverfault.com/a/883019/110020 pour quelques explications.Essentiellement, si vous savez que vous avez spécifiquement besoin persistantes entre vos amont et front-end, les chances sont que c'est seulement de faire votre architecture moins élastique et moins favorisés.
(Notez que votre solution actuelle est également mal en raison d'un changement d'adresse IP sera de même passer inaperçue, parce que vous faites de la résolution de nom d'hôte à la config de recharger seulement; donc, même si nginx démarre, il va fondamentalement arrêt de travail une fois les adresses IP des serveurs en amont ne change).
Les solutions possibles, choisissez:
La meilleure solution semble juste se débarrasser de
upstream
keepalive
que probablement inutile dans un environnement de centre de données, et utiliser des variables avecproxy_pass
pour up-to-date de la résolution DNS pour chaque demande (nginx est encore smart-assez pour continuer à en faire la mise en cache de ces résolutions)Une autre option serait d'obtenir une version payante de nginx par le biais d'un abonnement payant, qui a un
résoudre
paramètre pour laserver
directive dans leupstream
contexte.Enfin, une autre chose à essayer peut-être d'utiliser un
set
variable et/ou unmap
pour spécifier les serveurs au sein deupstream
; ce n'est ni confirmé ni nié avoir été mis en œuvre; par exemple, il peut ou peut ne pas fonctionner.Une solution possible est d'impliquer un cache de DNS local. Il peut être un serveur DNS local comme à Lier ou à Dnsmasq (avec quelques petits malins configuration, notez que nginx pouvez également utiliser serveur dns spécifié à la place de la valeur par défaut du système), ou tout simplement maintenir le cache dans
hosts
fichier.Il semble que l'utilisation de
hosts
fichier avec une certaine script est assez simple. Le fichier hosts doit être divisé en parties statiques et dynamiques (à savoircat hosts.static hosts.dynamic > hosts
), et la partie dynamique doit être généré (et mis à jour automatiquement par un script.Peut-être-il un sens à vérifier de temps en temps les noms d'hôte pour changer les IPs, et de mettre à jour le fichier d'hôtes et recharger la configuration de nginx sur les changements. Dans le cas de certains nom d'hôte ne peut pas être résolu à l'ancienne adresse IP ou certaines IP par défaut (comme 127.0.1.9) doit être utilisé.
Si vous n'avez pas besoin de les noms d'hôte dans le fichier de configuration de nginx (c'est à dire, IPs sont assez), le
upstream
section avec IPs (résolu les noms d'hôtes) peut être généré par un script et inclus dans nginx config et pas besoin de toucher au fichier hosts dans de tels cas.hosts
fichier. Suppose que ça ne se passe pas. Mais j'aime votre réponse de toute façon, pour l'instant il est le seul qui fonctionne réellement.Une alternative consiste à écrire un nouveau service qui ne fait que ce que je veux. Le paragraphe suivant remplace nginx pour proxy https connexions à l'aide de Node.js
Exemple d'utilisation:
curl http://localhost:3000/request_uri -H "Host: test.rinu.test"
ce qui est équivalent à:
curl https://test.rinu.test/request_uri
J'ai mis le résoudre paramètre sur le serveur et vous devez définir la Nginx Résolveur de nginx.conf comme ci-dessous:
/etc/nginx/nginx.conf:
Site.conf:
resolve
n'est pas disponible pour moi.resolve
mot-clé au sein de l'amont contexte qui est Plus seule; toutefois, cette question ignore complètement le keepalive la question que l'OP mentionne spécifiquement que dont ils ont besoin.Votre scénario est très similaire à celui lors de l'utilisation d'aws
ELB
comme uptreams où est essentiel pourresolve
la bonne IP d'un domaine défini.La première chose que vous devez faire et de veiller à ce que les serveurs DNS que vous utilisez peut résoudre vos domaines, vous pouvez créer votre config comme ceci:
Avis de la
resolver 10.0.0.2
il doit être l'adresse IP du serveur DNS qui fonctionne et de répondre à vos requêtes, en fonction de votre configuration, cela pourrait être un cache local de service comme unbound. puis il suffit d'utiliserresolve 127.0.0.1
Maintenant, il est très important d'utiliser un variable spécifier le nom de domaine, à partir de la documentation:
Vous pouvez vérifier votre résolveur en utilisant des outils comme
dig
par exemple:En cas faut utiliser des
keepalive
dans le rapport à l'amont, et si ce n'est pas une option pour utiliser Nginx +, alors vous pouvez essayer de openresty balancer, vous aurez besoin d'utiliser/mettre en œuvre lua-resty-dnslua
+nginx
fonctionne assez bien aussi vous pouvez étendre et de mettre en œuvre un WAF etc, et de couvrir un grand nombre de choses qui manquent sur la norme de Nginx