De polling a eventos

06/09/2007 - 13:12 por Lars | Informe spam
Hola a todos,

Tengo un WS que inserta datos en una base de datos. Es un sistema de
facturas con detalles de factura. Cuando el detalle de la factura se ha
completado debe ser procesado por un servicio (o varios en varias maquinas).
Una opción es que los servicios hagan pooling a la base de datos. Aqui tengo
una duda, ¿como puedo hacer para que en lugar de que el servicio haga
pooling montar un sistema de eventos? Teniendo en cuenta que el servicio
corre en varia maquinas.

Un saludete.

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
06/09/2007 - 17:36 | Informe spam
"Lars" wrote in message
news:
Tengo un WS que inserta datos en una base de datos. Es un sistema de
facturas con detalles de factura. Cuando el detalle de la factura se ha
completado debe ser procesado por un servicio (o varios en varias
maquinas). Una opción es que los servicios hagan pooling a la base de
datos. Aqui tengo una duda, ¿como puedo hacer para que en lugar de que el
servicio haga pooling montar un sistema de eventos? Teniendo en cuenta que
el servicio corre en varia maquinas.



Primera cuestión: ¿Es necesario que el evento lo dispare la base de
datos? Lo digo porque si el evento en cuestión corresponde con la inserción
de determinados datos, y los datos siempre los inserta un servicio web,
entonces el servicio web sabe cuándo hay que disparar el evento, y no es
necesario delegarlo a la base de datos. Esto puede simplificar las cosas ya
que el servicio web está formado por código .Net que suele ser más fácil de
manipular que el código de base de datos.
Si no fuera asi, es decir, si los datos pueden entrar en la base de
datos por distintas vías (no solo el servicio web), entonces sí que será
necesario que el evento lo dispare la base de datos. Esto se puede hacer de
dos formas: O bien todas las grabaciones se hacen por medio de un
procedimiento almacenado, en cuyo caso el procedimiento puede disparar el
evento después de grabar, o bien se añade un Trigger a la tabla o tablas
necesarias y es el trigger el que dispara el evento.
El problema en este caso es el cómo inicio una comunicación desde el
código de la base de datos contra el servidor o servidores que deben
procesar el evento. Asumiendo que sea Sql Server, si es la versión 2005 se
puede añadir un procedimiento o trigger escrito en .Net y que este inicie la
comunicación. Si es un 2000, habría que tirar de xp_cmdshell, lo cual es
lento y es delicado en cuanto a seguridad, o usar un objeto COM, o escribir
un procedimiento extendido en C++. Todo ello más complicado que la
alternativa de usar C# (teniendo en cuenta que la pregunta ha sido hecha en
un foro de C#).

Segunda cuestión: Quieres los eventos fuertemente acoplados o débilmente
acoplados.
Los fuertemente acoplados son aquellos en los que los clientes se
registran en el servidor, y el servidor conoce a los clientes (entendiendo
por "clientes" los suscriptores del evento, es decir los servicios que han
de recibirlo). El servidor "llama" a cada uno de los clientes cuando dispara
el evento, y se produce un error si el cliente no está disponible. En este
caso, la comunicación del servidor a los clientes podría hacerse por .Net
Remoting, o por colas de mensajes. Las dos cosas son sencillas de programar
en .Net.
Los eventos débilmente acoplados pasan por un servicio intermedio que
"registra" las suscripciones. El servidor publica un evento, y cuando lo
dispara solo tiene que enviarlo una vez y es ese servicio intermedio el que
lo "repite" hacia los clientes que estén en ese momento disponibles, sin que
el servidor tenga que preocuparse de saber cuáles son o de repartirles los
eventos. En el mundo Windows esto se hace mediante los Eventos Debilmente
Acoplados de COM+ (Servicios de Componentes). Desde .Net se pueden programar
por medio de System.EnterpriseServices, pero aviso que es bastante complejo.
Respuesta Responder a este mensaje
#2 Lars
07/09/2007 - 14:21 | Informe spam
En primer lugar, muchas gracias por la respuesta

La inserción en la BD la hace el WS. De este WS hay varias instancias
balanceadas y los servicios que procesan las facturas tambien hay varios
corriendo. Los WS podrían disparar los eventos pero la cuestión es ¿como los
recogerian los servicios? ¿Cómo se evitan los problemas de concurrencia?
¿Debería tener un componenete único que dispare los eventos? Tras todo esto,
¿es mejor que los servicios hagan pooling y evitar así todo lo demas?
Es un problema que me tiene entretenido.






