Подписка и публикация событий в Spring Cloud Bus (1)

задняя часть Микросервисы Архитектура

Последнее обновление блога год назад, всех заранее с Новым годом (и Днем святого Валентина)!

Введите тему ниже. Spring Cloud Bus соединяет узлы распределенных систем с облегченными брокерами сообщений. Это можно использовать для передачи состояния таблицы (например, изменений конфигурации) или других связанных команд. Ключевая идея заключается в том, что шина похожа на распределенный привод для расширений приложений Spring Boot, но ее также можно использовать в качестве канала связи между приложениями. Spring Cloud предоставляет брокеров для транспорта AMQP и стартеров Kafka, а в будущем также планируется поддержка других транспортных компонентов с тем же базовым набором функций.

Spring Cloud Bus

Spring Cloud BusвSpring Cloud StreamНа основе инкапсуляции публикация и подписка на сообщения по заданной теме осуществляется черезSpring Cloud StreamКонкретная реализация связующего. Таким образом, введенная зависимость может бытьspring-cloud-starter-bus-amqpиspring-cloud-starter-bus-kafkaОдин из них соответствует двум реализациям связующего. Согласно основному приложению из предыдущего раздела, мы заключаем, чтоSpring Cloud BusОсновные функции следующие:

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

В дальнейшем мы возьмем эти два аспекта в качестве основной линии,Spring Cloud Busанализ исходного кода. Эта статья в основном публикуется для подписчиков событий.

Подписка и публикация событий

модель, управляемая событиями

Эта часть требует, чтобы читатель сначала понял управляемую событиями модель Spring. Мы кратко познакомим вас с основными концепциями дизайна, чтобы помочь вам легко понять следующее содержание.
event-source

модель, управляемая событиями

Модель Spring, управляемая событиями, состоит из трех частей:

  • Событие: ApplicationEvent, унаследованное от EventObject JDK, все события будут наследоваться от него и получать источник события через источник.
  • Издатель событий: интерфейс ApplicationEventPublisher и ApplicationEventMulticaster, используя этот интерфейс, наш Сервис имеет возможность публиковать события.
  • Подписчик событий: ApplicationListener, унаследованный от EventListener JDK, его наследуют все слушатели.

Определение события

Определения событий управляемой событиями модели Spring унаследованы отApplicationEvent,Spring Cloud BusСуществует несколько классов событий, каждый из которых наследует важный абстрактный класс.RemoteApplicationEvent, давайте взглянем на диаграмму классов класса события:

bus-event

Определение различных событий

Участвующие классы событий: события, которые представляют собой подтверждение определенного событияAckRemoteApplicationEvent, события изменения средыEnvironmentChangeRemoteApplicationEvent, обновить событиеRefreshRemoteApplicationEvent, отправить событиеSentApplicationEvent, и неизвестные событияUnknownRemoteApplicationEvent. Рассмотрим определения этих событий отдельно.

Абстрактный базовый класс: RemoteApplicationEvent

Из приведенной выше диаграммы классов мы знаемRemoteApplicationEventЭто базовый класс других классов событий, определяющий общедоступные свойства объектов событий.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") //序列化时使用子类的名称作为type
@JsonIgnoreProperties("source") //序列化时,忽略 source
public abstract class RemoteApplicationEvent extends ApplicationEvent {
	private static final Object TRANSIENT_SOURCE = new Object();
	private final String originService;
	private final String destinationService;
	private final String id;
	protected RemoteApplicationEvent(Object source, String originService,
			String destinationService) {
		super(source);
		this.originService = originService;
		if (destinationService == null) {
			destinationService = "**";
		}
		if (!"**".equals(destinationService)) {
			if (StringUtils.countOccurrencesOf(destinationService, ":") <= 1
					&& !StringUtils.endsWithIgnoreCase(destinationService, ":**")) {
				//destination的所有实例
				destinationService = destinationService + ":**";
			}
		}
		this.destinationService = destinationService;
		this.id = UUID.randomUUID().toString();
	}
	...
}

существуетRemoteApplicationEventТри основных общих атрибута: служба источника события, служба назначения, служба назначения и случайно сгенерированный глобальный идентификатор определены в . В методе построения targetService может использовать подстановочный знак {serviceId}:{appContextId}. Если обе переменные опущены, все экземпляры всех служб будут уведомлены. Когда опущен только appContextId, соответствующая служба назначения — это все экземпляры соответствующего идентификатора службы. Кроме того, обратите внимание@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")В соответствии с сериализацией используйте имя подкласса в качестве типа; и@JsonIgnoreProperties("source")Указывает, что исходный атрибут игнорируется при сериализации, а источник определен в JDK.EventObject.

EnvironmentChangeRemoteApplicationEvent

Используется для динамического обновления свойств среды экземпляра службы, которые мы обновляем в базовом приложении.cloud.versionсвойство, связанное с событием.

