Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a: ✔️ Máquinas virtuales Windows ✔️ Conjuntos de escalado flexibles ✔️ Conjuntos de escalado uniformes
Scheduled Events es un servicio de Azure Metadata Service que proporciona el tiempo de aplicación para prepararse para el mantenimiento de la máquina virtual. Da información sobre los eventos de mantenimiento próximos (por ejemplo, un reinicio) para que la aplicación pueda prepararlos y así limitar las interrupciones. Está disponible para todos los tipos de máquina virtual de Azure, incluidos IaaS y PaaS, tanto en Windows como en Linux.
Para más información acerca de Scheduled Events en Linux, consulte Scheduled Events para máquinas virtuales Linux.
Los eventos programados proporcionan notificaciones proactivas sobre los próximos eventos, para obtener información reactiva sobre los eventos que se produjeron en el pasado, consulte Información de disponibilidad de máquinas virtuales en Azure Resource Graph y Creación de una regla de alerta de disponibilidad para la máquina virtual de Azure.
Nota
Scheduled Events está disponible con carácter general en todas las regiones de Azure. Consulte el apartado sobre la disponibilidad por región y versión para obtener información sobre la versión más reciente.
¿Por qué usar Scheduled Events?
Muchas aplicaciones pueden aprovechar el tiempo para preparar el mantenimiento de las máquinas virtuales. Este tiempo se puede usar para realizar tareas específicas de la aplicación con el fin de mejorar la disponibilidad, la confiabilidad y la capacidad de servicio, lo que incluye:
- Punto de control y restauración.
- Purga de la conexión.
- Conmutación por error de la réplica principal.
- Eliminación de un grupo de equilibradores de carga.
- Registros de eventos.
- Cierre estable.
Con Scheduled Events, la aplicación puede detectar cuándo se producirá el mantenimiento y desencadenar tareas para limitar sus efectos.
Eventos programados proporciona eventos en los casos de uso siguientes:
- Mantenimiento iniciado por la plataforma (por ejemplo, reinicio de máquina virtual, migración en vivo o actualizaciones con conservación de memoria para el host).
- La máquina virtual se ejecuta en un hardware de host degradado que se predice que fallará pronto.
- La máquina virtual se estaba ejecutando en un host en el que se produjo un error de hardware.
- Mantenimiento iniciado por el usuario (por ejemplo, el usuario reinicia o vuelve a implementar una máquina virtual).
- Expulsiones de instancias de máquina virtual de Spot y conjunto de escalado de Spot.
Conceptos básicos
Metadata Service expone información sobre la ejecución de máquinas virtuales mediante un punto de conexión de REST accesible desde la propia máquina virtual. La información se encuentra disponible a través de una dirección IP no enrutable y no se expone fuera de la máquina virtual.
Ámbito
Los eventos programados se entregan y se pueden confirmar mediante:
- Máquinas virtuales independientes.
- Todas las máquinas virtuales de un servicio en la nube de Azure (clásico).
- Todas las máquinas virtuales de un conjunto de disponibilidad.
- Todas las máquinas virtuales de un grupo de selección de ubicación de conjunto de escalado.
Los eventos programados para todas las máquinas virtuales (VM) de un conjunto de disponibilidad completo o de un grupo de selección de ubicación para un conjunto de escalado de máquinas virtuales se entregan a las demás máquinas virtuales del mismo grupo o conjunto, independientemente del uso de la zona de disponibilidad.
Por ello, revise el campo Resources
del evento para identificar cuáles son las máquinas virtuales que se verán afectadas.
Nota
Las máquinas virtuales aceleradas por GPU en un conjunto de escalado mediante un dominio de error (FD = 1) solo reciben eventos programados para el recurso afectado. Los eventos no se difundirán a todas las máquinas virtuales del mismo grupo de selección de ubicación.
Detección de punto de conexión
En el caso de las máquinas virtuales con red virtual habilitada, el servicio de metadatos está disponible desde una dirección IP no enrutable estática, 169.254.169.254
. El punto de conexión completo de la versión más reciente de Scheduled Events es:
http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
Si la máquina virtual no se crea dentro de una red virtual, los casos predeterminados para los servicios en la nube y las máquinas virtuales clásicas, se requiere otra lógica para detectar la dirección IP que se va a usar. Para aprender a detectar el punto de conexión de host, consulte este ejemplo.
Disponibilidad por región y versión
El servicio Scheduled Events tiene versiones. Las versiones son obligatorias; la actual es 2020-07-01
.
Versión | Tipo de versión | Regiones | Notas de la versión |
---|---|---|---|
01-07-2020 | Disponibilidad general | Todos | |
2019-08-01 | Disponibilidad general | Todos | |
01-04-2019 | Disponibilidad general | Todos | |
01/01/2019 | Disponibilidad general | Todos | |
01-11-2017 | Disponibilidad general | Todos | |
2017-08-01 | Disponibilidad general | Todos | |
2017-03-01 | Versión preliminar | Todos |
Nota
Versiones preliminares de Scheduled Events admitidas {más recientes} como la versión de API. Este formato ya no es compatible y dejará de utilizarse en el futuro.
Habilitación y deshabilitación de Scheduled Events
Scheduled Events se habilita para un servicio la primera vez que se realiza una solicitud de eventos. Debe esperar una respuesta diferida en la primera llamada de hasta dos minutos y empezará a recibir eventos en un plazo de 5 minutos. Scheduled Events se deshabilita para el servicio si no se realiza una solicitud al punto de conexión durante 24 horas.
Mantenimiento iniciado por el usuario
El mantenimiento de las máquinas virtuales iniciado por el usuario a través de Azure Portal, API, CLI o PowerShell, da lugar a un evento programado. Esto permite probar la lógica de preparación del mantenimiento en la aplicación, además de que la aplicación pueda prepararse para el mantenimiento iniciado por el usuario.
Si reinicia una máquina virtual, se programa un evento del tipo Reboot
. Si vuelve a implementar una máquina virtual, se programa un evento del tipo Redeploy
. Normalmente, los eventos con un origen del evento de usuario se pueden aprobar inmediatamente para evitar un retraso en las acciones iniciadas por el usuario. Se recomienda tener una máquina virtual principal, y una máquina secundaria que se comunique y apruebe los eventos programados generados por el usuario en el caso de que la máquina virtual principal deje de responder. La aprobación inmediata de eventos evita retrasos en la recuperación de la aplicación a un buen estado.
Los eventos programados para actualizaciones o restablecimientos de imagen inicial del SO invitado de Virtual Machine Scale Sets se admiten para tamaños de máquina virtual de uso general que solo admiten actualizaciones que conservan la memoria. No funciona para las series H, M, N y G. Los eventos programados para las actualizaciones del sistema operativo invitado de Virtual Machine Scale Sets y las imágenes de imagen están deshabilitados de forma predeterminada. Para habilitar eventos programados para estas operaciones en tamaños de máquina virtual compatibles, habilítelos primero mediante OSImageNotificationProfile.
Uso de la API
Información general de alto nivel
Hay dos componentes principales para controlar eventos programados, la preparación y la recuperación. Todos los eventos programados actuales que afectan a una máquina virtual están disponibles para leerse a través del punto de conexión de eventos programados de IMDS. Cuando el evento alcanza un estado terminal, se quita de la lista de eventos. En el diagrama siguiente se muestran las distintas transiciones de estado que puede experimentar un único evento programado:
Para los eventos en el estado "Programado", debe tomar medidas para preparar su carga de trabajo. Una vez completada la preparación, debe aprobar el evento mediante la API de eventos programados. De lo contrario, el evento se aprueba automáticamente cuando se alcanza la hora NotBefore. Si la máquina virtual está en la infraestructura compartida, el sistema esperará a que todos los demás inquilinos del mismo hardware también aprueben el trabajo o el tiempo de expiración. Una vez que se recopilan aprobaciones de todas las máquinas virtuales afectadas o se alcanza la hora de NotBefore, Azure genera una nueva carga de eventos programada con EventStatus:"Started" y desencadena el inicio del evento de mantenimiento. Cuando el evento alcanza un estado terminal, se quita de la lista de eventos. Esto sirve como señal para que el cliente recupere sus máquinas virtuales.
El código psudeo muestra un proceso para leer y administrar eventos programados en la aplicación:
current_list_of_scheduled_events = get_latest_from_se_endpoint()
#prepare for new events
for each event in current_list_of_scheduled_events:
if event not in previous_list_of_scheduled_events:
prepare_for_event(event)
#recover from completed events
for each event in previous_list_of_scheduled_events:
if event not in current_list_of_scheduled_events:
receover_from_event(event)
#prepare for future jobs
previous_list_of_scheduled_events = current_list_of_scheduled_events
A medida que los eventos programados se usan a menudo para las aplicaciones con requisitos de alta disponibilidad, hay algunos casos excepcionales que se deben tener en cuenta:
- Una vez completado y quitado un evento programado de la matriz, no habrá ningún impacto adicional sin un nuevo evento, incluido otro evento con el estado EventStatus:"Programado"
- Azure supervisa las operaciones de mantenimiento en toda la flota y, en raras circunstancias, determina que una operación de mantenimiento es demasiado riesgosa para su aplicación. En ese caso, el evento programado pasa directamente de "Programado" a quitarse de la matriz de eventos.
- Si se produce un error de hardware, Azure omite el estado "Programado" e inmediatamente pasa al estado EventStatus:"Started".
- Aunque el evento sigue en estado EventStatus:"Iniciado", puede haber otro impacto de una duración más corta que la anunciada en el evento programado.
Como parte de la garantía de disponibilidad de Azure, las máquinas virtuales de diferentes dominios de error no se verán afectadas por las operaciones de mantenimiento de rutina al mismo tiempo. Sin embargo, pueden tener operaciones serializadas una después de otra. Las máquinas virtuales de un dominio de error pueden recibir eventos programados con EventStatus:"Programado" poco después de que se complete el mantenimiento de otro dominio de error. Independientemente de la arquitectura que haya elegido, siga comprobando los nuevos eventos pendientes en las máquinas virtuales.
Aunque los tiempos exactos de los eventos varían, el diagrama siguiente proporciona una guía aproximada sobre cómo continúa una operación de mantenimiento típica:
- EventStatus:"Programado" a Tiempo de expiración de aprobación: 15 minutos
- Duración del impacto: 7 segundos
- EventStatus:"Iniciado" a Completado (evento quitado de la matriz Events): 10 minutos
Todas las operaciones que afectan a la disponibilidad de la máquina virtual crean un evento programado, pero no todos los eventos programados aparecen en otras superficies de Azure, como registros de actividad de Azure o Resource Health. La comprobación de eventos programados periódicamente garantizará que tenga la información más actualizada sobre los próximos impactos en las máquinas virtuales.
encabezados
Al realizar consultas a Metadata Service, debe proporcionar el encabezado Metadata:true
para asegurarse de que la solicitud no se haya redirigido de manera involuntaria. El encabezado Metadata:true
es necesario para todas las solicitudes de eventos programados. Un error al incluir el encabezado en la solicitud generará una respuesta del tipo "Solicitud incorrecta" de Metadata Service.
Consulta de eventos
Puede consultar los eventos programados; para ello, simplemente haga la siguiente llamada:
Ejemplo de Bash
curl -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
Ejemplo de PowerShell
Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01" | ConvertTo-Json -Depth 64
Ejemplo de Python
import json
import requests
metadata_url ="http://169.254.169.254/metadata/scheduledevents"
header = {'Metadata' : 'true'}
query_params = {'api-version':'2020-07-01'}
def get_scheduled_events():
resp = requests.get(metadata_url, headers = header, params = query_params)
data = resp.json()
return data
Una respuesta contiene una matriz de eventos programados. Una matriz vacía significa que actualmente no hay eventos programados. En caso de que haya eventos programados, la respuesta contiene una matriz de eventos.
{
"DocumentIncarnation": {IncarnationID},
"Events": [
{
"EventId": {eventID},
"EventType": "Reboot" | "Redeploy" | "Freeze" | "Preempt" | "Terminate",
"ResourceType": "VirtualMachine",
"Resources": [{resourceName}],
"EventStatus": "Scheduled" | "Started",
"NotBefore": {timeInUTC},
"Description": {eventDescription},
"EventSource" : "Platform" | "User",
"DurationInSeconds" : {timeInSeconds},
}
]
}
Propiedades de evento
Propiedad | Descripción |
---|---|
Encarnación de documentos | Entero que aumenta cuando cambia la matriz de eventos. Los documentos con la misma encarnación contienen la misma información de evento y la encarnación se incrementa cuando cambia un evento. |
EventId | Es un identificador único global del evento. Ejemplo:
|
Tipo de evento | Se producirá el impacto previsto de este evento. Valores:
|
TipoDeRecurso | Es el tipo de recurso al que este evento afecta. Valores:
|
Recursos | Es la lista de recursos a los que este evento afecta. Ejemplo:
|
EstadoDelEvento | Es el estado de este evento. Valores:
Completed ni otro estado similar se han proporcionado antes. El evento ya no vuelve cuando finaliza el evento. |
NotBefore | Hora a partir de la que puede iniciarse este evento. Se garantiza que el evento no se inicia antes de esta hora. Estará en blanco si el evento se inicia después de que se inicie el evento. Ejemplo:
|
Descripción | Descripción de este evento. Ejemplo:
|
FuenteDeEventos | Iniciador del evento. Ejemplo:
|
DuraciónEnSegundos | Duración que se espera de la interrupción causada por el evento. Puede haber efectos secundarios de una duración más corta durante la ventana de impacto. Ejemplo:
|
Programación de eventos
Cada evento se programa una cantidad mínima de tiempo en el futuro en función de su tipo. Este tiempo se refleja en la propiedad NotBefore
de un evento.
Tipo de evento | Aviso mínimo |
---|---|
Helar | 15 minutos |
Reiniciar | 15 minutos |
Volver a implementar | 10 minutos |
Prevenir | 30 segundos |
Terminar | Configurable por el usuario: de 5 a 15 minutos |
Esto significa que puede detectar una programación futura del evento al menos durante el tiempo de aviso mínimo antes de que se produzca el evento. Una vez que se programe un evento, pasará al estado Started
después de que se apruebe o pase el tiempo NotBefore
. Sin embargo, en raras ocasiones, Azure cancela la operación antes de iniciarla. En ese caso, el evento se quita de la matriz Events y el impacto no se producirá según lo programado anteriormente.
Nota
En algunos casos, Azure puede predecir errores de host debido a hardware degradado e intenta mitigar la interrupción del servicio mediante la programación de una migración. Las máquinas virtuales afectadas recibirán un evento programado con un valor de NotBefore
que habitualmente es unos días posteriores. El tiempo real varía en función de la valoración de riesgo de error predicha. Azure intenta dar aviso de 7 días de antelación cuando sea posible. El tiempo de aviso real varía y puede ser más corto si hay una alta probabilidad de que el hardware produzca un error inminente. Para minimizar el riesgo para el servicio si se produce un error en el hardware antes de la migración iniciada por el sistema, se recomienda volver a implementar automáticamente la máquina virtual lo antes posible.
Nota
En caso de que el nodo de host experimente un error de hardware, Azure omite el período de aviso mínimo e inicia inmediatamente el proceso de recuperación de las máquinas virtuales afectadas. De esta forma, se reduce el tiempo de recuperación en caso de que las máquinas virtuales afectadas no puedan responder. Durante el proceso de recuperación, se crea un evento para todas las máquinas virtuales afectadas con EventType = Reboot
y EventStatus = Started
.
Frecuencia de sondeo
Puede sondear el punto de conexión para obtener las actualizaciones con la frecuencia que quiera. Sin embargo, cuanto más tiempo transcurre entre solicitudes, más tiempo se pierde para reaccionar ante un evento próximo. La mayoría de los eventos tienen un aviso previo de 5 a 15 minutos, aunque en algunos casos el aviso previo podría llegar con muy poca antelación, como 30 segundos. Para asegurarse de que tiene tanto tiempo como sea posible para llevar a cabo acciones de mitigación, se recomienda sondear el servicio una vez por segundo.
Inicio de un evento
Cuando se haya enterado de un evento próximo y completado la lógica para llevar a cabo un apagado estable, puede aprobar el evento pendiente mediante una llamada de POST
a Metadata Service con EventId
. Esta llamada indica a Azure que puede acortar el tiempo de notificación mínimo (cuando sea posible). Es posible que el evento no se inicie inmediatamente después de la aprobación. En algunos casos, Azure requiere la aprobación de todas las máquinas virtuales hospedadas en el nodo antes de continuar con el evento.
A continuación se muestra el JSON de ejemplo en el cuerpo de la solicitud POST
. La solicitud debe contener una lista de StartRequests
. Cada StartRequest
contiene el elemento EventId
para el evento que desea acelerar:
{
"StartRequests" : [
{
"EventId": {EventId}
}
]
}
El servicio siempre devuelve un código correcto 200 si se pasa un identificador de evento válido, incluso si otra máquina virtual ya ha aprobado el evento. Un código de error 400 indica que el encabezado de solicitud o la carga tienen un formato incorrecto.
Nota
Los eventos no procederán a menos que sean aprobados a través de un mensaje POST o hasta que el tiempo de NotBefore haya transcurrido. Esto incluye eventos desencadenados por el usuario, como reinicios de la máquina virtual desde Azure Portal.
Ejemplo de Bash
curl -H Metadata:true -X POST -d '{"StartRequests": [{"EventId": "f020ba2e-3bc0-4c40-a10b-86575a9eabd5"}]}' http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
Ejemplo de PowerShell
Invoke-RestMethod -Headers @{"Metadata" = "true"} -Method POST -body '{"StartRequests": [{"EventId": "5DD55B64-45AD-49D3-BBC9-F57D4EA97BD7"}]}' -Uri http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01 | ConvertTo-Json -Depth 64
Ejemplo de Python
import json
import requests
def confirm_scheduled_event(event_id):
# This payload confirms a single event with id event_id
payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
response = requests.post("http://169.254.169.254/metadata/scheduledevents",
headers = {'Metadata' : 'true'},
params = {'api-version':'2020-07-01'},
data = payload)
return response.status_code
Nota
Reconocer un evento permite a este continuar para todos sus elementos Resources
, no solo para la máquina virtual que lo reconoce. Por lo tanto, puede elegir a un líder para coordinar la confirmación, que podría ser tan simple como la primera máquina del campo Resources
.
Respuestas de ejemplo
Los siguientes eventos son un ejemplo de dos máquinas virtuales que fueron migradas en vivo a otro nodo.
El valor de DocumentIncarnation
cambia cada vez que hay información nueva en Events
. Una aprobación del evento permitiría que la inmovilización continuara tanto para WestNO_0 como para WestNO_1.
{
"DocumentIncarnation": 1,
"Events": [
]
}
{
"DocumentIncarnation": 2,
"Events": [
{
"EventId": "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
"EventStatus": "Scheduled",
"EventType": "Freeze",
"ResourceType": "VirtualMachine",
"Resources": [
"WestNO_0",
"WestNO_1"
],
"NotBefore": "Mon, 11 Apr 2022 22:26:58 GMT",
"Description": "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
"EventSource": "Platform",
"DurationInSeconds": 5
}
]
}
{
"DocumentIncarnation": 3,
"Events": [
{
"EventId": "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
"EventStatus": "Started",
"EventType": "Freeze",
"ResourceType": "VirtualMachine",
"Resources": [
"WestNO_0",
"WestNO_1"
],
"NotBefore": "",
"Description": "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
"EventSource": "Platform",
"DurationInSeconds": 5
}
]
}
{
"DocumentIncarnation": 4,
"Events": [
]
}
Ejemplo de Python
El ejemplo consulta Metadata Service para eventos programados y aprueba cada evento pendiente. Puede encontrar el código en el repositorio vm-scheduled-events-mock-server en el archivo Listener.py.
#!/usr/bin/python
import json
import requests
from time import sleep
# The URL to access the metadata service
metadata_url ="http://169.254.169.254/metadata/scheduledevents"
# This must be sent otherwise the request will be ignored
header = {'Metadata' : 'true'}
# Current version of the API
query_params = {'api-version':'2020-07-01'}
def get_scheduled_events():
resp = requests.get(metadata_url, headers = header, params = query_params)
data = resp.json()
return data
def confirm_scheduled_event(event_id):
# This payload confirms a single event with id event_id
# You can confirm multiple events in a single request if needed
payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
response = requests.post(metadata_url,
headers= header,
params = query_params,
data = payload)
return response.status_code
def log(event):
# This is an optional placeholder for logging events to your system
print(event["Description"])
return
def advanced_sample(last_document_incarnation):
# Poll every second to see if there are new scheduled events to process
# Since some events may have necessarily short warning periods, it is
# recommended to poll frequently
found_document_incarnation = last_document_incarnation
while (last_document_incarnation == found_document_incarnation):
sleep(1)
payload = get_scheduled_events()
found_document_incarnation = payload["DocumentIncarnation"]
# We recommend processing all events in a document together,
# even if you won't be actioning on them right away
for event in payload["Events"]:
# Events that already started, logged for tracking
if (event["EventStatus"] == "Started"):
log(event)
# Approve all user initiated events. These are typically created by an
# administrator and approving them immediately can help to avoid delays
# in admin actions
elif (event["EventSource"] == "User"):
confirm_scheduled_event(event["EventId"])
# For this application, freeze events less that 9 seconds are considered
# no impact. This will immediately approve them
elif (event["EventType"] == "Freeze" and
int(event["DurationInSeconds"]) >= 0 and
int(event["DurationInSeconds"]) < 9):
confirm_scheduled_event(event["EventId"])
# Events that may be impactful (for example reboot or redeploy) may need custom
# handling for your application
else:
#TODO Custom handling for impactful events
log(event)
print("Processed events from document: " + str(found_document_incarnation))
return found_document_incarnation
def main():
# This will track the last set of events seen
last_document_incarnation = "-1"
input_text = "\
Press 1 to poll for new events \n\
Press 2 to exit \n "
program_exit = False
while program_exit == False:
user_input = input(input_text)
if (user_input == "1"):
last_document_incarnation = advanced_sample(last_document_incarnation)
elif (user_input == "2"):
program_exit = True
if __name__ == '__main__':
main()
Probar eventos programados
Dos formas comunes de probar la respuesta de las aplicaciones a los eventos programados son desencadenar manualmente eventos imitados por el usuario o usar un servidor ficticio.
Puede desencadenar manualmente los eventos de reimplementación y reinicio a través de Azure Portal o la CLI de Azure seleccionando la opción "reiniciar" o "volver a implementar" de la máquina virtual en la hoja de la máquina virtual. Esto creará un evento y lo enviará a su carga de trabajo.
Las operaciones que afectan a varias máquinas virtuales, como las actualizaciones de host, no se pueden desencadenar a petición para que pueda usar un servidor ficticio en su lugar. Vm-scheduled-events-mock-server proporciona un marco para probar la respuesta de la aplicación a diferentes escenarios mediante la reproducción de eventos reales para el desarrollo y las pruebas. De forma predeterminada, el servidor admite 9 escenarios diferentes, todos capturados de máquinas virtuales que se ejecutan en Azure y representan los casos más comunes. Los escenarios se pueden expandir para incluir más opciones en función de las características específicas de las aplicaciones.
Pasos siguientes
- Repase los ejemplos de código de Scheduled Events en el repositorio de GitHub Azure Instance Metadata Scheduled Events (Scheduled Events de Azure Instance Metadata).
- Revise los ejemplos de código de Scheduled Events de Node.js en el repositorio de GitHub de ejemplos de Azure.
- En Instance Metadata Service, puede obtener más información sobre las API disponibles.
- Obtenga información sobre cómo realizar el mantenimiento planeado para máquinas virtuales Windows en Azure.
- Obtenga información sobre cómo supervisar eventos programados para las máquinas virtuales mediante Log Analytics.
- Aprenda a registrar eventos programados mediante Azure Event Hubs en el repositorio de ejemplos de Azure en GitHub.
- Use vm-scheduled-events-mock-server para probar la respuesta de la aplicación a escenarios comunes de eventos programados.