У Node отличная практика

Node.js Java внешний интерфейс koa

I. Обзор

21 апреля было отличное событие для первого «День развития Tonghua». Я поделился практическим опытом в прошлом году в узле в прошлом году. Но потому что время обмена ограничено, я могу поделиться только наиболее важным контентом и поделиться его, поэтому я потратил несколько часов в эти выходные, в сочетании с обменом и улучшением некоторых из них, написание этой статьи. Статья, я надеюсь, что я может дать вам новое вдохновение.

2. Итерация и эволюция базовой структуры Node.

1. От Коа до Астробоя

(1) Коа + промежуточное ПО

Самый ранний относительно законченный Node-проект Youzan — это система управления внутри компании, разработанная с использованием полного стека Node, в основном включающая систему управления персоналом для отдела кадров и приложение для небольших партнеров. Как и большинство компаний, наш первый проект Node также напрямую использовал Koa, а затем интегрировал промежуточное ПО с открытым исходным кодом, так что проект был быстро создан.

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

(2) Шаблон проекта строительных лесов

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

(3) Астробой 1.0

После большого количества проектов недостатки этого метода быстро обнаруживаются, потому что код шаблона и бизнес-код связаны вместе.Если вы хотите изменить код, сгенерированный шаблоном, вы можете только обновлять каждый проект вручную, и со временем by, становится все труднее и труднее синхронизироваться, а структура каталогов и стиль кода каждого проекта могут сильно различаться, поэтому,Очень важно разделить код фреймворка и бизнес-код.. Поэтому мы извлекли фреймворк под названием Astroboy на основе шаблона скаффолдинга.Этот фреймворк инкапсулирован на основе Koa.Таким образом каждый проект разрабатывается на основе этого фреймворка.Если фреймворк обновляется,Проекту также нужно только изменить номер версии нижнего фреймворка.

(4) Астробой 2.0

Многие проекты начали использовать Node, и появились новые проблемы, потому что бизнес-сценарии каждого продукта разные, и требования к фреймворку тоже разные. Например, для определенного промежуточного программного обеспечения оно может понадобиться продукту А, но продукту Б это промежуточное программное обеспечение может вообще не понадобиться, а фреймворк в настоящее время не поддерживает настройку. Итак, для фреймворка были поставлены новые задачи, поэтому в начале этого года был проведен крупный рефакторинг фреймворка.

На основе Astro Boy 1.0 эта реконструкция добавила много новых функций, в основном в том числе следующие:

  • На основе разработки Koa2, отличная производительность
  • Предоставляет возможность настройки верхней рамки на базе Astroboy
  • Расширяемый механизм плагинов
  • постепенное развитие

Во-первых, он предоставляет возможность настройки фреймворка верхнего уровня на основе Astroboy.Как показано на рисунке ниже, Youzan Base Framework — это самый простой фреймворк Node Web, настроенный на основе Astroboy.Этот уровень в основном объединяет некоторые из самых основных Веб-фреймворки Node.Services, такие как:

  • Доступ к системе Skynet, это лог и система мониторинга бизнеса внутри Youzan
  • Проверка работоспособности, система мониторинга эксплуатации и технического обслуживания будет проверять доступность системных служб каждые 5 секунд.
  • Для полноканального мониторинга для одного HTTP-запроса обычно вызывается несколько внутренних интерфейсов, и соответствующие внутренние интерфейсы также вызывают другие интерфейсы, поэтому весь процесс вызова фактически представляет собой древовидную структуру. Очень важно выяснить проблему узкого места в производительности, и весь мониторинг ссылок направлен на решение этой проблемы.
  • Доступ к сервисным вызовам Dubbo, для этого см. введение ниже.

После того, как у вас есть Youzan Base Framework, нам необходимо развивать на нем бизнес.Это делится на два бизнес-сценария: для какого-то простого и единичного бизнеса вы можете напрямую наследовать разработку Youzan Base Framework, а для какого-то сложного бизнеса вы можете сначала , на основе Youzan Base Framework мы настроили бизнес-фреймворк.Например, у Wezan изначально был огромный PHP-проект (мы назвали его Iron), затем после разделения сервиса Node взял на себя исходную PHP-часть, так что мы Новый первый настроил структуру бизнес-уровня под названием Iron Base Framework, а затем разделил ее на несколько подпроектов в соответствии с бизнес-модулями (транзакции, магазины, пользователи, маркетинг).

