Pergunta

Eu tenho um aplicativo cliente WCF / servidor que está a comunicar através de HTTP utilizando o WSHttpBinding.

Configuração do servidor : auto-hospedagem, usando o ServiceHost WCF padrão. Minha classe de serviço real é atribuído como:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
 InstanceContextMode = InstanceContextMode.PerSession, 
 UseSynchronizationContext = false)]

Configuração do Cliente : (. Blocos proxy.call_server_method até o momento em que o servidor tenha respondido na íntegra) usando um visual-studio proxy do cliente gerado usando síncrona chamadas de serviço

Cenário : Eu tenho uma chamada de método particular que leva 20 segundos para executar no servidor. O cliente chama esse método em um segmento separado, por isso não está sendo realizada, e os meios ConcurrencyMode.Multiple WCF deve executá-lo em um segmento separado no servidor também.

Esta teoria é apoiada pelo fato de que quando eu configurar meu aplicativo para uso NetTcpBinding, tudo funciona bem.

Problema :
Se eu configurar o aplicativo para uso WSHttpBinding, então esta longa chamada de método faz com que as solicitações HTTP para 'backup'. Tenho verificado este comportamento tanto de inspecionar meus registros, e por depurar as solicitações HTTP usando violinista.

Exemplo:

  • iniciados cliente de 20 segundos longa pedido em uma discussão de fundo
  • iniciados cliente solicitar B e C no segmento de primeiro plano
  • Pedidos B e C são enviados para o servidor, que não processá-los até que seja feito com o 20-segundo pedido longo

Mas às vezes:

  • Pedidos B e C não são enviados (eles nem sequer aparecem em Fiddler) até o 20-segundo pedido volta (isso é raro).
    • Nota: definir <add address="*" maxconnection="100"/> no app.config do cliente fez esta (parecem) param de acontecer
    • .
  • Request B é enviado e recebe uma resposta imediatamente, enquanto solicitação C está de volta mantido até a 20 segundos um completa (isso é raro)

Aqui está um cronograma de violinista demonstra o problema: (clique para versão maior)

Como você pode ver, as solicitações são todos ficar apoiada no servidor. Uma vez que os 20 segundos concluída pedido, as respostas todos vêm inundando completamente, mas nota que há alguns pedidos que não são se levantou ...

Assim, Perguntas :

  • O que diabos está acontecendo aqui? Por que isso funciona muito bem usando NetTcpBinding e não trabalhar usando WSHttpBinding?
  • Por que o comportamento inconsistente?
  • O que posso fazer para corrigir isso?

Notas:

  • Não é bloqueio no servidor. Eu definir pontos de interrupção e !syncblk usado e consistentemente relatórios sem bloqueios estão sendo realizadas.
  • Não é minha segmentação (NetTcpBinding não devem trabalhar de outra forma)
  • Eu tenho set <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> no servidor é app.config
  • A 20 segunda chamada está apenas esperando em um temporizador, não está debatendo o CPU ou disco ou rede
  • Eu preferiria uma solução que não envolve re-arquitetar o aplicativo para usar chamadas assíncronas ... é um grupo grande de código legado e eu realmente não quero ser mexer com coisas que eu não entendo .
Foi útil?

Solução 3

[Auto-resposta para mostrar aos outros o que a nossa eventual solução foi]

No final, eu nunca conseguiu resolver isso.
Nossa solução final foi para mudar nosso aplicativo longe de WSHttpBinding e para NetTcpBinding na produção - que tinha sido pensando em fazer isso, eventualmente, de qualquer maneira, por razões de desempenho

.

Este é bastante lamentável, porém, como ele deixa uma marca preta em WSHttpBinding que pode ou não pode ser garantido. Se alguém é nunca chegar a uma solução que não envolve afundamento WSHttpBinding, eu adoraria saber sobre ele

Outras dicas

Há alguns fora do acelerador de WCF (uma coisa .NET ou Windows) que a inadimplência só para deixar um máximo de duas conexões simultâneas de saída HTTP. Infelizmente eu não posso lembrar para a vida de mim o nome da coisa (eo que seria de colocar em app.config ou seu aplicativo para substituí-lo). Tendo em conta que você não está vendo os pedidos de deixar o cliente, e que é apenas HTTP, eu acho que você está batendo "aquela coisa". Vou continuar procurando o seu nome.

Update: Encontrado o - tentar isso no cliente (mas mudar o '2' para um número maior):

<configuration>
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "2" />
    </connectionManagement>
  </system.net>
</configuration>

Vimos exatamente os mesmos sintomas com um serviço JSON hospedado em IIS / ASP.NET.

A causa acabou sendo ASP.NET sincronização dos pedidos - não WCF. Tivemos que o estado da sessão desativar (no nível do aplicativo) para obter métodos WCF simultâneos.

Web.config: <system.web> <sessionState mode="Off" /> </system.web>

Por favor, note que os nossos usos de serviços WebHttpBinding, não wsHttpBinding. Então, eu não tenho certeza se isso também resolve o problema de Orion.

Eu acho que você atingiu o limite de protocolo e ao trabalho em torno dele, é necessário modificar as configurações padrão na máquina do cliente:

http://support.microsoft.com/kb/183110

http://support.microsoft.com/kb/282402

Eu acho usos WSHttpBinding WinINET configurações ao emitir os pedidos.

Se você alterar a BasicHttpBinding, ele funciona?

é assim, parece que este é o seu problema, estrangulamento sessão, algo que me mordeu na bunda.

Considere o uso de ConcurrencyMode.Multiple sobre serviços por chamada para permitir que concorrentes chamadas.

Eu esqueço - poderia ser ordenação? Eu acho que talvez RM sobre http preserva a ordem, mas talvez sessões TCP não (a menos que você solicitá-lo explicitamente)? Existe um atributo no contrato de serviço que descreveu ordenou sessões / desordenadas (esqueci).

Não tenho certeza, mas às vezes o problema com as chamadas simultâneas de aplicação Silverlight estão relacionados com a gestão de ligação do browser. Para mim a solução foi colocar isso em nossas App.xaml.cs, método Application_Startup como descrive aqui: http://weblogs.asp.net/olakarlsson/simultaneously-calling-multiple-methods-on-a-wcf-service-from-silverlight

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top