java - tutorial - ¿Cuál es una buena práctica para implementar servicios web?
web service pdf (11)
¿Es una buena práctica implementar servicios web por separado o deberían ser parte de la aplicación web? Por ejemplo, estoy desarrollando un servicio web basado en el descanso de primavera . La función de este servicio es, digamos, obtener datos del usuario.
Cada aplicación que consulta este servicio web tiene sus datos de usuario en diferentes esquemas. Entonces, ahora el servicio web necesitará saber quién lo está llamando, ¿es la aplicación A o la aplicación B? Si es AppA, entonces debería obtener datos del Esquema A, si es AppB, entonces es otro esquema. Tenga en cuenta que AppA y AppB son el mismo código empaquetado en dos guerras diferentes y el esquema que se supone que deben consultar proviene del archivo de propiedades.
En una situación como esta, ¿tiene sentido empaquetar el servicio web con el código de aplicación web y desplegarlo en diferentes contextos, por lo que se convierte en un servicio duplicado que se ejecuta en un contexto diferente. O bien, ¿debería implementarse por separado y, de alguna manera, la AppA y la AppB deben identificarse en este servicio web?
En ese escenario, es una buena práctica tener solo un servicio web, de esta manera se mejora la mantenibilidad del sistema porque no se tiene el mismo código dos veces. Si tiene en el futuro otra aplicación similar nueva, no tiene que implementar un nuevo servicio.
Es una cuestión de opinión, ambas opciones están bien. Debe tener en cuenta el uso del servicio, escalar preocupaciones, etc.
Podrías mirar a Microservicios como una idea, pero tiene que tener sentido desde tu punto de vista.
Acerca de las dos aplicaciones diferentes: si las diferencias están solo en la configuración, intente externalizarla ( 23. Configuración externalizada ). De esta forma, puede tener un solo artefacto desplegado dos veces.
Personalmente, en mi experiencia, es mucho mejor separarlos, generalmente depende de qué tan grande y cuán crítico sea tu proyecto principal.
Pero incluso si al principio su proyecto no es tan grande y solo hay 1 persona trabajando en él, más adelante, a medida que siga creciendo, si tiene microservicios para todas las cosas que hace su proyecto principal, será mucho más fácil para mantener, en lugar de tener muchas personas trabajando en el mismo código manejando muchas versiones de un proyecto único, manejar muchos proyectos pequeños es menos confuso y los errores son más fáciles de encontrar.
Además, si algo falla, puedes tener 1 microservicio inactivo mientras tu principal todavía se ejecuta sin interrupción, solo por denegación de 1 servicio, en lugar de tenerlo todo apagado mientras lo arreglas.
La alta disponibilidad es muy importante en la producción, y tenerlos separados ayuda con esto.
mis entradas:
1) ¿Alguna razón específica para construir 2 guerras diferentes por el mismo código? ¿Es solo porque tienes dos fuentes de datos diferentes para cada uno de ellos? ¿Por qué no se puede implementar una sola aplicación con algún mecanismo parametrizado en cada solicitud para identificar de qué esquema obtener datos?
2) ¿Por qué necesitas un servicio web en primer lugar? ¿Por qué no aplicación de enlace directamente a la base de datos que necesitaba.
3) ¿La base de datos subyacente es una base de datos transaccional o algunos datos históricos? ¿Qué hay de combinar ambos esquemas en uno como esfuerzo de una sola vez O utilizando algún tipo de vistas virtualizadas que recoge datos de 2 esquemas basados en parámetros de entrada.
***** editado después de las aportaciones de Jay:
Mi sugerencia será que el servicio web se implemente por separado de 2 aplicaciones web, ya que brinda un lugar único para administrar el código a largo plazo. Tengo siguientes sugerencias adicionales:
Defina sus propios encabezados en el Esquema XML de SOAP, que puede proporcionarle tanto appContext (llamada a la aplicación) como userContext (usuario). Reflexione sobre este aspecto manteniendo una visión a largo plazo.
Mantenga la solicitud-respuesta SOAP sin estado, lo que le dará escalabilidad. No mantenga ningún estado de solicitud SOAP en el lado del servidor.
En el pasado, utilicé una solución de virtualización de datos (CISCO Composite) ... qué beneficios ofrece: si hay dos (o más) fuentes de datos que contienen un tipo similar de datos (entidades), puede unirse, limpiarse y fusionarse virtualmente y exponer como servicio web basado en REST / SOAP. Intenta evaluar esta opción también. Lo que puede ayudar aún más si en el futuro tiene otros consumidores para acceder a su información mediante una simple llamada SQL / JDBC, ellos podrán hacerlo ... también las soluciones de virtualización de datos admiten muchas otras interfaces para consumidores como Hadoop, OData, etc. De nuevo, depende del presupuesto y otras limitaciones del proyecto ... No estoy seguro de si hay alguna solución de virtualización de datos de código abierto disponible o no.
Enfoque 1: - (Preffered)
Debería tener una sola aplicación web en la que tenga el código completo para la interfaz de usuario de la aplicación y la interacción Repo / datos.
Según el tipo de solicitud, cambie dinámicamente la fuente de datos según sea necesario. Puede consultar el enrutamiento de datasource de Spring Dynamic aquí
Enfoque 2: -
En caso de que su UI tenga un tipo de interacción completamente diferente administrado por diferentes equipos, tiene sentido tener componentes de UI separados y los servicios web de back-end mantenidos en la misma ubicación.
De nuevo, según el tipo de solicitud, puede enrutar dinámicamente el origen de datos.
Espero que esto ayude :)
Dada su situación, aconsejaría ir con UNA aplicación web (un "proyecto") con algunas advertencias y luego considerar una de las dos soluciones:
1) Dado que estás usando la primavera, asumiré (espero) que también estés utilizando maven ... Haz un objetivo de compilación diferente y haz que, de acuerdo con el objetivo invocado para producir la guerra, el archivo de propiedades relevante sea diferente .. De esta forma tienes UNA aplicación web, y en base a la compilación (o más bien, basada en el archivo de propiedades vinculado a esa compilación específica) obtendrás una guerra ligada a un entorno y esquema específicos ... Despliegas una guerra individual para cada servicio web con una separación limpia, aunque el código raíz es el mismo y es solo una aplicación ... [SOLUCIÓN DE LIMPIEZA] 2) Haga que no solo obtenga la solicitud json, sino también el certificado https del remitente (por lo tanto, identifica una "aplicación web" específica basada en el certificado https expuesto), y en función del certificado Y de la fuente de la solicitud, garantizas que la fuente está "calificada" para recibir datos del esquema X en lugar del esquema Y ... Implementas UNA guerra solo eso, a su propia discreción, aplicará la lógica para redirigirlo r "consulta de obtención de datos de usuario" a una base de datos u otra [DISPONGO ESTA PRÁCTICA]
por supuesto, hay otro enfoque también, pero creo que estos dos son los más factibles ..
Realmente depende de lo que quieres lograr.
Si desea encapsular la base de datos / esquema / tabla, realmente debería ser un servicio para cada aplicación. La principal ventaja de hacer esto es que puede cambiar la base de datos más adelante si hay algún problema con la actual, también simplifica el almacenamiento en caché y la invalidación, etc., etc.
Si la base de datos / esquema / tabla no está encapsulada de todos modos, entonces el servicio individual es mucho más fácil y mejor. Cada aplicación web solo tiene que identificarse, y cada uno obtendrá exactamente lo que necesita. Esto se puede lograr colocando la información de consulta / esquema en el archivo de propiedad o creando vistas de BD con el mismo nombre como cliente, etc.
Si tuviéramos que ir por este enfoque, aparecerá una pregunta. ¿Por qué molestarse en tener esta capa? ¿No podría cada aplicación web simplemente consultar el archivo db directamente? Si la respuesta es sí, simplemente elimine toda la capa por completo.
Está intentando implementar un proveedor de datos o DAO como un servicio. Para hacerlo -
- Sencillo
- Escalable
- Compatible con el mantenimiento,
- Adaptable
Simplemente puede tener un único servicio web, desplegado fuera de la (s) aplicación (es) web y desconectado de la configuración. La configuración en sí misma puede almacenarse como un archivo de propiedad, o desde un DB. El identificador para el cliente se debe pasar en la solicitud del servicio web.
En realidad, se trata de un enfoque bastante estándar implementado para permitir optimizaciones en el nivel de datos fuera de DB, como el almacenamiento en caché (nuevamente controlado por la configuración), el vencimiento, la puesta en común, etc.
La otra opción, incluir como jar compartido dentro de la aplicación web, sí, tiene la ventaja de la reutilización de código (que también se obtiene con el servicio desplegado externamente), pero las siguientes desventajas superan a la opción.
- Acoplamiento
- Emplear optimizaciones es difícil
- Gestión de versiones (esto también depende de cómo esté organizado el código)
- Versiones
Espero eso ayude.
Me gustaría implementar en una instancia. No importa qué. Por supuesto, hay circunstancias en las que puede ser necesario implementarlas por separado. De la mejor práctica de "codificación", se debe usar una instancia para permitir "una vez correcta, usar muchas".
Entonces...
- Defina diferentes XSD para cada AppA, AppB, etc. Marshall en consecuencia.
- O bien, use Groovy para asignar objetos apropiados como json o xml.
Prefiero el enfoque a continuación, que está en uso para 50,000 usuarios simultáneos.
- Asegúrese de que cada servicio web encapsula tanto la interfaz de usuario como el esquema de forma independiente mediante la ejecución del caso de uso empresarial requerido. Cada servicio web tendrá las tres capas: modelo, vista y controlador para ese servicio comercial. Eso significa que su App-A es un servicio web y App-B es otro servicio web.
- Todos los servicios web se registrarán y anularán la inscripción en el servicio web maestro . El servicio web maestro es responsable de redirigir la solicitud del usuario al servicio web apropiado, como App-A OR App-B.
Debe tener un clúster de servicio web maestro y clúster de servicios web individuales : App-A y App-B
En este enfoque, su esquema puede residir en una base de datos diferente en lugar de una única base de datos
Ventajas de este enfoque:
Cada servicio web puede escalar horizontalmente . Simplemente agregue nodos VM adicionales si desea aumentar la escala.
Si tiene diferentes esquemas en diferentes bases de datos en diferentes ubicaciones, está evitando cuellos de botella de rendimiento de red en consultas OLTP (consultas de procesamiento de transacciones en línea).
Desventajas:
- Solo veo una desventaja ya que Master Web Services actúa como una Fachada y debe conocer los aspectos internos del servicio web individual . Pero no es un inconveniente para las ventajas que ofrece si considera la compensación.
No tengo idea sobre los requisitos de su empresa para mantener diferentes esquemas para los datos del usuario y acceder al servicio web.
Pero en lugar de mantener múltiples guerras con el mismo código, le sugiero que configure múltiples fuentes de datos dentro de la aplicación y cambie a la fuente de datos según su requisito.
Este enlace puede ayudarte a configurar múltiples DS
Si deja de lado la lógica antes mencionada, puede terminar con un solo contexto desplegable.
Todavía quiero seguir con múltiples guerras como servicio web, le sugiero que considere SpringBoot simple, contenedor menos desplegable y escalable.