Второе — это поддержка плагинов, для этого смотрите описание плагинов ниже.

2. Несколько основных концепций фреймворка

Выше описан процесс итерации и эволюции базовой структуры Youzan Node.Следующее в основном представляет несколько основных концепций платформы Astro Boy 2.0.

(1) Заявка Заявка

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

(2) Рамочная структура

Фреймворк Astroboy инкапсулирован на основе Koa2.Что касается концепции фреймворка, то я не буду здесь слишком много вводить.

(3) Плагин Плагин

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

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

Так в чем же разница между плагином и обычным пакетом NPM?

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

Какую информацию может содержать плагин?

  • Метаданные плагина, включая имя плагина, версию, описание и т. д.;
  • Сервисы (Service), промежуточное ПО (Middleware) и библиотеки функций инструментов (Lib) и т. д.;
  • Расширения встроенных объектов Koa, включая контекст, приложение, запрос и ответ;

Управление плагинами

  • Чтобы установить плагин, используйте команду npm install, например: npm install [<@scope>/]@
  • Включить подключаемый модуль. После установки подключаемого модуля необходимо включить его, прежде чем он начнет действовать. Включить плагин тоже очень просто, нужно только настроить plugin.default.js.Если конфигурация плагина отличается в разных окружениях, нужно только модифицировать конфигурацию соответствующего * окружения (plugin.${env}.js ), где env означает переменные среды для среды выполнения Node, такие как: разработка, тестирование, производство и т. д. Как показано в следующем коде:
'astroboy-cookie': {
    enable: true,
    path: path.resolve(__dirname, '../plugins/astroboy-cookie')
}

Если для параметра enable установлено значение true, подключаемый модуль можно включить. Путь представляет собой абсолютный путь к подключаемому модулю. Обычно это подходит для подключаемых модулей, которые все еще находятся в быстрой итерации. Если подключаемый модуль уже является стабильным, вы можете упаковать и опубликовать подключаемый модуль. как пакет NPM. Затем объявите свой плагин через пакет, как показано в следующем коде:

'astroboy-cookie': {
    enable: true,
    package: 'astroboy-cookie'
}
  • Отключить плагины, отключить плагины еще проще, просто установите для параметра enable значение false .

3. Процесс доступа Node к сервисной системе Youzan

1. Почему сервис?

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

2. Выбор стека технологий

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

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

Итак, по истечении определенного периода времени мы начинаем делать разделение услуг, затем первым соображением является выбор базовой технологии, мы учитываем следующие моменты:

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

3. После разделения службы, каковы обязанности каждого уровня?

Для уровня Node наше позиционирование — это очень тонкий средний слой. Уровень Node не слишком много занимается бизнес-логикой. Вся бизнес-логика передается Java. Он отвечает только за следующие три вещи:

  • Рендеринг шаблона: Рендеринг шаблона относится к рендерингу HTML-шаблонов;
  • Бизнес-оркестровка: для немного более сложной страницы обычно необходимо агрегировать данные, возвращаемые несколькими интерфейсами, для отображения полной страницы, поэтому в этом случае Node необходимо агрегировать результаты, возвращаемые несколькими интерфейсами, а затем объединять объединенные данные. Вернитесь на переднюю часть.
  • Переадресация интерфейса: службы Java не доступны напрямую в общедоступной сети для внешнего использования, поэтому в этом случае Node должен взять на себя роль переадресации интерфейса.

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

4. Как Node вызывает интерфейсы Java?

Затем, после разделения службы, первая проблема, которую нужно решить, это: как Node вызывает интерфейс, предоставляемый Java. Прежде всего, мы думаем о методе HTTP.Позвольте мне объяснить здесь, что инфраструктура распределенных служб, принятая в нашей компании, — это инфраструктура Dubbo с открытым исходным кодом от Alibaba, а сама инфраструктура Dubbo поддерживает создание Restful API путем добавления аннотаций. Поэтому на начальном этапе Мы используем это готовое решение.

С увеличением числа применений постепенно стали проявляться недостатки этого метода, в основном в следующих моментах:

  • Если интерфейс должен быть открыт для Node, дополнительные аннотации необходимо добавить вручную.
  • Каждый раз, когда добавляется приложение, при эксплуатации и обслуживании необходимо настроить доменное имя для каждого приложения, а в разных средах необходимо настроить разные доменные имена.Поэтому по мере увеличения количества приложений управление доменными именами приложений становится все более и более сложно поддерживать.
  • Соответственно, node также должен поддерживать очень длинный файл конфигурации доменного имени.
  • Поскольку Java напрямую предоставляет интерфейс HTTP, производительность будет ниже, чем у метода RPC.

