Обновить
Комментарии 34

Зачем использовать для микросервисов то, что для них не очень подходит?

А что для них не подходит в данном случае?

Spring boot уже научился работать без встроенного tomcat? Если нет, то неподходит tomcat, так как он из старого мира монолитных приложений и тащит много лишнего.

В теории Spring Boot можно использовать без встроенного tomcat, но на практике лично я не пробовал.
Но в целом, Spring Boot вроде как очень широко используется для микросервисов.

Если судить по статьям, вроде как предлагают использовать другие фрейморвки со встроенными http серверами.


Хотя, может я ошибаюсь, я давно не использовать Java и не знаю, как там сейчас дела(

Бут умеет работать с любым сервером, из коробки есть реализации для пары самых популярных. Эмбеддед-томкат ничего лишнего не тащит уже очень давно и разбит на модули. Так что спринг-бут это как раз идеальный инструмент для микросервисов, которые на нем можно поднять в несколько строк, если еще и со спринг клауд, то и большинство проблем описанных в статье решает, так что не надо сбивать людей.
Научился. При подключении зависимости отключаете tomcat, подключаете jetty или undertow — для них уже есть готовые артефакты.
Собственно на текущем проекте планируем подключить spring boot вместо обычного spring(наследный код) в том числе и для того, чтобы уйти от tomcat'а.
Можете раскрыть мысль по поводу «в томкате много лишнего»?
там по сути только сервер и контейнер сервелтов.
По весу-сейчас зашел на сайт томката -зип-архив стэндэлон томката весит 9.5Мб. Это будет меньше чем некоторые либы.

Томкат это почти Java EE и он поддерживает вроде неплохое число спецификаций (те же сервлеты). Как мне кажется, для микросервисов они излишни и только зря их нагружают.

Это не java ee и не так уж много он реализаций стандартов за собой тащит. Как я написал выше, есть возможность подключить только core, который реализует сервер+сервлеты. Сервлеты в свою очередь это тоже не бесполезная вещь, хоть и может быть излишней для мест, где особенно важна производительность, но в общем случае они дают достаточно тонкую абстракцию, где поток байт приходящих по хттп превращается в объект запроса и диспатчится в какой-то обработчик. Это всё равно обычно микросервису нужно. Так что ваши заявления похожи на откровенные домыслы и вообще джава тормозит.

Я не считаю, что Java тормозит, но мне определенно кажется, что вот такой вот workflow, с использованием нативных потоков немного устарел.


Я не прав?

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

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

Проблема микросервисной архитекруты в том, что один монолит заменяется на кучу мелких структур.


И если каждая структура инициализируется большим количеством излишеств, то потом возникают отбитые статьи в духе "Мы переписали микросервисы со Sprint+Tomcat на Golang и получил выграш по всем ресурсам в 10 раз, потому что мы поменяли архитектуру потому что Java шлак, а Golang рулит".

Имея некоторе желание и умение, можно на чем угодно написать приложение, которое будет в 10 раз медленнее, чем другое приложение делающее тоже самое. Только это не проблема спринга или томката, разруха как известно она в головах.
Пардон, а вы в свете современных веяней хотите в контексте духа святого запрос обрабатывать? Всё равно будет некоторый пул обработчиков, который будет делать собственно полезную работу. Конечно, бывает некоторая специфика, когда нам из io-треда надо отправить сразу байтики в другой асинхронный io и тогда вся эта архитектрура не очень походит, но для этих редких случаев никто и не навязывает использование томката. Можно использовать например netty-reactor или что-нибудь другое более подходящее для вашего решения. Для большинства же сервисов, когда нам нужно обработать рест запрос, пообщаться с базой и другими сервисами и ответить пользователю, вполне подойдет сервлет-апи, тем более, что начиная с 3 версии у сервлетов есть асинхронный api (и спринг это отлично поддерживает) который позволяет не занимать поток из пула, а утилизировать это время по-другому.
В проекте используется спринг с DI, я думаю он явно более тяжелый, чем томкат.
А сервлеты необходимы, поверх них работает спринг и по сути псе что бывает на аппликэйшн серверах
Можно вместо сервера по умолчанию использовать Jetty, например…
Spring Boot всегда можно было использовать без встроенного сервера. Кроме того, если вас не устраивает встроенный Tomcat, то его можно заменить на Undertow или Jetty.
Удивило, что клиент очень напомнил мне мой, недавно реализованный на C#
ApiClient
public class ApiClient
{
	protected readonly ApiContext _context;
	protected readonly string _apiPrefix;

	public ApiClient(ApiContext context, string apiPrefix)
	{
		_context = context;
		_apiPrefix = apiPrefix;
	}

	protected Task<ResponseT> GetAsync<ResponseT>(string method, string param = null)
	{
		return RestRequest.GetAsync<ResponseT>(
			RequestUrl( method, param ) + $"?accessToken={GetAccessToken()}"
		);
	}

	protected Task<ResponseT> PutAsync<ResponseT>(string method, string param = null)
	{
		return RestRequest.PutAsync<ResponseT>(
			RequestUrl( method, param ),
			$"accessToken={GetAccessToken()}"
		);
	}

	protected Task<ResponseT> PostAsync<ResponseT>(string method, Dictionary<string, string> fields)
	{
		return RestRequest.PostAsync<ResponseT>(
			RequestUrl( method ),
			fields
		);
	}

	protected Task<ResponseT> DeleteAsync<ResponseT>(string method, string param = null)
	{
		return RestRequest.DeleteAsync<ResponseT>(
			RequestUrl( method, param ) + $"?accessToken={GetAccessToken()}"
		);
	}

	protected string RequestUrl(string method, string param = null)
	{
		var url = $"{_context.apiServerUrl}{_apiPrefix}";

		if (!string.IsNullOrEmpty( method ))
			url += "/" + method;

		if (!string.IsNullOrEmpty( param ))
			url += "/" + param;

		return url;
	}

	protected string GetAccessToken()
	{
		if (!_context.isAuthorized)
			throw new Exception("Context ins't authorized");

		return _context.accessToken;
	}
}

Читается как
Помогите программисту J не добраться до виски.

Так специально задумано?
Вряд ли, скорее случайность
Spring Boot, микросервисы и без Spring Cloud?
Про авторизацию через токены — интересно было почитать, взял на заметку. Приходилось делать авторизацию только по логину-паролю.
По клиенту — можно посмотреть в сторону Feign, есть простое и красивое решение. Пример
спасибо, интересное решение
Так самый интересный вопрос — сколько времени ушло на реализацию этого hello world? Точнее, на переделку под микросервисы?

Сложно сказать, не засекал, но вроде как не сильно много, за исключением авторизации, с которой были проблемы. Сначала там смотрел на Redis сессии, потом уже JWT. Даже чисто по статье, на которую я ссылаюсь, сходу не вышло потому что AbstractAuthenticationProcessingFilter не подходит для моих целей.


Без авторизации статья вышла бы на пол года раньше, никак не мог найти время чтобы разобраться до конца.

Интересно, что Eureka не понадобилась. Я так понимаю, что удалось обойтись только разнесением сервисов по разным URL через Zuul?

Я не знаю что такое Eureka.
Каждый сервис запускается отдельно и имеет свой адрес, а в zuul они просто прописываются, чтобы он понимал куда слать запросы.

www.baeldung.com/spring-cloud-netflix-eureka

Eureka позволяет микросервисам находить друг-друга (discovery service). Насколько я понимаю, Zuul задумывался как входной proxy и балансировщик нагрузки, а Eureka должна была использоваться, для идентификации ресурсов при межсервисном взаимодействии внутри системы.

окей, понял, спасибо
В контексте статьи выше это не очень применимая штука. Потому что статья не о том, как правильно сделать архитектуру для прод решения, а о том, что такое вообще микросервисы и как переписать на них домашний проект без кучи новых библиотек.


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

Спасибо! Занимаюсь на данный момент подобным переписыванием монолитного приложения, очень помогло.

Очень рад что статья до сих пор полезна и помогает!

А как у вас с масштабированием приложения? Можно ли при росте нагурзки запустить дополнительный user или lesson сервис? Будет ли при этом система корректно работать?

Насколько я знаю, именно в этом основное преимущество микросервисной архитектуры.

Никто не мешает поднимать ещё инстансы отдельных сервисов и впилить в эту схему балансировщик.


Но статья просто про базовую архитектуру, а-ля hello-world: берём типичный pet project и разбиваем его его на сервисы.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.