"Alberto Poblacion"
escribió en el mensaje news:
"Lars" wrote in message
news:
Tengo un WS que inserta datos en una base de datos. Es un sistema de
facturas con detalles de factura. Cuando el detalle de la factura se ha
completado debe ser procesado por un servicio (o varios en varias
maquinas). Una opción es que los servicios hagan pooling a la base de
datos. Aqui tengo una duda, ¿como puedo hacer para que en lugar de que el
servicio haga pooling montar un sistema de eventos? Teniendo en cuenta
que el servicio corre en varia maquinas.



Primera cuestión: ¿Es necesario que el evento lo dispare la base de
datos? Lo digo porque si el evento en cuestión corresponde con la
inserción de determinados datos, y los datos siempre los inserta un
servicio web, entonces el servicio web sabe cuándo hay que disparar el
evento, y no es necesario delegarlo a la base de datos. Esto puede
simplificar las cosas ya que el servicio web está formado por código .Net
que suele ser más fácil de manipular que el código de base de datos.
Si no fuera asi, es decir, si los datos pueden entrar en la base de
datos por distintas vías (no solo el servicio web), entonces sí que será
necesario que el evento lo dispare la base de datos. Esto se puede hacer
de dos formas: O bien todas las grabaciones se hacen por medio de un
procedimiento almacenado, en cuyo caso el procedimiento puede disparar el
evento después de grabar, o bien se añade un Trigger a la tabla o tablas
necesarias y es el trigger el que dispara el evento.
El problema en este caso es el cómo inicio una comunicación desde el
código de la base de datos contra el servidor o servidores que deben
procesar el evento. Asumiendo que sea Sql Server, si es la versión 2005 se
puede añadir un procedimiento o trigger escrito en .Net y que este inicie
la comunicación. Si es un 2000, habría que tirar de xp_cmdshell, lo cual
es lento y es delicado en cuanto a seguridad, o usar un objeto COM, o
escribir un procedimiento extendido en C++. Todo ello más complicado que
la alternativa de usar C# (teniendo en cuenta que la pregunta ha sido
hecha en un foro de C#).

Segunda cuestión: Quieres los eventos fuertemente acoplados o débilmente
acoplados.
Los fuertemente acoplados son aquellos en los que los clientes se
registran en el servidor, y el servidor conoce a los clientes (entendiendo
por "clientes" los suscriptores del evento, es decir los servicios que han
de recibirlo). El servidor "llama" a cada uno de los clientes cuando
dispara el evento, y se produce un error si el cliente no está disponible.
En este caso, la comunicación del servidor a los clientes podría hacerse
por .Net Remoting, o por colas de mensajes. Las dos cosas son sencillas de
programar en .Net.
Los eventos débilmente acoplados pasan por un servicio intermedio que
"registra" las suscripciones. El servidor publica un evento, y cuando lo
dispara solo tiene que enviarlo una vez y es ese servicio intermedio el
que lo "repite" hacia los clientes que estén en ese momento disponibles,
sin que el servidor tenga que preocuparse de saber cuáles son o de
repartirles los eventos. En el mundo Windows esto se hace mediante los
Eventos Debilmente Acoplados de COM+ (Servicios de Componentes). Desde
.Net se pueden programar por medio de System.EnterpriseServices, pero
aviso que es bastante complejo.

Respuesta Responder a este mensaje
#3 Alberto Poblacion
07/09/2007 - 21:45 | Informe spam
"Lars" wrote in message
news:
En primer lugar, muchas gracias por la respuesta

La inserción en la BD la hace el WS. De este WS hay varias instancias
balanceadas y los servicios que procesan las facturas tambien hay varios
corriendo. Los WS podrían disparar los eventos pero la cuestión es ¿como
los recogerian los servicios? ¿Cómo se evitan los problemas de
concurrencia? ¿Debería tener un componenete único que dispare los eventos?
Tras todo esto, ¿es mejor que los servicios hagan pooling y evitar así
todo lo demas?
Es un problema que me tiene entretenido.



Bien, aquí la cuestión que me planteo es cuál es el mecanismo de balanceo
que utilizan los servidores que procesan las facturas, pues de él dependen
todas las demás respuestas. Puesto que puede haber varios servidores web
"disparando" eventos de "debe procesarse una factura", y varios servidores
de back-end capaces de procesarlas, hay que interponer entre medias un
mecanismo de reparto de cargas, o de balanceo, que distribuya entre los
servidores de back-end las peticiones que les envían los de front-end.

Se podría, desde luego, construir a medida ese mecanismo, pero ¿por qué
no usar los mecanismos ya existentes en el sistema operativo? En el caso de
Windows, el mecanismo del que se dispone se denomina Network Load Balancing
(NLB), que me imagino que es el que están usando ahora mismo los servidores
web, salvo que se use algún repartidor de carga por hardware tal como una
Hydraweb.

