wcf wcf-ria-services wcf-data-services astoria

Cómo mejorar el rendimiento de los servicios de datos WCF



wcf-ria-services wcf-data-services (8)

¿Cómo pasas esas 25 iteraciones para WCF?

var WCFobj = new ...Service(); foreach(var calling in CallList) WCFobj.Call(...)

Si llama así, significa que llama a WCF 25 veces, lo que consume demasiados recursos.

Para mí, solía construir todo en una tabla de datos y un nombre de tabla de usuario para el procedimiento almacenado que estoy llamando; DataRow es params. Cuando llame, simplemente pase el DataTable en forma cifrada mediante el uso de

var table = new DataTable("PROC_CALLING")... ... StringBuilder sb = new StringBuilder(); var xml = System.Xml.XmlWriter.Create(sb); table.WriteXml(xml); var bytes = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); [optional]use GZip to bytes WCFobj.Call(bytes);

Lo que pasa es que pasas las 25 llamadas a la vez, lo que puede ahorrar significativamente el rendimiento. Si el objeto de retorno es la misma estructura, simplemente páselo como DataTable en forma de bytes y conviértelo de nuevo a DataTable .

Solía ​​implementar estos métodos con GZip para módulos de datos de importación / exportación. Pasar una gran cantidad de bytes va a hacer que WCF no esté contento. Depende de lo que quieras consumir; recursos informáticos o recursos de red.

Soy nuevo en WCF Data Services, así que he estado jugando. Después de algunas pruebas iniciales, estoy decepcionado por el rendimiento de mi servicio de datos de prueba.

Me doy cuenta de que, debido a que un DS WCF está basado en HTTP, existe una sobrecarga inherente al protocolo, pero mis pruebas son aún mucho más lentas de lo que esperaba:

Ambiente:

  • Todo en una sola caja: computadora portátil de cuatro núcleos de 64 bits con 4 GB de RAM con W7. Máquina decente
  • Pequeña base de datos SQL (SQLExpress 2008 R2) con 16 tablas ... la tabla bajo prueba tiene 243 filas.
  • Organicé mi servicio de prueba en IIS con todos los valores predeterminados.

Código:

  • Creé un modelo de Entity Framework (DataContext) para esta base de datos (stock codegen de VS2010).
  • Creé un servicio de datos basado en este modelo.
  • Creé un cliente que tiene una referencia de servicio directo (ObjectContext) para este servicio (stock codegen por VS2010)
  • En el cliente también puedo llamar directamente al modelo EF y también usar Native SQL (ADO.NET SqlConnection)

Plan de prueba:

  • Cada iteración se conecta a la base de datos (hay una opción para volver a utilizar las conexiones), consulta todas las filas en la tabla de destino ("EVENTOS") y luego las cuenta (forzando así las ejecuciones diferidas a realizar).
  • Ejecutar para 25 iteraciones cada uno para SQL nativo (SqlConnection / SqlCommand), Entity Framework (DataContext) y WCF Data Services (ObjectContext).

Resultados:

  • 25 iteraciones de SQL nativo: 436ms
  • 25 iteraciones de Entity Framework: 656ms
  • 25 iteraciones de WCF Data Services: 12110ms

Ay. Eso es aproximadamente 20 veces más lento que EF.

Dado que WCF Data Services es HTTP, no hay oportunidad para la reutilización de la conexión HTTP, por lo que el cliente se ve obligado a volver a conectarse con el servidor web para cada iteración. Pero seguramente está sucediendo más aquí que eso.

EF en sí es bastante rápido y es el mismo código / modelo de EF que se reutiliza tanto para el servicio como para las pruebas del cliente directo a EF. Habrá una sobrecarga para la serialización Xml y la deserialización en el servicio de datos, ¡pero eso es mucho!?! He tenido un buen rendimiento con la serialización Xml en el pasado.

Voy a realizar algunas pruebas con codificaciones JSON y Protocol-Buffer para ver si puedo obtener un mejor rendimiento, pero tengo curiosidad si la comunidad tiene algún consejo para acelerar esto.

No soy fuerte con IIS, ¿entonces quizás hay algunos ajustes de IIS (cachés, grupos de conexiones, etc.) que se pueden configurar para mejorar esto?


Aumenté el rendimiento de nuestra API del Servicio de Datos WCF en un 41% simplemente habilitando la compresión. Fue realmente fácil de hacer. Siga este enlace que explica qué hacer en su servidor IIs: habilitación de compresión dinámica (gzip, desinflar) para feeds de datos WCF, OData y otros servicios personalizados en IIS7

¡No olvides iisReset después de tu cambio!

En el lado del cliente:

// This is your context basically, you should have this code throughout your app. var context = new YourEntities("YourServiceURL"); context.SendingRequest2 += SendingRequest2; // Add the following method somewhere in a static utility library public static void SendingRequest2(object sender, SendingRequest2EventArgs e) { var request = ((HttpWebRequestMessage)e.RequestMessage).HttpWebRequest; request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; }


Considere la implementación como un servicio de Windows en su lugar? IIS puede tener filtros ASAPI, reglas de reescritura, etc. que se ejecuta. incluso si ninguno de estos está activo, la interconexión de IIS es tan larga que algo puede ralentizarlo marginalmente.

un servicio debería brindarle una buena referencia de cuánto tiempo lleva la solicitud ejecutar, empaquetar, etc., sin la ralentización de IIS



Intente configurar la seguridad en "ninguno" en la sección de enlace en la configuración. Esto debería hacer una gran mejora.


Para eliminar la mayor parte de la sobrecarga de conexión, puede intentar agrupar todas las operaciones en WCF DS para ver si eso marca una diferencia significativa.

NorthwindEntities context = new NorthwindEntities(svcUri); var batchRequests = new DataServiceRequest[]{someCustomerQuery, someProductsQuery}; var batchResponse = context.ExecuteBatch(batchRequests);

Para más información, mira here .


WCF DataServices es para proporcionar a sus clientes dispares con el protocolo OpenData; para que no tenga que escribir / refactorizar múltiples métodos de servicio web para cada solicitud de cambio. Nunca aconsejo que se use si todo el sistema está basado en la tecnología de microsoft. Está destinado a clientes remotos.


cosas para probar:

1) codificación de resultados: utilice la codificación binaria de su canal WCF si es posible, consulte http://msdn.microsoft.com/en-us/magazine/ee294456.aspx - use alternativamente la compresión: http://programmerpayback.com/2009/02/18/speed-up-your-app-by-compressing-wcf-service-responses/

2) cambie el comportamiento de su instancia de servicio, consulte http://msdn.microsoft.com/en-us/magazine/cc163590.aspx#S6 - intente InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple - si puede verificar que su servicio está construido de una manera segura.

En cuanto a su punto de referencia, creo que debe simular una carga más realista (incluidos los usuarios concurrentes) e ignorar los valores atípicos, la primera solicitud a IIS será realmente lenta (tiene que cargar todas las DLL)