Avec le routage dynamique et sa capacité à fonctionner avec des règles de routage,
vous pouvez faire en sorte que les demandes soient sélectionnées sur la base de critères spécifiques afin
de leur appliquer un comportement de routage particulier.
Avant de commencer
Activez Dynamic Routing dans un contrôleur de collectivité. Effectuez les actions décrites dans Configuration de la fonction de routage dynamique pour les collectivités Liberty.
Conseil : Le routage vers plusieurs
collectivités suppose que chacune de ces dernières ait un nom différent. Utilisez l'option
--collectiveName pour nommer la collectivité en même temps que vous la créez
avec la commande
collective create. Si la collectivité est déjà créée, vous pouvez lui associer un nom logique
avec la propriété
connectorClusterName de l'élément XML
<dynamicRouting>. Dès lors que la propriété
connectorClusterName est spécifiée,
sa valeur est prioritaire sur le nom de collectivité
spécifié antérieurement avec l'option
--collectiveName. Consultez
Configuration du routage dynamique pour plusieurs collectivités Liberty.
Pourquoi et quand exécuter cette tâche
Par défaut, le routage dynamique équilibre la charge de manière à répartir équitablement les demandes sur tous les
serveurs à même de les traiter. Vous pouvez le configurer différemment, afin que les règles de routage
orientent les demandes vers des serveurs particuliers, qu'elles les redirigent ou qu'elles
les rejettent.
Remarque : Tous les contrôleurs d'une même collectivité doivent fournir le même ensemble de règles
de routage par le biais du service de routage dynamique. Ajoutez un fichier
.xml contenant cet ensemble de règles de règles de routage
au répertoire
configDropins/defaults de l'un des contrôleurs afin que
tous les autres contrôleurs l'utilisent également. Pour plus d'informations, consultez
Partage automatique des configurations entre les serveurs secondaires.
Procédure
- Ajoutez l'élément <routingRules> comme enfant de l'élément
<dynamicRouting>, dans le fichier server.xml du contrôleur.
Spécifiez l'attribut webServers de l'élément
<routingRules>. Chaque élément <routingRules> peut définir l'ensemble applicable de
serveurs web où les règles sont publiées. Lorsqu'un serveur web se connecte au service
DynamicRouting, ce dernier lui fournit les règles qui le concernent. Si vous ne spécifiez pas de serveur web, le service fournit les règles
à tous les serveurs web qui se connectent. Si vous spécifiez plusieurs
serveurs web, utiliser une virgule (,) comme délimiteur. Les règles dont l'attribut
webServers est spécifié avec la valeur * sont fournies à tous les serveurs web.
Examinez l'exemple suivant :
<dynamicRouting>
<routingRules webServers="webserver1,webserver2">
...
</routingRules>
</dynamicRouting>
Spécifiez l'attribut
overrideAffinity de l'élément
<routingRules>. Par défaut, une demande ayant une affinité avec un serveur particulier est envoyée à celui-ci, même
si cette demande concorde avec une règle de routage qui ne désigne pas ce serveur comme
destination. L'affinité est donc prioritaire. Si toutefois
la propriété
overrideAffinity (qui signifie "passer outre l'affinité")
est mise à
true, c'est la sélection de la destination désignée par la règle
concordante qui prend le pas sur l'affinité. Si le serveur avec lequel il existe une affinité satisfait aux critères de la règle concordante
(si, selon cette règle, il figure dans les destinations possibles pour la demande),
il est choisi prioritairement, y compris s'il fait partie d'un ensemble de points d'extrémité
de basculement (failover). La
propriété
overrideAffinity s'applique à toutes les règles de routage d'un même ensemble routingRules.
Elle ne peut
donc pas être fixée individuellement pour chaque règle de cet ensemble.
<dynamicRouting>
<routingRules webServers="webserver1"
overrideAffinity=”true”>
...
</routingRules>
</dynamicRouting>
- Ajoutez des éléments <routingRule> comme enfants de l'élément
<routingRules>.
- Spécifiez un attribut order pour chaque règle de routage et donnez-lui une
valeur entière.
L'attribut order est obligatoire. Les règles sont évaluées du numéro d'ordre le plus bas au
numéro d'ordre le plus élevé. Si plusieurs règles sont configurées avec la même valeur d'attribut
order, la première trouvée est publiée et les autres sont mises à l'écart. Il est bon de laisser des intervalles libres entre les numéros d'ordre des règles afin de permettre l'insertion
d'autres règles dans le futur.
- Pour chaque règle de routage, spécifiez un attribut matchExpression. Sa valeur doit être l'expression de critères particuliers de concordance avec les
demandes entrantes. Cette expression est une combinaison d'opérandes fixes et d'opérateurs. Vous pouvez lier entre eux plusieurs ensembles d'opérandes et d'opérateurs au moyen des
opérateurs logiques AND et OR.
<dynamicRouting>
<routingRules webServers="webserver1,webserver2">
<routingRule order="100" matchExpression="URI LIKE'/myapp%'">
...
</routingRule>
</routingRules>
</dynamicRouting>
Tableau 1. Opérandes utilisables dans matchExpression. Ce sont les opérandes qui peuvent être inclus dans une définition d'attribut matchExpression.Opérande |
Syntaxe |
Description |
IPV4 client |
clientipv4 |
Adresse IP du client dans le format Internet Protocol version 4 (IPv4) à quatre éléments séparés par des points : n.n.n.n. |
IPV6 client |
clientipv6 |
Adresse Internet Protocol version 6 (IPv6) 128 bits du type
x:x:x:x:x:x:x:x conforme au protocole RFC 1924 de l'ordinateur client. |
Nom de cookie |
cookie$nom |
Nom d'un cookie. Par exemple, l'expression
cookie$Mon_Cookie='Valeur_de_Mon_Cookie' teste une demande pour voir si elle contient un cookie
nommé Mon_Cookie ayant la valeur Valeur_de_Mon_Cookie. Pour vérifier qu'un cookie particulier est présent ou absent, utilisez l'une des deux
expressions suivantes, respectivement :
cookie$MyCookieName IS NOT NULL
cookie$MyCookieName IS NULL
|
Nom d'en-tête |
header$nom |
Nom et valeur d'un en-tête. Par exemple, l'expression header$Host='localhost'
teste une demande pour voir si elle contient un en-tête d'hôte (Host) HTTP ayant la valeur localhost. Pour vérifier que l'en-tête Host est présent ou absent, utilisez l'une des deux
expressions suivantes, respectivement :
header$Host IS NOT NULL
header$Host IS NULL
|
Pourcentage |
percentage$valeur |
L'opérande de pourcentage s'évalue à true pendant un pourcentage du temps. Par exemple, percentage$50 s'évalue à true 50 % du temps.
|
Paramètre de requête |
queryparm$nom |
Nom et valeur d'un paramètre de requête. Par exemple, l'expression
queryparm$timezone='EST' teste une demande pour voir si elle contient
le paramètre de requête HTTP nommé timezone (fuseau horaire) avec la
valeur EST (Eastern Time Zone, heure de l'Est d'Amérique du Nord). Pour vérifier qu'un paramètre de requête particulier est présent ou absent, utilisez l'une des deux
expressions suivantes (ici pour le paramètre timezone), respectivement :
queryparm$timezone IS NOT NULL
queryparm$timezone IS NULL
|
URI |
uri |
Uniform Resource Identifier (URI) |
Hôte virtuel |
virtualhost |
Hôte virtuel cible de la demande |
Port virtuel |
numeric |
Port virtuel cible de la demande |
Tableau 2. Opérateurs utilisables dans matchExpression. Ce sont les opérateurs qui peuvent être inclus dans une définition d'attribut matchExpression.Opérateur |
Syntaxe |
Description |
Égal à |
= |
Opérateur d'égalité tenant compte de la casse des caractères. |
Égal à (casse indifférente) |
EQUALSIGNORECASE |
Identique à 'chaîne = chaîne',
sauf que la casse des chaînes est ignorée. Par exemple, 'ABC' EQUALSIGNORECASE 'abc' s'évalue à
true, tandis que ('ABC' = 'abc') s'évalue à
false. |
IN |
IN |
Exprime l'ensemble des valeurs possibles d'un opérande. Par exemple, dans le cas d'un opérande nommé
port, pour exprimer que la valeur
peut être n'importe lequel des entiers
9080, 9090 et 9091, le fragment d'expression à utiliser sera port IN
(9080,9090,9091). L'expression des valeurs entre parenthèses dépend du type de donnée. Par exemple, si port
est un entier, les valeurs possibles seront entrées sans apostrophes. Si port est
une chaîne, la syntaxe correcte sera port IN
('9080','9090','9091').
|
N'est pas null |
IS NOT NULL |
S'évalue à true si l'opérande spécifié existe. |
Est null |
IS NULL |
S'évalue à true si l'opérande spécifié n'existe pas. |
Similaire à |
LIKE |
Exprime une correspondance partielle pour les valeurs d'opérande de type chaîne. La valeur
doit contenir le caractère générique pour cent (%) à la position où commence la recherche du
motif générique. Par
exemple :- L'expression host LIKE %blanca trouve le mot blanca ou
tout autre mot finissant par blanca.
- L'expression host LIKE blanca% trouve le mot blanca ou
tout mot commençant par blanca.
- L'expression host LIKE %blanca% trouve le mot blanca ou tout
mot contenant blanca.
|
Similaire à (casse indifférente) |
LIKEIGNORECASE |
Identique à 'chaîne LIKE chaîne',
sauf que la casse des chaînes est ignorée. |
Like in |
LIKEIN |
Evalue si une chaîne est présente dans une liste de chaînes. Par exemple string likein
(string1%, string2%, string3%, etc.) s'évalue à true si
string concorde avec une ou plusieurs des chaînes entre parenthèses. Dans cet exemple, les parenthèses contiennent trois valeurs
string. |
- Spécifiez un type d'action pour la règle de routage.
Les trois types d'action possibles sont
permitAction,
redirectAction et rejectAction. Pour chaque règle de routage, vous ne devez spécifier qu'un seul des
trois types d'action.
- Spécifiez le type d'action permitAction pour router les demandes vers
des points d'extrémité identifiés.
- Ajoutez l'élément <permitAction> à l'élément <routingRule> de la règle concernée.
- En option, ajoutez l'attribut allowMaintenanceModeServers à l'élément
<permitAction> pour indiquer si les demandes concordant avec la règle pourront
être envoyées aux serveurs en mode maintenance. La valeur par défaut de cet attribut est false. Si sa valeur est true, les demandes concordant avec la règle pourront être
envoyées aux serveurs qui sont en mode maintenance.
- Ajoutez un ou plusieurs éléments <loadBalanceEndPoints> à l'élément
<permitAction>.
Si un élément <permitAction> contient plusieurs
éléments <loadBalanceEndPoints>, le premier d'entre eux
agit comme ensemble principal de destinations. Tous les autres
éléments <loadBalanceEndPoints> agissent comme destinations
de basculement (failover). L'ordre dans lequel les éléments
<loadBalanceEndPoints> sont définis détermine la priorité
de basculement.
- Ajoutez un ou plusieurs éléments <endpoint> à chaque
élément <loadBalanceEndPoints>.
- Ajoutez un attribut destination à chaque élément <endpoint>.
Pour la valeur des attributs destination, spécifiez soit un type de serveur, soit
un type de cluster.
Pour spécifier un point d'extrémité de type
serveur, entrez la chaîne server= suivie d'une spécification de
serveur en quatre parties séparées les unes des autres par une virgule :
<endpoint destination="server=collective_name,host_name,wlp.user.dir,server_name"/>
- collective_name est le nom de la collectivité dont le serveur
est membre.
- host_name est l'adresse de l'hôte.
- wlp.user.dir est le répertoire d'utilisateur Liberty sur l'hôte où le serveur
est défini. Bien que possible, l'utilisation de la variable ${wlp.user.dir} ici
n'est pas forcément une bonne idée. En effet, lors de la lecture de ce fichier
server.xml, la variable
${wlp.user.dir} est interprétée comme le répertoire dans lequel
le serveur contrôleur est défini. Or, il ne s'agit pas forcément du répertoire dans lequel le serveur membre (celui de la destination) est
défini.
- server_name est le nom du serveur.
Pour spécifier un point d'extrémité de type
cluster, entrez la chaîne cluster= suivie d'une spécification
en deux parties séparées l'une de l'autre par une virgule :
<endpoint destination="cluster=collective_name,cluster_name"/>
- collective_name est le nom de la collectivité où le cluster est
défini.
- cluster_name est le nom du cluster.
Toutes les parties d'une spécification de destination, qu'elle soit de type serveur ou de type cluster,
peuvent utiliser le caractère générique
* pour remplacer n'importe quelle chaîne. Le routage vers plusieurs
collectivités suppose que chacune de ces dernières ait un nom différent. Si l'attribut connectorClusterName
de l'élément <dynamicRouting> est spécifié, sa valeur est
utilisée comme nom de collectivité. Si cet attribut n'est pas présent dans l'élément <dynamicRouting>,
le nom de collectivité utilisé est la valeur qui a été spécifiée pour l'option
--collectiveName lorsque vous avez créé
la collectivité avec la commande collective create. Enfin, si l'attribut
connectorClusterName n'est pas présent et que l'option
--collectiveName n'a pas été spécifiée dans la commande,
le nom de collectivité est defaultCollective.
L'exemple suivant montre un élément <permitAction> avec un point d'extrémité de type serveur :
<dynamicRouting maxRetries="5" retryInterval="10000">
<routingRules webServers="myWebServer">
<routingRule order="100" matchExpression="URI LIKE '/myapp%'">
<permitAction>
<loadBalanceEndPoints>
<endpoint destination="server=collective1,myhost,/opt/IBM/liberty/wlp/usr,member1"/>
</loadBalanceEndPoints>
</permitAction>
</routingRule>
</routingRules>
</dynamicRouting>
- Spécifiez le type d'action redirectAction pour router la demande vers un
autre emplacement.
- Ajoutez l'élément <redirectAction> à un élément <routingRule>.
- Ajoutez un attribut location à l'élément <redirectAction>. Indiquez la nouvelle destination de la demande comme valeur de l'attribut location.
L'exemple suivant montre un élément <redirectAction> :
<dynamicRouting maxRetries="5" retryInterval="10000">
<routingRules webServers="myWebServer">
<routingRule order="200" matchExpression="URI LIKE '/myapp%'">
<redirectAction location="http://some.other.destination" />
</routingRule>
</routingRules>
</dynamicRouting>
- Spécifiez le type d'action rejectAction pour rejeter la demande en renvoyant
un code réponse spécifique.
- Ajoutez l'élément <rejectAction> à un élément <routingRule>.
- Ajoutez un attribut code à l'élément <rejectAction>. Pour la valeur de l'attribut code, spécifiez le code réponse HTTP à utiliser lorsque la
demande concorde avec la règle. Il doit s'agir d'un code d'erreur reconnu par le serveur web.
L'exemple suivant montre un élément <rejectAction> :
<dynamicRouting maxRetries="5" retryInterval="10000">
<routingRules webServers="myWebServer">
<routingRule order="300" matchExpression="URI LIKE '/myapp%'">
<rejectAction code="503" />
</routingRule>
</routingRules>
</dynamicRouting>
Résultats
Une fois les règles définies, lorsqu'un serveur web se connecte au service de routage dynamique,
celui-ci lui fournit les règles qui lui sont associées. Il lui fournit également, ainsi qu'à tous les autres serveurs
web, les règles qui concernent tous les serveurs web sans distinction (celles dont l'attribut
webServers contient la valeur '*'). Le serveur web confronte les demandes qui lui parviennent aux expressions (matchExpression) figurant dans
chaque règle qui le concerne. L'ordre d'évaluation des expressions est déterminé par le numéro d'ordre de chaque règle.
Les plus petits numéros en premier, les plus grands en dernier. La règle sélectionnée et donc appliquée est la première règle évaluée dont l'expression concorde avec la demande. L'action associée à la règle détermine comment
la demande est traitée. Si aucune règle concordante n'est trouvée, la demande est envoyée à l'un des serveurs à même de la traiter, celui-ci
étant choisi en tenant compte
de l'équilibrage de charge (répartition équitable des demandes sur tous les
serveurs d'un ensemble).
Par défaut, lorsqu'une demande présente une affinité de session, la sélection du
serveur se fait par rapport à cette affinité. Si une affinité est trouvée avec un serveur,
celui-ci est choisi et les règles de routage ne sont alors pas évaluées. Pour que les règles de routage soient appliquées en toutes circonstances et prennent le pas
sur la sélection par affinité, vous pouvez ajouter l'attribut overrideAffinity
avec la valeur 'true'
à l'élément <routingRules> du fichier
server.xml.
Exemple
L'exemple suivant combine plusieurs règles :
<dynamicRouting>
<routingRules webServers="myWebServer">
<routingRule order="100" matchExpression="URI LIKE '/myapp%'">
<permitAction>
<loadBalanceEndPoints>
<endpoint destination="server=collective1,*,*,member1"/>
</loadBalanceEndPoints>
<loadBalanceEndPoints>
<endpoint destination="server=collective2,*,*,member1"/>
</loadBalanceEndPoints>
</permitAction>
</routingRule>
<routingRule order="200" matchExpression="uri like '/AppX%' AND queryparm$test = 'true'">
<permitAction allowMaintenanceModeServers="true">
<loadBalanceEndPoints>
<endpoint destination="cluster=collective1,clusterB"/>
<endpoint destination="cluster=collective2,clusterB"/>
</loadBalanceEndPoints>
</permitAction>
</routingRule>
<routingRule order="300" matchExpression=" uri like '/AppX%' ">
<permitAction>
<loadBalanceEndPoints>
<endpoint destination="cluster=collective1,clusterA"/>
<endpoint destination="cluster=collective2,clusterA"/>
</loadBalanceEndPoints>
</permitAction>
</routingRule>
<routingRule order="400" matchExpression="URI LIKE '/myoldapp'">
<redirectAction location="http://mysite/mynewapp" />
</routingRule>
<routingRule order="500" matchExpression="URI LIKE '/myveryoldapp'">
<rejectAction code="503" />
</routingRule>
</routingRules>
</dynamicRouting>
La règle de routage avec l'attribut order="100" recherche les demandes
dont l'URI commence par /AppX et limite leurs destinations de routage à deux clusters
particuliers, dans deux collectivités.
La règle de routage avec l'attribut order="200"
illustre le basculement (failover) d'un ensemble de points d'extrémité vers un
autre. Les demandes concordant avec l'expression sont envoyées aux serveurs
de collective1 capables de les traiter. Si aucun des serveurs
de collective1 n'est disponible, ceux
de collective2 sont choisis à la place.
La règle de routage avec l'attribut order="300"
est un exemple de règle autorisant le routage vers un serveur en mode maintenance. Si test=true figure comme paramètre de requête dans une demande,
celle-ci est envoyée à server1 dans collective1,
y compris si ce serveur est en mode maintenance.
La règle de routage avec l'attribut order="400" est un exemple de règle de redirection. La règle de routage avec l'attribut order="500" est un exemple de règle de rejet.