Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: немного практической кафки в топик  [new]
mayton
Member

Откуда: loopback
Сообщений: 49755
andreykaT

я понимаю что "конец" очереди это вещь весьма условная. потому что он может быть конец на определенный момент времени который у всех к тому же разный. я думаю что конец а за долю секунды до того или после того залетело уже новое сообщение а я не знаю и думаю что конец а оно прилетает. понятно что это всё ОЧЕНЬ условно.
поэтому цель стоит прочитать всё что нужно из топика до определенного оффсета,потому что после него уже читают другие. или незадолго до него.
оффсет это понятие абсолютное. вот когда ты его попросил у кафки оно посмотрело в партицию и отдало тебе это значение. всё. так же у партиции есть как минимум, начало.


Я не специалист в Кафке от слова вообще. Но если предположить что Кафка работает на принципах TCP/IP
протокола. (А она работает) Тогда у нас есть 2 базовые стратегии как пушить или поллать месседж.

1) 1 TCP сообщение == 1 JMS/MQ/Kafka ообщение.
2) 1 TCP сообщение == много JMS/MQ/Kafka ообщений.

И мне кажется что таймауты которые видел Андрейка это второй кейс. Но тут надо смотреть в настройки
и мониторинг. Без этой инфы - мы как слепые котята.
19 ноя 20, 15:49    [22235459]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
mayton
andreykaT

я понимаю что "конец" очереди это вещь весьма условная. потому что он может быть конец на определенный момент времени который у всех к тому же разный. я думаю что конец а за долю секунды до того или после того залетело уже новое сообщение а я не знаю и думаю что конец а оно прилетает. понятно что это всё ОЧЕНЬ условно.
поэтому цель стоит прочитать всё что нужно из топика до определенного оффсета,потому что после него уже читают другие. или незадолго до него.
оффсет это понятие абсолютное. вот когда ты его попросил у кафки оно посмотрело в партицию и отдало тебе это значение. всё. так же у партиции есть как минимум, начало.


Я не специалист в Кафке от слова вообще. Но если предположить что Кафка работает на принципах TCP/IP
протокола. (А она работает) Тогда у нас есть 2 базовые стратегии как пушить или поллать месседж.

1) 1 TCP сообщение == 1 JMS/MQ/Kafka ообщение.
2) 1 TCP сообщение == много JMS/MQ/Kafka ообщений.

И мне кажется что таймауты которые видел Андрейка это второй кейс. Но тут надо смотреть в настройки
и мониторинг. Без этой инфы - мы как слепые котята.

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

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

всё.

вот каунтеры сделал да на конкурентхашмапе, в которой по ключам каждый консамер сохраняет последний оффсет. но кейса когда разные консамеры дергают один и тот же ключь улсовно "параллельно" - у меня нет.
20 ноя 20, 11:50    [22235944]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
mayton
Member

Откуда: loopback
Сообщений: 49755
andreykaT
вот каунтеры сделал да на конкурентхашмапе, в которой по ключам каждый консамер сохраняет последний оффсет. но кейса когда разные консамеры дергают один и тот же ключь улсовно "параллельно" - у меня нет.


Я все равно ничего не понял. А хоть кто-то понял полёт твоей мысли?
20 ноя 20, 11:53    [22235948]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
mayton,
Я понялтолько то что интернет на симке это злостный оффтоп в теме.
20 ноя 20, 12:25    [22235966]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
забыл ник
Member

Откуда:
Сообщений: 3436
Я только понял что все через жопу. Но может это было главным пунктом в ТЗ - тогда все ок
20 ноя 20, 12:51    [22235984]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
забыл ник
Я только понял что все через жопу. Но может это было главным пунктом в ТЗ - тогда все ок

что именно через жопу? я сталкиваюсь всё чаще с кейсами когда задача чуть сложнее перетаскивания джейсона из угла в угол и всё все горят. типа слооожна.

еще раз медленно.

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

как я это по крайней мере пока сделал:

