O tráfego passa pela CDN para uma camada de servidor Web Apache, que oferece suporte a módulos, incluindo o Dispatcher. Para aumentar o desempenho, o Dispatcher é usado principalmente como cache para limitar o processamento nos nós de publicação.
As regras podem ser aplicadas à configuração do Dispatcher para modificar qualquer configuração padrão de expiração de cache, resultando em cache na CDN. O Dispatcher também respeita os cabeçalhos de expiração de cache resultantes se enableTTL
O é ativado na configuração do Dispatcher, o que significa que ele atualiza conteúdo específico mesmo fora do conteúdo que está sendo republicado.
Esta página também descreve como o cache do Dispatcher é invalidado e como o cache funciona no nível do navegador em relação às bibliotecas do lado do cliente.
cache-control
cabeçalho emitido pela camada do Apache. A CDN também respeita esse valor.DISABLE_DEFAULT_CACHING
variável em global.vars
:Define DISABLE_DEFAULT_CACHING
Esse método é útil, por exemplo, quando a lógica de negócios exige o ajuste fino do cabeçalho age (com um valor com base no dia do calendário), pois, por padrão, o cabeçalho age é definido como 0. Dito isto, tenha cuidado ao desativar o cache padrão.
pode ser substituído para todo o conteúdo de HTML/Texto definindo o EXPIRATION_TIME
variável em global.vars
uso das ferramentas do Dispatcher do SDK as a Cloud Service do AEM.
O pode ser substituído em um nível mais fino, incluindo o controle independente de CDN e cache do navegador, com o seguinte Apache mod_headers
diretivas:
<LocationMatch "^/content/.*\.(html)$">
Header set Cache-Control "max-age=200"
Header set Surrogate-Control "max-age=3600"
Header set Age 0
</LocationMatch>
O cabeçalho Surrogate-Control se aplica ao CDN gerenciado por Adobe. Se estiver usando um CDN gerenciada pelo cliente, um cabeçalho diferente pode ser necessário, dependendo do provedor de CDN.
Tenha cuidado ao definir cabeçalhos de controle de cache global ou cabeçalhos de cache semelhantes que correspondam a um regex amplo para que não sejam aplicados a conteúdo que você deve manter privado. Considere o uso de várias diretivas para garantir que as regras sejam aplicadas de maneira granular. Dito isso, o AEM as a Cloud Service remove o cabeçalho do cache se detectar que ele foi aplicado ao que ele detecta como não armazenável em cache pelo Dispatcher, conforme descrito na Documentação do Dispatcher. Para forçar o AEM a sempre aplicar os cabeçalhos de cache, é possível adicionar o always
opção, como segue:
<LocationMatch "^/content/.*\.(html)$">
Header unset Cache-Control
Header unset Expires
Header always set Cache-Control "max-age=200"
Header set Age 0
</LocationMatch>
Certifique-se de que um arquivo em src/conf.dispatcher.d/cache
O tem a seguinte regra (que está na configuração padrão):
/0000
{ /glob "*" /type "allow" }
Para evitar que conteúdo específico seja armazenado em cache na CDN, defina o cabeçalho Cache-Control como privado. Por exemplo, o seguinte impediria o conteúdo html em um diretório chamado seguro de ser armazenado em cache na CDN:
<LocationMatch "/content/secure/.*\.(html)$">. // replace with the right regex
Header unset Cache-Control
Header unset Expires
Header always set Cache-Control "private"
</LocationMatch>
Embora o conteúdo HTML definido como privado não seja armazenado em cache no CDN, ele pode ser armazenado em cache no Dispatcher se Armazenamento em cache sensível a permissões O está configurado, garantindo que somente usuários autorizados possam receber o conteúdo.
Os outros métodos, incluindo o Projeto Dispatcher-ttl AEM ACS Commons, não substitui valores com êxito.
O Dispatcher ainda pode armazenar conteúdo em cache de acordo com sua própria configuração regras de armazenamento em cache. Para tornar o conteúdo realmente privado, verifique se ele não está armazenado em cache pelo Dispatcher.
O comportamento padrão para programas criados após meados de maio de 2022 (especificamente para ids de programa superiores a 65000) é armazenar em cache por padrão, respeitando ao mesmo tempo o contexto de autenticação da solicitação. Programas mais antigos (ids de programa iguais ou inferiores a 65000) não armazenam em cache conteúdo de blob por padrão.
Em ambos os casos, os cabeçalhos de cache podem ser substituídos em um nível mais fino na camada do Apache/Dispatcher usando o Apache mod_headers
diretivas, por exemplo:
<LocationMatch "^/content/.*\.(jpeg|jpg)$">
Header set Cache-Control "max-age=222"
Header set Age 0
</LocationMatch>
Ao modificar os cabeçalhos de cache na camada do Dispatcher, tenha cuidado para não armazenar em cache muito. Consulte a discussão na seção HTML/texto acima. Além disso, verifique se os ativos que devem ser mantidos privados (em vez de em cache) não fazem parte do LocationMatch
filtros de diretiva.
A camada AEM define cabeçalhos de cache dependendo se o cabeçalho de cache já foi definido e o valor do tipo de solicitação. Se nenhum cabeçalho de controle de cache for definido, o conteúdo público será armazenado em cache e o tráfego autenticado será definido como privado. Se um cabeçalho de controle de cache for definido, os cabeçalhos de cache serão deixados intocados.
O cabeçalho de controle de cache existe? | Tipo de solicitação | AEM define cabeçalhos de cache como |
---|---|---|
Não | público | Controle de cache: público, max-age=600, imutável |
Não | autenticado | Cache-Control: private, max-age=600, imutável |
Sim | qualquer | inalterado |
Embora não seja recomendado, é possível alterar o novo comportamento padrão para seguir o comportamento mais antigo (IDs de programa iguais ou inferiores a 65000) definindo a variável de ambiente do Cloud Manager AEM_BLOB_ENABLE_CACHING_HEADERS
para falso.
A camada de AEM não armazena em cache conteúdo de blob por padrão.
Altere o comportamento padrão mais antigo para que seja consistente com o novo comportamento (IDs de programa maiores que 65000), definindo a variável de ambiente do Cloud Manager AEM_BLOB_ENABLE_CACHING_HEADERS como true. Se o programa já estiver ativo, verifique se, após as alterações, o conteúdo se comporta conforme esperado.
Agora, as imagens no armazenamento de blob marcadas como privadas não podem ser armazenadas em cache no Dispatcher usando Armazenamento em cache sensível a permissões. A imagem é sempre solicitada a partir da origem AEM e veiculada se o usuário estiver autorizado.
Os outros métodos, incluindo o dispatcher-ttl projeto AEM ACS Commons, não substitua os valores com êxito.
EXPIRATION_TIME
variável usada para tipos de arquivo html/textoEvite usar User-Agent
como parte da Vary
cabeçalho. As versões anteriores da configuração padrão do Dispatcher (antes da versão 28 do arquétipo) o incluíam e o Adobe recomenda que você o remova usando as etapas abaixo.
<Project Root>/dispatcher/src/conf.d/available_vhosts/*.vhost
Header append Vary User-Agent env=!dont-vary
de todos os arquivos vhost, exceto default.vhost, que é somente leituraUse o Surrogate-Control
cabeçalho para controlar o cache do CDN independentemente do cache do navegador
Considere aplicar stale-while-revalidate
e stale-if-error
diretivas para permitir a atualização em segundo plano e evitar erros de cache, mantendo seu conteúdo rápido e atualizado para os usuários.
stale-while-revalidate
para todos os cabeçalhos de controle de cache é um bom ponto de partida.Alguns exemplos seguem para vários tipos de conteúdo, que podem ser usados como guia ao configurar suas próprias regras de armazenamento em cache. Considere e teste cuidadosamente sua configuração e requisitos específicos:
Armazene em cache recursos mutáveis da biblioteca do cliente por 12 horas e atualize em segundo plano após 12 horas.
<LocationMatch "^/etc\.clientlibs/.*\.(?i:json|png|gif|webp|jpe?g|svg)$">
Header set Cache-Control "max-age=43200,stale-while-revalidate=43200,stale-if-error=43200,public" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Armazenar em cache recursos imutáveis da biblioteca do cliente a longo prazo (30 dias) com atualização em segundo plano para evitar o MISS.
<LocationMatch "^/etc\.clientlibs/.*\.(?i:js|css|ttf|woff2)$">
Header set Cache-Control "max-age=2592000,stale-while-revalidate=43200,stale-if-error=43200,public,immutable" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Armazene em cache páginas de HTML por cinco minutos com atualização em segundo plano uma hora no navegador e 12 horas no CDN. Os cabeçalhos de controle de cache são sempre adicionados, portanto, é importante garantir que as páginas html correspondentes em /content/* sejam destinadas a serem públicas. Caso contrário, considere usar um regex mais específico.
<LocationMatch "^/content/.*\.html$">
Header unset Cache-Control
Header always set Cache-Control "max-age=300,stale-while-revalidate=3600" "expr=%{REQUEST_STATUS} < 400"
Header always set Surrogate-Control "stale-while-revalidate=43200,stale-if-error=43200" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Armazene em cache as respostas json do exportador de modelo de Sling/Content Services por cinco minutos com atualização em segundo plano de uma hora no navegador e 12 horas no CDN.
<LocationMatch "^/content/.*\.model\.json$">
Header set Cache-Control "max-age=300,stale-while-revalidate=3600" "expr=%{REQUEST_STATUS} < 400"
Header set Surrogate-Control "stale-while-revalidate=43200,stale-if-error=43200" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Armazene em cache URLs imutáveis do componente de imagem principal a longo prazo (30 dias) com atualização em segundo plano para evitar o MISS.
<LocationMatch "^/content/.*\.coreimg.*\.(?i:jpe?g|png|gif|svg)$">
Header set Cache-Control "max-age=2592000,stale-while-revalidate=43200,stale-if-error=43200,public,immutable" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Armazene em cache recursos mutáveis do DAM, como imagens e vídeos, por 24 horas e atualize em segundo plano após 12 horas para evitar o MISS.
<LocationMatch "^/content/dam/.*\.(?i:jpe?g|gif|js|mov|mp4|png|svg|txt|zip|ico|webp|pdf)$">
Header set Cache-Control "max-age=43200,stale-while-revalidate=43200,stale-if-error=43200" "expr=%{REQUEST_STATUS} < 400"
Header set Age 0
</LocationMatch>
Quando uma solicitação HEAD é recebida na CDN Adobe para um recurso que é não Em cache, a solicitação é transformada e recebida pelo Dispatcher e/ou pela instância do AEM como uma solicitação do GET. Se a resposta for armazenável em cache, as solicitações de HEAD subsequentes serão enviadas pelo CDN. Se a resposta não puder ser armazenada em cache, as solicitações de HEAD subsequentes serão passadas para o Dispatcher, a instância do AEM ou ambas por um tempo que dependa do Cache-Control
TTL
Os URLs do site frequentemente incluem parâmetros de campanha de marketing que são usados para rastrear o sucesso de uma campanha.
Para ambientes criados em outubro de 2023 ou posteriormente, para melhorar as solicitações de cache, a CDN removerá parâmetros de consulta comuns relacionados a marketing, especificamente aqueles que correspondem ao seguinte padrão regex:
^(utm_.*|gclid|gdftrk|_ga|mc_.*|trk_.*|dm_i|_ke|sc_.*|fbclid)$
Envie um tíquete de suporte se quiser que esse comportamento seja desativado.
Para ambientes criados antes de outubro de 2023, é recomendável definir as configurações do Dispatcher ignoreUrlParams
propriedade como documentado aqui.
Em geral, não é necessário invalidar o cache do Dispatcher. Em vez disso, você deve confiar no Dispatcher atualizando seu cache quando o conteúdo estiver sendo republicado e o CDN respeitando os cabeçalhos de expiração de cache.
Assim como as versões anteriores do AEM, publicar ou desfazer a publicação de páginas limpa o conteúdo do cache do Dispatcher. Se houver suspeita de um problema de armazenamento em cache, você deverá republicar as páginas em questão e garantir que um host virtual que corresponda à ServerAlias
localhost, que é necessário para a invalidação do cache do Dispatcher.
Para a invalidação adequada do Dispatcher, verifique se as solicitações de "127.0.0.1", "localhost", ".local", ".adobeaemcloud.com" e ".adobeaemcloud.net" são todas correspondidas e tratadas por uma configuração vhost para que a solicitação possa ser atendida. Você pode fazer essa tarefa ao fazer a correspondência global "*" em uma configuração do vhost "catch-all" seguindo o padrão na referência Arquétipo de AEM. Ou você pode garantir que a lista mencionada anteriormente seja capturada por um dos vhosts.
Quando a instância de publicação recebe uma nova versão de uma página ou ativo do autor, ela usa o agente de limpeza para invalidar caminhos apropriados em seu Dispatcher. O caminho atualizado é removido do cache do Dispatcher, junto com seus pais, até um nível (você pode configurar esse nível com o statfileslevel).
A Adobe recomenda que você confie nos cabeçalhos de cache padrão para controlar o ciclo de vida da entrega de conteúdo. No entanto, se necessário, é possível invalidar o conteúdo diretamente no Dispatcher.
A lista a seguir contém cenários em que talvez você queira invalidar explicitamente o cache (enquanto escuta, opcionalmente, a conclusão da invalidação):
Há duas abordagens para invalidar explicitamente o cache:
As abordagens diferem em termos de disponibilidade de nível, capacidade de desduplicação de eventos e garantia de processamento de eventos. A tabela abaixo resume essas opções:
N/A | Disponibilidade de nível | Desduplicação | Garantia | Ação | Impacto | Descrição |
---|---|---|---|---|---|---|
API de distribuição de conteúdo do Sling (SCD) | Autor | Possível usar a API de descoberta ou ativar o modo de desduplicação. | Pelo menos uma vez. |
|
|
|
API de replicação | Publicação | Não possível, evento gerado em cada instância de publicação. | Melhor esforço. |
|
|
|
As duas ações diretamente relacionadas à invalidação de cache são Invalidação da API de distribuição de conteúdo do Sling (SCD) e Desativação da API de replicação.
Além disso, na tabela, você pode observar que:
A API SCD é necessária quando cada evento deve ser garantido, por exemplo, sincronização com um sistema externo que requer conhecimento preciso. Se houver um evento de upscaling do nível de publicação no momento da chamada de invalidação, um evento extra será gerado quando cada nova publicação processar a invalidação.
O uso da API de replicação não é um caso de uso comum, mas pode ser usado nos casos em que o acionador para invalidar o cache vem do nível de publicação e não do nível de criação. Esse método pode ser útil se o TTL do Dispatcher estiver configurado.
Concluindo, se você deseja invalidar o cache do Dispatcher, a opção recomendada é usar a ação Invalidar da API SCD do Author. Além disso, você também pode acompanhar o evento para acionar mais ações downstream.
Ao usar as instruções apresentadas abaixo, teste o código personalizado em um ambiente de Desenvolvimento do AEM Cloud Service e não localmente.
Ao usar a ação SCD do autor, o padrão de implementação é o seguinte:
@Reference
private Distributor distributor;
ResourceResolver resolver = ...; // the resource resolver used for authorizing the request
String agentName = "publish"; // the name of the agent used to distribute the request
String pathToInvalidate = "/content/to/invalidate";
DistributionRequest distributionRequest = new SimpleDistributionRequest(DistributionRequestType.INVALIDATE, false, pathToInvalidate);
distributor.distribute(agentName, resolver, distributionRequest);
package org.apache.sling.distribution.journal.shared;
import org.apache.sling.discovery.DiscoveryService;
import org.apache.sling.distribution.journal.impl.event.DistributionEvent;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.sling.distribution.DistributionRequestType.INVALIDATE;
import static org.apache.sling.distribution.event.DistributionEventProperties.DISTRIBUTION_PATHS;
import static org.apache.sling.distribution.event.DistributionEventProperties.DISTRIBUTION_TYPE;
import static org.apache.sling.distribution.event.DistributionEventTopics.AGENT_PACKAGE_DISTRIBUTED;
import static org.osgi.service.event.EventConstants.EVENT_TOPIC;
@Component(immediate = true, service = EventHandler.class, property = {
EVENT_TOPIC + "=" + AGENT_PACKAGE_DISTRIBUTED
})
public class InvalidatedHandler implements EventHandler {
private static final Logger LOG = LoggerFactory.getLogger(InvalidatedHandler.class);
@Reference
private DiscoveryService discoveryService;
@Override
public void handleEvent(Event event) {
String distributionType = (String) event.getProperty(DISTRIBUTION_TYPE);
if (INVALIDATE.name().equals(distributionType)) {
boolean isLeader = discoveryService.getTopology().getLocalInstance().isLeader();
// process the OSGi event on the leader author instance
if (isLeader) {
String[] paths = (String[]) event.getProperty(DISTRIBUTION_PATHS);
String packageId = (String) event.getProperty(DistributionEvent.PACKAGE_ID);
invalidated(paths, packageId);
}
}
}
private void invalidated(String[] paths, String packageId) {
// custom logic
LOG.info("Successfully applied package with id {}, paths {}", packageId, paths);
}
}
invalidated(String[] paths, String packageId)
acima.O CDN do Adobe não é liberado quando o Dispatcher é invalidado. O CDN gerenciado por Adobe respeita TTLs e, portanto, não há necessidade de ele ser liberado.
Veja abaixo o padrão de implementação ao usar a ação Desativar da API de replicação:
O ponto de extremidade do agente de limpeza não é configurável, mas pré-configurado para apontar para o Dispatcher, correspondente ao serviço de publicação em execução junto com o agente de limpeza.
O agente de limpeza geralmente pode ser acionado por um código personalizado com base em eventos OSGi ou workflows.
String[] paths = …
ReplicationOptions options = new ReplicationOptions();
options.setSynchronous(true);
options.setFilter( new AgentFilter {
public boolean isIncluded (Agent agent) {
return agent.getId().equals("flush");
}
});
Replicator.replicate (session,ReplicationActionType.DELETE,paths, options);
As páginas são compostas por HTML, JavaScript, CSS e imagens. Os clientes são incentivados a usar o Estrutura de bibliotecas do lado do cliente (clientlibs) para importar recursos JavaScript e CSS para páginas HTML, levando em conta as dependências entre as bibliotecas JS.
A estrutura clientlibs fornece gerenciamento automático de versões. Isso significa que os desenvolvedores podem fazer check-in das alterações nas bibliotecas JS no controle de origem e a versão mais recente é disponibilizada quando um cliente envia o lançamento. Sem esse fluxo de trabalho, os desenvolvedores devem alterar manualmente o HTML com referências à nova versão da biblioteca, o que é especialmente oneroso se a mesma biblioteca compartilhar muitos modelos de HTML.
Quando as novas versões das bibliotecas são lançadas para produção, as páginas de HTML de referência são atualizadas com novos links para essas versões atualizadas da biblioteca. Depois que o cache do navegador expira para uma determinada página de HTML, não há preocupação de que as bibliotecas antigas sejam carregadas do cache do navegador. O motivo é que a página atualizada (do AEM) agora garante a referência às novas versões das bibliotecas. Ou seja, uma página de HTML atualizada inclui todas as versões mais recentes da biblioteca.
O mecanismo por trás dessa capacidade é um hash serializado, que é anexado ao link da biblioteca do cliente. Ele garante um URL exclusivo com versão para que o navegador armazene em cache o CSS/JS. O hash serializado é atualizado somente quando o conteúdo da biblioteca do cliente é alterado. O que significa que, se ocorrerem atualizações não relacionadas (ou seja, sem alterações no css/js subjacente da biblioteca do cliente), mesmo com uma nova implantação, a referência permanecerá a mesma. Por sua vez, garante menos interrupções no cache do navegador.
As inclusões padrão de clientlib em uma página de HTML são semelhantes ao seguinte exemplo:
<link rel="stylesheet" href="/etc.clientlibs/wkndapp/clientlibs/clientlib-base.css" type="text/css">
Quando o controle de versão estrito da clientlib é ativado, uma chave de hash de longo prazo é adicionada como seletor à biblioteca do cliente. Como resultado, a referência clientlib tem esta aparência:
<link rel="stylesheet" href="/etc.clientlibs/wkndapp/clientlibs/clientlib-base.lc-7c8c5d228445ff48ab49a8e3c865c562-lc.css" type="text/css">
O controle de versão estrito do clientlib é ativado por padrão em todos os ambientes as a Cloud Service do AEM.
Para ativar o controle de versão estrito das bibliotecas de clientes no Quickstart do SDK local, faça o seguinte:
<host>/system/console/configMgr