Diseño del marco del motor de reglas distribuidas

MirAIe Rules Engine es un marco de motor de reglas extensible y extensible que permite a los usuarios agrupar y automatizar múltiples actividades.

        Mientras desarrollábamos la plataforma MirAIe IoT en los últimos años, nos dimos cuenta de la necesidad de un marco de motor de reglas extensible y extensible. El motor de reglas le permite agrupar, gestionar y automatizar diversas acciones y puede utilizarse en una variedad de aplicaciones, como domótica, detección de fraude, gestión de riesgos y automatización del flujo de trabajo. En Panasonic participamos en varias iniciativas en los campos de la movilidad, la Industria 4.0, la gestión de edificios y la domótica. Por lo tanto, el marco debe poder adaptarse a diversas aplicaciones. En este artículo, describo el diseño de alto nivel de nuestro marco de motor de reglas.

análisis de reglas

        Básicamente, las reglas permiten a los usuarios agrupar y automatizar una gran cantidad de tareas. Ejemplos de reglas generadas por el usuario incluyen encender el aire acondicionado en el dormitorio cada vez que la temperatura ambiente supera los 27 grados; encender un juego de luces en el vestíbulo de la oficina a las 6 p.m. todas las noches; enviar una notificación automática a su automóvil eléctrico cuando la batería El nivel cae por debajo del 30% y encuentra estaciones de carga cercanas con vacantes.

 

        Las reglas tienen condiciones de activación que especifican cuándo se activa la regla. Los disparadores pueden depender de la ubicación del usuario, el estado de los sensores, un momento específico, condiciones climáticas externas o cualquier otro factor. Se pueden acoplar varios activadores utilizando uno o más operadores lógicos que juntos especifican las condiciones de activación de la regla.

        Las reglas también tienen una o más acciones que se activan cuando se cumplen estas condiciones desencadenantes. Las acciones pueden ser tan simples como encender una luz o tan complejas como crear un informe y enviarlo como archivo adjunto a varios usuarios.

Consideraciones de diseño

        Las condiciones de activación de reglas pueden depender de múltiples fuentes de entrada. Las fuentes de datos pueden ser internas, como sensores instalados en un laboratorio que envían estados periódicos cada pocos segundos, o externas, como datos meteorológicos, que deben recuperarse y almacenarse diariamente porque los datos no cambian con frecuencia. El desafío es tomar múltiples fuentes de entrada para crear un valor único y determinar si una regla debe activarse o no.

        Dado que nuestro marco debe admitir una amplia gama de aplicaciones, decidimos centrarnos en dos principios de diseño fundamentales. El primer principio es que la arquitectura debe ser extensible para admitir varios activadores de entrada y operaciones de salida. Para los casos de uso de automatización del hogar, los desencadenantes más comunes pueden depender de la hora del día, el estado del dispositivo o las condiciones climáticas externas. Mientras que en nuestro caso de uso de fábrica inteligente, el desencadenante podría ser la actividad del usuario o los datos agregados recopilados a lo largo del tiempo, como la eficiencia de la máquina. La idea es garantizar que se puedan agregar nuevos tipos de desencadenadores sin realizar demasiados cambios en el esquema. Asimismo, las acciones de reglas son extensibles. Las acciones comunes pueden ser llamar a una API, enviar una notificación o crear una tarea y enviarla a una cola de tareas. 

        Nuestro segundo principio rector para este diseño fue priorizar la flexibilidad, permitiendo que cada componente escale de forma independiente. Un sistema flexible puede adaptarse a las necesidades cambiantes sin necesidad de escalar todo el sistema, lo que aumenta la resiliencia y la rentabilidad. Por ejemplo, si es necesario activar una gran cantidad de reglas a las 6 de la tarde, el sistema solo necesita expandir adecuadamente el servicio de activación del temporizador y el servicio de ejecución de reglas, mientras que otros servicios continúan funcionando a la escala original. Al proporcionar esta flexibilidad, el sistema puede satisfacer diferentes necesidades de manera eficiente y efectiva.

