¿WhatsApp usa RabbitMQ?
El conejo se basa en Erlang Lenguaje de programación de uso general y también lo utiliza WhatsApp para mensajes.
Resumen
WhatsApp usa RabbitMQ, que se basa en Erlang, como su cola de mensajería para la entrega de mensajes.
Al diseñar un sistema de chat en tiempo real, es importante considerar la cola utilizada por plataformas de mensajería populares como WhatsApp y Facebook Messenger. Si bien puede parecer lógico tener una cola por persona o una Kafka-Topic para cada usuario, dados los miles de millones de usuarios en estas plataformas, este enfoque requeriría un número poco práctico de colas o temas. Sin embargo, se ha observado que WhatsApp y Facebook Messenger usan una cola llamada “iris” (similar a Kafka) para la entrega de mensajes.
Existen sistemas internos que llenan las bases de datos (como HBase y Myrocks) de la cola de mensajes, pero estas bases de datos no son el sistema de entrega principal.
Preguntas y respuestas
1. ¿En qué se construye el conejo??
RabbitMQ se basa en el lenguaje de programación de uso general de Erlang.
2. ¿Cómo usa whatsapp rabbitmq??
WhatsApp usa RabbitMQ como cola de mensajería para la entrega de mensajes.
3. ¿Cuál es el propósito de una cola de mensajería??
Se utiliza una cola de mensajería para desacoplar los componentes de un sistema, lo que permite enviar mensajes entre ellos asíncronamente.
4. ¿Se puede utilizar una cola por persona para la entrega de mensajes en WhatsApp o Facebook Messenger??
Si bien una cola por persona puede parecer lógica, requeriría un número poco práctico de colas dados los miles de millones de usuarios en estas plataformas.
5. Qué cola usa Whatsapp y Facebook Messenger para la entrega de mensajes?
WhatsApp y Facebook Messenger usan una cola llamada “iris” para la entrega de mensajes. “Iris” es similar a Kafka.
6. ¿Cuáles son algunas de las bases de datos utilizadas por WhatsApp para almacenar mensajes??
WhatsApp utiliza bases de datos como HBase y Myrocks para almacenar mensajes. Estas bases de datos están pobladas de la cola de mensajes.
7. ¿Es RabbitMQ el sistema de entrega principal para WhatsApp??
No, RabbitMQ no es el sistema de entrega principal para WhatsApp. Se usa como cola de mensajería para la entrega de mensajes.
8. ¿Es la entrega de mensajes en WhatsApp y Facebook Messenger síncrono o asíncrono??
La entrega de mensajes en WhatsApp y Facebook Messenger es asíncrono, lo que significa que los mensajes se envían y reciben independientemente el uno del otro.
9. ¿Cuáles son los beneficios de usar una cola de mensajería como RabbitMQ??
El uso de una cola de mensajería como RabbitMQ permite el desacoplamiento de componentes, escalabilidad mejorada y comunicación asincrónica entre elementos del sistema.
10. ¿Puede RabbitMQ manejar altos volúmenes de mensajes??
Sí, RabbitMQ está diseñado para manejar altos volúmenes de mensajes y es capaz de entregarlos de manera eficiente y confiable.
11. ¿Cuáles son las alternativas a RabbitMQ para implementar una cola de mensajería??
Algunas alternativas a RabbitMQ incluyen Apache Kafka, Activemq y Redis Streams.
12. ¿Hay alguna limitación al usar una cola de mensajería como RabbitMQ??
Algunas limitaciones del uso de una cola de mensajería como RabbitMQ incluyen la necesidad de configurarlo correctamente y sintonizarlo para un rendimiento óptimo, pérdida potencial de mensajes si no se configuran correctamente y la necesidad de una infraestructura adicional para admitir la cola de mensajería.
13. ¿Se puede utilizar el conejo para otros fines además de los mensajes??
Sí, RabbitMQ se puede utilizar para otros fines además de la mensajería, como la programación de tareas, las arquitecturas impulsadas por eventos y la transmisión de datos.
14. ¿La persistencia del mensaje de soporte de RabbitMQ?
Sí, RabbitMQ admite la persistencia del mensaje, permitiendo que los mensajes se almacenen y recuperen incluso en caso de fallas del sistema.
15. ¿Cómo garantiza RabbitMQ para la fiabilidad de entrega de mensajes??
RabbitMQ garantiza la confiabilidad de la entrega de mensajes a través de características como el reconocimiento de mensajes, el editor confirma y la durabilidad de la cola.
¿WhatsApp usa RabbitMQ?
El conejo se basa en Erlang Lenguaje de programación de uso general y también lo utiliza WhatsApp para mensajes.
Cola utilizada en WhatsApp o FB Messenger
Mientras piensa en un diseño de un sistema para el chat en tiempo real, tengo curiosidad por saber qué tipo de cola está utilizando WhatsApp o FB Messenger en el lado del servidor para entregar el mensaje al destinatario. Lo que estaba pensando era que hay una cola por persona/kafka-topic, por lo que cuando se debe entregar un nuevo mensaje al usuario A, el mensaje es la cola de A de A. Sin embargo, puede haber miles de millones de usuarios (FB tiene 2 mil millones de usuarios), eso significa que necesitamos 2 mil millones de colas/temas (en Kafka Term)? Si es así, qué cola puede manejar esto perfectamente. Cualquier comentario es bienvenido! Gracias!
preguntó el 25 de junio de 2019 a las 16:44
1,669 8 8 Insignias de oro 23 23 Insignias de plata 37 37 Insignias de bronce
Puede encontrar documentación de que Messager se construyó sobre HBase, y ahora Myrocks. Hay sistemas internos que popularían esas bases de datos desde una cola, sí, pero no es el sistema de entrega principal. código.pensión completa.com/core-data/…
26 de junio de 2019 a las 3:08
@cricket_007 gracias por los comentarios. Yeap, parece que FB usa Iris (Kafka como) como cola para la entrega.
Alifzl/Yomkippur
Esta confirmación no pertenece a ninguna rama en este repositorio, y puede pertenecer a una bifurcación fuera del repositorio.
Cambiar ramas/etiquetas
Etiquetas de ramas
No pudo cargar ramas
Nada que mostrar
No se pudo cargar etiquetas
Nada que mostrar
Nombre ya en uso
Ya existe una etiqueta con el nombre de rama proporcionado. Muchos comandos GIT aceptan los nombres de etiquetas y ramas, por lo que crear esta rama puede causar un comportamiento inesperado. ¿Estás seguro de que quieres crear esta rama??
Cancelar crear
- Local
- Espacios de códigos
Https github cli
Use git o consulte con SVN utilizando la URL web.
Trabaja rápido con nuestra CLI oficial. Aprenda más sobre el CLI.
Inicio de sesión requerido
Inicie sesión para usar CodeSpaces.
Lanzamiento de Github Desktop
Si no pasa nada, descargue el escritorio de Github y vuelva a intentarlo.
Lanzamiento de Github Desktop
Si no pasa nada, descargue el escritorio de Github y vuelva a intentarlo.
Lanzamiento de Xcode
Si no pasa nada, descargue Xcode e intente nuevamente.
Lanzamiento del código Visual Studio
Tu CodeSpace se abrirá una vez que esté listo.
Hubo un problema para preparar su espacio de código, intente nuevamente.
Último cometer
Estadísticas de git
Archivos
No se pudo cargar información de confirmación más reciente.
Último mensaje de confirmación
Tiempo de compromiso
Readme.Maryland
Yom Kippur es una herramienta de automatización de WhatsApp que tiene como objetivo ser una solución consistente y permanente para el uso no comercial de WhatsApp como un bot automatizado.
Qué hace?
- Enviar/recibir un solo mensaje en una aplicación WhatsApp preconfigurada en el AVD (dispositivo virtual Android)
- Cree la lista de contacto en AVD y úsela para las cosas de envío/recepción
- Literalmente puede hacer todo con AVD (crea numerosas posibilidades para persuadir)
Al principio, vi a Yowsup mi única opción, pero debido a los problemas enumerados a continuación, cambié de opinión para implementarlo de otra manera:
- Variedad de problemas comunitarios (vinculado aquí)
- Yosup es un tipo de API asincrónico que interactúa con WhatsApp Restapi, con respecto a las consideraciones de alta seguridad de WhatsApp, fue muy sensible sobre las sesiones activas actuales de cada usuario y no será muy amigable con las soluciones sincrónicas. (Como probablemente sabe las restricciones de usar la visión web de WhatsApp que dice que debemos tener una conexión a Internet activa consistente en el teléfono simultáneamente)
- la pereza mía y también desafiándome a hacerlo de la manera difícil
Bueno, dependencias en este proyecto, son bastante! Primero de ustedes debe tener este requisito satisfecho:
Los instaladores de Windows se refidan, pero se puede implementar en la máquina Linux o MacOS (ambos no probados)
Dependencia | Enlaces de descripción / descarga |
---|---|
Estudio de Android | Android Studio con Android API 28 |
JAVA | Java JDK 11 |
Mysql | MySQL Installer Community 8.X o superior |
Python 2.7 | Python 2.7 |
Appio | V1.10 o más |
Conejo | Última versión de Rabbitmq |
Cartero | Última versión de Postman |
Consideraciones: Puedes usar Conda Virenv para el Python 2.7, pero me impulsó un dolor de cabeza serio (no recomendado)
La razón principal por la que utilicé Python 2 para este proyecto es que Appium, MySQL Connector Client y RabbitMQ fueron incompatibiles juntos en la versión 3.
En primer lugar, sea paciente en esta parte. Me tomó sangre y lágrimas para limpiar las mierdas de dependencia para hacer esta tarea tan simple.
1.Dispositivo virtual de Android
Luanch AVD Manager de Android Studio, configurar un dispositivo con Android 9.0 con API 28 (seleccione y nombre apropiado para el AVD porque lo necesitamos en pasos adicionales).
Observe que debe instalar WhatsApp a través del AVD en sí, así que seleccione la versión compatible con PlayStore.
Verifique que tenga estas variables de entorno en su cuenta:
Nombre de la variable | Valor variable |
---|---|
Android_home | C: \ users \ fzl \ appdata \ local \ android \ sdk |
Java_home | C: \ Archivos de programa \ java \ jdk-11.0.2 |
Pitonpath | C: \ python27; c: \ python27 \ lib \ sitio de sitio; c: \ python27 \ lib; c: \ python27 \ dlls; c: \ python27 \ scripts |
Parche | C: \ python27; c: \ python27 \ scripts; c: \ python27 \ lib \ sitio-paquetes; c: \ archivos de programa \ java \ jdk-11.0.2; C: \ Archivos de programa \ java \ jdk-11.0.2 \ bin; |
Luego debe iniciar su AVD, instalar WhatsApp en eso y también autorizar el ADB con su dispositivo (obligatorio)
Para hacerlo, debe ejecutar dispositivos ADB o USB ADB para verificar la autorización del AVD.
C:\ Users\FZL\Appdata\ Local\Android\Sdk\pagLatform-Tools: dispositivos ADB Lista de dispositivos Adjuntos Emulador-5554 Dispositivo
Si está viendo el resultado no autorizado, debe seguir este enlace.
2.Configuración de RabbitMQ
Después de la instalación de RAABITMQ, debe ejecutar RabbitMQ-Plugins habilitar RABBITMQ_MANAMENT en el directorio RabbitMQ SBIN para habilitar la web-GUI del Sytem de gestión de RabbitMQ. puede ser necesario restringir el servicio RabbitMQ.
Después de esto, debería poder acceder al RabbitMQ Web-Gui con http: // localhost: 15672/#/dirección en su máquina local. En caso afirmativo, cree un nuevo usuario por los siguientes comandos y hágalo AdministARTOR:
Contraseña de nombre de usuario de RabbitMQCTL ADD_USER # Esto hace del usuario un administrador rabbitmqctl set_user_tags Administrador de nombre de usuario # Esto establece permisos para el usuario rabbitmqctl set_permissions -p / username ".*" ".*" ".*"
Inicie sesión con credenciales recién creadas e importe las especificaciones de la cola que ya se adjunta en este repositorio que se llama RabbitMQ_Conf.JSON en las secciones de definiciones de importación en la descripción general Menue.
Crearía las configuraciones necesarias para el rabbitmq y habilita los privilegios necesarios.
3.Appio
Simplemente ejecute el servidor Appium con la configuración predeterminada. APPIUM –Fault-CapAbity ” ya está incrustado en el código. TL; DR: No hay nada que hacer en este paso.
4.Mysql
Instale la edición comunitaria del MySQL, cree una cuenta de DB apropiada y establezca el servicio ejecutado automáticamente cuando se inicia el sistema operativo.
5.Instale las dependencias de Python
Simplemente ejecute PIP Install –Re dependencias.txt para resolver la dependencia de las bibliotecas usadas.
Puede enfrentar la versión desactivada de la biblioteca mySQLDB que se puede solucionar con la instalación de esto y esto. Cuida la instalación de Python 2.X versión de bibliotecas mencionadas.
6.Crear directorios para los archivos de registro
Crea los directorios y archivos tal como está’s mencionado a continuación:
# directorios C:\ VArkansas\ lOG [Directorio] C:\ VArkansas\ log\ Whatsapp_api [directorio] # archivos de registro C:\ VArkansas\ log\aPi.Registro C:\ VArkansas\ log\ Whatsapp_single_consumer.Registro C:\ VArkansas\ log\ Whatsapp_single_worker.Registro C:\ VArkansas\ lOG \
7.Establecer el Yom Kippur’S FILE DE CONFIGURACIÓN
Vaya a Yomkippur-Master \ configs \ config.CFG e ingrese lo siguiente.
(No cambie nada esle a menos que sepa qué está haciendo)
[mysql] host = 127.0.0.1 nombre de usuario ='tu nombre de usuario mysql' contraseña ='Tu contraseña mysql' base de datos = whatsapp [rabbitmq] ip = 127.0.0.1 ipQueUename = ipaddr.cola username ='Tu nombre de usuario de RabbitMQ' contraseña ='Su contraseña de RabbitMq' [queue_name] single_message = whatsapp_singlemessage_queue broadcast_message = whatsapp_broadcastmessage_queue add_contact = whatsapp_newcontact_listener_queue oyear_message = whatsapp_messageListener_queue
Ejecutar el principal.PY y ADD_NEW_CONTACT_PRODUCER.PY en dos entornos de terminal/CMD separados.
Si no vio ningún error, está listo para comenzar.
- Asegúrese de que MySQL Server se esté ejecutando
- Asegúrese de que RabbitMq sever sea runnig
- Ejecutar Appium con configuraciones de Defualt
- Ejecute estos scripts
Python principal.py python add_new_contact_producer.py python single_message_producer.py
- Ejecute Postman y cree comandos de publicación deseables en la lista a continuación:
Agregar contacto en la aplicación de contactos de Google
Enviar un solo mensaje a través de WhatsApp
Desarrollo y contribuyendo?
Quiere contribuir? Excelente! Siéntete libre de llamarme a un.fazeli95 [at] gmail [dot] com o simplemente crear una solicitud de extracción.
Todos los componentes utilizados en este proyecto son de código abierto y tienen licencia MIT y se pueden usar en cualquier producto no comercial
Acerca de
Broker de mensajes de WhatsApp con Rabbitmq, AvD y Appium
Introducción al conejo
Aquí aprenderemos qué es RabbitMQ, usos de RabbitMQ y por qué necesitamos usar RabbitMQ en nuestras aplicaciones con ejemplos.
¿Qué es Rabbitmq??
Conejo es un AMQP Broker de mensajería y es el corredor de mensajes de código abierto más popular y multiplataforma.
RabbitMQ también es una forma de intercambiar los datos entre diferentes aplicaciones de plataforma, como un mensaje enviado desde .Neto La aplicación puede ser leída por un Nodo.js aplicación o Java solicitud.
El conejo se basa en Erlang Lenguaje de programación de uso general y también lo utiliza WhatsApp para mensajes.
Que es amqp?
El protocolo de cola de mensajes avanzado (AMQP) es un protocolo de capa de aplicación estándar abierta para los mensajes orientados a los mensajes y las características de AMQP son la orientación de mensajes, la cola, el enrutamiento (incluyendo punto a punto y publicar y suscribirse), confiabilidad y seguridad.
Fue desarrollado por JPMorgan e Imatix Corporation. AMQP fue diseñado con las siguientes características principales como objetivos:
- Seguridad
- Fiabilidad
- Interoperabilidad
- Estándar
- Abierto
RabbitMQ es liviano y fácil de implementar en las instalaciones disponibles y admite múltiples protocolos de mensajería. RabbitMQ se puede implementar en configuraciones distribuidas y federadas para cumplir con los requisitos de alta disponibilidad de alta escala.
La siguiente es la representación pictórica de cómo RabbitMQ actuará como mediador entre el remitente y el consumidor en nuestras aplicaciones.
Por qué y cuándo usar RabbitMQ?
Hoy en día, la mayoría de las personas realizarán múltiples tareas en una aplicación única, como enviar correos electrónicos o SMS, informes y creará una carga pesada en la aplicación, por lo que si separa estas tareas, obtendremos más espacio (memoria) para atender más solicitudes.
Mediante el uso de RabbitMQ, podemos eliminar un trabajo pesado de nuestras aplicaciones web, como enviar informes en formato de Excel o PDF’s o enviar un correo electrónico, SMS u otra tarea, como activar algunas otras aplicaciones para comenzar a procesar.
RabbitMQ es un código abierto y corredor de mensajes multiplataforma, por lo que’es fácil de usar con muchos idiomas como .Net, Java, Python, Ruby, Node.Js.
Bibliotecas de clientes compatibles con RabbitMQ
RabbitMQ admitirá múltiples sistemas operativos y lenguajes de programación. RabbitMQ ha proporcionado varias bibliotecas de clientes para seguir los lenguajes de programación.
- .Neto
- Java
- Marco de primavera
- Rubí
- Pitón
- Php
- Objetivo-C y Swift
- Javascript
- IR
- Perl
Diseño del sistema: whatsapp
Diseñemos un servicio de mensajería instantánea de WhatsApp, similar a servicios como WhatsApp, Facebook Messenger y WeChat.
Que es whatsapp?
WhatsApp es una aplicación de chat que proporciona servicios de mensajería instantánea a sus usuarios. Es una de las aplicaciones móviles más utilizadas en el planeta que conecta a más de 2 mil millones de usuarios en más de 180 países. WhatsApp también está disponible en la web.
Requisitos
Nuestro sistema debe cumplir con los siguientes requisitos:
Requerimientos funcionales
- Debe admitir chat uno a uno.
- Chats grupales (máximo 100 personas).
- Debe admitir compartir archivos (imagen, video, etc.).
requerimientos no funcionales
- Alta disponibilidad con latencia mínima.
- El sistema debe ser escalable y eficiente.
Requisitos extendidos
- Enviado, entregado y leído recibos de los mensajes.
- Muestre el último tiempo visto de usuarios.
- Notificaciones push.
Estimación y restricciones
Comencemos con la estimación y las limitaciones.
Nota: Asegúrese de verificar cualquier escala o suposición relacionada con el tráfico con su entrevistador.
Tráfico
Supongamos que tenemos 50 millones de usuarios activos diarios (DAU) y, en promedio, cada usuario envía al menos 10 mensajes a 4 personas diferentes todos los días. Esto nos da 2 mil millones de mensajes por día.
50 m i l l i o n × 20 m e s s a g e s = 2 b i l l i o n / d a y 50 \ space millones \ times 20 \ space Mensajes = 2 \ espacio mil millones / día 50 mi ll i o n × 20 m ess a g es = 2 bi ll i o n / d a y y y d a y y
Los mensajes también pueden contener medios como imágenes, videos u otros archivos. Podemos suponer que el 5 por ciento de los mensajes son archivos multimedia compartidos por los usuarios, lo que nos brinda 200 millones de archivos adicionales que necesitaríamos almacenar.
5 p e r c e n t × 2 b i l l i o n = 200 m i l l i o n / d a y 5 \ space porcentaje \ times 2 \ space mil millones = 200 \ space millones / día 5 p × t × 2 bi ll i o n = 200 mil i o n / d a y y
¿Cuáles serían las solicitudes por segundo (RPS) para nuestro sistema?? 2 mil millones de solicitudes por día se traducen en 24k solicitudes por segundo.
2 b i l l i o n (24 h r s × 3600 s e c o n d s) = ∼ 24 k r e q u e s t s / s e c o n d \ frac<2 \space billion> <(24 \space hrs \times 3600 \space seconds)>= \ sim 24k \ Solicitudes de espacio / segundo (24 h rs × 3600 seco n d s) 2 bi ll i o n = ∼ 24 k re q u es t s / seco n d d2>
### Almacenamiento Si suponemos que cada mensaje en promedio es de 100 bytes, requeriremos aproximadamente 200 GB de almacenamiento de bases de datos todos los días.
2 b i l l i o n × 100 b y t e s = ∼ 200 g b / d a y 2 \ space mil millones \ times 100 \ space bytes = \ sim 200 \ space gb / day 2 bi ll i o n × 100 b y t es = ∼ 200 gb / d a y y
Según nuestros requisitos, también sabemos que alrededor del 5 por ciento de nuestros mensajes diarios (100 millones) son archivos multimedia. Si asumimos que cada archivo es de 50 kb en promedio, requeriremos 10 TB de almacenamiento todos los días.
100 m i l l i o n × 100 k b = 10 t b / d a y 100 \ space millones \ veces 100 \ space kb = 10 \ space tb / día 100 mi ll i o n × 100 k b = 10 tb / d a y
Y durante 10 años, requeriremos aproximadamente 38 PB de almacenamiento.
(10 T B + 0.2 T B) × 10 y E A R S × 365 D A Y S = ∼ 38 P B (10 \ Space TB + 0.2 \ Space tb) \ Times 10 \ Space Years \ Times 365 \ Space Days = \ Sim 38 \ Space Pb (10 TB + 0.2 tb) × 10 ye a rs × 365 d a ys = ∼ 38 pb
### Ancho de banda como nuestro sistema está manejando 10.2 TB de entrada todos los días, requeriremos un ancho de banda mínimo de alrededor de 120 MB por segundo.
10.2 t b (24 h r s × 3600 s e c o n d s) = ∼ 120 m b / s e c o n d \ frac<10.2 \space TB> <(24 \space hrs \times 3600 \space seconds)>= \ Sim 120 \ Space MB/Second (24 H RS × 3600 SECO N D S) 10.2 TB = ∼ 120 Mb / Seco N D10.2>
### Estimación de alto nivel Aquí está nuestra estimación de alto nivel:
Tipo | Estimar |
---|---|
Usuarios activos diarios (dau) | 50 millones |
Solicitudes por segundo (RPS) | 24k/s |
Almacenamiento (por día) | ~ 10.2 TB |
Almacenamiento (10 años) | ~ 38 PB |
Banda ancha | ~ 120 MB/s |
Diseño del modelo de datos
Este es el modelo de datos general que refleja nuestros requisitos. Tenemos las siguientes tablas: usuarios Esta tabla contendrá la información de un usuario, como el nombre, el número de teléfono y otros detalles. mensajes Como su nombre indica, esta tabla almacenará mensajes con propiedades como tipo (texto, imagen, video, etc.), contenido y marcas de tiempo para la entrega de mensajes. El mensaje también tendrá un chatid o groupid correspondiente . charlatanes Esta tabla básicamente representa un chat privado entre dos usuarios y puede contener múltiples mensajes. usuarios_chats Esta tabla mapea a los usuarios y chats, ya que varios usuarios pueden tener múltiples chats (N: M relación) y viceversa. grupos Esta tabla representa un grupo entre varios usuarios. users_groups Esta tabla mapea a los usuarios y grupos, ya que múltiples usuarios pueden ser parte de múltiples grupos (relación N: M) y viceversa.
¿Qué tipo de base de datos debemos usar??
Si bien nuestro modelo de datos parece bastante relacional, no necesariamente necesitamos almacenar todo en una sola base de datos, ya que esto puede limitar nuestra escalabilidad y convertirnos rápidamente en un cuello de botella. Dividiremos los datos entre diferentes servicios, cada uno de los cuales tiene propiedad sobre una tabla en particular. Entonces podemos usar una base de datos relacional como PostgreSQL o una base de datos NoSQL distribuida como Apache Cassandra para nuestro caso de uso.
Diseño de API
Hagamos un diseño de API básico para nuestros servicios:
Obtenga todos los chats o grupos
Esta API obtendrá todos los chats o grupos para un ID de usuario determinado .
obtener toda(ID de usuario: Uuid) Charlar[] | Grupo[]
Ingrese el modo de pantalla completa
Salir al modo de pantalla completa
Parámetros ID de usuario (UUID): ID del usuario actual. Devoluciones Resultado (chat [] | grupo []): todos los chats y grupos del usuario es parte de.
Obtener mensajes
Obtenga todos los mensajes para un usuario dado el canalid (ID de chat o grupo).
getMessages(ID de usuario: Uuid, Canal ID: Uuid) Mensaje[]
Ingrese el modo de pantalla completa
Salir al modo de pantalla completa
Parámetros ID de usuario (UUID): ID del usuario actual. ID de canal (UUID): ID del canal (chat o grupo) del que se deben recuperar los mensajes. Devoluciones Mensajes (mensaje []): todos los mensajes en un chat o grupo determinado.
Enviar mensaje
Envíe un mensaje de un usuario a un canal (chat o grupo).
enviar mensaje(ID de usuario: Uuid, Canal ID: Uuid, mensaje: Mensaje) booleano
Ingrese el modo de pantalla completa
Salir al modo de pantalla completa
Parámetros ID de usuario (UUID): ID del usuario actual. ID de canal (UUID): ID del usuario del canal (chat o grupo) El usuario desea enviar un mensaje a. Mensaje (mensaje): el mensaje (texto, imagen, video, etc.) que el usuario quiere enviar. Devoluciones Resultado (booleano): representa si la operación fue exitosa o no.
Unirse o dejar un grupo
Envíe un mensaje de un usuario a un canal (chat o grupo).
unirse al grupo(ID de usuario: Uuid, Canal ID: Uuid) booleano grupo de licencia(ID de usuario: Uuid, Canal ID: Uuid) booleano
Ingrese el modo de pantalla completa
Salir al modo de pantalla completa
Parámetros ID de usuario (UUID): ID del usuario actual. ID de canal (UUID): ID del canal (chat o grupo) El usuario desea unirse o dejar. Devoluciones Resultado (booleano): representa si la operación fue exitosa o no.
Diseño de alto nivel
Ahora hagamos un diseño de alto nivel de nuestro sistema.
Arquitectura
Utilizaremos la arquitectura de microservices, ya que facilitará la escala horizontal y desacoplará nuestros servicios. Cada servicio tendrá la propiedad de su propio modelo de datos. Intentemos dividir nuestro sistema en algunos servicios básicos. Servicio de usuario Este es un servicio basado en HTTP que maneja las preocupaciones relacionadas con el usuario, como la autenticación y la información del usuario. Servicio de chat El servicio de chat utilizará WebSockets y establecerá conexiones con el cliente para manejar la funcionalidad relacionada con los mensajes de chat y grupos. También podemos usar caché para realizar un seguimiento de todas las conexiones activas como sesiones similares que nos ayudarán a determinar si el usuario está en línea o no. Servicio de notificación Este servicio simplemente enviará notificaciones push a los usuarios. Se discutirá en detalle por separado. Servicio de presencia El servicio de presencia realizará un seguimiento del último estado visto de todos los usuarios. Se discutirá en detalle por separado. Servicio de medios Este servicio manejará los medios (imágenes, videos, archivos, etc.) Sube. Se discutirá en detalle por separado. ¿Qué pasa con la comunicación entre servicios y el descubrimiento de servicios?? Dado que nuestra arquitectura está basada en microservicios, los servicios también se comunicarán entre sí. En general, REST o HTTP funcionan bien, pero podemos mejorar aún más el rendimiento usando GRPC, que es más liviano y eficiente. El descubrimiento de servicios es otra cosa que tendremos que tener en cuenta. También podemos usar una malla de servicio que permita la comunicación administrada, observable y segura entre los servicios individuales. Nota: Obtenga más información sobre REST, GraphQL, GRPC y cómo se comparan entre sí.
Mensajes en tiempo real
¿Cómo enviamos y recibimos mensajes de manera eficiente?? Tenemos dos opciones diferentes: Modelo El cliente puede enviar periódicamente una solicitud HTTP a los servidores para verificar si hay algún mensaje nuevo. Esto se puede lograr a través de algo así como largas encuestas. Modelo de empuje El cliente abre una conexión de larga vida con el servidor y una vez que hay nuevos datos disponibles, se enviará al cliente. Podemos usar WebSockets o Eventos de Servidor (SSE) para este. El enfoque del modelo de extracción no es escalable, ya que creará una solicitud de solicitud innecesaria en nuestros servidores y la mayoría de las veces la respuesta estará vacía, desperdiciando así nuestros recursos. Para minimizar la latencia, usar el modelo PUSH con WebSockets es una mejor opción porque podemos enviar datos al cliente una vez que esté disponible sin demora dado que la conexión está abierta con el cliente. Además, WebSockets proporcionan comunicación duplex, a diferencia de los eventos (SSE) de Servidor (SSE) que solo son unidireccionales. Nota: Obtenga más información sobre las encuestas largas, WebSockets, los eventos de Servidor (SSE).
Ultima vez visto
Para implementar la última funcionalidad vista, podemos usar un mecanismo de latidos, donde el cliente puede hacer ping a los servidores indicando su vida. Dado que esto debe ser lo más bajo posible, podemos almacenar la última marca de tiempo activa en la memoria caché de la siguiente manera:
Llave | Valor |
---|---|
Usuario A | 2022-07-01T14: 32: 50 |
Usuario B | 2022-07-05T05: 10: 35 |
Usuario C | 2022-07-10T04: 33: 25 |
Esto nos dará la última vez que el usuario estuvo activo. Esta funcionalidad será manejada por el servicio de presencia combinado con Redis o Memcached como nuestro caché. Otra forma de implementar esto es rastrear la última acción del usuario, una vez que la última actividad cruza un cierto umbral, como “El usuario no ha realizado ninguna acción en los últimos 30 segundos”, Podemos mostrarle al usuario como fuera de línea y última vista con la última marca de tiempo grabada. Este será más un enfoque de actualización perezosa y podría beneficiarnos a los latidos en ciertos casos.
Notificaciones
Una vez que se envía un mensaje en un chat o un grupo, primero verificaremos si el destinatario está activo o no, podemos obtener esta información tomando la conexión activa del usuario y la última vez que se ve en consideración. Si el destinatario no está activo, el servicio de chat agregará un evento a una cola de mensajes con metadatos adicionales como la plataforma de dispositivo del cliente que se utilizará para enrutar la notificación a la plataforma correcta más adelante. El servicio de notificación luego consumirá el evento de la cola de mensajes y reenviará la solicitud a Firebase Cloud Messaging (FCM) o el Servicio de notificación Push de Apple (APNS) basado en la plataforma del dispositivo del cliente (Android, iOS, Web, etc.). También podemos agregar soporte para correo electrónico y SMS. ¿Por qué estamos usando una cola de mensajes?? Dado que la mayoría de las colas de mensajes proporcionan el pedido de mejor esfuerzo, lo que garantiza que los mensajes generalmente se entreguen en el mismo orden que se envían y que un mensaje se entrega al menos una vez, lo que es una parte importante de nuestra funcionalidad de servicio. Si bien esto parece un caso de uso clásico de publicación de suscripción, en realidad no es como dispositivos móviles y navegadores, cada uno tiene su propia forma de manejar notificaciones push. Por lo general, las notificaciones se manejan externamente a través de Firebase Cloud Messaging (FCM) o el Servicio de Notificación Push de Apple (APN) a diferencia del ventilador de mensajes que comúnmente vemos en los servicios de backend. Podemos usar algo como Amazon SQS o RabbitMQ para respaldar esta funcionalidad.
Leer recibos
El manejo de los recibos de lectura puede ser complicado, para este caso de uso podemos esperar algún tipo de reconocimiento (ACK) del cliente para determinar si se entregó el mensaje y actualizar el campo entregados correspondiente. Del mismo modo, marcaremos el mensaje del mensaje que se ve una vez que el usuario abre el chat y actualizaremos el campo de tiempo de tiempo de Seenat correspondiente.
Diseño
Ahora que hemos identificado algunos componentes centrales, hagamos el primer borrador del diseño de nuestro sistema.
Diseño detallado
Es hora de discutir nuestras decisiones de diseño en detalle.
División de datos
- Partición basada en hash
- División basada en listas
- Partición basada en rango
- Partición compuesta
Los enfoques anteriores aún pueden causar datos desiguales y distribución de carga, podemos resolver esto utilizando hashing consistente.
Almacenamiento en caché
En una aplicación de mensajería, debemos tener cuidado con el uso de caché, ya que nuestros usuarios esperan los datos más recientes, pero muchos usuarios solicitarán los mismos mensajes, especialmente en un chat grupal. Entonces, para evitar picos de uso de nuestros recursos, podemos almacenar en caché los mensajes más antiguos.
Algunos chats grupales pueden tener miles de mensajes y enviar eso a través de la red será realmente ineficiente, para mejorar la eficiencia, podemos agregar paginación a nuestras API del sistema. Esta decisión será útil para los usuarios con ancho de banda de red limitado, ya que no tendrán que recuperar mensajes antiguos a menos que se solicite.
Qué política de desalojo de caché para usar?
Podemos usar soluciones como Redis o Memcached y caché del 20% del tráfico diario, pero qué tipo de política de desalojo de caché se ajustaría mejor a nuestras necesidades?
Menos utilizado recientemente (LRU) puede ser una buena política para nuestro sistema. En esta política, descartaremos primero la clave menos utilizada recientemente.
Cómo manejar la cache Miss?
Siempre que hay una falla de caché, nuestros servidores pueden presionar la base de datos directamente y actualizar el caché con las nuevas entradas.
Para más detalles, consulte el almacenamiento en caché.
Acceso y almacenamiento de medios
Como sabemos, la mayor parte de nuestro espacio de almacenamiento se utilizará para almacenar archivos multimedia como imágenes, videos u otros archivos. Nuestro servicio de medios manejará tanto el acceso como el almacenamiento de los archivos de medios de usuario.
Pero, ¿dónde podemos almacenar archivos a escala?? Bueno, el almacenamiento de objetos es lo que estamos buscando. Object Stores divide los archivos de datos en piezas llamadas objetos. Luego almacena esos objetos en un solo repositorio, que se puede extender a través de múltiples sistemas en red. También podemos usar el almacenamiento de archivos distribuido como HDFS o GLUSTFS.
Dato curioso: WhatsApp elimina los medios en sus servidores una vez que ha sido descargado por el usuario.
Podemos usar tiendas de objetos como Amazon S3, Azure Blob Storage o Google Cloud Storage para este caso de uso.
Red de entrega de contenido (CDN)
Red de entrega de contenido (CDN) aumenta la disponibilidad y redundancia de contenido al tiempo que reduce los costos de ancho de banda. En general, se sirven archivos estáticos como imágenes y videos de CDN. Podemos usar servicios como Amazon CloudFront o Cloudflare CDN para este caso de uso.
Puerta de enlace de la API
Dado que utilizaremos múltiples protocolos como HTTP, WebSocket, TCP/IP, la implementación de los equilibradores de carga L4 (capa de transporte) o L7 (capa de aplicación) por separado para cada protocolo será costoso. En su lugar, podemos usar una puerta de enlace API que admite múltiples protocolos sin ningún problema.
API Gateway también puede ofrecer otras características, como autenticación, autorización, limitación de tarifas, aceleraciones y versiones de API que mejorará la calidad de nuestros servicios.
Podemos usar servicios como Amazon API Gateway o Azure API Gateway para este caso de uso.
Identificar y resolver cuellos de botella
Identifiquemos y resuelvemos cuellos de botella, como puntos de falla individuales en nuestro diseño:
- “¿Qué pasa si uno de nuestros servicios se bloquea?”
- “¿Cómo distribuiremos nuestro tráfico entre nuestros componentes??”
- “¿Cómo podemos reducir la carga en nuestra base de datos??”
- “Cómo mejorar la disponibilidad de nuestro caché?”
- “No sería API Gateway un solo punto de falla?”
- “¿Cómo podemos hacer que nuestro sistema de notificación sea más robusto?”
- “¿Cómo podemos reducir los costos de almacenamiento de medios”?
- “¿El servicio de chat tiene demasiada responsabilidad?”
Para que nuestro sistema sea más resistente, podemos hacer lo siguiente:
- Ejecutar múltiples instancias de cada uno de nuestros servicios.
- Introducción de equilibradores de carga entre clientes, servidores, bases de datos y servidores de caché.
- Uso de réplicas de lectura múltiples para nuestras bases de datos.
- Múltiples instancias y réplicas para nuestro caché distribuido.
- Podemos tener una réplica de espera de nuestra puerta de enlace API.
- Exactamente una vez que la entrega y el pedido de mensajes son desafiantes en un sistema distribuido, podemos usar un corredor de mensajes dedicado como Apache Kafka o Nats para que nuestro sistema de notificación sea más robusto.
- Podemos agregar capacidades de procesamiento de medios y compresión al servicio de medios para comprimir archivos grandes similares a WhatsApp que ahorrará mucho espacio de almacenamiento y reducirá el costo.
- Podemos crear un servicio grupal separado del servicio de chat para desacoplarse aún más nuestros servicios.
Este artículo es parte de mi curso de diseño del sistema de código abierto disponible en Github.
KaranPratapsingh / System-Diseño
Aprenda a diseñar sistemas a escala y prepararse para las entrevistas de diseño del sistema
Curso de diseño del sistema
Oye, bienvenido al curso. Espero que este curso proporcione una excelente experiencia de aprendizaje.
Este curso también está disponible en mi sitio web y como un libro electrónico sobre LeanPub. Deje una ⭐ como motivación si esto fue útil!
Tabla de contenido
- Empezando
- ¿Qué es el diseño del sistema??
- IP
- Modelo OSI
- TCP y UDP
- Sistema de nombres de dominio (DNS)
- Balanceo de carga
- Agrupación
- Almacenamiento en caché
- Red de entrega de contenido (CDN)
- Apoderado
- Disponibilidad
- Escalabilidad
- Almacenamiento
- Bases de datos y dbms
- Bases de datos SQL
- Bases de datos NoSQL
- Bases de datos SQL vs nosql
- Replicación de la base de datos
- Índices
- Normalización y desnormalización
- Modelos de consistencia ácido y base
- Teorema de la tapa
- Teorema de Pacelc
- Actas
- Transacciones distribuidas
- Fragmento
- Hashing consistente
- Federación de bases de datos
- Arquitectura de nivel N
- Corredores de mensajes
- Colas de mensajes
- Publicar
- Enterprise Service Bus (ESB)
- Monolitos y microservicios
- Arquitectura basada en eventos (EDA)
- Abastecimiento de eventos
- Segregación de responsabilidad de comando y consulta (CQRS)
- Puerta de enlace de la API
- REST, GRAPHQL, GRPC
- Largas encuestas, websockets, eventos de servidor (SSE)