Эволюция серверной архитектуры Python

задняя часть Python Архитектура

Эволюция серверной архитектуры Python

Jul 19 2018

До прихода в Tencent я 3 года работал над back-end разработкой бывшей компании, прошел процесс SaaS продукта от 0 до 10 (еще не до 100, хахаха). -конечная архитектура постепенно развивалась В процессе работы с микросервисами возникает все больше и больше проблем, которые вкратце описаны здесь.

Продукт представляет собой онлайн-сервис SaaS, обслуживающий человеческие ресурсы.Существует несколько клиентов апплета Web Android/iOS для управления персоналом, а серверная часть использует RESTful API для предоставления услуг.В основном используется язык Python, который удобен для быстрой итерации.

Эволюция архитектуры прошла 4 основных этапа: 1. MVC 2. Разделение сервисов 3. Микросервисная архитектура 4. Дизайн, управляемый доменом.

1. MVC

В начале проекта было не более 5 back-end коллег, основная работа на этом этапе заключалась в реализации прототипа продукта без особого рассмотрения архитектуры, для быстрой реализации функций использовался Django, после БД была разработана структура таблицы, функции были абстрагированы.Вид, потому что дизайн продукта также очень несовершенен, серверной части требуется много зарезервированного дизайна, чтобы избежать изменений во всей структуре таблицы, вызванных изменениями в логике продукта.Самое главное на этом этапе кода заключается в том, чтобы определить спецификацию кода, подходящую для команды, правила проверки кода.

Общая архитектура показана на рисунке выше.Nginx отвечает за балансировку нагрузки, распределение трафика между несколькими службами Django, логику обработки Django и передачу асинхронных задач Celery, а затем использование Redis для кэширования, когда объем данных относительно большой.Есть также уведомления о сообщениях в режиме реального времени.Необходимо использовать Nginx Push Module.

Проблема и метод оптимизации:

  1. У Django низкая производительность параллелизма.Используйте uWSGI Master+Worker с gevent и Ctrip для поддержки высокого параллелизма.
  2. Слишком много соединений Redis. Используйте пул соединений, который поставляется с redis-py, чтобы реализовать мультиплексирование соединений.
  3. Используется слишком много соединений MySQLdjorm-ext-poolМультиплексирование соединений пула соединений
  4. Celery настраивает gevent для поддержки одновременных задач

С развитием все большего количества функций приложений под Django становится все больше и больше, что вносит неудобства в публикацию.Каждый раз при выпуске версии приходится перезапускать все сервисы Django.Если есть проблема с публикацией, только Overtime И количество кода в рамках одного проекта Django также увеличивается, что не так просто поддерживать.

2. Разделение услуг

С ростом бэкенд-команды требования, предъявляемые к каждому коллеге, становятся все более детализированными.Если мы продолжим разрабатывать весь код в одном проекте, стоимость обслуживания будет слишком высока, а в нашей предыдущей архитектуре она была уже в Django. Приложения разделены по модулям, с высокой кластеризацией внутри приложения и низкой связью между приложениями, что облегчает разделение сервисов. Процесс разделения не вызвал слишком много проблем, и первоначальное разделение было просто кодом Разделение общий код извлекается для реализации общей библиотеки Python, база данных и Redis по-прежнему являются общими.По мере увеличения нагрузки база данных также имеет несколько экземпляров.

Как показано на рисунке выше, сервисы должны максимально избегать вызовов друг друга, а места, которые должны взаимодействовать, используются в виде http-запросов, а вызовы интрасети используют хосты для указания на адрес интрасети.

Проблема и метод оптимизации:

  • Nginx Push Module давно не поддерживается, а максимального количества длинных подключений не хватает, реализовано с помощью Tornado + ZeroMQtormqсервис для поддержки уведомлений о сообщениях

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

3. Микросервисная архитектура

Во-первых, это введение Kong API Gateway на основе OpenResty на уровне доступа и настройка подключаемых модулей, таких как аутентификация и ограничение тока.Уровень доступа берет на себя и удаляет общедоступную аутентификацию, ограничение тока и другие функции прикладного уровня. выпуск новых сервисов. В сценарии выпуска API-интерфейс администратора Kong вызывается для регистрации адреса сервиса в Kong, а для загрузки API требуется подключаемый модуль.

Для решения проблемы взаимных вызовов поддерживается инфраструктура службы RPC на основе gevent+msgpack.doge, с помощью etcd для управления сервисом, и реализует функции ограничения тока, высокой доступности и балансировки нагрузки на rpc-клиенте.

Выбор самой сложной технологии, API-шлюза с открытым исходным кодом, в основном с Golang и OpenResty (lua), для достижения на этом этапе, чтобы соответствовать потребностям нашего бизнеса, нам нужно выполнить настройку.На изучение OpenResty ушло на месяц раньше и Golang, а использование OpenResty реализует службу коротких URL-адресов.shorturlОн используется в бизнесе. Окончательный выбор Kong основан на удобстве выпуска Lua. Готовое использование Kong и разработка плагинов относительно просты. Соображения производительности не являются наиболее важными, чтобы поддерживать больше параллелизма, Он также использует сервис LB, предоставляемый облачной платформой, для распределения трафика на кластер, состоящий из серверов Kong 2. Конфигурация автоматически синхронизируется между кластерами.

Ele.me поддерживает структуру протокола бережливости, реализованную на чистом Python.thriftpy, и предоставляет множество вспомогательных инструментов.Если команда достаточно большая, этот набор RPC-решений действительно подходит, но наша команда недоукомплектована и уровень неравномерный, поэтому сложно продвигать этот набор дорогостоящих обучающих решений В конце концов, мы разработали Duboo-подобный RPC-фреймворк.doge, Код в основном относится к motan с открытым исходным кодом weibo.

4. Дизайн, ориентированный на домен

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

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

Суммировать

Дизайн архитектуры и выбор технологий не могут полностью следовать популярным технологиям, и в конечном итоге служить продуктам и потребностям клиентов.Из-за структуры команды и персонала в процессе проектирования существует множество компромиссов.Как найти компромисс Найти оптимальное решение – самая большая проблема.

Service Mesh, новое поколение микросервисной архитектуры, становится мейнстримом, хотя текущая работа не имеет ничего общего с микросервисами, она по-прежнему будет сосредоточена на обучении.