В предыдущей статье мы рассмотрели как работает KafkaConsumer и как реализован механизм auto-commit.
В этой статье я хочу остановиться на том как получает и обрабатываются сообщения spring-kafka.
Стоит оговориться, что сейчас мы рассматриваем ситуацию с enable.auto.commit = true. Согласно документации начиная с версии 2.3 настройка auto.commit по-умолчанию выставлена в false, хотя раньше это значение было аналогично значению по-умолчанию в kafka-clients, т.е. true. Это связанно с тем что контейнер KafkaMessageListenerContainer имеет собственные механизмы управления коммитом. Насколько это удобнее и какие тут есть плюсы и минусы — пожалуй тема отдельной статьи.
Because the listener container has it’s own mechanism for committing offsets, it prefers the Kafka ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG to be false. Starting with version 2.3, it unconditionally sets it to false unless specifically set in the consumer factory or the container’s consumer property overrides.
Я постараюсь ответить на следующие вопросы:
ТУТОРИАЛ КАК НАУЧИТЬСЯ БЫСТРО СТРОИТЬСЯ | Minecraft
- Как в spring-kafka построена работа с KafkaConsumer?
- Какие есть возможности для параллельной обработки сообщений?
- Что происходит при возникновении ошибок при обработки сообщений?
Рассмотрим типичный минимальный пример для получения сообщений из топика. Прежде всего нам понадобится конфигурация для подключения к топику:
И код который будет совершать какую-то работу с полученными сообщениями:
Сперва остановимся подробнее на конфигурации. Тут в игру вступают две сущности:
- DefaultKafkaConsumerFactory
- ConcurrentKafkaListenerContainerFactory
Первая фабрика по сути своей принимает от нас все необходимые свойства конфигурации и создает уже знакомый нам KafkaConsumer из библиотеки kafka-clients в методе createRowConsumer(. ):
protected Consumer createRawConsumer(Map configProps) < return new KafkaConsumer<>(configProps, this.keyDeserializerSupplier.get(), this.valueDeserializerSupplier.get()); >
ConcurrentKafkaListenerContainerFactory также прост по своей сути. Он создаёт объект ConcurrentKafkaListenerContainer, который в свою очередь создает KafkaMessageListenerContainer в количестве указанном в поле concurrent. Если наш топик имеет партиций меньше чем указанно в поле concurrent, то значение поля изменяется на количество партиций. Это сделано ввиду бесполезности создания большего числа слушателей, чем у топика есть партиций, т.к. kafka на своей стороне позволяет подключиться к одной партиции только одному слушателю в пределах одной группы слушателей, все остальные слушатели из этой группы будут распределены по другим партициям либо останутся незадействоваными. Все это можно наглядно увидеть в методе doStart()
Итак, мы добрались наконец добрались до KafkaMessageListenerContainer.
Object messageListener = containerProperties.getMessageListener();
Далее в коде мы видим получение объекта AsyncListenableTaskExecutor и если этого объекта не существует будет создан объект с типом SimpleAsyncTaskExecutor, который создаст отдельный поток для нашего слушателя.
AsyncListenableTaskExecutor consumerExecutor = containerProperties.getConsumerTaskExecutor(); if (consumerExecutor == null)
В конце концов мы создаем обертку над полученным слушателем из класса ListenerConsumer() объявленного тут же в KafkaMessageListenerContainer, а вот он уже в свою очередь создаст в конструкторе экземпляр KafkaConsumer с помощью фабрики DefaultKafkaConsumerFactory объявленной нами в конфигурации
this.consumer = KafkaMessageListenerContainer.this.consumerFactory.createConsumer( this.consumerGroupId, this.containerProperties.getClientId(), KafkaMessageListenerContainer.this.clientIdSuffix, consumerProperties);
Теперь посмотрим как же происходит получение и обработка сообщения.
Итак у ListenerConsumer есть метод pollAndInvoke() в котором происходит вызов метода в котором в свою очередь непосредственно происходит вызов метода poll() у KafkaConsumer для получения новых сообщений (и коммита offset в случае enable.auto.commit = true) Полученный сообщения передаются в метод invokeListener() для непосредственной обработки.
private void invokeListener(final ConsumerRecords records) < if (this.isBatchListener) < invokeBatchListener(records); >else < invokeRecordListener(records); >>
А что же происходит если в нашем коде при обработке сообщения выбрасывается исключение?
При получении и обработки сообщений ListenerConsumer отлавливает все возможные типы исключений в методе doRun() При обработке неспецифичных исключений используются два разных механизма в зависимости от версии spring-kafka. В версиях младше 2.5 мы можем наблюдать следующее поведение: если мы самостоятельно не настроили обработчик ошибок, то будет создан LoggingErrorHandler, который просто напросто залогирует ошибку и обработка продолжится.
Начиная с версии 2.5 обработчиком по-умолчанию становится SeekToCurrentErrorHandler в котором произойдет 10 попыток обработать сообщение без задержки и если все они закончатся неудачей ошибка также будет залогирована и мы перейдем к обработке следующего сообщения.
Это необходимо учитывать при оценки гарантий обработки сообщений, которые поддерживает наше приложение, т.к. со своей стороны kafka выполнила все обязательства по доставке сообщения.
У нас остался еще один момент, который стоит прояснить: как часто spring-kafka будет вызывать метод poll() у KafkaConsumer ? В нашей конфигурации при создании KafkaListenerContainerFactory мы можем указать следующий параметр:
factory.getContainerProperties().setPollTimeout(3000);
что будет означать следующее: при вызове метода poll() у KafkaConsumer ему в качестве аргумента будет передаваться это значение (само значение задает время в миллисекундах, т.е. в нашем случае 3 секунды). Именно это происходит в методе doPoll()
this.consumer.poll(this.pollTimeout);
KafkaConsumer же в свою очередь при вызове метода poll будет ждать переданное ему количество времени пока не наберется столько сообщений сколько мы указали в параметре max.poll.records (значение по-умолчанию 500 записей). Если pollTimeout будет равен 0, то вызов метода poll будет происходить без задержек возвращая пустой результат.
Подведем итог.
- Под капотом spring-kafka использует все тот же KafkaConsumer из библиотеки kafka-clients и работа с ним осуществляется в отдельном потоке.
- Мы можем смело использовать механизм auto-commit, но этот параметр лучше всего явно прописывать в конфигурации.
- Следует внимательно отнестись к обработчикам ошибок по-умолчанию и учитывать их поведение при расчетах надежности нашей системы.
Источник: habr.com
SMARTYcraft
Чтобы начать развивать данный мод, следует хорошенько подготовиться: запастись землей и терпением .
Начальная эссенция ( Minicio ) выпадает из любых сущностей, поэтому, если у вас ещё нет платформы с мобами или мобофермы, бегите её строить. Получив Minicio essence , соединяем их в верстаке с семечком пшеницы и получаем Minicio seeds — основной ресурс нашего мода.
Перейдем к улучшению данной эссенции
Для этого существуют шары(Infusion stone),которых бывает 5 видов:
* Weak Infusion Stone Minicio — Accio
* Regular Infusion Stone Accio — Crucio
* Strong Infusion Stone Crucio — Imperio
* Extreme Infusion Stone Imperio — Zivicio
* Master Infusion Stone Все вышеперечисленные крафты
Последнюю и самую лучшую эссенцию — Zivicio , можно также получить в размере 2шт, убив иссушителя. Инструменты из данной эссенции имеют бесконечную прочность , в отличие от инструментов из предыдущих эссенций.
Вероятно, одной из важнейших вещей в minecraft является печь, улучшенные версии которой есть и в моде Magical crops
Чем лучше эссенция , из которой сделана печь, тем быстрее она плавит, увеличивая длительность горения топлива. Так, в последней версии печи Ultimate furnace , одного угля хватает на 27 стаков материала, а ее скорость поражает- стак за 3 секунды!
И вот, мы пришли к самому «вкусному» — растениям,что дают ресурсы в виде урожая(у нас на сервере их зовут «кропсы», как и саму модификацию)
Есть , опять же , 5 «уровней» семян:
1)Семена из Minicio (minicio seeds);
2)Семена из Accio (coal seeds , water seeds , nature seeds , rubber seeds , air seeds , earth seeds , fire seeds , dye seeds);
3)Семена из Crucio (redstone seeds , glowstone seeds , obsidian seeds , cow seeds , pig seeds , chicken seeds , sheep seeds , copper seeds , certus quartz seeds , lead seeds , tin seeds , bronze seeds , nether seeds);
4)Семена из Imperio (iron seeds , gold seeds , lapis lazuli seeds , experience seeds , quartz seeds , reeper seeds , blaze seeds , enderman seeds , skeleton seeds , slime seeds , spider seeds , ghast seeds , nickel seeds , ruby seeds , silver seeds , electrum seeds , fluix seeds , steel seeds);
5)Семена из Zivicio (diamond seeds , emerald seeds).
Представлю крафт на примере Diamond seeds
Крафтятся они все одинаково, разве что меняется эссенция и требуемый ресурс.
Обратите внимание , что при отсутствии освещения семена расти не будут.Примерное время роста одного кропса , как у семечек арбуза.
Автоматизация
Существует несколько способов автоматизации сбора.
1) Мультиферма из мода Forestry (Нужно использовать плату для зерновых культур).
2) Комбайн + Сеятель из мода Minefactory Reloaded.
Эти способы достаточно хороши, однако у них есть и свои минусы.
*Мультиферма совмещает в себе и комбайн, и сеятель, тратит мало энергии, но ей нужно удобрение, вода и много места.
*Комбайн с сеятелем представляют идеальный дуэт, который быстро и точно выполняет свою работу. Из комбайна в сеятель семена можно отправлять по трубам, получая некий круговорот. Большой плюс этой системы — её компактность. Минимальные ее размеры составляют 2х2, что подойдёт для небольших фермочек. Со всеми плюсами существуют и минусы. Один из них состоит конечно же в Тоннах энергии, которую потребляет данная система (Комбайн 5000Rf/Wk* , а сеятель 1600Rf/Wk).Однако, используя этот способ, можно ставить Growth Pulser под пашни.что позволит семенам расти быстрее.**
|Росток
|Пашня
|Growth Pulser
Важно! С каждым последующим «Пульсаром» их эффективность будет падать.
И напоследок, броня. Ее есть 4 вида : Accio , Crucio , Imperio , Zivicio . Все они дают дикий резист от физического урона,однако в последней урон от падения сокращен на 100%, уменьшение урона на 96%, а также возможность летать, как в креативе.
Дополнения
*- Wk (Work) — Работа. 1 Wk = 1 собранное/высаженное семя
**-В виде бустера кропсов можно использовать светильник роста из Thaumcraft , который требует эссенцию Herba .
Если вы прочли этот гайд до конца,значит он вам помог.
P.s. Подробные гайды, «как начать развиваться на сервере » Можно найти у НиП’а Телепортер на спауне (вкладка Информация).
После некоторых обновлений будет больше информации.
За предоставленный гайд выражаем благодарность игроку SlonikVanya
Смотрите также:
Пробежимся по Magical Crops |
Источник: www.smartycraft.ru
MineFactory Reloaded/Сеятель
Сеятель (англ. Planter) — механизм, добавляемый модификацией MineFactory Reloaded, который сажает семена над собой в области 3×3. Необходимо использовать подходящую почву для того типа семян или саженца, который вы используете (например, для адского нароста требуется песок душ). В отличие от других механизмов MineFactory Reloaded, этот механизм стоит использовать в паре с комбайном. Затраты на одну посадку культуры равны 160 RF.
При использовании вместе с удобрителем рост растения значительно ускоряется (как если бы использовалась костная мука к растущим растениям), в противном случае для выращивания сельскохозяйственных культур потребуется стандартное количество времени.
Сеятель попытается разложить урожай в соответствии с планом своего инвентаря 3×33, причем верхний средний слот (жёлтый) будет северным. Это становится более полезным с обновлением диапазона.
Увеличение диапазона, за счет ⇧ Shift + ПКМ Крафт
Источник: minecraft.fandom.com