Componentes del motor de reglas

        Para lograr escalabilidad, desacoplamos el servicio de activación de reglas, el motor de procesamiento de reglas y el servicio de ejecución de reglas. Un servicio de activación de reglas es una colección de microservicios y cada microservicio puede manejar un tipo específico de lógica de activación de reglas. El motor de reglas combina los distintos estados de activación según la definición de la regla para determinar si la regla debe activarse. Finalmente, el Servicio de ejecución de reglas es la lógica de ejecución de reglas específica de la aplicación que ejecuta las acciones previstas especificadas en las reglas. Cada componente se desarrolla de forma independiente. Implementan interfaces bien definidas y pueden ampliarse de forma independiente.

 

servicio de activación de reglas

        El servicio de activación de reglas implementa lógica para determinar cuándo se debe activar una regla. Es una colección de microservicios, cada uno de los cuales es capaz de manejar un tipo de desencadenante muy específico. Por ejemplo, la lógica para las activaciones en un momento dado y los activadores basados ​​en la duración la manejan microservicios activados por temporizador. Además, diferentes servicios manejan activadores de estado del dispositivo o activadores basados ​​en el clima. 

        Dependiendo de las condiciones de activación de reglas en la definición de regla, una regla se registra en uno o más servicios de activación de reglas cuando se crea por primera vez. Cada servicio de activación proporciona tres API principales para registrar, actualizar y cancelar el registro de reglas. La carga útil real de un activador registrado puede variar de un servicio a otro; sin embargo, la API de creación/actualización de reglas está diseñada de tal manera que el servicio de administración de reglas puede identificar rápidamente el tipo de activador y delegar el análisis y la interpretación de las condiciones del activador al servicio de activación adecuado. Los puntos finales para tipos de desencadenadores individuales se pueden compartir como parte de la configuración o variables de entorno, o se pueden descubrir en tiempo de ejecución utilizando patrones de descubrimiento de servicios estándar.

        Cada tipo de activador tiene una lógica de servicio de activación diferente. Los activadores pueden capturar datos de una o más fuentes de entrada, procesarlos, almacenarlos en caché si es necesario y emitir eventos al decidir si se debe activar una regla. El servicio de activación de reglas emite un valor booleano verdadero cuando una regla específica cumple las condiciones de activación y falso en caso contrario. 

         Una regla puede incluir uno o más desencadenantes, cada uno de los cuales establece una condición específica que debe cumplirse para que se ejecute la regla. Por ejemplo, considere una regla para encender las luces de la sala a las 6 p.m. todos los días o cuando el nivel de iluminación ambiental cae por debajo de 100 lux. La regla utiliza lógica OR para combinar dos condiciones: la primera es un disparador basado en el tiempo y la segunda es un disparador de estado del dispositivo (sensor ALS). También se pueden crear reglas más complejas combinando múltiples activadores y operadores lógicos. 

 

        Para gestionar el estado de cada disparador, se utiliza un caché persistente, que es actualizado por el servicio de disparador correspondiente. Esto garantiza que el último estado de activación esté siempre disponible para el motor de procesamiento de reglas, lo que le permite evaluar las condiciones e invocar las acciones apropiadas. En la figura anterior, el estado de activación rojo indica que no se cumple la condición de activación actual y el estado verde indica que se cumple la condición de activación. Una vez que cambia el estado de activación de una regla, el servicio de activación correspondiente agregará la identificación de la regla a la cola para su procesamiento y luego el motor de procesamiento de reglas la consumirá. 

        Cada servicio de activación de reglas está diseñado para ser escalable horizontalmente e independiente de otros componentes del sistema según la cantidad de reglas registradas. Este desacoplamiento también permite que la lógica de activación de cada activador evolucione de forma independiente a medida que evoluciona la aplicación. Además, se pueden agregar nuevos tipos de disparadores al sistema con cambios mínimos.