Итак, мы исследовали, как Node вызывает Java, когда другие компании используют платформу Dubbo? Как показано ниже:

Во-первых, когда служба приложения Java запускается, она регистрирует службу в реестре служб.Реестр служб здесь может быть ETCD или Zookeeper.Затем, когда приложение Node запускается, оно сначала извлекает список служб из реестра служб, а затем Node.Длинный TCP-канал будет установлен со службой Java.Кроме того, Node также должен отвечать за анализ протокола Hession и балансировку нагрузки.

Нетрудно обнаружить, что обязанности Node таким образом тяжелее, и требования к разработке Node будут очень высокими. Поэтому мы улучшили этот метод, как показано на следующем рисунке:

Мы добавили слой промежуточного прокси-слоя Tether между Node и Java. Tether — это локальный прокси-сервер, написанный на языке Go. Tether будет предоставлять HTTP-сервис для внешнего мира. Для Node нам нужно только вызвать локальный сервис через HTTP. то есть обнаружение других сервисов, анализ протоколов, балансировка нагрузки, создание и обслуживание длинных цепей — все это обрабатывается Tether. Таким образом, уровень Node очень легковесный Затем, наконец, как Node вызывает службы Java? Как показано в следующем коде:

const Service = require('../base/BaseService');

class GoodsService extends Service {
  /**
   * 根据商品 alias 获取商品详情
   * @param  {String} alias 商品 alias
   */
  async getGoodsDetailByAlias(alias) {
    const result = this.invoke(
      'com.youzan.ic.service.GoodsService',
      'getGoodsDetailByAlias',
      [alias]
    );
    return result;
  }
}
module.exports = GoodsService;

Для Node при вызове службы Java необходимо обращать внимание только на три момента:

  • Имя службы: имя службы состоит из имени пакета Java + имени класса, например com.youzan.ic.service.GoodsService выше.
  • Имя метода: метод, предоставляемый классом Java, например метод getGoodsDetailByAlias, показанный в приведенном выше коде, для запроса сведений о продукте в соответствии с псевдонимом продукта.
  • Параметры: Параметр — это список параметров, передаваемых в Java.

Наконец, резюмируем преимущества этого метода:

  • Первый из них прост в использовании и очень удобен для фронтенд-разработки, просто вызовите локальную службу Tether через HTTP;
  • Во-вторых, низкая стоимость многоязычного доступа.Если есть другие языки (Python, Ruby) на более позднем этапе, им также необходимо получить доступ ко всей сервисной системе.Как и Node, им нужно только вызвать HTTP-сервис выставляется местным Tether.Дополнительные затраты на разработку.
  • В-третьих, на более позднем этапе удобнее оптимизировать уровень протокола, так как Tether фактически является прокси-сервером.Если вам нужно оптимизировать производительность уровня протокола на более позднем этапе, вам нужно только оптимизировать Производительность Tether.

Итак, увидев это, некоторые люди могут подумать, здесь Node также вызывает Java через HTTP, есть ли проблема с производительностью? Итак, здесь мы делаем некоторые оптимизации, как показано в следующем коде:

const Agent = require('agentkeepalive');

module.exports = new Agent({
  maxSockets: 100,
  maxFreeSockets: 10,
  timeout: 60000,
  freeSocketKeepAliveTimeout: 30000,
});

Здесь мы имеем в виду пакет agentkeepalive. В первые дни существования HTTP для каждого HTTP-запроса требовалось открытие соединения TCP Socket, а соединение TCP разрывалось после одного использования. Использование keep-alive может улучшить это состояние, т. е. то есть в TCP несколько копий данных могут непрерывно отправляться во время соединения без отключения. Таким образом, используя механизм поддержания активности, вы можете уменьшить количество установленных TCP-соединений.

4. Ссылки

https://github.com/apache/incubator-dubbo https://github.com/QianmiOpen/dubbo2.js https://github.com/QianmiOpen/dubbo-node-client https://github.com/p412726700/node-zookeeper-dubbo https://zh.wikipedia.org/wiki/HTTP%E6%8C%81%E4%B9%85%E8%BF%9E%E6%8E%A5