Linguagem de Política de Roteamento para Balanceadores de Carga
Saiba como gravar instruções de condição de política de roteamento que orientem o comportamento de roteamento de um balanceador de carga.
Para controlar como as solicitações de entrada para recursos como servidores Web são roteadas, crie políticas. Essas políticas assumem uma forma geral de "Se isso acontecer, encaminhe o tráfego para um conjunto de backend". O conjunto de backend deve ser um que você já tenha criado.
As políticas de roteamento funcionam das seguintes maneiras:
- Cada solicitação HTTP é avaliada segundo as regras.
- As regras são executadas na ordem definida na política.
- Cada regra tem pelo menos uma condição e um conjunto de backend.
- Se a condição da solicitação HTTP corresponder a uma regra, a solicitação será encaminhada para o conjunto de backend definido para a regra. As outras regras na política são ignoradas e a solicitação não é avaliada de acordo com elas.
Exemplo: Uma Regra de Caminho
Veja um exemplo de conjunto de regras de política de roteamento que contém apenas uma regra baseada em caminho:
{
"name": "BasicPathBasedPolicy",
"conditionLanguageVersion": "V1",
"rules": [
{
"name": "Documents_rule",
"condition" : "any(http.request.url.path eq (i '/documents'))",
"actions": [{
"name": "FORWARD_TO_BACKENDSET",
"backendSetName": "backendSetForDocuments"
}]
}
]
}
Esse exemplo mostra os seguintes elementos:
-
O conjunto de regras está entre chaves
{ }
e contém um nome e o número da versão do idioma. -
O nome do conjunto de regras no exemplo é
"BasicPathBasedPolicy"
. As regras no conjunto estão contidas entre colchetes. -
A única regra no conjunto é denominada
"Documents_rule"
. -
A condição da regra informa que se
any
(qualquer uma) das condições for atendida, execute a ação em"actions"
. -
A condição compara o caminho do URL da solicitação HTTP de entrada com
/documents
. A comparação éeq
, que significa igual e também pode ser escrito como=
. -
Na instrução de condição
(i '/documents')
declara que'/documents'
não faz distinção entre maiúsculas e minúsculas. -
Quando a condição é atendida, a medida tomada é encaminhar a solicitação para um conjunto de backend específico; nesse caso, "backendSetForDocuments". Esse conjunto de backend deve existir para que a regra seja válida.
A regra pode ser parafraseada como "Se o caminho do URL solicitado for uma correspondência exata para /documents
, encaminhe a solicitação ao conjunto de backend backendSetForDocuments
.
Exemplo: Duas Regras de Caminho Simples
Veja um exemplo de conjunto de regras de política de roteamento que contém duas regras simples baseadas em caminho. Uma consulta de entrada é enviada para outro conjunto de backend com base no caminho do URL da solicitação, e o encaminhamento acontecerá se a primeira ou a segunda condição for atendida. Várias regras são avaliadas em sua ordem na política. Se uma consulta corresponder a ambas as condições, a ação será executada na primeira correspondente e a segunda correspondência será ignorada.
{
"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"
}]
}
]
}
Exemplo: Uma Regra com Duas Condições
A próxima política tem uma regra com duas condições (cada condição é separada por uma vírgula). A primeira condição examina os cabeçalhos de solicitação e a segunda examina a string de consulta da solicitação:
{
"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"
}]
}
]
}
A regra agora exige que duas condições sejam verdadeiras para encaminhar uma solicitação a um conjunto de backend, uma vez que ela começa com a palavra-chave all. As condições da regra podem ser parafraseadas como "Se o valor user-agent solicitado no cabeçalho for definido como mobile e o valor department no cabeçalho for HR, encaminhe para o conjunto de backend especificado.
Exemplo: Duas Regras
O exemplo final mostra duas regras. Cada regra tem uma ação diferente e ambas têm duas condições. É importante ressaltar que a segunda regra começa com a palavra-chave any, o que significa que somente uma das duas condições precisa ser verdadeira para disparar a ação. Se mais de duas condições forem especificadas, se uma delas for verdadeira, a ação será disparada.
{
"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"
}]
}
]
}
Condições da Regra
As condições da regra são escritas na forma de predicados. Vários predicados podem ser usados em uma condição, usando combinadores. Os dois combinadores: any()
e all()
se comportam como um OR ou AND lógico. Uma combinação também pode ser negada colocando a palavra-chave não antes dela. Um predicado simples pode ser expresso como:
left value
matcher
right value
Uma condição para uma regra que deve corresponder se o caminho da URL de solicitação HTTP começar com /foo/bar
for:
http.request.url.path sw '/foo/bar'
Mais detalhes sobre os correspondentes disponíveis estão em Correspondentes.
Mais detalhes sobre as variáveis disponíveis estão em Variáveis.
Sintaxe para vários predicados
not? any|all(<condition>,<condition>,...)
Por exemplo:
all(http.request.url.path sw '/foo', 'bar' in (http.request.url.query))
Exemplos de Condição
Veja a seguir mais exemplos de como as condições podem ser usadas. Veja a seguir mais detalhes sobre sintaxe exata e funcionalidade.
- Para corresponder a uma solicitação HTTP se seu caminho de URL começar com
/category/element
:http.request.url.path sw '/category/element'
- Para corresponder a uma solicitação HTTP se seu caminho do URL começar com
/category
ou terminar com/id
:any(http.request.url.path sw '/category', http.request.url.path ew '/id')
- Para corresponder a uma solicitação HTTP se um cabeçalho da solicitação
User-Agent
estiver presente:(i 'User-Agent') in (http.request.headers)
- Para corresponder uma solicitação HTTP se o cabeçalho
User-Agent
tiver o valorSome User Agent
:http.request.headers[(i 'User-Agent')] eq 'Some User Agent'
- Para corresponder uma solicitação HTTP se a string da consulta do URL tiver uma chave com distinção entre maiúsculas e minúsculas
search
, por exemplo, como no URLhttps://www.example.com/category/?search=item+foo%20bar&page=1
:'search' in (http.request.url.query)
- Para vincular uma solicitação HTTP se a string de consulta URL tiver uma chave com distinção entre maiúsculas e minúsculas
search
(com distinção entre maiúsculas e minúsculas) com um valor sem distinção entre maiúsculas e minúsculasitem+foo%20bar
, por exemplo, como no URL:https://www.domain.com/category/?search=item+foo%20bar&page=1
http.request.url.query['search'] = (i 'item foo bar')
A correspondência da consulta de URL (chaves e valores) deve ser feita usando as versões de seus valores sem escape de URL.
- Para corresponder sem distinção entre maiúsculas e minúsculas a uma solicitação HTTP de um cookie chamado
tastycookie
:(i 'tastycookie') in (http.request.cookies)
- Para fazer a correspondência sem distinção de maiúsculas/minúsculas de uma solicitação HTTP para um cookie chamado
tastycookie
que contém o valor de distinção de maiúsculas/minúsculasstrawberry
:http.request.cookies[(i 'tastycookie')] = 'strawberry'
Correspondentes
Vários correspondentes estão disponíveis para uso em condições.
Correspondentes de String
A próxima tabela lista os correspondentes que operam em valores de string. Alguns correspondentes têm variantes alternativas, o que significa que qualquer uma dessas variantes pode ser usada de forma intercambiável para esse correspondente.
Os exemplos de cada correspondente correspondem ao http.request.url.path
que contém /category/element/id
:
Nome | Alternativas | Descrição | Exemplo |
---|---|---|---|
eq
|
=, ==, equal, equals
|
Corresponde se os valores do lado esquerdo e direito do correspondente são iguais. |
http.request.url.path eq "/category/element/id"
|
ew
|
Corresponde se o valor do lado esquerdo termina com o valor do lado direito. |
http.request.url.path ew '/id'
|
|
sw
|
Corresponde se o valor do lado esquerdo começa com o valor do lado direito. |
http.request.url.path sw '/category'
|
|
not eq
|
!=, not equal, not equals
|
Corresponde se os valores do lado esquerdo e direito do correspondente não são iguais. |
http.request.url.path neq '/some/other/path'
|
not ew
|
Corresponde se o valor do lado esquerdo não termina com o valor do lado direito. |
http.request.url.path not ew '/not_id'
|
|
not sw
|
Corresponde se o valor do lado esquerdo não começa com o valor do lado direito. |
http.request.url.path not sw '/not_category'
|
Correspondentes Parciais
Algumas das variáveis usadas nas regras contêm mapas arbitrários de chave/valor de dados quando as regras são executadas. Por exemplo, http.request.headers
contém os cabeçalhos de solicitação HTTP. Para obter mais detalhes sobre os mapas disponíveis, consulte Variáveis.
Os correspondentes in
e not in
podem ser usados para verificar se uma variável de mapa contém uma chave específica. Depende da variável que a chave realmente representa.
A sintaxe para verificar se uma variável de mapa contém uma chave específica é:
<key> in (<map variable>)
-
<key>
deve ser uma string com distinção entre maiúsculas e minúsculas ou sem distinção entre maiúsculas e minúsculas. - O valor do lado direito deve estar entre parênteses.
Por exemplo, essa condição corresponde se a solicitação HTTP tiver um cookie com o nome Foo
:
'Foo' in (http.request.cookies)
Valores
Os valores usados em predicados podem ser valores constantes ou variáveis que são avaliados no runtime.
Constantes
As regras suportam constantes de string gravadas entre aspas simples.
Exemplo:
http.request.url.path sw '/foo'
Distinção entre maiúsculas e minúsculas da string
A correspondência de string usa comparações com distinção entre maiúsculas e minúsculas por padrão.
Por exemplo, se o caminho do URL da solicitação HTTP para alguma solicitação fosse /foo, o seguinte predicado não corresponderia a essa solicitação porque a comparação de string com distinção entre maiúsculas e minúsculas é usada:
http.request.url.path eq '/FOO'
A correspondência sem distinção entre maiúsculas e minúsculas será feita se pelo menos um dos valores comparados for uma string sem distinção entre maiúsculas e minúsculas. A sintaxe de uma string que não faz distinção entre maiúsculas e minúsculas é:
(i '<string content>')
Por exemplo, essas strings não fazem distinção entre maiúsculas e minúsculas, portanto são equivalentes quando usadas em predicados:
(i 'foo')
(i 'Foo')
(i 'FOO')
Em comparação com o exemplo original - esse predicado não corresponde, porque usa comparação sem distinção entre maiúsculas e minúsculas:
http.request.url.path eq (i '/FOO')
String - Distinção entre Maiúsculas e Minúsculas
A correspondência de string usa comparações com distinção entre maiúsculas e minúsculas por padrão.
Por exemplo, se o caminho de URL de solicitação HTTP para alguma solicitação for /foo
, o predicado a seguir não corresponderia à solicitação, porque é usada a comparação entre strings com distinção entre maiúsculas e minúsculas:
http.request.url.path eq '/FOO'
A vinculação sem distinção entre maiúsculas e minúsculas é feita se pelo menos um dos valores comparados for uma string sem distinção entre maiúsculas e minúsculas. A sintaxe de uma string que não faz distinção entre maiúsculas e minúsculas é:
(i '<string content>')
Por exemplo, essas strings não fazem distinção entre maiúsculas e minúsculas e, portanto, são as mesmas, quando usadas em predicados:
(i 'foo')
(i 'Foo')
(i 'FOO')
Em comparação com o exemplo original, este predicado não corresponde, porque usa comparação sem distinção entre maiúsculas e minúsculas:
http.request.url.path eq (i '/FOO')
Variáveis
As variáveis são usadas em condições para corresponder a algum valor específico da solicitação HTTP. Os valores reais de cada variável são decididos quando as regras são executadas, durante cada solicitação HTTP individual.
Variáveis de Tipo de Mapa
Algumas variáveis contêm mapas de chave/valor arbitrários de dados de solicitação, por exemplo, cabeçalhos ou cookies de solicitação. Para cada chave, pode haver um ou mais valores. Por exemplo, pode haver diversos cabeçalhos de solicitação com o mesmo nome.
Normalmente, as variáveis de mapa podem ser usadas nas regras destas maneiras:
- Para verificar se um mapa tem uma chave específica.
- Para verificar se um mapa tem uma chave específica com um valor específico.
Verificando se um mapa tem uma chave específica:
Verificando se uma variável de mapa tem uma chave específica é feita com o correspondente in
. Para obter mais detalhes, consulte Linguagem de Política de Roteamento para Balanceadores de Carga.
Por exemplo:
'Foo' in (http.request.cookies)
Esta condição corresponde se a solicitação HTTP tiver um cookie com o nome Foo
.
Verificando se um mapa tem uma chave específica com um valor específico:
Verificar se um mapa tem uma chave específica com um valor específico é feito usando uma notação de colchete []
para obter os valores em uma chave específica. A sintaxe para usar a notação de colchete é:
<variable>[<key>]
<key>
deve ser especificado como uma string que diferencia maiúsculas de minúsculas ou que não diferencia maiúsculas de minúsculas.
A verificação real de um valor específico é feita usando o correspondente eq
para verificar se any
dos valores nessa chave são iguais a esse valor específico. O predicado corresponderá se pelo menos um dos valores nessa chave corresponder a esse valor específico.
Exemplos:
- Para fazer correspondência se qualquer valor do cabeçalho
header-name
for igual aheader-value
:http.request.headers[(i 'header-name')] eq 'header-value'
O cabeçalho
name
é comparado sem distinção, mas o cabeçalhovalue
é comparado com distinção entre maiúsculas e maiúsculas. - Para fazer a correspondência se qualquer valor do cookie "cookie-name" for igual a
cookie-value
:http.request.cookies['cookie-name'] eq 'cookie-value'
O correspondente not eq
pode ser usado para verificar se none
dos valores nessa chave são iguais a um valor específico.
Exemplos:
- Para corresponder se nenhum valor do cabeçalho
header-name
for igual aheader-value
:http.request.headers[(i 'header-name')] not eq 'header-value'
O nome do cabeçalho é comparado sem distinção entre maiúsculas e minúsculas. O valor do cabeçalho é comparado com distinção entre maiúsculas e minúsculas.
- Para corresponder se nenhum valor do cookie "cookie-name" for igual a
cookie-value
:http.request.cookies['cookie-name'] not eq 'cookie-value'
Todas as variáveis disponíveis
As variáveis disponíveis para uso nas condições são:
Nome | Descrição | Exemplo |
---|---|---|
http.request.headers
|
Um mapa contendo cabeçalhos de solicitação HTTP. Este mapa tem algum comportamento especial - as chaves (nomes de cabeçalhos) devem ser strings sem distinção entre maiúsculas e minúsculas. Não é permitido o uso de strings que diferenciam maiúsculas de minúsculas para chaves |
|
http.request.url.path
|
Caminho do URL de solicitação HTTP Este é o URL de solicitação, sem protocolo, domínio, porta e string de consulta. | |
http.request.url.query
|
Um mapa contendo elementos de consulta de URL de solicitação HTTP. Se o URL da solicitação ainda não tiver uma consulta (não tiver um caractere ? ) ou se a consulta estiver vazia (o caractere ? é o último no URL), este mapa ficará vazio.A consulta é analisada para produzir o mapa
O primeiro caractere Dentro de um par de chave/valor, o primeiro caractere = presente separa a chave do valor. Se caracteres = extras estiverem presentes, elas serão tratadas como parte do valor. Chaves e valores não têm escape de acordo com as regras de escape de URL. |
URL:https://www.domain.com/path?key=value&key=%61&another%20key=another+value
Os dados
Nesse exemplo, a correspondência de chave e valor faz distinção entre maiúsculas e minúsculas. Portanto, se em vez de No entanto, um par de chave/valor da string da consulta do URL não foi adicionado ao mapa
Se o lado direito do caractere |
http.request.cookies |
Um mapa contendo cookies da solicitação HTTP, submetido a parse do cabeçalho da solicitação "Cookie" , conforme chamado em RFC-6265, em que a chave é um nome de cookie e o valor é o valor correspondente do cookie. Se o cabeçalho de solicitação "Cookie" não está presente na solicitação - este mapa está vazio. |
Exemplos
Uma solicitação HTTP/1.1 de entrada se parece com esta (linha e cabeçalhos da solicitação):
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
Em seguida, as variáveis disponíveis para regras seriam preenchidas com dados dessa solicitação da seguinte forma: (os dados para variáveis estruturadas são mostrados no formato 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"]
}
Veja alguns exemplos de como poderíamos fazer a correspondência dessa solicitação:
- Se quiséssemos fazer a correspondência das solicitações ao domínio
www.domain.com
e aos caminhos de URL que começam com/category/
, usaríamos uma condição como esta:all(http.request.headers[(i 'Host')] eq 'www.domain.com', http.request.url.path sw '/category')
- Para corresponder às solicitações em que o caminho do URL é exatamente
/category/some_category
ou o elemento de consulta de solicitaçãoaction=search
:any(http.request.url.path eq '/category/some_category', http.request.url.query['action'] eq 'search')
- Para corresponder as solicitações que têm um elemento da string de consulta chamado
query
com o valorsearch terms
(após o cancelamento do escape do URL):http.request.url.query['query'] eq 'search terms'
- Para corresponder às solicitações que têm um cookie
cookie_a
, mas não têm um cookiecookie_c
:all('cookie_a' in (http.request.cookies), 'cookie_c' not in (http.request.cookies))