motor de procesamiento de reglas

        El motor de procesamiento de reglas procesa reglas de la cola de reglas pendientes y las ejecuta de acuerdo con el estado del activador. Si la lógica de activación es una combinación de uno o más activadores de reglas, el motor de procesamiento combina los estados de cada activador de entrada de acuerdo con la lógica de activación especificada en la definición de la regla para calcular el valor booleano final. Una vez que determina que la regla debe activarse, llama al servicio de ejecución de reglas para ejecutar la regla.

        Hay aproximadamente dos tipos de estados desencadenantes. Los activadores de punto de tiempo solo son válidos cuando el estado del activador cambia, como activar una regla a las 6 p.m. o activar un cambio de estado del dispositivo (como apagar el ventilador cuando el aire acondicionado está encendido). Esta regla debería activarse inmediatamente después del evento, siempre que también se cumplan todas las demás condiciones desencadenantes. El motor de procesamiento de reglas restablece el valor de dichos activadores inmediatamente después de procesar la regla.

         El segundo tipo de desencadenante representa el estado persistente de una entidad durante un período de tiempo más largo. Por ejemplo, considere un escenario en el que la luz del porche debería encenderse si se detecta movimiento entre las 6 p.m. y las 6 a.m. El servicio de activación del temporizador establece el valor de activación en verdadero a las 6 p. m. y luego en falso a las 6 a. m. El motor de procesamiento de reglas no restablece estos estados y permanecen sin cambios hasta que el servicio desencadenante los modifica explícitamente. Esto permite que el sistema mantenga el estado persistente de las entidades y tome decisiones basadas en su estado persistente.

 

Servicio de ejecución de reglas

        El servicio de ejecución de reglas puede invocar API HTTP, enviar mensajes MQTT o activar notificaciones push para ejecutar reglas. La lista de acciones que puede realizar una regla es extensible y específica de la aplicación. Al igual que el servicio de activación de reglas, el servicio de acción de reglas está desacoplado del motor de reglas principal y se puede ampliar de forma independiente. 

 

        Una forma de desacoplar el servicio de ejecución de reglas de múltiples servicios de acción de reglas es utilizar una cola de mensajes, como Kafka. Dependiendo del tipo de operación, el Servicio de ejecución de reglas puede publicar acciones de reglas en temas individuales de Kafka, que pueden ser consumidos por un grupo de consumidores y realizar acciones relacionadas. Las cargas útiles de acciones de reglas pueden ser específicas del tipo de acción y se capturan como parte de la definición de la regla y se pasan tal cual a la cola de tareas.

Servicio de activación extendido

        Los servicios activados por reglas pueden tener estado, por lo que escalarlos puede ser un desafío. No existe una forma general de ampliar todos los servicios desencadenantes, ya que su implementación subyacente varía según el tipo de desencadenador y los servicios externos de los que pueden depender. En esta sección, explico los métodos de escala utilizados para dos tipos de desencadenadores importantes.

Activador de estado del dispositivo

        Para activar una regla de registro de servicio con un estado de dispositivo, el servicio de administración de reglas proporcionará el identificador del dispositivo, las propiedades del dispositivo y sus umbrales correspondientes. El servicio de activación del estado del dispositivo los almacenará en una caché compartida (como Redis) y garantizará que sean accesibles utilizando únicamente la ID del dispositivo.

         En el ejemplo dado, las notificaciones sobre cambios de estado del dispositivo se envían a través del protocolo MQTT y luego se agregan a la cola de mensajes de Kafka. Un consumidor de Kafka responsable del estado del dispositivo recibe y procesa cada evento entrante. Comprueba la caché de activación de reglas para ver si hay alguna regla asociada con el dispositivo. Con base en esta información, el consumidor actualiza la caché de estado del disparador correspondiente para reflejar el estado actual del disparador del dispositivo. Este mecanismo garantiza que la caché del estado del activador se mantenga sincronizada con los últimos cambios de estado del dispositivo, lo que permite al sistema evaluar con precisión las reglas con respecto a la información más reciente.

        Todos nuestros servicios están en contenedores y se ejecutan en clústeres de Kubernetes. El servicio de activación de estado del dispositivo es un servicio API estándar que se escala a través de grupos de equilibrio de carga y escalamiento automático de aplicaciones. El grupo de consumidores de estado del dispositivo escala según la tasa de eventos de cambio de estado del dispositivo entrantes. El escalado automático basado en eventos de Kubernetes (KEDA) puede impulsar el escalado de los consumidores del estado del dispositivo en función de la cantidad de eventos que deben procesarse. Además, existen herramientas que predicen las cargas de trabajo de Kafka, que se pueden utilizar para escalar a los consumidores más rápidamente, mejorando así el rendimiento.

