Rick Reed aquí habla sobre algunas de las cosas que su equipo hizo para escalar su aplicación: Rick Reed, ingeniero de software de WhatsApp.
El resto de la respuesta es mi suposición sobre lo que una versión ingenua de WhatsApp podría hacer para implementar sus características. WhatsApp o la mayoría de las otras aplicaciones de mensajería rara vez funcionan de igual a igual. Por lo tanto, no abriría una conexión (desde su dispositivo) a cada uno de los dispositivos de sus amigos. En cambio, su dispositivo se conecta a su servidor. Luego podría usar un protocolo TCP personalizado o quizás HTTP para comunicar sus mensajes al servidor. El servidor a cambio los enviaría a los dispositivos de tus amigos. Si su amigo tenía su aplicación abierta o al menos el proceso de la aplicación en ejecución podría haber una conexión en vivo con el servidor. WhatsApp usará esa conexión para enviarles sus mensajes. Si su aplicación está “fuera de línea”, podrían optar por enviarles una notificación automática.
WhatsApp ha elegido Erlang, un lenguaje creado para escribir aplicaciones escalables que están diseñadas para soportar errores. Erlang usa una abstracción llamada modelo de actor por su concurrencia: http://en.wikipedia.org/wiki/Act…. En lugar del enfoque de memoria compartida más tradicional, los actores se comunican enviándose mensajes entre sí. Los actores, a diferencia de los hilos, están diseñados para ser livianos. Los actores pueden estar en la misma máquina o en máquinas diferentes y el mensaje que pasa abstracciones funciona para ambos. Una implementación simple de WhatsApp podría ser:
Cada usuario / dispositivo está representado como un actor. Este actor es responsable de manejar la bandeja de entrada del usuario, cómo se serializa en el disco, los mensajes que envía el usuario y los mensajes que recibe el usuario. Supongamos que Alice y Bob son amigos en WhatsApp. Entonces hay un actor de Alice y un actor de Bob.
Tracemos una serie de mensajes que fluyen de un lado a otro:
- Alice decide enviarle un mensaje a Bob. El teléfono de Alice establece una conexión con el servidor de WhatsApp y se establece que esta conexión es definitivamente del teléfono de Alice. Alice ahora envía a través de TCP el siguiente mensaje: “Para Bob: un monstruo gigante está atacando el puente Golden Gate “. Uno de los servidores front-end de WhatsApp deserializa este mensaje y lo entrega al actor llamado Alice.
- Alice, el actor, decide serializar esto y almacenarlo en un archivo llamado “Mensajes enviados de Alice”, almacenado en un sistema de archivos replicado para evitar la pérdida de datos debido a un alboroto de monstruos impredecible. Alice, el actor, decide enviar este mensaje a Bob, el actor, pasándole un mensaje ” Msg1 de Alice: un monstruo gigante está atacando el puente Golden Gate “. Alice, el actor, puede volver a intentarlo con un retroceso exponencial hasta que Bob, el actor, reconozca haber recibido el mensaje.
- Bob el actor finalmente recibe el mensaje de (2) y decide almacenar este mensaje en un archivo llamado “Bandeja de entrada de Bob”. Una vez que haya almacenado este mensaje de forma duradera, Bob el actor acusará recibo del mensaje enviándole a Alice el actor un mensaje propio diciendo “Recibí Msg1 “. Alice, el actor, ahora puede detener sus intentos de reintento. Bob, el actor, comprueba si el teléfono de Bob tiene una conexión activa con el servidor. Lo hace y Bob el actor transmite este mensaje al dispositivo a través de TCP.
- Bob ve este mensaje y responde con “Para Alice: creemos robots gigantes para luchar contra ellos “. Esto ahora lo recibe Bob el actor como se describe en el Paso 1. Bob el actor luego repite los Pasos 2 y 3 para asegurarse de que Alice finalmente reciba la idea que salvará a la humanidad.
WhatsApp en realidad usa el protocolo XMPP en lugar del protocolo ampliamente superior que describí anteriormente, pero entiendes el punto.
- ¿Cuál es la tarifa de consultoría por hora para un desarrollador de Android en el Área de la Bahía?
- ¿Cómo contrato a personas para desarrollar una aplicación de Android?
- ¿Cuáles son las principales empresas de desarrollo de aplicaciones de Android en Londres?
- ¿Qué aplicaciones te gustaría ver en Android portadas desde otras plataformas?
- ¿Android Studio viene con tutoriales?
Para su propia aplicación, cosas a tener en cuenta:
- Es posible que no tenga control sobre los clientes que envían coordenadas GPS al servidor cada 10 minutos. Si su cliente se está ejecutando en un dispositivo móvil, el sistema operativo podría decidir privarlo de los recursos o simplemente matar su proceso.
- Debe mantener el estado de los clientes que están conectados a su servidor para asegurarse de que puede enviar mensajes a clientes activos cuando se cumplan sus requisitos. Esta es una ligera modificación del ejemplo de la “aplicación Comet” que casi todos los framework tienen.
- Establecer una conexión TCP no es un gran desperdicio de recursos ni del lado del cliente ni del lado del servidor. Si el ecosistema de software de su servidor admite E / S sin bloqueo, el estado requerido por conexión es pequeño. Podrías soportar más de 100k conexiones en una caja mediocre si te esfuerzas mucho. Si estás en JVM Netty podría ayudarte aquí. Python tiene Twisted y Tornado. C ++ / C puede hacer uso de epoll, kqueue o select si está en un sistema * NIX. Golang admite una gran cantidad de conexiones a través de su biblioteca estándar. Aquí hemos abordado la escalabilidad vertical, es decir, cuántos usuarios podría admitir en una caja simple.
- Si realmente desea escalar y construir un sistema distribuido que mantenga el estado, puede considerar Erlang (con OTP) u otras implementaciones del modelo Actor, como Akka (JVM) que también admite mensajes remotos. Una combinación de fuente de eventos y una arquitectura de transmisión de mensajes podría proporcionarle toda la escalabilidad horizontal que necesita.