Откажитесь от Spring Cloud Gateway! Как финтех-приложение Huanbei использует Apache APISIX
Yeliang Wang
September 21, 2022
Любовь и ненависть к Java
Почему финансовые системы предпочитают Java
Java всегда была популярна и предпочитаема многими разработчиками с момента своего выпуска благодаря своим языковым преимуществам и огромной экосистеме.
За последние 15–20 лет многие финансовые системы выбрали Java в качестве своей основной технологической стеки. После некоторых исследований мы пришли к следующим преимуществам Java:

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

Во-первых, Java имеет слабую производительность; вы поймете, почему я так говорю, сравнив Java с технологическим стеком, связанным с C.
Во-вторых, Java работает на виртуальных машинах, и виртуальные машины занимаются управлением памятью Java. Поэтому Java становится менее конкурентоспособной, когда требуется высокая производительность или динамические изменения.
Кроме того, Java требует гораздо больше ресурсов. Фреймворк легко построить, не заботясь о стоимости. Однако, поскольку вычисления стали гораздо более детализированными и гранулированными в эпоху облачных технологий, ресурсы стали более ценными, чем когда-либо. Более того, Java потребовала бы огромных ресурсов для работы, поскольку она тяжелая и требует периодической перезагрузки. В результате Java столкнулась бы с проблемами при высоком спросе на QPS и непрерывность бизнеса.
Наконец, проблема указателей также заслуживает обсуждения. Указатель — это хороший ресурс для разработчиков, знакомых с C/C++. Однако Java работает на виртуальной машине, что означает, что управление памятью осуществляется GC (Garbage Collection), а не разработчиками. В этом случае производительность Java может быть недостаточной для некоторых ситуаций, когда есть строгие требования к высокой параллельности, трафику и производительности.
Почему HuanBei выбрал APISIX
Shuhe Group — это финансовая технологическая платформа, которая предоставляет эффективные и интеллектуальные услуги для компаний и частных лиц в бизнесе; у нее есть такие продукты, как HuanBei, EnjoyPay и другие. HuanBei — это платформа, которая предлагает услуги рассрочки, обслуживающие множество сценариев потребления. Работая с лицензированными финансовыми учреждениями, HuanBei также предоставляет услуги персональных кредитов и предлагает стартовые кредитные средства. HuanBei всегда использует технологический стек Java для разработки своих продуктов в бизнесе.
Spring Cloud Gateway — это шлюз, предназначенный для лучшего управления микросервисами в экосистеме Spring Cloud. Spring Cloud Gateway — это достойный API-шлюз для компаний, использующих Java в качестве основного языка разработки. Однако в последнем обновлении API-шлюза HuanBei отказался от долго используемого Spring Cloud Gateway и начал использовать Apache APISIX.
Архитектурные различия между Spring Cloud Gateway и APISIX
HuanBei использовал три различных системы API-шлюзов перед адаптацией APISIX. HuanBei использовал Spring Cloud Gateway в качестве шлюза для операционных и выходных систем и OpenResty в качестве шлюза для бизнес-систем.
HuanBei изначально использовал Spring Cloud Gateway в качестве шлюза для операционных и выходных систем из-за огромной экосистемы Spring Cloud Gateway и легкости развертывания и поддержки распределенной системы разработки. Чтобы быстро построить бизнес-модели, HuanBei использовал все услуги, предоставляемые Spring Cloud, когда была построена бизнес-основа.
С развитием бизнеса шлюз начал сталкиваться с некоторыми проблемами стабильности в оригинальной архитектуре, такими как переполнение памяти, высокая загрузка процессора и т.д. Поэтому HuanBei использует Apache APISIX в качестве единственного шлюза в архитектуре для улучшения производительности шлюза и единого управления несколькими шлюзами.
В новой архитектуре шлюза шлюз будет напрямую передавать трафик запросов в бизнес-систему через сервисное обнаружение. Однако, если backend-приложение не поддерживает сервисное обнаружение или не имеет здорового Pod в Consul, система перенаправит трафик на предыдущий внутренний K8s Ingress.
Практическое применение APISIX
HuanBei приходится изменять конфигурацию APISIX в реальных бизнес-сценариях, поскольку он не может напрямую использовать Apache APISIX из-за множества внутренних фреймворков шлюзов.
Сборка и развертывание APISIX
Во время внутренней разработки HuanBei разместил исходные коды шлюза APISIX и пользовательские коды в разных маршрутах и позволил им сотрудничать и итерироваться независимо. HuanBei использовал Docker-образ для развертывания шлюза. Сначала он создавал образ по умолчанию на основе определенной версии APISIX, а затем использовал пользовательские коды для обертывания его в новый образ.
Обертывание пользовательских кодов не использовало lua_package_path для указания каталога кодов; вместо этого оно напрямую перезаписывало образ по умолчанию apisix в каталоге исходных кодов, если существовал файл с тем же именем. Dockerfile показан ниже:
FROM registry.xxx.net:5001/apisix-shuhe:v1.5 ENV APP_NAME={{APP_NAME}} COPY {{PRODUCT_FILE}} /tmp/deploy2/artifact.tar.gz RUN mkdir /tmp/deploy/ && tar -xf /tmp/deploy2/artifact.tar.gz -C /tmp/deploy/ && \ cp -R /tmp/deploy/apisix/ /usr/local/apisix/ && \ cp /tmp/deploy/bin/apisix /usr/bin/apisix && \ cp /tmp/deploy/conf/apisix-$APP_NAME.yaml /usr/local/apisix/conf/apisix.yaml && \ cp /tmp/deploy/conf/config-$APP_NAME.yaml /usr/local/apisix/conf/config.yaml && \ set -x && \ bin='#! /usr/local/openresty/luajit/bin/luajit\npackage.path = "/usr/local/apisix/?.lua;" .. package.path' && \ sed -i "1s@.*@$bin@" /usr/bin/apisix && \ rm -rf /tmp/*
Логи APISIX хранятся локально (могут быть собраны через Syslog или другие плагины); мы можем изменить шаблон конфигурации NGINX и проверить используемый профиль, чтобы решить, хотим ли мы хранить логи локально или отправлять их в FLUENTD через Syslog. Также необходимо заменить переменную FLUENTD_HOST при сборке образов, как показано ниже:
{% **if** gw_profile and **string**.find( gw_profile,'local') then %} access_log logs/access.**log** main;error_log logs/ **error**.**log** warn; {%else%} access_log syslog:server=${FLUENTD_HOST}:5141 json_format; error_log syslog:server=${FLUENTD_HOST}:5142 warn; {%end%}
В шаблоне конфигурации NGINX HuanBei не только изменил хранение логов, но также добавил переменные окружения ENV и конфигурацию lua_shared_dicts в циклах и исправил некоторые параметры оптимизации NGINX.
HuanBei разделяет трафик на основе различных бизнес-потребностей и создает несколько шлюзов с похожими функциями. Поэтому HuanBei использует план "один исходный код, но несколько приложений шлюзов" внутри компании. Сначала HuanBei настраивает файл config-xxx.yaml каждого шлюза с помощью функции профиля, а затем может создавать Docker-образы разных шлюзов на основе имени приложения при сборке образов через платформу DevOps.
Корпоративные пользовательские плагины
При посещении операционной системы внутри компании система вызывает множество backend-API для получения данных, и эти API должны быть включены в белый список конфигурации API-шлюза. Система разрешений должна поддерживать связанный список API, поскольку страница будет предлагать разные диапазоны API в зависимости от роли каждого пользователя в операционной системе. Каждый раз, когда на странице появляется новый вызов API, разработчикам нужно дважды настраивать конфигурацию в шлюзе и системе разрешений, что избыточно и повторяется.
Чтобы достичь этого, HuanBei убирает барьер между конфигурацией шлюза и конфигурацией системы разрешений и оставляет только вход в систему разрешений. Система управления конфигурацией шлюза будет периодически получать API разрешений и затем преобразовывать их в конфигурацию белого списка API шлюза. Это действие устраняет одно ненужное действие пользовательской конфигурации и помогает системе разрешений осуществлять контроль доступа. Кроме того, это гарантирует, что backend-API, вызываемые на операционной странице, существуют в конфигурации системы разрешений.
В бизнес-сценариях всегда есть потребности, которые нативные плагины не могут удовлетворить, что требует пользовательской разработки. APISIX предоставляет множество инструментов, которые могут помочь легко настраивать нативные плагины. В следующей таблице перечислены некоторые пользовательские плагины, разработанные на основе APISIX внутри HuanBei:
| Плагин | Этап | Описание |
|---|---|---|
| gw-token-check | access_by_lua | Проверка токена, токен имеет специальные правила проверки |
| gw-limit-rate | access_by_lua | Ограничение скорости приоритетных запросов API |
| gw-request-decrypt | access_by_lua | Расшифровка запросов |
| gw-sign-check | access_by_lua | Проверка запросов |
| gw-mock-plugin | access_by_lua | Подключение к mock-платформе компании и перенаправление mock-API на mock-платформу, только для среды разработки и тестирования |
| gw-micro-env | rewrite_by_lua header_filter_by_lua | Поддержка микросервисной среды компании, только для среды разработки и тестирования |
| registry-plus | access_by_lua | Получение внешних уведомлений |
| serv-maintenance-check | access_by_lua | Закрытие режима технического обслуживания сайта |
| ingress-metric-rpt | log | Пользовательские отчеты метрик |
Канареечное развертывание шлюза
Ранее HuanBei использовал OpenShift в качестве своих контейнеров K8s (в настоящее время он обновился до кластера ACK), а Ingress был построен с использованием Haproxy.
Из-за того, что Haproxy Ingress в публичной сети K8s не мог разделить трафик одного домена на два разных маршрута в разных Namespace, нам нужно было рассмотреть развертывание нового шлюза в том же Namespace, что и старый шлюз. Другими словами, каждый маршрут домена будет иметь несколько сервисов, и мы можем контролировать трафик нового и старого шлюза, назначая разные доли общего трафика.
Фактический процесс реализации показан ниже, он добавляет группы c и d для развертывания нового шлюза в Namespace старого шлюза, и он может контролировать пропорцию трафика нового и старого шлюзов.
Факторы шлюза, связанные с Java
Многие Java-разработчики выбирают Spring Cloud в микросервисной архитектуре, поскольку Spring Cloud может поддерживать Java бесшовно и встраивает библиотеки классов в исходные коды. Однако на практике возникают сложности с обновлением. Например, если команде нужно поддерживать несколько библиотек классов, и есть 10 разных языков с 10 разными версиями, то этой команде нужно поддерживать 100 разных библиотек классов.
Сейчас мы можем легко использовать прокси (API-шлюз) для решения проблем с многовариантностью и многоязычностью. Какие преимущества получают компании, использующие технологический стек Java и выбирающие APISIX в качестве своего API-шлюза? Мы делаем выводы на основе двух аспектов из практического опыта HuanBei.
Для компании
1. Отличная функциональность и производительность
QPS APISIX может достигать 80k, если HuanBei использует 4-ядерные виртуальные машины без каких-либо плагинов для стресс-тестирования APISIX. Более того, APISIX идеально решает проблему производительности Spring Cloud Gateway при получении потребительского трафика, и его производительность улучшилась на 30% в производственной среде по сравнению с предыдущими шлюзами.
Кроме того, APISIX может удовлетворить все требования компании в реальных тестах, такие как аутентификация и идентификация, наблюдаемость, сервисное обнаружение, ограничение скорости и передача трафика на уровне 4 и 7. Что касается расширения функциональности, APISIX поддерживает более 70 плагинов, и большинство бизнесов могут использовать его нативные плагины, что значительно сокращает объем разработки.
2. Снижение бизнес-затрат
До использования APISIX компаниям приходилось увеличивать количество серверов для решения проблем с производительностью, что значительно увеличивало затраты на оборудование.
HuanBei подсчитал затраты и обнаружил, что стоимость серверов снизилась примерно на 60% после использования APISIX. Более того, после объединения технологического стека бизнес может быстро расширять различные функции на основе нативной архитектуры APISIX, снижать затраты на разработку и ускорять время выпуска продукта.
Для разработчиков
1. Удовлетворение бизнес-требований
Все программное обеспечение или технологии, используемые в бизнесе, должны служить потребностям. Однако, согласно результатам практических тестов и исследований, APISIX имеет лучшую стабильность, наблюдаемость и расширяемость.
Программное обеспечение предназначено для обслуживания бизнеса. Поэтому, если бизнес-требование может помочь компании сэкономить ресурсы, независимо от того, какой технологический стек использует эта компания, она также должна использовать компоненты, которые соответствуют компании.
2. Снижение затрат на обслуживание
По сравнению с ранее используемым OpenResty, APISIX имеет более низкую стоимость обучения и проще в обслуживании. В то же время, богатые плагины APISIX упрощают развертывание и разработку стандартных функций, сокращая время выпуска продукта.
Кроме того, мощные логи и функция динамической отладки APISIX помогают обнаруживать точки сбоя в бизнесе, что позволяет быстро локализовать ошибку и сэкономить время.
Заключение: Тенденции развития финансовой индустрии
На этапе бурного роста единственное, что имеет значение, — это эффективность. Поэтому руководители предпочитают использовать знакомый язык для построения системы и выбирают разные технологические стеки при выборе низкоуровневых фреймворков для быстрого запуска бизнес-моделей. Разные руководители выбирают разные технологические стеки, что вызывает множество будущих проблем. Однако большинство активных финансовых предприятий и компаний, предоставляющих финансовые услуги, сталкиваются с одной и той же технической проблемой: проблема множества технологических стеков. Когда эта проблема возникает, им нужно объединить свои технологические стеки в один.
Когда бизнес компании выходит на правильный путь, наступает время для вертикального разделения системы. Компания должна превратить свою архитектуру информационных силосов в трехслойную архитектуру, состоящую из фронтенда, мидленда и бэкенда. Затем, когда система стабильно работает, наступает время для компаний самостоятельно реализовывать низкоуровневые компоненты.
Конечная цель построения системы — это обмен. Система имеет более низкие затраты на обслуживание, если она имеет более высокую повторяемость. Поэтому, когда бизнес-операции стабилизируются, многие компании начинают вертикальное разделение или реализацию низкоуровневых фундаментальных компонентов для контроля затрат на обслуживание.
Для компаний затраты всегда являются самым важным принципом, который нужно учитывать. На этапе бурного роста компании просто нужно запустить и позволить бизнесу работать как можно быстрее. Однако в этой большой среде затраты должны иметь наивысший приоритет в рамках бюджета. В этом случае нам приходится выбирать между эффективностью и стоимостью. Поэтому компании не будут использовать передовые технологии, если бюджет ограничен. Точно так же технические специалисты не будут учитывать следующие вопросы при выборе технологического стека: Как эта новая технология повлияет на команду? Сколько преимуществ может принести эта новая технология текущей инфраструктуре?
Технические специалисты будут учитывать только затраты на эту новую технологию.