public class EnvironmentChangeRemoteApplicationEvent extends RemoteApplicationEvent {
	private final Map<String, String> values;
	public EnvironmentChangeRemoteApplicationEvent(Object source, String originService,
			String destinationService, Map<String, String> values) {
		super(source, originService, destinationService);
		this.values = values;
	}
	...
}

можно увидеть,EnvironmentChangeRemoteApplicationEventРеализация класса событий проста. Определена переменная-член типа Map, ключ соответствует имени переменной среды, а значение соответствует обновленному значению.

RefreshRemoteApplicationEvent

Событие обновления конфигурации удаленного приложения используется для получения запроса на удаленное обновление.

public class RefreshRemoteApplicationEvent extends RemoteApplicationEvent {
	public RefreshRemoteApplicationEvent(Object source, String originService,
			String destinationService) {
		super(source, originService, destinationService);
	}
}

Унаследовано от абстрактного класса событийRemoteApplicationEvent, без специальных свойств членов.

AckRemoteApplicationEvent

Подтверждение событий удаленного приложения, которые представляют определенныйRemoteApplicationEventИнцидент подтвержден.

public class AckRemoteApplicationEvent extends RemoteApplicationEvent {
	private final String ackId;
	private final String ackDestinationService;
	private Class<? extends RemoteApplicationEvent> event;
	public AckRemoteApplicationEvent(Object source, String originService,
			String destinationService, String ackDestinationService, String ackId,
			Class<? extends RemoteApplicationEvent> type) {
		super(source, originService, destinationService);
		this.ackDestinationService = ackDestinationService;
		this.ackId = ackId;
		this.event = type;
	}
	...
	
	public void setEventName(String eventName) {
		try {
			event = (Class<? extends RemoteApplicationEvent>) Class.forName(eventName);
		} catch (ClassNotFoundException e) {
			event = UnknownRemoteApplicationEvent.class;
		}
	}
}

Класс события находится вRemoteApplicationEventНа основе определяются свойства члена ackId, ackDestinationService и событие.
ackId и ackDestinationService представляют собой идентификатор времени подтверждения и соответствующей целевой службы соответственно. Событие соответствует типу события, и необходимо подтвердить, что событие может быть подтверждено.RemoteApplicationEventПодкласс , поэтому свойство события необходимо проверять при установке значения, и если при преобразовании возникает исключение, оно определяется как неизвестный тип события. Эти события могут прослушиваться любым приложением, которому необходимо реагировать на события шины статистики. Они ведут себя как обычные события удаленного приложения, т. е. если целевая служба соответствует идентификатору локальной службы, приложение запускает событие в своем контексте.

SentApplicationEvent

Отправка события приложения указывает на то, что куда-то в системе было отправлено удаленное событие.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonIgnoreProperties("source")
public class SentApplicationEvent extends ApplicationEvent {
	private static final Object TRANSIENT_SOURCE = new Object();
	private final String originService;
	private final String destinationService;
	private final String id;
	private Class<? extends RemoteApplicationEvent> type;
	protected SentApplicationEvent() {
		// for serialization libs like jackson
		this(TRANSIENT_SOURCE, null, null, null, RemoteApplicationEvent.class);
	}
	public SentApplicationEvent(Object source, String originService,
			String destinationService, String id,
			Class<? extends RemoteApplicationEvent> type) {
		super(source);
		this.originService = originService;
		this.type = type;
		if (destinationService == null) {
			destinationService = "*";
		}
		if (!destinationService.contains(":")) {
			// All instances of the destination unless specifically requested
			destinationService = destinationService + ":**";
		}
		this.destinationService = destinationService;
		this.id = id;
	}
	...
}

Вы можете видеть, что класс события наследуется отApplicationEvent, что само по себе не являетсяRemoteApplicationEventСобытия не передаются через шину, а генерируются локально (в основном в ответ на удаленные события). Приложения, которые хотят проводить аудит удаленных событий, могут прослушивать событие, и всеAckRemoteApplicationEventИдентификатор в событии получен из соответствующегоSentApplicationEventидентификатор определен в . В его определенных свойствах члена есть еще один тип типа события, чем событие удаленного приложения, которое ограниченоRemoteApplicationEventподкласс .

UnknownRemoteApplicationEvent

Неизвестное событие удаленного приложения, а такжеRemoteApplicationEventПодкласс класса событий. Этот класс события такой же, как и предыдущий.SentApplicationEvent,AckRemoteApplicationEventСвязано это с тем, что когда во время сериализации встречается исключение преобразования типа события, оно автоматически создается как неизвестное событие удаленного приложения.

Слушатели событий, а также подписка и публикация сообщений будут обновлены позже. .

Ссылаться на

Spring Cloud Bus-v1.3.3