Традиционная структура программного стека онлайн -приложений Taobao - Nginx + Velocity + Java, то есть::
В этой системе Nginx направляет запрос в приложение Java, которое обрабатывает транзакцию и передает данные на последнюю страницу, используя шаблон скорости.
После введения node.js мы неизбежно столкнемся с следующими проблемами:
Как разработать структуру топологии технологического стека и как выбрать метод развертывания, считается ли он научным и разумным? После завершения проекта, как разделить трафик, что удобно и быстро для эксплуатации и технического обслуживания? При столкновении с проблемами в Интернете, как устранить опасность как можно скорее и избежать больших потерь? Как обеспечить здоровье приложения и управлять им на уровне планирования балансировки нагрузки? Топология системы
Согласно нашему мышлению и практике при разделении передних и задних концов (ii) - на основе изучения шаблонов передних и задних концов, скорость должна быть заменена на node.js, чтобы эта структура становилась:
Это, конечно, идеальная цель. Тем не менее, первое введение слоя node.js в традиционном стеке - это новая попытка. Чтобы быть в безопасности, мы решили включить только новые технологии на странице фаворитов (shoucang.taobao.com/item_collect.htm) наших фаворитов, в то время как другие страницы продолжают использовать традиционные решения. То есть Nginx определяет тип страницы запроса и определяет, должен ли запрос быть направлен на node.js или java. Итак, окончательная структура стала:
План развертывания
Вышеуказанная структура, кажется, в порядке, но на самом деле новая проблема все еще ждет фронта. В традиционной структуре Nginx и Java развернуты на одном и том же сервере. Nginx слушает порт 80 и общается с Java, прослушивая порт 7001 в высоком бите. Теперь, когда введен Node.js, необходим новый процесс для запуска порта прослушивания. Должны ли Node.js быть развернуты на той же машине с Nginx + Java или Node.js быть развернуты на отдельном кластере?
Давайте сравним характеристики двух методов:
Фавориты Taobao - это приложение с ежедневным PV десятков миллионов, что имеет чрезвычайно высокие требования к стабильности (на самом деле, нестабильность любого продукта в Интернете недопустима). Если вы принимаете одно и то же решение для развертывания кластера, вам нужно распространять файлы только один раз и перезагрузиться дважды, чтобы завершить релиз. В случае, если вам нужно откатиться, вам нужно работать только один раз. С точки зрения производительности, одно и то же кластерное развертывание также имеет некоторые теоретические преимущества (хотя пропускная способность переключения и задержка интрасети очень оптимистична). Что касается отношений от одного до одного или от многих к одному, то теоретически она может быть более полно использоваться сервером, но по сравнению с требованиями к стабильности, этот момент не так срочно решает. Таким образом, в преобразовании фаворитов мы выбрали одно и то же решение для развертывания кластера.
Серого
Чтобы обеспечить максимальную стабильность, это преобразование не полностью удалило код скорости полностью. В кластере приложений около 100 серверов. Мы используем сервер как гранулярность и постепенно вводим трафик. Другими словами, хотя процессы Java + node.js работают на всех серверах, существуют ли соответствующие правила пересылки на Nginx, определяет, будет ли запрос на получение коллекции ребенка на этом сервере обрабатываться через node.js. Конфигурация Nginx:
location = "/tem_collect.htm" {proxy_pass http://127.0.0.1:6001; # Node.js процесс прослушивания}Только серверы, которые добавили это правило nginx, позволят node.js обрабатывать соответствующий запрос. Благодаря конфигурации NGINX он очень удобен и быстро увеличивает и уменьшает трафик серого, а стоимость очень низкая. Если вы столкнетесь с проблемами, вы можете напрямую отбросить конфигурацию Nginx и мгновенно вернуться к традиционной структуре стека технологий, чтобы снять опасность.
Когда мы впервые выпустили, мы включили это правило только на двух серверах, что означает, что менее 2% онлайн -трафика обрабатываются в node.js, а запросы на оставшийся трафик все еще отображаются по скорости. В будущем трафик будет постепенно увеличиваться в зависимости от ситуации, и, наконец, на третьей неделе все серверы будут включены. На этом этапе страницы сбора продуктов со 100% трафиком в производственной среде отображаются node.js (вы можете проверить исходный код для поиска ключевого слова node.js).
изменять
Процесс серого не гладкий. Прежде чем разрезать поток полностью, я столкнулся с некоторыми проблемами, большими или маленькими. Большая часть бизнеса связана с конкретным бизнесом, и то, что стоит узнать, - это ловушка, связанная с техническими деталями.
Проверка здоровья
В традиционной архитектуре система планирования балансировки нагрузки будет инициировать запрос get каждую секунду к конкретному URL -адресу на порту 80 каждого сервера и определит, работает ли сервер нормально на основе того, является ли возвращаемый код состояния HTTP 200 . Если время ожидания после 1S запрашивается или код состояния HTTP не составляет 200 , на сервере нет трафика, чтобы избежать онлайн -проблем.
Путь к этому запросу -nginx -> java -> nginx, что означает, что до возврата 200 , Nginx и Java этого сервера находятся в здоровом состоянии. После введения node.js этот путь становится nginx -> node.js -> java -> node.js -> nginx. Соответствующий код:
var http = require ('http'); app.get ('/status.taobao', function (req, res) {http.get ({host: '127.1', port: 7001, path: '/status.taobao'}, function (res) {res.send (res.statuscode);}). On ('error', function (err) {loger.error.error. });Однако во время процесса тестирования было обнаружено, что когда Node.js продвигает такие запросы, потребовалось несколько секунд или даже десяти секунд, чтобы получить возврат стороны Java раз в шесть или семь раз. Это приведет к тому, что система планирования балансировки нагрузки считает, что на сервере произошла аномалия, а затем отключите трафик, но на самом деле сервер может работать нормально. Это, очевидно, большая проблема.
После поиска я обнаружил, что по умолчанию node.js будет использовать класс HTTP Agent для создания HTTP -соединений. Этот класс реализует пул подключения к сокетам. Верхний предел по умолчанию количества подключений для каждой пары портов хоста + составляет 5. В то же время запросы, инициированные классом HTTP Agent включают Connection: Keep-Alive к по умолчанию, что приводит к тому, что возвращаемое соединение не будет выпущено во времени, и инициированные поздние запросы могут быть в очереди.
Есть три окончательных решения:
Отключить HTTP Agent , то есть добавить дополнительный agent: false при вызове метода get , а окончательный код - это:
var http = require ('http'); app.get ('/status.taobao', function (req, res) {http.get ({host: '127.1', порт: 7001, агент: false, path: '/status.taobao'}, function (res) {res.send (res.statuscode);}). res.send (404); Установите верхний предел глобального номера гнезда объектов http :
http.globalagent.maxsockets = 1000;
Когда запрос возвращается, он своевременно и активно отключен:
http.get (options, function (res) {}). On ("socket", function (socket) {socket.emit ("AgentRemove"); // Слушайте события сокета и диспетчерские события в обратном вызове});На практике мы выбрали первый метод. После этой корректировки не было обнаружено никаких других проблем в экзамене в области здравоохранения.
комбинировать
Практика объединения Node.js с традиционными бизнес -сценариями только началась, и все еще есть много точек оптимизации, которые стоит подробно изучить. Например, после того, как Java -приложения полностью централизованы, можете ли вы пройти тест развертывания кластера для улучшения использования сервера? Или могут ли методы выпуска и отката быть более гибкими и управляемыми? Все детали стоят дальнейших исследований.