2010-10-12 17 views
23

Soy nuevo en los servicios de datos de WCF, así que he estado jugando. Después de algunas pruebas iniciales, estoy decepcionado por el rendimiento de mi servicio de datos de prueba.Cómo mejorar el rendimiento de los servicios de datos de WCF

que se dan cuenta de que, debido a un WCF DS es HTTP basado en que hay sobrecarga inherente al protocolo, pero mis pruebas son todavía muy lento de lo que se puede esperar:

Medio Ambiente:

  • Todo en una caja : Computadora portátil Quad Core 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:

  • He creado un modelo de Entity Framework (DataContext) de esta base de datos (archivo codegen por VS2010).
  • He creado un servicio de datos basado en este modelo.
  • He creado un cliente que tiene una referencia de servicio directo (ObjectContext) para este servicio (de la codegen por VS2010)
  • En el cliente también soy capaz de llamar el modelo EF directamente y también utilizar SQL Native (ADO .NET SqlConnection)

plan de pruebas:

  • Cada iteración se conecta a la base de datos (no es una opción para reutilizar las conexiones), consultas de todas las filas de la tabla de destino ("Eventos") y luego los cuenta (lo que obliga a realizar recuperaciones diferidas).
  • Ejecutar para 25 iteraciones cada una para SQL nativo (SqlConnection/SqlCommand), Entity Framework (DataContext) y WCF Data Services (ObjectContext).

Resultados:

  • 25 iteraciones de SQL Native: 436ms
  • 25 iteraciones del marco de la entidad: 656ms
  • 25 iteraciones de WCF Data Services: 12110ms

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

Dado que los servicios de datos WCF son 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 es bastante rápido y es el mismo código/modelo EF que se reutiliza para las pruebas de servicio y de 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 las 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, por lo que quizás haya algunos ajustes de IIS (cachés, pools de conexión, etc.) que se pueden configurar para mejorar esto?

+0

interesante ... una serie de puntos de vista, unos up-votos, y un par de favoritos añade, pero no hay respuestas. Estoy abriendo una recompensa por esto para dar más vida a esta pregunta. Espero que alguien tenga una respuesta. –

+0

No utilizaría WCF Data Services a menos que estuviera planeando exponer mis datos a otras aplicaciones. Si todo se está ejecutando en la misma caja, ¿por qué no simplemente usar EF directamente? –

+0

No se está ejecutando en la misma caja. Pero las fuentes de datos están todas en una red corporativa (muy grande e internacional). Estoy tratando de poner una capa de servicio frente a una serie de fuentes de datos diferentes (SQL, XML, archivos planos, etc.) que aísla la semántica de almacenamiento real de la capacidad de descubrir y consultar los datos. –

Respuesta

0

Para eliminar la mayor parte de la sobrecarga de la conexión, puede intentar realizar todas las operaciones en el 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 vea here.

+0

La agrupación en lotes solo es posible cuando conoce las operaciones que está realizando con anticipación. En mi caso, necesito reaccionar a los datos, por lo que desafortunadamente es un ciclo de consulta-> proceso-> pantalla-> consulta-> proceso-> pantalla. –

0

¿Cómo pasa 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 un DataTable y el nombre de la tabla de usuario para el procedimiento almacenado que estoy llamando; DataRow es params. Al llamar, sólo tiene que pasar la DataTable de forma encriptada 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 pase los 25 llamadas a la vez, que pueden ahorrar significativamente el rendimiento. Si el objeto de retorno es la misma estructura, simplemente páselo como DataTable en bytes y conviértelo de nuevo a DataTable.

Solía ​​implementar estos métodos con GZip para importar/exportar módulos de datos. 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.

+0

Esto es específicamente para un Servicio de Datos WCF ... el problema es muy solucionable para un servicio WCF estándar donde hay un mejor control del enlace y la codificación del mensaje. –

1

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

+0

Buena idea ... Voy a intentarlo. Por supuesto, todavía necesito seguridad en mi aplicación final. Pero tengo curiosidad por lo que es la sobrecarga. –

-1

cosas para probar:

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

2) cambiar su comportamiento 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 manera segura.

Con respecto a su índice de referencia, creo que debe simular la carga más realista (incluyendo usuarios concurrentes) e ignorar los valores extremos, la primera solicitud a IIS será muy lento (tiene que cargar todos los archivos DLL)

+1

Parece que proporciona una guía WCF más general que la guía específica del servicio de datos WCF. No es posible (que yo sepa) cambiar el método de codificación para WCF Data Services ... deben ser puntos finales HTTP con datos de texto. .el formato de serialización puede ser Xml o Json, pero debe ser texto. Así que la compresión y la codificación binaria no es posible (ojalá lo fuera). –

+0

Voy a ver la instancia y la concurencia. La mejor práctica para WCF establece que se debe usar la instanciación de PerCall, pero una instancia única con concurrencia múltiple también podría funcionar. Lo intentaré. –

+0

En cuanto al punto de referencia, el realismo es menos un problema que la coherencia entre las operaciones entre diferentes proveedores. Ya estoy descartando los valores atípicos ... la iniciación lleva alrededor de 4-5 segundos por sí solo. Puedo vivir con eso si es solo una vez. La compresión –

3

Considere el despliegue 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 debe darle una buena base de cuánto tiempo tarda la solicitud para funcionar, ser envasados, etc., sin el IIS desaceleraciones

+0

Esa es una buena idea. También daré una oportunidad cuando regrese a esta parte del proyecto. –

0

DataServices WCF son 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.

0

Aumenté el rendimiento de nuestra API de 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: Enabling dynamic compression (gzip, deflate) for WCF Data Feeds, OData and other custom services in IIS7

¡No olvide iisReset después de su 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; 
} 
Cuestiones relacionadas