запускаем с бегиннинга консамеры на топик1, при подключении все консамеры дружно запоминают максимальный оффсет на момент подключения. (та самая конкурентная мапа где ключ - партиция, значение - максОффсет на момент снятия данных. т.е. если я даже следом добавлю еще консамеров, или они отвалятся - ничего не произойдет они просто ребалансятся сами а данные берут оттуда же и доступ по ключам между консамерами конкурентный в принципе исключен. каждый консамер мутирует только значение своего ключа или ключей).

параллельно запускаем консамеры на топик2, но уже с КОНЦА (т.е. лови сообщения созданные после подключения). ждем пока консамеры топика1 дойдут до максимального оффсета, и гасим их. бд синхронизирована. топик2 консамеры продолжают работать. бд в состоянии синхрона.

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

зачем два топика? ведь можно было бы и дальше содержать только топик1? отвечаю. в топике1 нет событий по удалению записей. они через томбстон оттуда просто "исчезают" по ключам и эти события прилетают только через топик2. поэтому топик1 годен только для инициальной заливки бд, но не годен для постоянного синхрона. топик2 же наоборот имеет вменяемый ретеншн типа 2 недели и с него ты не вытянешь все данные для инициализации.

почему так сложно? а вот так вот. в идеале хорошо иметь один топик. и одну консамергруппу. но в данном случае это невозможно потому что нету поставщиков данных.

Сообщение было отредактировано: 20 ноя 20, 13:10
20 ноя 20, 13:08    [22235994]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9249
andreykaT

что именно через жопу?

Использовать вместо нормальной БД какой-то самокат с треугольными колесами.

andreykaT

надо в бд слить с

INSERT INTO tableB SELECT * FROM tableA;

)))
20 ноя 20, 13:31    [22236008]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
забыл ник
Member

Откуда:
Сообщений: 3436
Не знаю как вы, но все равно нихера не понял.

Зачем нужен максимальный оффсет? Зачем надо гасить консюмеров? Почему не юзать стримы? Почему tombstone приходят во второй топик только? Почему не взять нормальный механизм репликации данных?

Вообще похоже что система создана взбесившимся архитектором, который услышал про NoSQL, асинхронность и кафку.
20 ноя 20, 13:40    [22236014]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
vimba
Member

Откуда: Санкт-Петербург
Сообщений: 2214
andreykaT

ожидаемое поведение - стартуем 10 консамеров - все 10 консамеров гребут по 1000 сообщений.
что в реале - из 10-ти консамеров рандомно 2-3 консамера выгребают от 200 и до 1000 сообщений за один цикл

что за фигня. понимаю это больше не касательно джавы но все же. выходит кафка еще и не гарантирует отдачу сообщения даже если оно есть? ну то есть отдам когда-нибудь.

1. Не гарантируется что все доступные сообщения прийдут вам за один poll.
2. Если сервер таки даже смог на FetchRequest вывалить всё что у него было, то в общем случае не факт что poll отдаст их все за раз, хотя бы из-за той же настройки max.poll.records, которая по дефолту равна 500 и если вы её не меняли то уж 1000 за раз никак не получите.
2. Ecли даже poll вернул пустой список, это не значит что в топике нет мессаджей. poll банально может возвращать пустой список при возникновении большинства типов ошибок начиная с версии 2.1, до 2.1 poll мог просто виснуть.

Что касается клиента то теоритический максимум рекордов которые poll может вернуть вам за раз определяется как минимум настройками:
1. max.poll.records (default 500)
2. max.partition.fetch.bytes (default 1048576 aka 1Mb)
3. fetch.max.bytes (default 52428800 aka 5Mb)
4. Из пункта 2 и 3 очевидно что размер мессаджей тоже имеет значение и ещё какое.
5. На брокере есть аналогичные настройки вроде message.max.bytes
6. Также таймаут который вы передали в poll как аргумент в сочетании со способом которым продьюсер мессаджи записывал(успевал он их писать по одному или групировал в бэтчи).
7. Общая загруженость CPU и сети на консумере.

