Langage de politique d'acheminement pour les équilibreurs de charge
Voyez comment écrire des énoncés de condition de politique de routage qui guident le comportement d'acheminement d'un équilibreur de charge.
Pour contrôler l'acheminement des demandes entrantes vers des ressources telles que des serveurs Web, vous devez créer des politiques. Le format général de ces politiques est : "Si telle condition est vraie, alors le trafic doit être transmis à un jeu dorsal". Le jeu dorsal doit déjà exister.
Les politiques d'acheminement fonctionnent de la façon suivante :
- Chaque demande HTTP est évaluée par rapport aux règles.
- Les règles sont exécutées dans l'ordre défini dans la politique.
- Chaque règle comporte au moins une condition et un jeu dorsal.
- Si la condition de la demande HTTP correspond à une règle, la demande est transmise au jeu dorsal défini pour la règle. Les autres règles de la politique sont ignorées et la demande n'est pas évaluée par rapport à celles-ci.
Exemple : Une seule règle basée sur un chemin
Voici un exemple de jeu de règles de politique d'acheminement qui ne contient qu'une règle basée sur un chemin :
{
"name": "BasicPathBasedPolicy",
"conditionLanguageVersion": "V1",
"rules": [
{
"name": "Documents_rule",
"condition" : "any(http.request.url.path eq (i '/documents'))",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForDocuments"
}]
}
]
}
Cet exemple présente les éléments suivants :
-
Le jeu de règles figure entre accolades
{ }
et contient le nom du jeu de règles, le numéro de version du langage et le nom de la règle dans le jeu. -
Le nom du jeu de règles dans l'exemple est
"BasicPathBasedPolicy"
. Les règles de l'ensemble sont contenues entre crochets. -
Le nom de la seule règle du jeu est
"Documents_rule"
. -
La condition de règle indique que si
any
(n'importe quelle) condition est satisfaite, alors l'action dans"actions"
doit être effectuée. -
La condition compare le chemin de l'URL de la demande HTTP entrante à
/documents
. La comparaison esteq
(égal à), et peut également être représentée par le signe=
. -
Dans l'énoncé de condition,
(i '/documents')
déclare que'/documents'
n'est pas sensible à la casse. -
Lorsque la condition est satisfaite, l'action effectuée consiste à transmettre la demande à un jeu dorsal spécifique, dans ce cas "backendSetForDocuments". Ce jeu dorsal doit exister pour que la règle soit valide.
La règle peut être paraphrasée comme suit : "Si le chemin d'URL demandé correspond exactement à /documents
, alors la demande doit être transmise au jeu dorsal backendSetForDocuments
.
Exemple : Deux règles basées sur un chemin simple
Voici un exemple de jeu de règles de politique d'acheminement qui contient deux règles basées sur un chemin simple. Une interrogation entrante est envoyée à un autre jeu dorsal en fonction du chemin de l'URL de la demande et la transmission est effectuée si la première ou la deuxième condition est remplie. Plusieurs règles sont évaluées dans leur ordre dans la politique. Si une interrogation correspond à ces deux conditions, l'action est effectuée sur la première correspondance et la seconde correspondance est ignorée.
{
"name": "PathBasedPolicy",
"conditionLanguageVersion": "V1",
"rules": [
{
"name": "Documents_rule",
"condition" : "any(http.request.url.path eq (i '/documents'))",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForDocuments"
}]
},
{
"name": "Videos_rule",
"condition" : "any(http.request.url.path eq (i '/videos'))",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForVideos"
}]
}
]
}
Exemple : Une règle avec deux conditions
La politique suivante comporte une règle avec deux conditions (les conditions sont séparées par une virgule). La première condition examine les en-têtes de demande et la deuxième condition examine la chaîne d'interrogation de la demande :
{
"name": "Example_policy",
"conditionLanguageVersion": "V1",
"rules": [
{
"name": "HR_mobile_user_rule",
"condition" : "all(http.request.headers[(i 'user-agent')] eq (i 'mobile'), http.request.url.query['department'] eq 'HR')",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForHRMobileUsers"
}]
}
]
}
La règle exige que les deux conditions soient vraies pour transmettre une demande à un jeu dorsal, car elle commence par le mot clé all. Les conditions de la règle peuvent être paraphrasées comme suit : "Si la valeur user-agent demandée dans l'en-tête est réglée à mobile et que la valeur department dans l'en-tête est HR, alors la demande doit être transmise au jeu dorsal spécifié.
Exemple : Deux règles
Le dernier exemple présente deux règles. Chaque règle est associée à une action différente, et les deux règles contiennent deux conditions. Il est important que la deuxième règle commence par le mot clé any, ce qui signifie qu'une seule des deux conditions doit être vraie pour déclencher l'action. Si plus de deux conditions sont spécifiées, si l'une d'entre elles est vraie, l'action est déclenchée.
{
"name": "Example_policy",
"conditionLanguageVersion": "V1",
"rules": [
{
"name": "HR_mobile_user_rule",
"condition" : "all(http.request.headers[(i 'user-agent')] eq (i 'mobile'), http.request.url.query['department'] eq 'HR')",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForHRMobileUsers"
}]
},
{
"name": "Documents_rule",
"condition" : "any(http.request.url.path eq (i '/documents'), http.request.headers[(i 'host')] eq 'doc.myapp.com')",
"actions": [{
"name": "FORWARD_TO_BACKENDSET"
"backendSetName": "backendSetForDocuments"
}]
}
]
}
Conditions de règle
Les conditions de règle sont écrites sous forme de prédicats. Plusieurs prédicats peuvent être utilisés dans une condition, à l'aide de combinateurs. Les combinateurs any()
et all()
se comportent comme un opérateur logique OR ou AND. Un combinateur peut également être inversé en plaçant le mot clé not devant lui. Un prédicat simple peut être exprimé comme suit :
left value matcher right value
Une condition pour une règle qui doit correspondre si le chemin de l'URL de la demande HTTP commence par /foo/bar
se présente comme suit :
http.request.url.path sw '/foo/bar'
Pour plus de détails sur les coupleurs disponibles, voir Coupleurs.
Pour plus de détails sur les variables disponibles, voir Variables.
Syntaxe pour plusieurs prédicats
not? any|all(<condition>,<condition>,...)
Par exemple :
all(http.request.url.path sw '/foo', 'bar' in (http.request.url.query))
Exemples de condition
Voici d'autres exemples d'utilisation des conditions. Vous trouverez également des informations supplémentaires sur la syntaxe et les fonctionnalités exactes.
- Pour mettre en correspondance une demande HTTP si son chemin d'URL commence par
/category/element
:http.request.url.path sw '/category/element'
- Pour mettre en correspondance une demande HTTP si son chemin d'URL commence par
/category
ou se termine par/id
:any(http.request.url.path sw '/category', http.request.url.path ew '/id')
- Pour mettre en correspondance une demande HTTP si un en-tête de demande
User-Agent
est présent :(i 'User-Agent') in (http.request.headers)
- Pour mettre en correspondance une demande HTTP si l'en-tête
User-Agent
a la valeurSome User Agent
:http.request.headers[(i 'User-Agent')] eq 'Some User Agent'
- Pour mettre en correspondance une demande HTTP si la chaîne d'interrogation d'URL comporte une clé sensible à la casse
search
, par exemple comme dans l'URLhttps://www.example.com/category/?search=item+foo%20bar&page=1
:'search' in (http.request.url.query)
- Pour mettre en correspondance une demande HTTP si la chaîne d'interrogation d'URL comporte une clé sensible à la casse
search
avec une valeur non sensible à la casseitem+foo%20bar
, par exemple comme dans l'URL :https://www.domain.com/category/?search=item+foo%20bar&page=1
http.request.url.query['search'] = (i 'item foo bar')
La mise en correspondance de l'interrogation d'URL doit être effectuée à l'aide de versions sans caractère d'échappement des clés et des valeurs.
- Pour mettre en correspondance de manière non sensible à la casse une demande HTTP pour un témoin nommé
tastycookie
:(i 'tastycookie') in (http.request.cookies)
- Pour mettre en correspondance de manière non sensible à la casse une demande HTTP pour un témoin nommé
tastycookie
qui contient la valeur sensible à la cassestrawberry
:http.request.cookies[(i 'tastycookie')] = 'strawberry'
Coupleurs
Plusieurs coupleurs peuvent être utilisés dans les conditions.
Coupleurs de chaîne
Le tableau suivant répertorie les coupleurs applicables aux valeurs de chaîne. Certains coupleurs ont des variantes, ce qui signifie que n'importe laquelle de ces variantes peut être utilisée de manière interchangeable pour ce coupleur.
Les exemples pour chaque coupleur correspondent tous à http.request.url.path
avec /category/element/id
:
Nom | Variantes | Description | Exemple |
---|---|---|---|
eq |
=, ==, equal, equals |
Il y a correspondance si les valeurs de gauche et de droite du coupleur sont identiques. | http.request.url.path eq "/category/element/id" |
ew |
ll y a correspondance si la valeur du côté gauche se termine par la valeur du côté droit. | http.request.url.path ew '/id' |
|
sw |
ll y a correspondance si la valeur du côté gauche commence par la valeur du côté droit. | http.request.url.path sw '/category' |
|
not eq |
!=, not equal, not equals |
Il y a correspondance si les valeurs de gauche et de droite du coupleur sont différentes. | http.request.url.path neq '/some/other/path' |
not ew |
ll y a correspondance si la valeur du côté gauche ne se termine pas par la valeur du côté droit. | http.request.url.path not ew '/not_id' |
|
not sw |
ll y a correspondance si la valeur du côté gauche ne commence pas par la valeur du côté droit. | http.request.url.path not sw '/not_category' |
Coupleurs partiels
Certaines des variables utilisées dans les règles contiennent des mappages clé-valeur arbitraires de données lors de l'exécution des règles. Par exemple, http.request.headers
contient les en-têtes de demande HTTP. Pour plus de détails sur les mappages disponibles, voir Variables.
Les coupleurs in
et not in
peuvent être utilisés pour vérifier si une variable de mappage contient une clé spécifique. Cela dépend de la variable que représente réellement la clé.
La syntaxe pour vérifier si une variable de mappage contient une clé spécifique est la suivante :
<key> in (<map variable>)
<key>
doit être une chaîne sensible à la casse ou non.- La valeur du côté droit doit être entre parenthèses.
Par exemple, cette condition est correspondante si la demande HTTP contient un témoin nommé Foo
:
'Foo' in (http.request.cookies)
Valeurs
Les valeurs utilisées dans les prédicats peuvent être des valeurs constantes ou des variables évaluées au moment de l'exécution.
Constantes
Les règles prennent en charge les constantes de chaîne entre guillemets simples.
Exemple :
http.request.url.path sw '/foo'
Sensibilité à la casse des chaînes
La correspondance de chaînes utilise par défaut des comparaisons sensibles à la casse.
Par exemple, si le chemin de l'URL d'une demande HTTP est /foo, le prédicat suivant ne correspond pas pour cette demande, car une comparaison de chaîne sensible à la casse est utilisée :
http.request.url.path eq '/FOO'
Une mise en correspondance non sensible à la casse est effectuée si au moins une des valeurs comparées est une chaîne non sensible à la casse. La syntaxe d'une chaîne non sensible à la casse est la suivante :
(i '<string content>')
Par exemple, ces chaînes sont toutes non sensibles à la casse et sont donc équivalentes, lorsqu'elles sont utilisées dans des prédicats :
(i 'foo')
(i 'Foo')
(i 'FOO')
Par rapport à l'exemple initial, ce prédicat correspond, car il utilise une comparaison non sensible à la casse :
http.request.url.path eq (i '/FOO')
Sensibilité à la casse des chaînes
La correspondance de chaînes utilise par défaut des comparaisons sensibles à la casse.
Par exemple, si le chemin de l'URL d'une demande HTTP est /foo
, le prédicat suivant ne correspond pas pour cette demande, car une comparaison de chaîne sensible à la casse est utilisée :
http.request.url.path eq '/FOO'
Une mise en correspondance non sensible à la case est effectuée si au moins une des valeurs comparées est une chaîne non sensible à la case. La syntaxe d'une chaîne non sensible à la casse est la suivante :
(i '<string content>')
Par exemple, ces chaînes sont toutes non sensibles à la casse et sont donc les mêmes, lorsqu'elles sont utilisées dans des prédicats :
(i 'foo')
(i 'Foo')
(i 'FOO')
Par rapport à l'exemple initial, ce prédicat correspond, car il utilise une comparaison sans distinction majuscules/minuscules :
http.request.url.path eq (i '/FOO')
Variables
Les variables sont utilisées dans des conditions pour correspondre à une valeur spécifique de la demande HTTP. Les valeurs réelles de chaque variable sont décidées lors de l'exécution des règles, lors de chaque demande HTTP individuelle.
Variables de type de mappage
Certaines variables contiennent des mappages clé-valeur arbitraires des données de la demande, par exemple des en-têtes ou des témoins de demande. Pour chaque clé, il peut y avoir une ou plusieurs valeurs. Par exemple, plusieurs en-têtes de demande peuvent porter le même nom.
En général, les variables de mappage peuvent être utilisées dans les règles comme suit :
- Pour vérifier si un mappage contient une clé spécifique.
- Pour vérifier si un mappage contient une clé spécifique avec une valeur spécifique.
Vérification de la présence d'une clé spécifique dans un mappage :
Pour vérifier si une variable de mappage contient une clé spécifique, le sélecteur in
est utilisé. Pour plus de détails, voir Langage de politique d'acheminement pour les équilibreurs de charge.
Par exemple :
'Foo' in (http.request.cookies)
Cette condition est correspondante si la demande HTTP contient un témoin nommé Foo
.
Vérification de la présence d'une clé spécifique avec une valeur spécifique dans un mappage :
Pour vérifier si un mappage contient une clé spécifique avec une valeur spécifique, des crochets []
sont utilisés pour obtenir les valeurs d'une clé spécifique. La syntaxe de la notation à crochets est la suivante :
<variable>[<key>]
La valeur <key>
doit être spécifiée en tant que chaîne sensible à la casse ou non.
La recherche réelle d'une valeur spécifique est effectuée à l'aide du coupleur eq
pour vérifier si any
des valeurs de cette clé sont égales à cette valeur spécifique. Le prédicat correspond si au moins une des valeurs de la clé correspond à cette valeur.
Exemples :
- Pour établir une correspondance si une valeur de l'en-tête
header-name
est égale àheader-value
:http.request.headers[(i 'header-name')] eq 'header-value'
La comparaison de l'en-tête
name
n'est pas sensible à la casse, mais celle de l'en-têtevalue
est sensible à la casse. - Pour établir une correspondance si une valeur du témoin "cookie-name" est égale à
cookie-value
:http.request.cookies['cookie-name'] eq 'cookie-value'
Le coupleur not eq
peut être utilisé pour vérifier que none
des valeurs de cette clé sont égales à une valeur spécifique.
Exemples :
- Pour établir une correspondance si aucune valeur de l'en-tête
header-name
n'est égale àheader-value
:http.request.headers[(i 'header-name')] not eq 'header-value'
La comparaison du nom de l'en-tête n'est pas sensible à la casse. La comparaison de la valeur de l'en-tête est sensible à la casse.
- Pour établir une correspondance si aucune valeur du témoin "cookie-name" ne correspond à
cookie-value
:http.request.cookies['cookie-name'] not eq 'cookie-value'
Toutes les variables disponibles
Les variables disponibles pour être utilisées dans les conditions sont les suivantes :
Nom | Description | Exemple |
---|---|---|
http.request.headers |
Mappage contenant les en-têtes de demande HTTP. Ce mappage a un comportement particulier : les clés (noms d'en-tête) doivent être des chaînes non sensibles à la casse. L'utilisation de chaînes sensibles à la casse pour les clés |
|
http.request.url.path |
Chemin de l'URL de la demande HTTP. Il s'agit de l'URL de la demande, sans protocole, domaine, port ni chaîne d'interrogation. | |
http.request.url.query |
Mappage contenant les éléments de l'interrogation d'URL de la demande HTTP. Si l'URL de la demande ne contient pas d'interrogation (le caractère ? est absent) ou si l'interrogation est vide (le caractère ? est le dernier de l'URL), ce mappage est vide.L'interrogation est analysée pour produire le mappage
Le premier caractère Dans une paire clé- valeur, le premier caractère = sépare la clé de la valeur. Si d'autres caractères = sont présents, ils sont considérés comme faisant partie de la valeur. Les clés et les valeurs sont spécifiées sans caractère d'échappement conformément aux règles d'utilisation de caractère d'échappement pour les URL. |
URL :https://www.domain.com/path?key=value&key=%61&another%20key=another+value Les données
Dans cet exemple, la clé et la valeur sont mises en correspondance de manière sensible à la casse. Ainsi, si au lieu de Toutefois, une paire clé-valeur de la chaîne d'interrogation de l'URL n'est pas ajoutée au mappage
Si le côté droit du caractère |
http.request.cookies |
Mappage contenant les témoins de la demande HTTP, analysés à partir de l'en-tête de demande "Cookie" comme indiqué dans la RFC-6265, où la clé est un nom de témoin et la valeur est la valeur de témoin correspondante. Si l'en-tête de demande "Cookie" n'est pas présent dans la demande, ce mappage est vide. |
Exemples
Une demande HTTP/1.1 entrante se présente comme suit (ligne et en-têtes de la demande) :
GET /category/some_category?action=search&query=search+terms&filters[]=5&features[]=12 HTTP/1.1
Accept-Encoding: gzip, deflate, br
Cookie: cookie_a=1; cookie_b=foo
Host: www.domain.com
User-Agent: Browser Foo/1.0
X-Forwarded-For: 1.2.3.4, 5.6.7.8
X-Forwarded-For: 9.10.11.12
Ensuite, les variables disponibles pour les règles sont alimentées avec les données de cette demande comme suit (les données des variables structurées sont affichées au format JSON) :
http.request.url.path: "/category/some_category"
http.request.url.query: {
"action": ["search"],
"query": ["search terms"],
"filters[]": ["5", "12"]
}
http.request.headers: {
"Accept-Encoding": ["gzip, deflate, br"],
"Cookie": ["some_cookie=1; another_cookie=foo"],
"Host": ["www.domain.com"],
"User-Agent": ["Browser Foo/1.0"],
"X-Forwarded-For": ["1.2.3.4, 5.6.7.8", "9.10.11.12"]
}
http.request.cookies: {
"cookie_a": ["1"],
"cookie_b": ["foo"]
}
Voici quelques exemples de mise en correspondance de cette demande :
- Pour mettre en correspondance les demandes avec le domaine
www.domain.com
et les chemins d'URL commençant par/category/
, une condition semblable à la suivante est utilisée :all(http.request.headers[(i 'Host')] eq 'www.domain.com', http.request.url.path sw '/category')
- Pour mettre en correspondance les demandes où le chemin d'URL est exactement
/category/some_category
ou l'élément d'interrogation de demandeaction=search
:any(http.request.url.path eq '/category/some_category', http.request.url.query['action'] eq 'search')
- Pour mettre en correspondance les demandes comportant un élément de chaîne d'interrogation nommé
query
avec la valeursearch terms
(sans caractères d'échappement dans l'URL) :http.request.url.query['query'] eq 'search terms'
- Pour mettre en correspondance les demandes comportant le témoin
cookie_a
, mais pas le témoincookie_c
:all('cookie_a' in (http.request.cookies), 'cookie_c' not in (http.request.cookies))