disparador del temporizador

        El servicio de activación por temporizador maneja activadores de momento y de duración. La carga útil de una solicitud de activación puede ser tan simple como una hora específica del día o tan detallada como la especificación de un trabajo cron de Unix. El servicio no necesita mantener todas las solicitudes de reglas registradas en la memoria, porque es posible que una regla no se active durante días o meses. En cambio, una vez que recibe una solicitud de registro de regla, calcula cuándo debe ejecutarse la regla a continuación y almacena los detalles de la regla en la base de datos junto con el tiempo de ejecución siguiente.
        A intervalos regulares, el servicio recupera y guarda en la memoria todas las reglas que deben activarse en ventanas de tiempo posteriores. Esto se puede hacer filtrando por el siguiente campo de tiempo de ejecución de la regla. Una vez que ha identificado todas las reglas que deben ejecutarse, el servicio las clasifica según el tiempo de activación y genera uno o más Kubernetes Pods para procesarlas. A cada Pod solo se le asignará un subconjunto de reglas. Las reglas asignadas a diferentes Pods se pueden compartir a través de Zookeeper o Definiciones de recursos personalizados (CRD) de Kubernetes.

 

        Los CRD de Kubernetes se pueden utilizar para compartir datos y distribuir el trabajo entre varios Pods definiendo recursos personalizados que representan tareas específicas. Un servicio activado por temporizador utiliza esta funcionalidad dividiendo todas las reglas que deben procesarse en la siguiente ventana de tiempo en tareas separadas y almacenándolas en el CRD. Luego se crean múltiples unidades de trabajo y se les asignan tareas específicas. Luego, cada Pod procesa la regla y actualiza la caché de estado del activador en consecuencia. 

Mantenibilidad y escalabilidad

        El servicio de gestión de reglas y el servicio de ejecución de reglas son servicios sin estado y la lógica es bastante simple. Rule Management proporciona API estándar para la creación, actualización y eliminación de reglas. El Servicio de ejecución de reglas funciona de forma independiente para ejecutar acciones de reglas, invocando principalmente acciones específicas de la aplicación.

        La comunicación entre el servicio de administración de reglas y el servicio de activación puede ocurrir de forma asíncrona, eliminando la necesidad de descubrimiento de servicios. Por ejemplo, cada servicio desencadenante podría tener su propia cola dedicada en el intermediario de mensajes de Kafka. El servicio de administración de reglas puede agregar solicitudes de activación a la cola correspondiente según el tipo de activación, que puede ser procesada y consumida por el consumidor de Kafka (servicio de activación) del tipo de activación.

        Agregar soporte para nuevos tipos de desencadenantes y nuevos tipos de acciones es simple porque todos los componentes clave están desacoplados entre sí. El servicio de administración de reglas tiene un diseño basado en complementos, donde para cada tipo de disparador y tipo de acción admitidos se agrega un complemento para validar las cargas útiles de disparador y acción correspondientes en la definición de regla. Los nombres de los activadores de reglas y de los tipos de acción se pueden convertir en nombres de cola Kafka correspondientes para la comunicación entre el servicio de administración de reglas y el servicio desencadenante, y entre el servicio de procesamiento de reglas y el servicio de ejecución.

