Práticas recomendadas de hospedagem dos Serviços de Informações da Internet
Este tópico descreve algumas práticas recomendadas para hospedar serviços do Windows Communication Foundation (WCF).
Implementando serviços WCF como DLLs
A implementação de um serviço WCF como uma DLL implantada no diretório \bin de um aplicativo Web permite que você reutilize o serviço fora do modelo de aplicativo Web, por exemplo, em um ambiente de teste que pode não ter o IIS (Serviços de Informações da Internet) implantado.
Hosts de serviço em aplicativos hospedados no IIS
Não use as APIs de autohost imperativas para criar novos hosts de serviço que escutam em transportes de rede não suportados nativamente pelo ambiente de hospedagem do IIS (por exemplo, o IIS 6.0 para hospedar serviços TCP, porque a comunicação TCP não é suportada nativamente no IIS 6.0). Esta abordagem não é recomendada. Os hosts de serviço criados imperativamente não são conhecidos no ambiente de hospedagem do IIS. O ponto crítico é que o processamento feito por serviços criados imperativamente não é contabilizado pelo IIS quando ele determina se o pool de aplicativos de hospedagem está ocioso. O resultado é que os aplicativos que têm esses hosts de serviço criados imperativamente têm um ambiente de hospedagem do IIS que descarta agressivamente os processos de host do IIS.
URIs e pontos de extremidade hospedados no IIS
Os pontos de extremidade para um serviço hospedado no IIS devem ser configurados usando URIs (Uniform Resource Identifiers) relativos, não endereços absolutos. Isso garante que o endereço do ponto de extremidade esteja dentro do conjunto de endereços URI que pertencem ao aplicativo de hospedagem e garante que a ativação baseada em mensagem aconteça conforme o esperado.
Gestão Estadual e Reciclagem de Processos
O ambiente de hospedagem do IIS é otimizado para serviços que não mantêm o estado local na memória. O IIS recicla o processo de host em resposta a uma variedade de eventos externos e internos, fazendo com que qualquer estado volátil armazenado exclusivamente na memória seja perdido. Os serviços hospedados no IIS devem armazenar seu estado externo ao processo (por exemplo, em um banco de dados) ou em um cache na memória que pode ser facilmente recriado se ocorrer um evento de reciclagem de aplicativo.
Nota
Os protocolos que o WCF usa para confiabilidade e segurança da camada de mensagem usam o estado volátil na memória. Sessões confiáveis e sessões de segurança do WCF podem ser encerradas inesperadamente devido a reciclagens de aplicativos. Os aplicativos hospedados no IIS que usam esses protocolos devem depender de algo diferente da chave de sessão fornecida pelo WCF para correlacionar o estado da camada de aplicativo (por exemplo, uma construção de camada de aplicativo ou cabeçalho de correlação personalizado) ou desabilitar a reciclagem de processos do IIS para o aplicativo hospedado.
Otimizando o desempenho em cenários de camada intermediária
Para obter um desempenho ideal em um cenário de camada intermediária — um serviço que chama outros serviços em resposta a mensagens de entrada — instancie o cliente de serviço WCF para o serviço remoto uma vez e reutilize-o em várias solicitações de entrada. Instanciar clientes de serviço WCF é uma operação cara em relação a fazer uma chamada de serviço em uma instância de cliente pré-existente, e os cenários de camada intermediária produzem ganhos de desempenho distintos armazenando em cache clientes remotos entre solicitações. Os clientes de serviço WCF são thread-safe, portanto, não é necessário sincronizar o acesso a um cliente em vários threads.
Os cenários de camada intermediária também produzem ganhos de desempenho usando as APIs assíncronas svcutil /a
geradas pela opção. A /a
opção faz com que a ServiceModel Metadata Utility Tool (Svcutil.exe) gere BeginXXX/EndXXX
métodos para cada operação de serviço, o que permite que chamadas potencialmente de longa duração para serviços remotos sejam feitas em threads em segundo plano.
WCF em cenários multi-homed ou multi-named
Você pode implantar serviços WCF dentro de uma Web farm do IIS, onde um conjunto de computadores compartilha um nome externo comum (como http://www.contoso.com
), mas são endereçados individualmente por nomes de host diferentes (por exemplo, http://www.contoso.com
pode direcionar o tráfego para duas máquinas diferentes chamadas http://machine1.internal.contoso.com
e http://machine2.internal.contoso.com
). Esse cenário de implantação é totalmente suportado pelo WCF, mas requer configuração especial do site do IIS que hospeda serviços WCF para exibir o nome de host correto (externo) nos metadados do serviço (Web Services Description Language).
Para garantir que o nome de host correto apareça nos metadados de serviço gerados pelo WCF, configure a identidade padrão para o site do IIS que hospeda serviços WCF para usar um nome de host explícito. Por exemplo, os www.contoso.com
computadores que residem dentro do farm devem usar uma associação de site do IIS de *:80:www.contoso.com para HTTP e *:443:www.contoso.com para HTTPS.
Você pode configurar associações de site do IIS usando o snap-in Console de Gerenciamento Microsoft (MMC) do IIS.
Pools de aplicativos em execução em contextos de usuário diferentes substituem assemblies de outras contas na pasta temporária
Para garantir que os pools de aplicativos executados em contextos de usuário diferentes não possam substituir assemblies de outras contas na pasta de arquivos de ASP.NET temporários, use identidades e pastas temporárias diferentes para aplicativos diferentes. Por exemplo, se você tiver dois aplicativos virtuais /Application1 e / Application2, poderá criar dois pools de aplicativos, A e B, com duas identidades diferentes. O pool de aplicativos A pode ser executado sob uma identidade de usuário (user1), enquanto o pool de aplicativos B pode ser executado sob outra identidade de usuário (user2) e configurar /Application1 para usar A e /Application2 para usar B.
Em Web.config, você pode configurar a pasta temporária usando <system.web/compilation/@tempFolder>. Para /Application1, pode ser "c:\tempForUser1" e para application2 pode ser "c:\tempForUser2". Conceda a permissão de gravação correspondente a essas pastas para as duas identidades.
Em seguida, user2 não pode alterar a pasta de geração de código para /application2 (em c:\tempForUser1).
Habilitando o processamento assíncrono
Por padrão, as mensagens enviadas para um serviço WCF hospedado no IIS 6.0 e versões anteriores são processadas de maneira síncrona. ASP.NET chama o WCF em seu próprio thread (o thread de trabalho ASP.NET) e o WCF usa outro thread para processar a solicitação. O WCF mantém o thread de trabalho ASP.NET até concluir seu processamento. Isso leva ao processamento síncrono de solicitações. O processamento assíncrono de solicitações permite maior escalabilidade porque reduz o número de threads necessários para processar uma solicitação –o WCF não mantém o thread ASP.NET durante o processamento da solicitação. O uso de comportamento assíncrono não é recomendado para máquinas que executam o IIS 6.0 porque não há como limitar solicitações de entrada que abrem o servidor para ataques de negação de serviço (DOS). A partir do IIS 7.0, uma limitação de solicitação simultânea foi introduzida: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0]"MaxConcurrentRequestsPerCpu
. Com este novo acelerador é seguro usar o processamento assíncrono. Por padrão no IIS 7.0, o manipulador assíncrono e o módulo são registrados. Se isso tiver sido desativado, você poderá habilitar manualmente o processamento assíncrono de solicitações no arquivo Web.config do seu aplicativo. As configurações que você usa dependem da sua aspNetCompatibilityEnabled
configuração. Se você tiver aspNetCompatibilityEnabled
definido como false
, configure o System.ServiceModel.Activation.ServiceHttpModule
conforme mostrado no trecho de configuração a seguir.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules>
<remove name="ServiceModel"/>
<add name="ServiceModel"
preCondition="integratedMode,runtimeVersionv2.0"
type="System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel,Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</modules>
</system.webServer>
Se você tiver aspNetCompatibilityEnabled
definido como true
, configure o System.ServiceModel.Activation.ServiceHttpHandlerFactory
conforme mostrado no trecho de configuração a seguir.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
<system.webServer>
<handlers>
<clear/>
<add name="TestAsyncHttpHandler"
path="*.svc"
verb="*"
type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
</handlers>
</system.webServer>