Осмыслите эти настройками и если всё равно что-то останется непонятным кидайте self-executable код (демонстрирующий непонятные моменты) на github, с помощью TestContainers это сейчас делать несложно, и я смогу посмотреть.
20 ноя 20, 13:57    [22236027]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
andreykaT,
У тебя уже четвертый топик и всё дальше ты погружаешься....
Ничего личного (с)
20 ноя 20, 14:08    [22236039]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
vimba,
Он не может осмыслить что асинхронный код по другому пишется.
Это значит, к примеру, есть кнопка стр3. Но при нажатии на страницу 3 вывалится Нет данных.
Это значит нет понятия ВЫГРЕБ ДО КОНЦА.
Идеотизм. Можно поиск гугла выгрести до конца?
20 ноя 20, 14:11    [22236042]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
Leonid Kudryavtsev
andreykaT

что именно через жопу?

Использовать вместо нормальной БД какой-то самокат с треугольными колесами.

andreykaT

надо в бд слить с

INSERT INTO tableB SELECT * FROM tableA;

)))

а если базы НЕТ? тут чуть ранее все топили 1 бд 1 сервис и всё остальное на ивентах. получите распишитесь. а то как то непоследовательно.

топик это бд с определенной натяжкой и определенной спецификой. но тем не менее это в той самой определенной степени - бд. где ты можешь двигаться вперед-назад. далее, я не пишу свой проект с нуля я использую те инструменты и ту инфраструктуру которая сделана до меня.
20 ноя 20, 14:32    [22236059]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
забыл ник
Не знаю как вы, но все равно нихера не понял.

Зачем нужен максимальный оффсет? Зачем надо гасить консюмеров? Почему не юзать стримы? Почему tombstone приходят во второй топик только? Почему не взять нормальный механизм репликации данных?

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

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

максимальный оффсет нужен чтоб знать - залились ли данные в промежутке от сих и до сих или нет. оффсет это что то что всегда растет и никогда не падает (по крайней мере в кафке).

еще раз. речь идет НЕ о репликации, речь идет о ремаппинге данных как минимум. они не кладутся в базу в том виде в каком летят из топика. то есть о подготовке и хранении в ином формате, считай скрс.
20 ноя 20, 14:39    [22236062]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
Боже мой сколько слов ненужных
andreykaT
еще раз медленно.
надо в бд слить

andreykaT
а если базы НЕТ?

Дак есть бд или нет?)
20 ноя 20, 15:05    [22236076]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
забыл ник
Member

Откуда:
Сообщений: 3436
andreykaT
забыл ник
Не знаю как вы, но все равно нихера не понял.

Зачем нужен максимальный оффсет? Зачем надо гасить консюмеров? Почему не юзать стримы? Почему tombstone приходят во второй топик только? Почему не взять нормальный механизм репликации данных?

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

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

максимальный оффсет нужен чтоб знать - залились ли данные в промежутке от сих и до сих или нет. оффсет это что то что всегда растет и никогда не падает (по крайней мере в кафке).

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


Писал долгий комментарий, что мол так нифига и не понял, и вдруг меня осенило - то есть походу ситуация следующая -

есть два топика, которые надо слить воедино и сохранить при этом некий ордеринг. Для этого ты вычитываешь оффсеты двух топиков, сохраняешь их, вычитываешь все что есть в первом топике(ну надеешься вычитать), после того как все вычитано - ты начинаешь читать из второго топика, используя оффсет прочитанный в самом начале?
20 ноя 20, 15:24    [22236092]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9249
Если все так, все равно выглядит как забивание гвоздей мало приспособленного для этого предметами.

Слушать две очереди (Queu), новые необработанные события где-то буфферизировать, когда появится полный "комплект" событий из обоих очередей - сливать, обрабатывать, результат выдавать в результирующую очередь.

