Веб-службы RESTful vs Socket Programming для интенсивного использования данных

Я создаю веб-приложение с Ruby on Rails, которое должно быть очень масштабируемым. В этом приложении данные производятся мобильным клиентом (приблизительно 20 байт) каждую секунду. Все эти данные должны быть переданы на сервер в какой-то момент, желательно как можно скорее.

Чтобы выполнить эту задачу, я хочу, чтобы сервер работал как служба RESTful. Клиент может буферизовать места (скажем, каждые 5-30 секунд), а затем снимать их как запрос HTTP-запроса, где сервер может их сохранить. Я считаю, что эта модель проще реализовать и лучше обрабатывает большой объем трафика, так как клиенты могут сохранять данные буферизации, пока не услышат ответ от сервера.

Мой босс, с другой стороны, хочет реализовать сервер, используя программирование сокетов. Он считает, что программирование сокетов приведет к уменьшению количества передаваемых данных, что увеличит общую эффективность системы. Я не могу не согласиться на этот вопрос, но я думаю, что с учетом современной пропускной способности дополнительные накладные расходы с HTTP стоит того. Плюс, я думаю, что попытка поддерживать тысячи (или миллионы) одновременных подключений к пользователям приведет к собственным проблемам и значительно увеличит сложность сервера.

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

Спасибо.

Обновление

Теперь у нас появилось несколько дополнительных требований. Во-первых, мобильный клиент не может загружать более 5 ГБ данных в месяц. В этом случае мы говорим одно сообщение в секунду по восемь часов в день в месяц. Во-вторых, мы хотим как можно меньше сочетать сообщения. Это делается для того, чтобы что-то случилось с мобильным клиентом (скажем, с автокатастрофой), мы теряем как можно меньше данных.

Ответ 1

Ваш босс, по-видимому, оптимизируется преждевременно, что на самом деле не очень хорошая идея.

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

Если дело доходит до этого, пусть ваш босс точно описывает, как он будет маршировать данные через его сокет-соединение, а затем выполнить некоторые быстрые вычисления, чтобы увидеть, можете ли вы сопоставить или побить их с помощью HTTP. Будет ли он использовать что-то вроде буферов протокола Google или написать собственный протокол маршалинга? Если да, то будет ли это самоописанием? Как насчет приложений "глаголов", как то, что вы получите бесплатно в HTTP? Будут ли его связи постоянными? Там гораздо больше "сокетов", чем просто открытие соединения и извержение байтов.

Вы также правильно отметили, что ваш босс, похоже, предпочитает сырую скорость сокетов по всему остальному: масштабируемость, ремонтопригодность, доступность инструментов для разработки и тестирования, снифферы протоколов, полезная семантика HTTPS-глаголов и т.д. HTTP хорошо понимается балансирами нагрузки и брандмауэрами и т.п. Ваш проприетарный протокол сокетов не будет таким удачным.

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

Ответ 2

Придерживайтесь HTTP.

Намного проще создать парк HTTP-серверов и поместить их за балансировщик нагрузки, чем попытаться сделать то же самое с вашим собственным протоколом. Зачем? Все уже существует для HTTP.

Update

Что вам нужно для переопределения:

  • Управление буфером (важно, если ваша загрузка высока)
  • Убедитесь, что вы получили целое сообщение (простой Receive/BeginReceive недостаточно)
  • Обработка асинхронных сокетов
  • Аутентификация
  • Балансировщик нагрузки (эта часть сложна, и вам нужно ее тщательно спроектировать).
  • Ваш собственный протокол (вам нужно определить, когда вы получили сообщение целиком)

Если вы используете ASP.NET MVC + JSON (шаги для merb или rails похожи):

  • Создайте новый веб-сайт
  • Активировать аутентификацию дайджеста в IIS
  • Создайте новый контроллер, пометьте его атрибутом [Authorize]
  • Добавить действие

Что самое дешевое? Сервер или вы потратили месяц на то, что уже было сделано?

Ответ 3

Ваш босс и вы оба правы, и правильный выбор зависит от бизнес-требований: как скоро вам придется масштабироваться.

Если вы запускаете новую услугу и боитесь, что не сможете управлять миллионами новых пользователей, которых у вас будет в течение 3 месяцев, тогда @Брайан-Келли прав - это преждевременная оптимизация. OTOH, если вы Twitter, и вы строите новый сервис на основе местоположения, тогда масштаб - это основная проблема, с которой вам следует иметь дело. Если вы где-то посередине, ну, это ваш бизнес - сделайте выбор.

Создание веб-сервиса RESTful с помощью Rails выполняется быстро и просто, а вызов его с мобильного клиента также прост (хотя для буферизации на стороне мобильного клиента требуется больше кода). Это основное (и только имхо) преимущество этого подхода в вашем случае - и это огромное преимущество.

Тем не менее, HTTP добавляет много накладных расходов. Если ваши сообщения длиной 20 байт, на самом деле в несколько раз больше накладных расходов, чем полезная нагрузка на сообщение. Это означает большую пропускную способность сети и больше времени процессора. Да, вы можете добавить больше серверов для его обработки, но это будет стоить вам - требуя нескольких серверов для выполнения работы, достигаемой одним.

Если ваша служба просто получает очень короткие сообщения от мобильных клиентов, и если это нормально, чтобы она потеряла случайное сообщение, я бы подумал об использовании UDP. Ваши 20 байтов должны помещаться внутри одного пакета. Это значительно экономит по сравнению с TCP несколькими обходами, чтобы сначала установить соединение, а затем отправить данные.

Еще одна вещь, о которой стоит помнить, когда вы считаете, что оптимизация в вашем случае преждевременна, - это мобильные клиенты: просто внести изменения на свой сервер, но нажав новую версию, которая использует более оптимизированный протокол обмена сообщениями для миллионов устройств, в поле 'не является тривиальным.

Обновить, после обновления к вопросу:

5 ГБ в месяц много. Сообщение каждую секунду в течение месяца означает 86 400 * 30 = ~ 2,6 М сообщений. Это позволяет вам тратить почти 2 К за сообщение. Не проблема, если ваша полезная нагрузка составляет ~ 20 байт...

Что касается вашего предпочтения, чтобы не объединять сообщения, чтобы не потерять какую-либо информацию, вам нужно спросить себя, сколько сообщений в порядке, чтобы проиграть. Может быть, целая минута слишком много, но 10 секунд не проблема? клиент, движущийся со скоростью 60 миль в час, будет двигаться только на 0,16 мили за 10 секунд.

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

Ответ 4

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

Вопрос в том, можете ли вы позволить себе время начинать с нуля, или HTTP достаточно хорошо для ваших нужд. Не зная подробностей о вашем приложении, я думаю, что трудно дать хороший совет.