wcf - saber - soa vs rest
Preguntas de diseño de SOA y WCF: ¿Es este un diseño de sistema inusual? (2)
Todos los servicios tienen el mismo OperationContract: exponen un método Register () y Send ().
Su diseño parece inusual en algunas partes, exponiendo especialmente solo dos operaciones. No he trabajado con WCF, usamos Java. Pero, en mi opinión, el objetivo general de los servicios web es exponer las operaciones que sus socios pueden utilizar.
Tener solo dos Operaciones me parece un diseño extraño. Generalmente expone su API usando WSDL. En este caso, el WSDL no agregaría nada de valor a los socios, a menos que tenga mucha documentación. En general, el nombre de la operación debe ser autoexplicativo. En este momento, su sistema no puede ser utilizado por socios sin tener conocimiento interno.
Hacer toda la comunicación de vuelta a un cliente a través de CallbackContracts es inusual. Sin duda, la solicitud de respuesta de sincronización o asyc es más simple.
De acuerdo con usted. Async solo debe usarse para procesos de larga ejecución. Async agrega la sobrecarga de la correlación.
Me he responsabilizado de continuar con el desarrollo de un sistema que originalmente no diseñé y no puedo preguntar a los diseñadores originales por qué se tomaron ciertas decisiones de diseño, ya que ya no están aquí. Soy un desarrollador junior en cuestiones de diseño, así que no sabía qué preguntar cuando comencé el proyecto, que fue mi primer proyecto SOA / WCF.
El sistema tiene 7 servicios WCF, crecerá a 9, cada uno alojado en una aplicación de consola independiente / servicio de Windows. Todos ellos son de instancia única y de un solo subproceso. Todos los servicios tienen el mismo OperationContract: exponen un método Register () y Send (). Cuando los servicios del cliente desean conectarse a otro servicio, primero llaman a Register (), y si tienen éxito, hacen todo el resto de su comunicación con Send (). Tenemos un DataContract que tiene un MessageType enum y una propiedad de contenido que puede contener otras "cargas útiles" de DataContract. Lo que hace el servicio con el mensaje está determinado por la enumeración MessageType ... todo viene a través del método Send () y luego se enruta a una declaración de cambio ... Sospecho que esto es inusual
Register () y Send () son en realidad OneWay y Async ... TODOS los resultados de los servicios son devueltos a los servicios del cliente por un WCF CallbackContract. Creo que la resonancia para usar CallbackContracts es facilitar el modelo Publish-Subscribe que estamos usando. El problema no es que toda nuestra comunicación se adapte publicar-suscribir y utilizar CallbackContracts significa que tenemos que incluir los datos de origen en los mensajes de resultado devueltos para que los clientes puedan determinar para qué fueron originalmente los resultados devueltos ... otra vez los clientes tienen una instrucción switch para resolver qué hacer con los mensajes que llegan de los servicios basados en el MessageType (y otros detalles integrados).
En términos de topología: los servicios forman "nodos" en un gráfico. Cada servicio ha codificado una lista de otros servicios a los que debe conectarse cuando se inicia, y no permitirá que los servicios del cliente se "registren" hasta que haya realizado todas las conexiones que necesita. Como ejemplo, tenemos un LoggingService y un DataAccessService. DataAccessSevice es un cliente de LoggingService y, por lo tanto, el servicio de DataAccess intentará registrarse en el LoggingService cuando se inicie. Hasta que pueda registrar correctamente el servicio DataAccess, no permitirá que ningún cliente se registre en él. El resultado es que cuando el sistema se enciende como un todo, los servicios se inician en cascada. No veo esto como un problema, pero ¿es esto inusual?
Para hacer las cosas más complejas, uno de los requisitos del sistema es que los servicios o "nodos" no necesitan registrarse directamente entre ellos para enviarse mensajes entre sí, sino que pueden comunicarse a través de enlaces indirectos. Por ejemplo, supongamos que tenemos 3 servicios A, B y C conectados en una cadena, A puede enviar un mensaje a C mediante B ... utilizando 2 saltos.
En realidad, me encargaron esto y escribí el sistema de enrutamiento, fue divertido, pero antes de que pudiera preguntarme por qué era realmente necesario. Por lo que puedo ver, no hay ninguna razón por la cual los servicios no puedan conectarse directamente a los otros servicios que necesitan. Además, tenía que escribir un sistema de confiabilidad además de todo, ya que el requisito era tener mensajes confiables en todos los nodos del sistema, mientras que con simples enlaces punto a punto, WCF hace el trabajo de manera confiable.
Antes de este proyecto, solo había trabajado en las aplicaciones de escritorio winforms durante 3 años, no sabía nada mejor. Mis sospechas son que las cosas se complican demasiado con este proyecto: supongo que para resumir, mis preguntas son:
1) ¿Es inusual la idea de una topología de gráfico con mensajes saltando sobre enlaces indirectos? ¿Por qué no simplemente conectar servicios directamente a los servicios a los que necesitan acceder (que en realidad es lo que hacemos de todos modos ... no creo que tengamos ningún mensaje que salte)?
2) ¿Expone solo 2 métodos en OperationContract y usa la enumeración MessageType para determinar qué es lo que el mensaje es / qué hacer con él inusual? ¿No debería un servicio WCF exponer muchos métodos con fines específicos en su lugar y el cliente elige qué métodos desea llamar?
3) Hacer todas las comunicaciones a un cliente a través de CallbackContracts inusual. Sin duda, la solicitud de respuesta de sincronización o asyc es más simple.
4) ¿La idea de un servicio no permite que los servicios del cliente se conecten a ella (Registro) hasta que se haya conectado a todos sus servicios (para los cuales es cliente) un diseño de sonido? Creo que este es el único aspecto de diseño con el que estoy de acuerdo, me refiero a que DataAccessService no debe aceptar clientes hasta que tenga una conexión con el servicio de registro.
Tengo tantas preguntas WCF, más vendrán en hilos posteriores. Gracias por adelantado.
Bueno, todo parece un poco extraño, de acuerdo.
Todos ellos son de instancia única y de un solo subproceso.
Eso definitivamente va a volver y causar dolores de cabeza de rendimiento masivo - garantizado. No entiendo por qué alguien querría escribir un servicio WCF de Singleton para empezar (excepto en algunos casos extremos, donde tiene sentido), y si tiene un servicio WCF de singleton, para obtener un rendimiento decente, debe ser de subprocesos múltiples (lo cual es una programación complicada, y es por eso que casi siempre desaconsejo).
Todos los servicios tienen el mismo OperationContract: exponen un método Register () y Send ().
Eso es bastante extraño, también. Entonces, ¿quién llama tendrá primero .Register (), y luego llamará a .Send () con diferentes parámetros varias veces? Diseño divertido, realmente ... La suposición de SOA es que diseñes tus servicios para que sean el modelo de un conjunto de funcionalidades que deseas exponer al mundo exterior, por ejemplo, tu CustomerService
podría tener métodos como GetCustomerByID
, GetAllCustomersByCountry
, etc. dependiendo de lo que necesites
Tener solo un único método Send () con parámetros que definen lo que se está haciendo parece un poco ... inusual y poco intuitivo / claro.
¿Es inusual la idea de una topología de gráfico con mensajes saltando sobre enlaces indirectos?
No necesariamente. Puede tener sentido exponer una sola interfaz al mundo exterior, y luego utilizar algunos servicios internos de back-end para hacer el trabajo real. .NET 4 realmente introducirá un servicio de enrutamiento en WCF que facilita este tipo de escenarios. No creo que este sea un gran no-no.
Hacer toda la comunicación de vuelta a un cliente a través de CallbackContracts es inusual.
Sí, inusual, frágil, desordenado, si alguna vez puede prescindir de él, apúntelo. Si tiene llamadas en su mayoría sencillas, como GetCustomerByID
, realice una llamada de solicitud / respuesta estándar, el cliente solicita algo (proporcionando una ID de cliente) y recupera un objeto de Customer
como valor de retorno. ¡Mucho más simple!
Si tiene llamadas de servicio de larga ejecución, puede llevar minutos o más completarlas, entonces puede considerar las llamadas One-Way que simplemente depositan una solicitud en una cola, y esa solicitud se maneja más adelante. En general, aquí puede depositar la respuesta en una cola de respuesta que el cliente verifica o puede tener dos métodos de servicio adicionales que le dan el estado de una solicitud (¿ya está hecho?) Y un segundo método para recuperar el resultado (s) de esa solicitud.
Espero que te ayude a empezar!