Спасибо всем, кто дал полезные советы по существу вопроса. Ещё раз кратко. Имеется микросервис хранения картинок, который нужно масштабировать.
Решение получилось следующим. Микросервис поднимается на нескольких серверах:
s1.site.ru
s2.site.ru
s3.site.ru
Также поднимается nginx-балансировщик s.site.ru:
# Список серверов для балансировки запросов на запись (upload).
upstream storage_backend {
server s1.site.ru:80;
server s2.site.ru:80;
server s3.site.ru:80;
}
# Определение локации сервера для запросов на запись и удаление файла. Опция default нужна
# только для того, чтобы в случае неопределённого запроса получить 404, а не 500.
map $uri $storage_location {
"~/(storage|delete)/s1-" "s1.site.ru:80";
"~/(storage|delete)/s2-" "s2.site.ru:80";
"~/(storage|delete)/s3-" "s3.site.ru:80";
default "s1.site.ru:80";
}
server {
listen 80;
server_name s.site.ru;
location / {
proxy_pass http://$storage_location;
}
location /upload/ {
proxy_pass http://storage_backend;
}
}
В блоке map часть паттерна "s1...s2...s3" - это префикс имени файла, который формируется и возвращается сервером, выполнившим запрос на запись. Т.е. сервер, записывающий файл, цепляет к имени префикс, по которому затем в этом блоке можно будет однозначно определить локацию. Это добавляет лишних хлопот при добавлении нового сервиса в пул: нужно "ручками" назначить ему этот префикс так, чтобы он был уникальным. Есть в этом какая-то неровность, но я не знаю в данный момент способа это обойти.
В итоге при поступлении запросов на запись, типа POST
s.site.ru/upload балансировщик выбирает очередной сервер из storage_backend, а при запросах на получение по uri определяет локацию по $storage_location.
Ну и ssl прикручивается только к балансировщику, стандартно.
Сделал небольшой тестовый пул локально, всё работает. Буду пробовать на реальном железе.