Langage de stratégie de routage pour les équilibreurs de charge
Découvrez comment écrire des instructions de condition de stratégie de routage qui guident le comportement de routage d'un équilibreur de charge.
Vous devez créer des stratégies pour contrôler la façon dont les demandes entrantes sont acheminées vers des ressources telles que des serveurs Web. Ces stratégies prennent la forme générale suivante : "Si (condition quelconque), alors transmettre le trafic à un ensemble de back-ends." L'ensemble de back-ends doit avoir été créé au préalable.
Les stratégies de routage fonctionnent comme suit :
- 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 stratégie.
- Chaque règle comporte au moins une condition et un ensemble de back-ends.
- Si la condition de demande HTTP correspond à une règle, la demande est transmise à l'ensemble de back-ends défini pour cette dernière. La demande n'est pas évaluée par rapport aux autres règles de la stratégie, qui sont ignorées.
Exemple : une règle reposant sur un chemin
Voici un exemple d'ensemble de règles de stratégie de routage contenant une seule règle reposant 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 :
-
L'ensemble de règles est placé entre accolades
{ }
, et contient le nom de l'ensemble de règles, le numéro de version du langage et le nom de l'ensemble de règles. -
Le nom de l'ensemble de règles dans l'exemple est
"BasicPathBasedPolicy"
. Les règles de l'ensemble sont contenues entre crochets. -
La seule règle de l'ensemble est nommée
"Documents_rule"
. -
La condition de la règle indique que si n'importe laquelle (
any
) des conditions est remplie, alors l'action qui figure dans"actions"
doit être effectuée. -
La condition compare le chemin d'URL de demande HTTP entrante à
/documents
. L'opérateur de comparaison esteq
, ce qui signifie "égal", qui peut aussi être écrit sous la forme=
. -
Dans l'instruction de condition,
(i '/documents')
déclare que'/documents'
ne distingue pas les majuscules des minuscules. -
Lorsque la condition est remplie, l'action entreprise consiste à transmettre la demande à un ensemble de back-ends spécifique, en l'occurrence "backendSetForDocuments". Cet ensemble de back-ends doit exister pour que la règle soit valide.
La règle peut être paraphrasée comme suit : "Si le chemin d'URL demandé présente une correspondance exacte avec /documents
, alors transmettre la demande à l'ensemble de back-ends backendSetForDocuments
."
Exemple : deux règles de chemin simples
Voici un exemple d'ensemble de règles de stratégie de routage contenant deux règles simples reposant sur un chemin : En fonction du chemin d'URL de demande, les requêtes entrantes sont envoyées vers un ensemble de back-ends différent. La transmission se produit si la première condition ou la seconde est remplie. Les règles sont évaluées dans l'ordre dans lequel elles figurent dans la stratégie. Si une requête remplit les deux conditions, l'action est exécutée pour la première correspondance. La seconde 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 stratégie suivante comporte une règle avec deux conditions (séparées par une virgule). La première condition examine les en-têtes de demande et la seconde la chaîne de requête 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"
}]
}
]
}
Dans le cas présent, la règle exige que les deux conditions soient remplies pour transmettre une demande à un ensemble de back-ends, 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 définie sur mobile et que la valeur department dans l'en-tête est HR, alors transmettre à l'ensemble de back-ends 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 comporte deux conditions. Il est important de noter que la seconde règle commence par le mot-clé any, ce qui signifie qu'une seule des deux conditions doit être remplie pour déclencher l'action. Si plus de deux conditions étaient spécifiées, il suffirait que l'une d'elles soit remplie pour que l'action soit 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. Les combinateurs permettent d'utiliser plusieurs prédicats dans une même condition. Les deux combinateurs : any()
et all()
se comportent comme des opérateurs logiques OR ou AND. Pour inverser un combinateur, vous pouvez placer le mot-clé not devant lui. Un prédicat simple peut être exprimé comme suit :
left value matcher right value
La condition d'une règle qui doit avoir la correspondance si le chemin d'URL de demande HTTP commence par /foo/bar
est la suivante :
http.request.url.path sw '/foo/bar'
Pour plus de détails sur les opérateurs de correspondance disponibles, reportez-vous à Opérateurs de correspondance.
Pour plus de détails sur les variables disponibles, reportez-vous à Variables.
Syntaxe en cas de prédicats multiples
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 davantage de détails 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 l'en-tête
User-Agent
de demande 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
, procédez comme suit :http.request.headers[(i 'User-Agent')] eq 'Some User Agent'
- Pour mettre en correspondance une demande HTTP si la chaîne d'URL comporte une clé
search
sensible à la casse, 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'URL comporte une clé "search"
search
sensible à La casse avec une valeur non sensible à La casseitem+foo%20bar
, comme dans l'URLhttps://www.domain.com/category/?search=item+foo%20bar&page=1
http.request.url.query['search'] = (i 'item foo bar')
La mise en correspondance de la requête d'URL (clés et valeurs) doit être effectuée à l'aide de versions des valeurs sans échappement d'URL.
- Pour faire correspondre (sans respect de la casse) une demande HTTP pour un cookie nommé
tastycookie
:(i 'tastycookie') in (http.request.cookies)
- Afin de mettre en correspondance (sans respecter la casse) une demande HTTP pour un cookie nommé
tastycookie
contenant la valeur sensible à La cassestrawberry
, procédez comme suit :http.request.cookies[(i 'tastycookie')] = 'strawberry'
Opérateurs de correspondance
Plusieurs opérateurs de correspondance peuvent être utilisés dans les conditions.
Opérateurs de correspondance de chaîne
Le tableau suivant répertorie les opérateurs de correspondance utilisés avec les valeurs de chaîne. Certains opérateurs de correspondance ont des variantes utilisables de manière interchangeable.
Les exemples donnés pour chaque opérateur de correspondance correspondent tous au chemin http.request.url.path
contenant /category/element/id
:
Nom | Variantes | Description | Exemple |
---|---|---|---|
eq |
=, ==, equal, equals |
Etablit une correspondance si les valeurs à gauche et à droite de l'opérateur de correspondance sont identiques. | http.request.url.path eq "/category/element/id" |
ew |
Etablit une correspondance si la valeur à gauche se termine par celle à droite. | http.request.url.path ew '/id' |
|
sw |
Etablit une correspondance si la valeur à gauche commence par celle à droite. | http.request.url.path sw '/category' |
|
not eq |
!=, not equal, not equals |
Etablit une correspondance si les valeurs à gauche et à droite de l'opérateur de correspondance ne sont pas identiques. | http.request.url.path neq '/some/other/path' |
not ew |
Etablit une correspondance si la valeur à gauche ne se termine pas par celle à droite. | http.request.url.path not ew '/not_id' |
|
not sw |
Etablit une correspondance si la valeur à gauche ne commence pas par celle à droite. | http.request.url.path not sw '/not_category' |
Opérateurs de correspondance partiels
Certaines des variables utilisées dans les règles contiennent des correspondances de données clé-valeur arbitraires lors de l'exécution des règles. Par exemple, http.request.headers
contient les en-têtes des demandes HTTP. Pour plus d'informations sur les correspondances disponibles, reportez-vous à Variables.
Les opérateurs de correspondance in
et not in
peuvent être utilisés pour vérifier si une variable d'association contient une clé spécifique. Ce que la clé représente réellement dépend de la variable.
Syntaxe permettant de vérifier si une variable de correspondance contient une clé spécifique :
<key> in (<map variable>)
<key>
doit être une chaîne sensibles à la casse ou non.- La valeur à droite doit être entre parenthèses.
Par exemple, cette condition établit la correspondance si la demande HTTP comporte un cookie portant le nom 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 lors de l'exécution.
Constantes
Les règles prennent en charge les constantes de chaîne écrites entre guillemets simples.
Exemple :
http.request.url.path sw '/foo'
Respect de la casse des chaînes
Par défaut, la mise en correspondance de chaînes utilise des comparaisons sensibles à la casse.
Par exemple, si le chemin d'URL d'une demande HTTP est /foo, le prédicat suivant n'établit pas de correspondance pour cette demande, car la comparaison de chaînes sensible à la casse est utilisée :
http.request.url.path eq '/FOO'
Pour effectuer une mise en correspondance non sensible à la casse, au moins une des valeurs comparées doit être 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, les chaînes suivantes ne sont pas 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 d'origine, ce prédicat établit une correspondance car il utilise une comparaison non sensible à la casse :
http.request.url.path eq (i '/FOO')
Respect de la casse pour les chaînes
Par défaut, la mise en correspondance de chaînes utilise des comparaisons sensibles à la casse.
Par exemple, si le chemin d'URL d'une demande HTTP est /foo
, le prédicat suivant n'établit pas la correspondance pour cette demande, car une comparaison de chaînes sensibles à la casse est utilisée :
http.request.url.path eq '/FOO'
La mise en correspondance n'est pas sensible aux majuscules/minuscules si au moins l'une des valeurs comparées est une chaîne non sensible aux minuscules. La syntaxe d'une chaîne non sensible à la casse est la suivante :
(i '<string content>')
Par exemple, les chaînes suivantes sont toutes sensibles à la casse et sont donc équivalents lorsqu'elles sont utilisées dans des prédicats :
(i 'foo')
(i 'Foo')
(i 'FOO')
Par rapport à l'exemple d'origine, ce prédicat établit la correspondance car il utilise une comparaison non sensible à la casse :
http.request.url.path eq (i '/FOO')
Variables
Les variables sont utilisées dans les conditions pour établir une correspondance avec une valeur particulière de la demande HTTP. Les valeurs réelles de chaque variable sont définies lors de l'exécution des règles, c'est-à-dire lors de chaque demande HTTP.
Variables de type correspondance
Certaines variables contiennent une correspondance clé-valeur arbitraires des données de demande, par exemple des en -têtes de demande ou des cookies. Il peut exister plusieurs valeurs pour chaque clé. Par exemple, plusieurs en-têtes de demande peuvent porter le même nom.
En règle générale, les variables d'association peuvent être utilisées dans les règles pour :
- vérifier si une correspondance comporte une clé spécifique,
- vérifier si une correspondance comporte une clé spécifique avec une valeur spécifique.
Vérification de la présence d'une clé spécifique dans une correspondance :
La vérification de l'existence d'une variable correspondance dans une clé spécifique est effectuée avec le programme de correspondance in
. Pour plus de détails, reportez-vous à Langage de stratégie de routage pour les équilibreurs de charge.
Par exemple :
'Foo' in (http.request.cookies)
Cette condition établit la correspondance si la demande HTTP comporte un cookie portant le nom Foo
.
Vérification de la présence d'une clé spécifique avec une valeur spécifique dans une correspondance :
La vérification de l'existence d'une clé spécifique avec une valeur spécifique dans une correspondance est effectuée à l'aide de la notation entre crochets []
qui permet d'obtenir les valeurs au niveau d'une clé spécifique. Voici la syntaxe pour utiliser la notation entre crochets :
<variable>[<key>]
La valeur <key>
doit être indiquée sous la forme d'une chaîne sensibles à la casse ou non.
La vérification réelle de l'existence d'une valeur spécifique est effectuée à l'aide du programme de correspondance eq
qui vérifie si l'une (any
) des valeurs de la clé sont identiques à cette valeur spécifique. Le prédicat établit une correspondance si au moins l'une des valeurs de la clé correspond à la valeur considérée.
Exemples :
- Pour établir une correspondance si l'une des valeur de l'en-tête
header-name
est égale àheader-value
:http.request.headers[(i 'header-name')] eq 'header-value'
Le nom
name
de l'en-tête est comparé sans respect de la casse, mais la valeurvalue
de l'en-tête est comparée avec respect de La casse. - Pour établir la correspondance si une des valeurs du cookie "cookie-name" est identique à
cookie-value
, procédez comme suit :http.request.cookies['cookie-name'] eq 'cookie-value'
L'opérateur de correspondance not eq
peut être utilisé pour vérifier que none
des valeurs de la clé n'est identique à une valeur spécifique.
Exemples :
- Pour établir la correspondance si aucune valeur de l'en-tête
header-name
n'est identique àheader-value
:http.request.headers[(i 'header-name')] not eq 'header-value'
Le nom d'en-tête est comparé sans respect de la casse. La valeur d'en-tête est comparée avec respect de la casse.
- Pour établir la correspondance si aucune valeur du cookie "cookie-name" n'est égale à
cookie-value
:http.request.cookies['cookie-name'] not eq 'cookie-value'
Toutes les variables disponibles
Les variables pouvant être utilisées dans les conditions sont les suivantes :
Nom | Description | Exemple |
---|---|---|
http.request.headers |
Correspondance contenant des en-têtes de demande HTTP. Cette correspondance présente un comportement particulier : les clés (noms d'en-tête) doivent être une chaîne non sensible à la casse. L'utilisation de chaînes sensibles à La casse pour les clés |
|
http.request.url.path |
Chemin d'URL de demande HTTP. Il s'agit de l'URL de demande sans le protocole, le domaine, le port et la chaîne de requête. | |
http.request.url.query |
Correspondance contenant des éléments de requête d'URL de demande HTTP. Si l'URL de demande n'a pas de requête (le caractère ? n'est pas absent) ou si la requête est vide (le caractère ? est le dernier de l'URL), la correspondance est vide.La requête est analysée pour produire la correspondance
Le premier caractère Dans une paire clé-valeur, le premier caractère = présent sépare la clé de la valeur. Si d'autres caractères = apparaissent, ils ont été traités comme faisant partie de la valeur. Les clés et les valeurs ne sont pas échappées conformément aux règles d'échappement d'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 avec respect de la casse. Ainsi, si au lieu de Cependant, aucune paire clé-valeur de la chaîne
Si la partie droite du caractère |
http.request.cookies |
Correspondance contenant les cookies de demande HTTP, analysés à partir de l'en-tête d'une demande "Cookie" , comme indiqué dans RFC-6265, où la clé est le nom d'un cookie et la valeur, la valeur du cookie correspondante. Si l'en-tête de demande "Cookie" n'est pas présent dans la demande, la correspondance est vide. |
Exemples
Une demande HTTP/1.1 entrante se présente comme suit (ligne de demande et en-têtes) :
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
Les variables disponibles pour les règles sont alors remplies avec les données de la 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 et les chemins d'URL qui commencent par
/category/
avec le domainewww.domain.com
, nous utiliserions une condition telle que La suivante :all(http.request.headers[(i 'Host')] eq 'www.domain.com', http.request.url.path sw '/category')
- Pour mettre les demandes dont le chemin d'URL est exactement
/category/some_category
ou l'élément de requête de demandeaction=search
, procédez comme suit :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 de requête nommé
query
avec la valeursearch terms
(après annulation de l'échappement d'URL) :http.request.url.query['query'] eq 'search terms'
- Pour mettre En correspondance les demandes comportant un cookie
cookie_a
, mais pas le cookiecookie_c
:all('cookie_a' in (http.request.cookies), 'cookie_c' not in (http.request.cookies))