O tráfego passa pelo CDN para uma camada de servidor da Web apache, que suporta módulos, incluindo o dispatcher. Para aumentar o desempenho, o dispatcher é usado principalmente como um 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 do cache, resultando no armazenamento em cache no CDN. Observe que o dispatcher também respeita os cabeçalhos de expiração do cache resultante se enableTTL
estiver ativado na configuração do dispatcher, o que implica que ele atualizará o 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, bem como como 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 apache. A CDN também respeita esse valor.DISABLE_DEFAULT_CACHING
em global.vars
:Define DISABLE_DEFAULT_CACHING
Isso pode ser útil, por exemplo, quando sua lógica comercial requer o ajuste fino do cabeçalho da idade (com um valor com base no dia do calendário), já que, por padrão, o cabeçalho da idade é 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 a variável EXPIRATION_TIME
em global.vars
usando as ferramentas AEM as a Cloud Service do SDK Dispatcher.
pode ser substituído em um nível mais refinado, incluindo o controle independente de CDN e cache de navegador, com as seguintes diretivas apache mod_headers:
<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 Controle de Substituição se aplica à CDN gerenciada pelo Adobe. Se estiver usando um CDN gerenciada pelo cliente, um cabeçalho diferente pode ser necessário, dependendo do provedor CDN.
Tenha cuidado ao definir cabeçalhos de controle de cache global ou aqueles que correspondem a um grande regex, de modo que eles não sejam aplicados ao conteúdo que você pretende manter privado. Considere o uso de várias diretivas para garantir que as regras sejam aplicadas de forma refinada. Dito isso, AEM as a Cloud Service removerá o cabeçalho do cache se detectar que ele foi aplicado ao que 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 da seguinte forma:
<LocationMatch "^/content/.*\.(html)$">
Header unset Cache-Control
Header unset Expires
Header always set Cache-Control "max-age=200"
Header set Age 0
</LocationMatch>
Você deve garantir que um arquivo de src/conf.dispatcher.d/cache
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 Controle de Cache como private. Por exemplo, o seguinte impediria o conteúdo html em um diretório chamado seguro de ser armazenado em cache no CDN:
<LocationMatch "/content/secure/.*\.(html)$">. // replace with the right regex
Header unset Cache-Control
Header unset Expires
Header always set Cache-Control “private”
</LocationMatch>
Os outros métodos, incluindo o dispatcher-ttl AEM projeto ACS Commons, não substituirá os valores com êxito.
Observe que o dispatcher ainda pode armazenar o conteúdo em cache de acordo com seu próprio regras de armazenamento em cache. Para tornar o conteúdo realmente privado, você deve garantir que ele não seja armazenado em cache pelo dispatcher.
O comportamento padrão dos programas criados após meados de maio de 2022 (especificamente, para ids de programa maiores que 65000) é armazenar em cache por padrão, respeitando também o contexto de autenticação da solicitação. Os programas mais antigos (ids de programa iguais ou inferiores a 65000) não armazenam em cache o conteúdo do blob por padrão.
Em ambos os casos, os cabeçalhos de armazenamento em cache podem ser substituídos em um nível de granularidade 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 above. Além disso, verifique se os ativos destinados a serem mantidos privados (em vez de armazenados em cache) não fazem parte do LocationMatch
filtros de diretiva.
A camada de AEM definirá cabeçalhos de cache dependendo se o cabeçalho do cache já foi definido e do valor do tipo de solicitação. Observe que, se nenhum cabeçalho de controle de cache tiver sido 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 tiver sido definido, os cabeçalhos do cache não serão tocados.
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 | Controle de cache: 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
como falso.
A camada de AEM não armazenará em cache o conteúdo do blob por padrão.
É recomendável alterar o comportamento padrão mais antigo para que seja consistente com o novo comportamento (ids de programa mais altas 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, depois das alterações, o conteúdo se comporta conforme o esperado.
Os outros métodos, incluindo o dispatcher-ttl AEM projeto ACS Commons, não substituirá os valores com êxito.
EXPIRATION_TIME
variável usada para tipos de arquivo html/textEvite usar User-Agent
como parte da Vary
cabeçalho. Versões anteriores da configuração padrão do dispatcher (antes do arquétipo versão 28) incluíam isso e recomendamos que você remova isso 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, com exceção do default.vhost, que é somente leituraUse o Surrogate-Control
cabeçalho para controlar o armazenamento em cache CDN independentemente do armazenamento em cache do navegador
Considere aplicar stale-while-revalidate
e stale-if-error
diretivas para permitir a atualização em segundo plano e evitar falhas no cache, mantendo o 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 se seguem para vários tipos de conteúdo, que podem ser usados como guia ao configurar suas próprias regras de cache. Considere e teste cuidadosamente a configuração e os requisitos específicos:
Armazene em cache os recursos da biblioteca do cliente mutável para 12h e atualize em segundo plano após 12h.
<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>
Armazene 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 HTML pages por 5 minutos com a atualização em segundo plano 1 h no navegador e 12 h no CDN. Os cabeçalhos de controle de cache sempre serão adicionados, portanto, é importante garantir que as páginas html correspondentes em /content/* sejam destinadas ao público. 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 dos serviços de conteúdo/exportador de modelo Sling por 5 minutos com atualização em segundo plano em 1h no navegador e 12h 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 a 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 para 24 horas e atualize o plano de fundo 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 de HEAD é recebida na CDN do Adobe para um recurso que é not em cache, a solicitação é transformada e recebida pelo dispatcher e/ou AEM instância como uma solicitação GET. Se a resposta for armazenada em cache, as solicitações de HEAD subsequentes serão atendidas a partir da CDN. Se a resposta não puder ser armazenada em cache, as solicitações de HEAD subsequentes serão passadas para o dispatcher e/ou AEM instância por um período que depende do Cache-Control
TTL.
Em geral, não será 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 respeitar os cabeçalhos de expiração do cache.
Como nas versões anteriores do AEM, a publicação ou o cancelamento da publicação de páginas limpará o conteúdo do cache do dispatcher. Se houver suspeita de um problema de cache, os clientes devem republicar as páginas em questão e garantir que um host virtual esteja disponível que corresponda ao host local ServerAlias, o que é necessário para a invalidação do cache do dispatcher.
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 os caminhos apropriados em seu dispatcher. O caminho atualizado é removido do cache do dispatcher, juntamente com seus pais, até um nível (você pode configurar isso com a variável statfileslevel).
O Adobe recomenda confiar em 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 você pode querer invalidar explicitamente o cache (enquanto, opcionalmente, escuta a conclusão da invalidação):
Há duas abordagens para invalidar explicitamente o cache:
As abordagens diferem em termos de disponibilidade de camada, da capacidade de desduplicar eventos e da 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 Sling Content Distribution (SCD) | Autor | Possível usando a API de descoberta ou habilitando a variável 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. |
|
|
|
Observe que as duas ações diretamente relacionadas à invalidação do cache são Invalidar a API da Distribuição de conteúdo de sling (SCD) e Desativar a API de replicação.
Além disso, a partir da tabela, observamos que:
A API SCD é necessária quando todos os eventos devem ser garantidos, por exemplo, sincronização com um sistema externo que requer conhecimento preciso. Observe que, se houver um evento de aumento do nível de publicação no momento da chamada de invalidação, um evento adicional 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 deve 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. Isso pode ser útil se o TTL do dispatcher estiver configurado.
Em conclusão, se você estiver procurando invalidar o cache do dispatcher, a opção recomendada é usar a ação Invalidar da API SCD do Autor. Além disso, você também pode acompanhar o evento para depois acionar outras ações de downstream.
Ao usar as instruções apresentadas abaixo, esteja ciente de que você deve testar o código personalizado em um ambiente de desenvolvimento 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 Adobe CDN não é liberado quando o dispatcher é invalidado. A CDN gerenciada por Adobe respeita os TTLs e, portanto, não há necessidade de liberá-la.
Apresentado abaixo é o padrão de implementação ao usar a ação de desativação da API de replicação:
O endpoint do agente de limpeza não é configurável, mas sim 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 código personalizado com base em eventos ou fluxos de trabalho OSGi.
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 aproveitar 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ão, o que significa que os desenvolvedores podem fazer check-in de alterações nas bibliotecas JS no controle de origem e a versão mais recente será disponibilizada quando um cliente enviar o lançamento. Sem isso, os desenvolvedores precisariam alterar manualmente o HTML com referências à nova versão da biblioteca, que é especialmente onerosa se muitos templates de HTML compartilharem a mesma biblioteca.
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 expirar para uma determinada HTML page, não há preocupação de que as bibliotecas antigas sejam carregadas do cache do navegador, pois a página atualizada (de AEM) agora é garantida para fazer referência às novas versões das bibliotecas. Em outras palavras, uma página de HTML atualizada incluirá todas as versões mais recentes da biblioteca.
O mecanismo para isso é um hash serializado, que é anexado ao link da biblioteca do cliente, garantindo um url exclusivo com versão para o navegador armazenar em cache o CSS/JS. O hash serializado só é atualizado quando o conteúdo da biblioteca do cliente muda. Isso 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, garantindo menos interrupção do cache do navegador.
As inclusões padrão de clientlib em uma página 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 restrito 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 clientlib restrito é ativado por padrão em todos os ambientes AEM as a Cloud Service.
Para ativar o controle de versão restrito do clientlib no Quickstart do SDK local, execute as seguintes ações:
<host>/system/console/configMgr