Банальный, немного модифицированный, merge join из 3-его тома всем известного автора.

p.s. what is "топик" in Kafka - не знаю. Мое знание message driving архитектуры заканчивается на ConcurrentQueu
20 ноя 20, 15:35    [22236101]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
mayton
Member

Откуда: loopback
Сообщений: 49755
Что такое "максимальный оффсет на момент подключения" ?
20 ноя 20, 16:11    [22236123]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
забыл ник
andreykaT
пропущено...

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

максимальный оффсет нужен чтоб знать - залились ли данные в промежутке от сих и до сих или нет. оффсет это что то что всегда растет и никогда не падает (по крайней мере в кафке).

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


Писал долгий комментарий, что мол так нифига и не понял, и вдруг меня осенило - то есть походу ситуация следующая -

есть два топика, которые надо слить воедино и сохранить при этом некий ордеринг. Для этого ты вычитываешь оффсеты двух топиков, сохраняешь их, вычитываешь все что есть в первом топике(ну надеешься вычитать), после того как все вычитано - ты начинаешь читать из второго топика, используя оффсет прочитанный в самом начале?


почти. только читать начинаю с обоих топиков одновременно.
у одного топика настройка ирлест у второго латест.

итого таймлайн 1,2,3,4,5,6,7,8,9,10... итп. у нас точка входа типа в 7 (это таймлайн, это НЕ оффсеты), где 7 это настоящее время, 1 - это далекое прошлое и 10 это недалекое будущее. так вот, с топика А (который не содержит удаленных записей) мы читаем с 1 по 7. ,
с топика Б мы читаем с 7 - и дальше в будущее. читание начинается одновременно. то есть до того как топик А выключится у нас 1,7
12,78 123,789 и т.п. и в какой то момент времени становится 1,2,3...10. 1,2,3...11. 1,2,3...12 и т.п. топик А же выключится тогда когда гарантированно построится картина 1,2,3,4,5,6,7 (дальше не важно).
20 ноя 20, 21:05    [22236229]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
Leonid Kudryavtsev
Если все так, все равно выглядит как забивание гвоздей мало приспособленного для этого предметами.

Слушать две очереди (Queu), новые необработанные события где-то буфферизировать, когда появится полный "комплект" событий из обоих очередей - сливать, обрабатывать, результат выдавать в результирующую очередь.

никаких комплектов нет. синхронизаций нет буферов нет. говорю же. есть два топика - один компакт который содержит все ФАКТИЧЕСКИЕ записи, второй с ретеншеном, который содержит события удаления записей.

первый топик это типа "исторический" второй - текущий.

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

вкратце при запуске консамеров я один раз сохраняю все оффсеты всех партиций топика внутри консамера, и периодически снимаю с кафки значения закоммиченных оффсетов по всем партициям в рамках этой консамергруппы. далее просто сравниваю что первое минус второе дает. если больше нуля значит не доехал до "точки входа", если ноль и меньше - доехали. отваливаемся. понятно что могут быть некоторые накладки с другим топиком, но это небольшое количество дублей на "шве" которое не критично. доставку ат-лист-ванз оно вроде гарантирует.
20 ноя 20, 21:11    [22236233]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
mayton
Что такое "максимальный оффсет на момент подключения" ?

ты вошел в топик и говоришь кафке - покажи мне ласт оффсеты по всем партициям. понятно что на момент выдачи тебе этих значений они могут быть уже и устаревшими. но как минимум они очень близки к неким "реальным". хотя что такое реальность?

Сообщение было отредактировано: 20 ноя 20, 21:09
20 ноя 20, 21:13    [22236234]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
andreykaT
Member

Откуда: Finland
Сообщений: 3233
vimba
andreykaT

ожидаемое поведение - стартуем 10 консамеров - все 10 консамеров гребут по 1000 сообщений.
что в реале - из 10-ти консамеров рандомно 2-3 консамера выгребают от 200 и до 1000 сообщений за один цикл