Usando NLB se podría hacer, simplemente, que los servidores de los web
service envíen las peticiones de procesamiento de facturas a una única
dirección IP, en la que estarían escuchando todos los servidores de
back-end, los cuales tendrían activado el NLB, y éste se encargaría de que
cada una de las peticiones sea atendida por uno de los servidores.

Los servicios Windows que procesan las facturas podrían estar escuchando
en un puerto Tcp, mediante un Socket, y se realizaría NLB sobre dicho
puerto. Los servidores del WS enviarían las peticiones a ese puerto, en la
dirección ip compartida por todos los servidores, por ejemplo mediante la
clase TcpClient. El envío de esta petición desde el WS al back-end
constituye la ocurrencia del "evento" del que venimos hablando desde el
principio de este hilo.

Si resulta muy complicado lo de programar la escucha en un socket y el
establecer un protocolo específico sobre TCP para este fin, hay una forma de
simplificarlo: bastaría con usar soap sobre http. ¿Cómo? Pues instalando IIS
sobre los servidores que procesan las facturas, creando un WS alojado en ese
IIS, y usando NLB para balancear estos servidores web (igual que ahora mismo
estás haciendo con los del front-end). Los WS del front-end a su vez
llamarían a un WS sobre el back-end, consiguiendo de esta forma enviar el
evento y balancear la carga sin tener que configurar ni programar nada que
no conozcas ya, puesto que todo esto ya lo estás haciendo por delante del
front-end, así que no hay más que repetir lo mismo por delante del back-end.
Respuesta Responder a este mensaje
#4 Lars
10/09/2007 - 11:51 | Informe spam
Muchisimas gracias por la ayuda Alberto



"Alberto Poblacion"
escribió en el mensaje news:
"Lars" wrote in message
news:
En primer lugar, muchas gracias por la respuesta

La inserción en la BD la hace el WS. De este WS hay varias instancias
balanceadas y los servicios que procesan las facturas tambien hay varios
corriendo. Los WS podrían disparar los eventos pero la cuestión es ¿como
los recogerian los servicios? ¿Cómo se evitan los problemas de
concurrencia? ¿Debería tener un componenete único que dispare los
eventos? Tras todo esto, ¿es mejor que los servicios hagan pooling y
evitar así todo lo demas?
Es un problema que me tiene entretenido.



Bien, aquí la cuestión que me planteo es cuál es el mecanismo de
balanceo que utilizan los servidores que procesan las facturas, pues de él
dependen todas las demás respuestas. Puesto que puede haber varios
servidores web "disparando" eventos de "debe procesarse una factura", y
varios servidores de back-end capaces de procesarlas, hay que interponer
entre medias un mecanismo de reparto de cargas, o de balanceo, que
distribuya entre los servidores de back-end las peticiones que les envían
los de front-end.

Se podría, desde luego, construir a medida ese mecanismo, pero ¿por qué
no usar los mecanismos ya existentes en el sistema operativo? En el caso
de Windows, el mecanismo del que se dispone se denomina Network Load
Balancing (NLB), que me imagino que es el que están usando ahora mismo los
servidores web, salvo que se use algún repartidor de carga por hardware
tal como una Hydraweb.

Usando NLB se podría hacer, simplemente, que los servidores de los web
service envíen las peticiones de procesamiento de facturas a una única
dirección IP, en la que estarían escuchando todos los servidores de
back-end, los cuales tendrían activado el NLB, y éste se encargaría de que
cada una de las peticiones sea atendida por uno de los servidores.

Los servicios Windows que procesan las facturas podrían estar escuchando
en un puerto Tcp, mediante un Socket, y se realizaría NLB sobre dicho
puerto. Los servidores del WS enviarían las peticiones a ese puerto, en la
dirección ip compartida por todos los servidores, por ejemplo mediante la
clase TcpClient. El envío de esta petición desde el WS al back-end
constituye la ocurrencia del "evento" del que venimos hablando desde el
principio de este hilo.

Si resulta muy complicado lo de programar la escucha en un socket y el
establecer un protocolo específico sobre TCP para este fin, hay una forma
de simplificarlo: bastaría con usar soap sobre http. ¿Cómo? Pues
instalando IIS sobre los servidores que procesan las facturas, creando un
WS alojado en ese IIS, y usando NLB para balancear estos servidores web
(igual que ahora mismo estás haciendo con los del front-end). Los WS del
front-end a su vez llamarían a un WS sobre el back-end, consiguiendo de
esta forma enviar el evento y balancear la carga sin tener que configurar
ni programar nada que no conozcas ya, puesto que todo esto ya lo estás
haciendo por delante del front-end, así que no hay más que repetir lo
mismo por delante del back-end.

email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida