Я использую Spring-boot или Spring-Cloud Framework для разработки веб-приложения. Система будет в основном обрабатывать запросы HTTP Restful со стороны клиента, а затем сохранять их в базе данных MySQL.
Но я планирую сделать его более расширяемым. Он должен иметь возможность запускать больше экземпляров каждой службы и делать так, чтобы система могла обрабатывать больше входящих запросов.
Но я не уверен, что поступаю правильно, может ли кто-нибудь прийти и помочь мне проверить, разумен ли мой текущий подход, или поднять какие-либо потенциальные риски в моем подходе.
Что я делаю:
Служба A получает запросы в свой контроллер, а затем асинхронно записывает их в RocketMQ. RocketMQ используется для обрезки пика.
Затем служба B подписывается на тему RocketMQ, в которую служба A записывает сообщения, и кэширует сообщения в Redis в формате списка.
Служба C запускает поток демона, проверяющий номера сообщений в Redis. Если размер списка кеша достигает определенного значения, он извлечет все сообщения и сохранит их в MySQL, а затем сбросит кеш в Redis.
Ты сказал, что хочешь
make the system can handle more incoming requests.
разве это не зависит от машины?
Я думаю, что в вашем случае вам следует подумать о том, чтобы сделать ваши приложения масштабируемыми со всеми сервисами.
В облаке или создайте самостоятельно.
Как Кубернет. https://kubernetes.io/
Или KNative, построенный на Kubernetes. https://cloud.google.com/knative/
Также Amazon Web Services обеспечивает масштабируемость.
Спасибо за ответ, но здесь я хотел бы больше поговорить о проблемах на уровне системной архитектуры. У нас есть оборудование F5 для балансировки нагрузки. И сервисы будут развернуты в докере и могут автоматически масштабироваться.
Привет, масштабирование очень зависит от нагрузки, которую вы собираетесь обрабатывать:
Но вы можете обрабатывать несколько запросов, используя этот шаблон шины событий:
1) Служба A: опубликует сообщение в шине событий (тема/обмен)
2) Broker(ActiveMq/RabbitMq/etc..): перенаправит эти сообщения в очереди.
3) Сервис B: прослушивание из очереди и обновление записей в MySQL.
Несколько экземпляров нижестоящей службы (службы B) обеспечат масштабируемость по запросу (если нагрузка больше, разверните больше экземпляров, если нагрузка меньше, разверните меньше экземпляров).
Просто я могу разделить ваш вопрос на две подтемы.
But I plan to make it more expandable. It should be able to start more instance of each service and make the system can handle more incoming requests.
Чтобы сделать ваше приложение более отзывчивым на входящий запрос, вам необходимо
Если вы рассматриваете первый подход, вы можете просто ввести более мощное оборудование, оптимизировать использование протокола транспортного уровня или просто удалить ненужные этапы обработки (например, вместо использования шагов B и C вы можете просто ввести Kafka, как брокер сообщений, и надежно сохранять сообщения в нем). , Так что тогда вы можете удалить зависимость Redis)
Чтобы оптимизировать управление сетью и использование протоколов в вашей системе, обратитесь к книге Высокопроизводительная браузерная сеть.
Для масштабирования просто используйте Docker swarm или Kubernetes с учетом нагрузки. Самое главное, вы можете упростить свои зависимости в приложении для повышения производительности и простоты использования.
Благодарю за подробный ответ. Ваше мнение об использовании Kafka и его сохранении действительно открывает мне глаза.
Как всегда, решений одной проблемы может быть больше. Следующие предложения основаны на моей повседневной работе и опыте архитектора программного обеспечения.
Ваша система состоит из трех (микро) служб (A, B и C), брокера сообщений (RocketMQ), кеша (Redis) и базы данных (MySQL). В комментариях вы также упоминаете, что планируете запустить его на оборудовании F5 и Docker.
Служба A предоставляется во внешнем интерфейсе для обработки HTTP-запросов. Асинхронная обработка используется для управления нагрузкой, однако эффективность по-прежнему ограничена производительностью службы A. Поэтому Сервис А должен быть масштабируемым для включения более высокой пропускной способности. Производительность отдельного модуля должна быть оценена (взгляните на тестирование производительности, стресс-тестирование ...), чтобы определить масштабирование.
Чтобы включить автоматическое масштабирование контейнеров Docker, вам понадобится инструмент оркестровки (например, Kubernetes), который будет масштабировать вашу систему на основе настроенных показателей. Также подумайте о системных ресурсах, которые может использовать масштабируемая система.
Также сервисы B и C можно легко масштабировать. Оцените, можно ли объединить функции услуги B и услуги C в единая услуга. Вместо того, чтобы B просто помещал новые данные в Redis, он также мог бы хранить их в MySQL. Это зависит от того, насколько вам нужна фрагментация и как вы будете справляться с дополнительной сложностью, связанной с фрагментацией. B уже будет реагировать на опубликованный контент, в то время как служба C, похоже, постоянно объединяет кеш Redis для количества записей (это можно решить с помощью уведомлений о пространстве ключей).
Будьте осторожны, когда вы читаете данные из Redis, сохраняете их в MySQL и сбрасываете. Вы можете легко пропустить или сбросить некоторые данные, которые не были сохранены в MySQL, когда или если вы используете один ключ Redis для всех экземпляров служб, которые в него записываются.
При работе с асинхронной обработкой вы часто имеете дело с окончательная согласованность, что означает, что данные, которые обрабатывает служба A, не будут сразу доступны для других служб, которые могут захотеть прочитать их из MySQL (просто мысль для более широкой картины, важность варьируется от случая к случаю) .
Очень признателен за ваши любезные объяснения. Я использую распределенную блокировку на основе Redis для хранения и очистки кеша, поэтому только один процесс может получить доступ к кешу Redis за раз. Я также объединяю mirco-service B и C в один сервис, как вы предложили.
Пока вы а) используете Spring Boot и б) хотите масштабируемости... тогда подумайте о «микросервисах». Разделите ваше приложение на микросервисы, которые вы можете развернуть в контейнер (например, Docker), и позвольте Kubernetes (или его эквиваленту) справиться с «масштабируемостью». Просто мысль...