что за фигня. понимаю это больше не касательно джавы но все же. выходит кафка еще и не гарантирует отдачу сообщения даже если оно есть? ну то есть отдам когда-нибудь.

1. Не гарантируется что все доступные сообщения прийдут вам за один poll.
2. Если сервер таки даже смог на FetchRequest вывалить всё что у него было, то в общем случае не факт что poll отдаст их все за раз, хотя бы из-за той же настройки max.poll.records, которая по дефолту равна 500 и если вы её не меняли то уж 1000 за раз никак не получите.
2. Ecли даже poll вернул пустой список, это не значит что в топике нет мессаджей. poll банально может возвращать пустой список при возникновении большинства типов ошибок начиная с версии 2.1, до 2.1 poll мог просто виснуть.

Что касается клиента то теоритический максимум рекордов которые poll может вернуть вам за раз определяется как минимум настройками:
1. max.poll.records (default 500)
2. max.partition.fetch.bytes (default 1048576 aka 1Mb)
3. fetch.max.bytes (default 52428800 aka 5Mb)
4. Из пункта 2 и 3 очевидно что размер мессаджей тоже имеет значение и ещё какое.
5. На брокере есть аналогичные настройки вроде message.max.bytes
6. Также таймаут который вы передали в poll как аргумент в сочетании со способом которым продьюсер мессаджи записывал(успевал он их писать по одному или групировал в бэтчи).
7. Общая загруженость CPU и сети на консумере.

Осмыслите эти настройками и если всё равно что-то останется непонятным кидайте self-executable код (демонстрирующий непонятные моменты) на github, с помощью TestContainers это сейчас делать несложно, и я смогу посмотреть.


это выглядит так (по крайней мере внешне) что полл дернул но ничего не пришло.
те конфиги что ты показал я естественно заиспользовал. размеры мессаджей там несоклкьо сотен килбоайт. батч на полл как раз 500.
поллит раз в полсекунды.

я поигрался с настройками, ты ставишь батч 500 тебе с 10-ти партиций прилетает только в 1-2. ставишь батч 50 - тебе прилетает со всех 10ти партиций. :) но.. оптяь же оно может и по 500 с 10-ти партиций слать, но гораздо реже.
20 ноя 20, 21:20    [22236238]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
mayton
Member

Откуда: loopback
Сообщений: 49755
andreykaT
mayton
Что такое "максимальный оффсет на момент подключения" ?

ты вошел в топик и говоришь кафке - покажи мне ласт оффсеты по всем партициям. понятно что на момент выдачи тебе этих значений они могут быть уже и устаревшими. но как минимум они очень близки к неким "реальным". хотя что такое реальность?

Главное чтоб они были консистентны друг с другом и с твоей предментной областью на некий момент времени t.
Чтоб ты получил 2+2=4. А не 3 и не 5.

Пример - я делаю SELECT в Oracle по табличке которая интенсивно UPDAtE-ится. Я все равно
получу 100% строк консистентных с неким тайм-штампом (технически это SCN) который был синхронным
с началом моей читающей транзакции.
20 ноя 20, 21:56    [22236246]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
mayton,
Автор выбрал message driven. А это отказ от консистентности))))
21 ноя 20, 11:37    [22236347]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
andreykaT
это выглядит так (по крайней мере внешне) что полл дернул но ничего не пришло.
у тебя не должно ничего ломаться в данном случае. Трагедию нашел.
Бери РСУБД. Там дернул и 100 процентов получил.
Микросервисники блин.
21 ноя 20, 11:40    [22236348]     Ответить | Цитировать Сообщить модератору
 Re: немного практической кафки в топик  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 6525
mayton,

Вот теорема САР
https://ru.m.wikipedia.org/wiki/Теорема_CAP
И он хочет упрямо как баран чтобы у него все 3 буквы С и А и Р работали.
Уже пол года хочет а в школу не ходил.
21 ноя 20, 12:00    [22236357]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Java Ответить