Los sistemas se pueden probar en múltiples niveles. Es relativamente fácil cubrir servicios individuales con pruebas unitarias y centrarse en una funcionalidad específica. Para facilitar la depuración y la resolución de problemas en un entorno distribuido, se deben seguir las mejores prácticas para el registro y seguimiento distribuidos. Los mecanismos de registro y rastreo implementados correctamente nos permitirán rastrear el flujo de solicitudes entre diferentes servicios, identificar y diagnosticar problemas de manera efectiva. Seguir estas mejores prácticas garantiza una mejor comprensión del comportamiento del sistema y simplifica el proceso de depuración.

fiabilidad

        Primero identifiquemos los posibles desafíos que puedan surgir. Es importante reconocer que cualquier servicio dentro del sistema puede experimentar un tiempo de inactividad no planificado, la carga del sistema puede crecer más rápido que su capacidad para escalar de manera efectiva y algunos servicios o componentes de infraestructura pueden experimentar una indisponibilidad temporal. 

        Usar Kafka para la comunicación ayuda a lograr múltiples niveles de confiabilidad. Kafka proporciona características que facilitan la entrega de mensajes y la confiabilidad del consumidor, incluida la persistencia de mensajes, sólidas garantías de durabilidad, replicación tolerante a fallas, distribución de carga entre grupos de consumidores y al menos una semántica de entrega.

        El caso de confiabilidad más inmediato involucra la activación de servicios. Para los activadores de estado del dispositivo, Kafka está configurado para garantizar la entrega al menos una vez para que no se pierdan los eventos de cambio de estado. Sin embargo, lograr confiabilidad para los servicios activados por temporizador requiere pasos adicionales. Aquí, es importante no abrumar a ningún trabajador con la gran cantidad de eventos que deben manejarse simultáneamente.  

        Nuestro enfoque es ordenar cronológicamente la lista de reglas que se procesarán en la siguiente ventana de tiempo y distribuirlas entre los servicios de los trabajadores de forma circular. Además, la cantidad de grupos de trabajadores es proporcional a la cantidad de tareas del temporizador dentro de la ventana de tiempo y la cantidad máxima de tareas a ejecutar en un momento dado. Esto garantiza que haya una cantidad suficiente de nodos trabajadores para manejar una cantidad potencialmente grande de tareas del temporizador simultáneamente. Además, es beneficioso configurar una unidad de trabajo para que se reinicie automáticamente cuando falla, lo que le permite recuperarse y completar las tareas asignadas sin intervención manual.  

        Además, Kubernetes tiene la ventaja de definir límites de recursos y requisitos mínimos para cada servicio. Esto incluye especificar la cantidad máxima de recursos de CPU o RAM que un servicio puede utilizar y los recursos mínimos necesarios para iniciarse correctamente. Con Kubernetes, se pueden aliviar las preocupaciones sobre problemas como los de "vecinos ruidosos" (donde el comportamiento de un Pod que consume muchos recursos afecta a otros Pods en el mismo nodo del clúster). Kubernetes proporciona capacidades de aislamiento y gestión de recursos que ayudan a mantener la estabilidad y confiabilidad general del sistema. 

resumir

        MirAIe Rules Engine es un marco de motor de reglas extensible y extensible que permite a los usuarios agrupar y automatizar múltiples actividades. El marco admite varios activadores internos o externos y se centra en dos principios de diseño: extensibilidad y flexibilidad. La arquitectura tenía que ser extensible para soportar una amplia variedad de flip-flops de entrada y operaciones de salida, permitiendo agregar nuevos tipos sin demasiados cambios. El sistema también prioriza la flexibilidad para permitir el escalamiento independiente de cada componente, aumentando la resiliencia y la rentabilidad.

Supongo que te gusta

Origin blog.csdn.net/qq_28245905/article/details/132140742
Recomendado
Clasificación