• Как работают современные мессенджеры?

    EvgenyMamonov
    @EvgenyMamonov
    Senior software developer, system architect
    как сервер за столь короткое время умеет прошерстить базу данных, найти сообщения конкретного пользователя и отдать их

    Я бы делал немного иначе, например пользователь отправляет сообщение, которое принимает сервер.
    В случае, если получатель сообщения также подключен - сервер параллельно доставляет получателю сообщение, за счёт этого имеем быструю доставку сообщений, и параллельно сохраняет сообщение в базу.

    Что касается быстрой загрузки истории сообщений - то тут нужно сохранять сообщения таким образом, чтобы сообщения одного пользователя всегда были на одном и том же сервере (если используется шардинг). Тогда обычный SELECT из базы по user_id будет вполне себе быстро работать даже на огромной базе. Также таблицы можно еще партицировать, чтобы еще быстрее загружать последние сообщения в истории.

    Что касается безопасности, если не использовать e2e шифрование, как вариант, можно использовать обычные RSA ключи. Например на сервере генерируем два ключа, открытый отправляем кленту, он шифрует им сообщение и передает сообщение на сервер. Вы на сервере его расшифровываете при помощи закрытого ключа. Для отправки сообщения клиенту, можно сделать тоже самое. Клиент также генерирует два RSA ключа и открытый ключ отправляет серверу. Когда серверу нужно доставить сообщение клиенту, он шифрует сообщение открытым ключём, который ему высылал клиент и отправляет ему.

    Мне тоже интересно узнать другие варианты решения этой задачи, буду следить за этой темой :)

    Хорошее дополнение по хранению сообщения и организации поиска от Ильи
    Распределение нагрузки решается шардингом — получается много небольших БД вместо одной огромной. Скорее всего каждое сообщение разбивается по словам/частям слов и сохраняется в поисковый индекс типа слово—message_id и такой индекс строится для каждого пользователя и тоже шардируется. При поиске сначала получаем идентификаторы подходящих сообщений из поискового индекса, потом выгружаем сообщения из БД с сообщениями.

    Дополнение от Stalker_RED
    только не "сообщения одного пользователя всегда были на одном и том же сервере" а сообщения из одного чата/канала/группы (включая чаты, в котором всего два участника). То-же самое касается построения индекса.
    Ответ написан
    7 комментариев
  • Как работает websocket на низком уровне?

    bingo347
    @bingo347
    Crazy on performance...
    Вопрос 1
    Браузер инициирует новое tcp соединение на тот же 80 порт сервера или бывают случаи что на другой ?
    WebSocket работает не поверх голого tcp, а поверх http (а тот уже поверх tcp или tls -> tcp). 80 порт стандартный для http, а 443 - для https (http поверх tls). WebSocket по умолчанию использует те же 80 и 443 порты для ws и wss протоколов соответственно. Но никто не мешает использовать кастомный порт. Конкретные порты для конкретных протоколов - это не более соглашения. Порты работают на IP уровне, который ничего не знает о прикладном уровне.

    Вопрос 2
    Что сервер делает с ws пакетами - проксирует их к СП как есть в обертке, или же обертку раскрывает и передает "чистые/сырые" данные далее ?
    Если речь идет о nginx как о реверси прокси, то для него это обычный http запрос, просто клиент очень долго шлет тело запроса, а сервер тело ответа (главное таймауты тут выключить). Так как http в принципе не запрещает серверу начать слать ответ не закончив чтение запроса, все вполне прекрасно работает.

    Вопрос 3
    Как сервер отличает ws от http - по некой сигнатуре - типа по последовательности первых пришедших байт, по которым можно распознать что это именно ws а не http ?
    По http заголовкам. В частности клиент шлет заголовок upgrade в котором говорит, что хочет WebSocket и еще несколько специфичных для WebSocket заголовков, а сервер отвечает статусом 101 и своим набором заголовков. Это и есть WebSocket рукопожатие. Само общение происходит уже в теле запроса и теле ответа.

    Вопрос 4
    Как эти данные передаются в сторону СП - через переменные окружения, или через unix-socket или через tcp стек?
    Если используя последние два варианта, то получается что сервер держит внутри системы соединения с СП до тех пор пока "наружное" tcp соединение между клиентом и сервером не буде закрыто?
    На уровне tcp вообще пофиг сколько времени открыто соединение, какая из сторон в какой последовательности и сколько данных отправляет. Тут лишь то, что клиент может попробовать открыть соединение, сервер его может принять (или отклонить), а после любая из сторон может слать данные другой или закрыть соединение. Ну и плюс есть гарантии, что потерянные данные будут отправлены повторно и порядок получения совпадет с порядком отправки. На уровне http у нас обычный запрос-ответ, просто клиент слишком долго шлет тело запроса, а сервер - тело ответа. На уровне WebSocket у нас в обе стороны ходят MessageFrame'ы, содержащие данные + метаданные и имеющие четкие границы.

    Вопрос 5
    В свою очередь СП это отдельный unix процесс отличный от основного бекенд приложения, которое работает по принципу "спросили - запустился - обработал - сформировал ответ - отправил - завершился" Или же это все то же бекенд приложение только в том случае если с ним установлено ws-соединение, оно не прекращает свою работу?
    Как реализуете, так и будет. Но одно можно сказать точно, соединение должно быть открытым на протяжении всего сеанса обмена сообщениями.
    Важно еще понимать, что в контексте WebSocket нет понятий запрос и ответ (хотя их могут реализовывать нижележащие протоколы), есть лишь понятие сообщение. Каждая из сторон, пока открыто соединение, может в любой момент времени отправлять любое количество сообщений.

    P.S. если обе стороны (и клиент и сервер) не ограничены только http протоколом для общения через tcp (как например это происходит у браузерных приложений), то WebSocket будет лишней нагрузкой как на сеть, так и на вычисления. Лучше взять какой-нибудь бинарный сериализатор, с четкими границами (msgpack, flatbuffer) и гонять данные по raw tcp или tls.
    Ответ написан
    2 комментария
  • Разработчик недисциплинированно трекает время. Что делать?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    А зачем вообще трекать время? Уложился в дедлайн - молодец. Не уложился - разбор полётов. Хронически не укладывается - понижение грейда или увольнение.
    Ответ написан
    21 комментарий
  • Как вы разрабатываете свои приложения?

    Robur
    @Robur
    Знаю больше чем это необходимо
    Я тут предполагаю что вы хотите сделать какой-то стоящий продукт, который кому-то нужен:

    Вас посетила очередная идея на миллиард. Вы полны решимости осуществить проект, но пока, кроме абстрактной идеи, ничего нет. Ваши действия?

    Перевернуться на другой бок и спать дальше. Асбтрактная идея на миллиард ничего не стоит, даже 10 минут времени. Сотня абстракных идей - это просто в сто раз больше потраченного в пустую времени.

    Если сильно верите в какую-то идею, для начала - валидируете.

    понимаешь, что нихрена не понимаешь - нет представления, какие элементы на самом деле должны быть на данной странице.

    Тут вы почти уловили суть. Ваша "идея" вам должна говорить, какие элементы нужны, зачем они нужны и почему именно их надо делать прямо вот сейчас а не что-то другое. Пока этого нет - у вас не идея а какая-то смутная фантазия, вы не знаете что делаете, и вряд ли что-то сделаете.

    Изучите все что сможете насчет построения продукта. Подходов много, информации тоже.
    проблема в том что это совершенно другая область, вы там новичок и ноль без палочки, сил нужно приложить немало и если вам оно не интересно, то мозг будет активно сопротивляться. Постояно будет соблазн вместо этого взять и запилить какой-нибудь код, придумать кнопочки, накидать тасок в трелло - это просто и понятно.

    Тут вариантов два - найти кофаундера который будет двигать эту сторону, а себе оставить реализацию, либо пересилить себя и научиться нужным скиллам.
    Ответ написан
    2 комментария
  • Что почитать/посмотреть про дизайн для разработчика?

    ArsenyMatytsyn
    @ArsenyMatytsyn
    Руководитель frontend направления, предприниматель
    Dribble. Интерфейсы в целом вау, но обычно просто красивое гавно. Тем не менее некоторые фишки высмотреть можно.

    Если много серьезнее настроен, посмотри в сторону неумирающей классики: Алан Купер. Что-то пoнoвee — библиотеку Горбунова. У них специфичный взгляд, я лично не со всем согласен и подход местами дурацкий, но скорее всего то, что ты ищешь.

    Ну а в целом, если ты прямо на серьязняке, не лезь в то, в чем не разбираешься и не можешь посвятить годы, найми дизайнера. Найми, ибо бестолковых полно, а толковый не будет делится знаниями просто так. Как понять, что это хороший дизайнер? Он попытается тебя убить)
    Ответ написан
    Комментировать
  • Какую книгу по go выбрать?

    @JekaMas
    Я бы предложил легкую вводную книгу www.golangbootcamp.com
    Затем более глубокую www.amazon.com/Programming-Language-Addison-Wesley...
    Отдельно советую по БД и Golang: https://www.vividcortex.com/resources/the-ultimate...
    И по concurrency (но эту книгу стоит с осторожностью) - www.amazon.com/Mastering-Concurrency-Go-Nathan-Koz...
    И две обязательные к прочтению
    devs.cloudimmunity.com/gotchas-and-common-mistakes... - на удивление эти ошибки 90% разработчиков делают. Практически настольное пособие.
    golang.org/doc/effective_go.html - стандарт, что тут добавить.

    Про интерфейсы тут - https://habrahabr.ru/post/276981/
    Про то, как работает конкурентность в Go(а по сути runtime) - https://habrahabr.ru/company/ua-hosting/blog/269271/

    Что хорошо - большая часть этих ресурсов полностью бесплатны.
    Ответ написан
    1 комментарий