Уже несколько дней (наверное, сразу после обновления до Discourse 2.5 beta 5 — и продолжается в beta 6, хотя это может быть совпадением) встраивание видео с YouTube работает нестабильно. После нескольких часов неработоспособности оно снова начинает работать нормально.
Со вчерашнего дня оно перестало работать полностью.
В логах форума я не вижу никаких конкретных подозрительных ошибок.
Может ли это быть проблемой тайм-аута? Есть ли способ провести целенаправленное расследование?
Ещё немного дополнительной информации.
Я использую Discourse 2.5.0.beta6, обновлённый до коммита 2d880b42a3 (перекомпилирован непосредственно перед отправкой этого сообщения).
При создании нового сообщения со ссылкой на YouTube в консоли Google Chrome появляется дополнительная ошибка непосредственно перед 404 для GET-запроса к onebox, связанная с ошибкой регистрации Service Worker.
Хочу отметить, что работают все onebox, кроме YouTube.
если я повторяю простой вызов GET (передавая заголовки и прочее, как ожидается) к /onebox?url=…, я просто получаю ошибку HTML 404.
если я повторяю на сервере запрос, который выполняет onebox, скопировав его из ruby-кода youtube_onebox.rb, а именно curl 'https://www.youtube.com/oembed?format=json&url=https://www.youtube.com/watch?v=Xl-PTTeRsik' для одного из не-встраиваемых видео, это, похоже, работает идеально.
Вызов фактически возвращает: {"author_name":"AstronautiCAST","version":"1.0","height":270,"author_url":"https:\/\/www.youtube.com\/user\/AstronautiCAST","provider_name":"YouTube","provider_url":"https:\/\/www.youtube.com\/","thumbnail_height":360,"width":480,"html":"\u003ciframe width=\"480\" height=\"270\" src=\"https:\/\/www.youtube.com\/embed\/Xl-PTTeRsik?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen\u003e\u003c\/iframe\u003e","type":"video","thumbnail_width":480,"title":"Loading cargo into HTV-9 Konutori","thumbnail_url":"https:\/\/i.ytimg.com\/vi\/Xl-PTTeRsik\/hqdefault.jpg"}root@fait-2020:/var/discourse#
что содержит всё необходимое для встраивания.
@Falco, извините за беспокойство, но отсутствие встраивания видео с YouTube серьёзно ухудшает пользовательский опыт на нашем форуме.
Вчера я пробовал несколько подходов: изучал исходный код (чтобы понять, на каком этапе и при каких условиях однобокс возвращает ошибку 404), а также клонировал текущий продакшн-форум на отдельный новый Droplet от DigitalOcean.
Чтение кода мало помогло, в основном из-за моего недостаточного знания платформы.
Остаётся один вопрос: ведётся ли где-то логирование процесса однобоксинга? Это было бы очень полезно для понимания ошибки, из-за которой однобокс прекращает работу и возвращает 404.
Клонированный Droplet был попыткой проверить, не заблокирован ли IP-адрес продакшн-сервера со стороны YouTube, а также нет ли проблем, связанных с используемым доменным именем.
Однако, несмотря на то, что IP-адрес и доменное имя были другими, встраивание видео с YouTube всё равно не работало.
Я очень надеюсь, что кто-то сможет подсказать хотя бы способ отследить, что именно происходит при однобоксинге.
Я нашел корневую причину: YouTube заблокировал наш IP-адрес, но непонятно почему, так как на момент этого события мы не выполняли массовую перевыпечку (rebake) или подобные операции.
Спасибо всем за ответы.
Однако для меня остаётся неясным, почему, если я имитирую запрос, который выполняет движок onebox (или, по крайней мере, я ожидаю, что это так. Это @Falco?), я получаю JSON-ответ с правильным ответом, а не ошибку 429.
Есть ли другой запрос, выполняемый Onebox, который возвращает 429, прежде чем будет выполнен запрос, показанный на моём скриншоте, то есть curl 'https://www.youtube.com/oembed?format=json&url=https://www.youtube.com/watch?v=Xl-PTTeRsik'?
Само собой разумеется, что эти запросы были сделаны с того же сервера, на котором работает Discourse (то есть с одного и того же исходящего IP-адреса).
Интересное открытие после выходных, посвящённых устранению неполадок.
Возможно, вам стоит обратить на это внимание, @Falco или @codinghorror?
На данный момент, изучая исходный код youtube_onebox.rb, я вижу, что он поддерживает 3 формата URL, из которых извлекается идентификатор видео:
http://youtu.be/<videoid>
https://www.youtube.com/embed/<videoid>
https://www.youtube.com/watch?v=<videoid>
Все попытки создать onebox для видео, ссылки на которые оформлены в форматах 1 и 3, завершаются ошибкой с кодом 404 (я полагаю, это связано с тем, что наш IP-адрес заблокирован).
Когда я пытаюсь встроить ссылки в формате 2, всё работает!
Интересно, может ли это как-то быть связано с фактом, объяснённым в этом посте.
Было бы очень полезно получить некоторое понимание (и логи) внутренней работы onebox (то есть, какие именно вызовы к YouTube совершаются)…
Возвращаюсь сюда, чтобы закрыть эту тему.
Вчера YouTube снял наш бан, и мы снова в деле.
Есть несколько моментов, которые, на мой взгляд, стоит прояснить:
возможно ли, чтобы onebox фиксировал детали в случае неудачной oneboxing-операции? Это очень помогло бы понять, почему именно oneboxing не работает.
поскольку для oneboxing видео с YouTube необходим только идентификатор видео, не было бы хорошей идеей попытаться получить данные из каждого из трёх типов URL перед возвратом 404 (как упоминалось выше, URL вида /embed/ каким-то образом никогда не переставал работать, даже во время бана).
Спасибо всем, кто ответил на мои панические вопросы!
ДА!!! (это очень хорошая идея, я уже упоминал об этом ранее)
Думаю, часть проблемы заключается в том, что если целевой сайт возвращает страницу без тегов og, Onebox не узнает, что это произошло из-за перенаправления. Однако это можно было бы логировать (“ONEBOX: теги og не найдены”?), и все ошибки, приводящие к пустым Onebox, определённо должны логироваться.
tl;dr: Я хочу добавить, что у нас наблюдается, по-видимому, та же проблема. Если существует ограничение скорости из-за каких-то недавних изменений, то, думаю, другие пользователи начнут сталкиваться с этим во время миграции, повторной обработки постов или, возможно, просто из-за очень активного форума. Тот факт, что onebox явно не работает молча, означает, что эти проблемы не видны, пока пользователи не начнут жаловаться на отсутствие onebox для YouTube.
Фон
Мы используем версию 2.6.0.beta 1
Пользователи получали сообщения о небезопасном контенте. При расследовании выяснилось, что Chrome жалуется на изображения, ссылки на которые ведут с HTTP-сайтов. Поэтому я настроил Discourse так, чтобы он загружал все изображения и медиафайлы и обслуживал их через HTTPS.
После изменения этой настройки потребовалась повторная обработка (re-bake) исторических постов. С тех пор как была проведена эта повторная обработка, большая часть видео YouTube, которые ранее отображались как onebox, снова превратились в обычные ссылки.
У нас есть одна ветка из 10 000 постов, состоящая исключительно из ответов с видео YouTube, и все посты содержат ссылки, а не onebox.
Во время повторной обработки все задачи в очереди обрабатывались штатно, так что это не застрявшие в очереди удаленные задачи.
Я не видел тех же сообщений об ошибках, что и @marcozambi, но считаю, что мы тоже упираемся в ограничение скорости.
Что я пробовал?
В подтверждение теории об ограничении скорости: небольшой фрагмент кода, который я написал для повторной обработки постов, сработал (создал onebox) для первых 80+ видео YouTube в ветке, а затем перестал конвертировать оставшиеся видео.
В этот момент даже редактирование поста, внесение небольших правок и повторное сохранение не заставляли URL превращаться в expanded onebox. В то же время все очереди были пусты или содержали незначительные задачи, которые обрабатывались мгновенно, как я и ожидал.
Попытки повторно запустить этот код в течение 30 минут не привели к созданию onebox для ссылок. Я не думаю, что число 80 здесь магическое, это просто то, что было доступно в рамках нашего квоты.
@marcozambi упомянул, что ссылка YouTube в формате /embed/ работала, когда другие не работали, поэтому я изменил код, чтобы использовать поиск и замену с помощью регулярного выражения для преобразования ссылок YouTube в формат /embed/.
Код сработал.
Повторный запуск кода только для повторной обработки постов снова не привел к созданию представлений onebox.
Мой план состоит в том, чтобы поэкспериментировать с задачей, которая преобразует все ссылки YouTube в большой ветке в формат YouTube /embed/. Если это не сработает или мы упремся в еще более жесткое ограничение скорости, я изучу Onebox Assistant от @merefield.
Хорошо, здесь определённо происходит что-то странное, и, похоже, это связано с ограничением скорости.
Я не уверен, попали ли мы под ограничение из-за массовой пересборки и оказались на «наказательной скамье», или же мы превышаем лимиты, которые увидят и другие.
Похоже, что для превращения ссылок на видео YouTube в превью (oneboxing) существует лимит, и после его достижения превью перестают формироваться без каких-либо уведомлений.
Думаю, это нужно исправить — по, надеюсь, очевидным причинам, но особенно для тех, кто выполняет миграцию или пересборку и не подозревает, что множество не развернутых или ранее развернутых превью теперь просто стали обычными ссылками.
@marcozambi выше упомянул, что формат URL YouTube, содержащий /embed/ перед идентификатором видео, работает, когда другие форматы не срабатывают (предположительно из-за проблемы с ограничением скорости).
Вот видео, которое хорошо иллюстрирует этот феномен.
Когда эта запись экрана была сделана, очереди задач не были перегружены, и форум в целом работал нормально.
До этого видео ссылки на YouTube уже начали не разворачиваться через OneBox.
Вы увидите окно ввода, где OneBox не может развернуть ссылку на YouTube в формате https://youtu.be/<video-id>.
Затем я меняю формат на https://youtube.com/embed/<video-id>, и OneBox успешно разворачивает ссылку.
После этого я снова пробую исходный формат, и он снова не работает.
Во время записи этого видео я отслеживал консоль браузера и вкладки сети. Я понимаю, что проблема, скорее всего, находится между нашим сервером и YouTube, а не между моим браузером и нашим сервером, но я привожу их ниже на случай, если они окажутся полезными.
(извините за уменьшенный масштаб изображения — надеюсь, их будет видно при увеличении)
Я не убеждён, что формат ссылок /embed/ является панацеей в данном случае.
Мне кажется, что это маршрут с отдельными лимитами запросов: когда маршрут https://youtu.be/<video-id> достигает своего лимита, вступает в силу другой маршрут с отдельным лимитом для https://youtube.com/embed/<video-id>.
Подтверждением того, что оба маршрута ограничены, служит утилита, которую я написал для изменения формата встраиваемых видео YouTube в огромной ветке из 10 тысяч постов, где 99% ответов были видео с YouTube.
На тот момент Onebox уже не мог раскрывать ссылки в формате https://youtu.be/<video-id>.
Моя утилита, которая меняла URL видео YouTube на формат https://youtube.com/embed/<video-id>, была запущена на первых 3000 постах в ветке.
Она успешно работала для первых 1108 постов, а затем, хотя формат был изменён для следующих ~1900 постов, Onebox не смог их раскрыть.
В это время было создано множество задач (мой код использовал post.revise), и все они были обработаны без ошибок или повторных попыток.
По наблюдению, я заметил, что обработка задач на определённом этапе резко ускорилась. Думаю, это могло быть связано с тем, что код Onebox быстро получал какую-то ошибку от YouTube, но я не фиксировал время, и это могло быть вызвано множеством других причин.
Я был бы рад предоставить более подробные доказательства, но не уверен, что смогу это сделать без внедрения инструментов отладки в gem Onebox.
Я хакер, а не эксперт по Ruby, но с удовольствием попробую следовать общим инструкциям высокого уровня.
Выполнение коротких повторяющихся скриптов curl с командной строки сервера с тем же user-agent может помочь изолировать проблему с ограничением частоты запросов.
Согласен, что обходное решение, вероятно, работает только потому, что это отдельный счётчик.
Вот ещё несколько результатов. Обратите внимание, что в сообщении ниже содержится множество предположений, основанных на недостатке реальных знаний.
В следующем сообщении я изложу своё мнение о том, что происходит и что должно произойти.
Спасибо за ответ, Роберт.
Обратите внимание, что Oneboxing видео по маршруту /watch (как и раньше!) не удавалось при моих попытках, поэтому мне не потребовался цикл, чтобы вызвать сбой.
Таким образом, одно из моих предположений состоит в том, что user-agent, используемый Onebox, — это Discourse Forum Onebox v2.6.0.beta1, исходя из этого кода…
Я выбрал случайное видео и попытался использовать curl для чтения заголовков.
Я выполнил это внутри Docker-контейнера на моём работающем сайте, что дало следующий ответ.
Результат первого запроса curl через маршрут /watch?
Таким образом, я был перенаправлен с помощью ответа 303 на URL, указанный в заголовке location, который был https://www.youtube.com/watch?v=s0ONj4TG0UA&app=desktop.
Это просто привело к добавлению &app=desktop к URL.
Результат второго запроса curl к перенаправленному URL — всё ещё по маршруту /watch?
команда curl --user-agent "Discourse Forum Onebox v2.6.0.beta1" -sD - -o /dev/null "https://www.youtube.com/watch?v=s0ONj4TG0UA&app=desktop"
Таким образом, мне возвращается код ответа 429 «слишком много запросов», но без заголовка retry-after — прекращение без переговоров.
В любом случае, если Onebox видит именно это, он игнорирует ответ, или, по крайней мере, я не знаю, где искать его, если он где-то логируется.
Хотя это может быть допустимым действием для единичного ответа 429, получение множества ответов 429 за очень короткий промежуток времени нельзя игнорировать.
Результат третьего запроса curl — на этот раз через маршрут /embed/
Для полноты картины я сразу же попытался получить то же видео, но на этот раз через маршрут /embed/.
Плагин lazy-yt, похоже, переписывает URL в формате /watch
Не уверен, имеет ли это какое-либо значение, но… включён ли по умолчанию плагин lazy-yt для встроенного контента? Я заметил его в своей установке для разработки.
Похоже, он патчит метод to_html однобоксера YouTube.
Не знаю, важно ли это, но исходный метод to_html однобоксера возвращает формат URL /embed/…
В то время как плагин lazy-yt использует формат URL /watch?v=.
Могу ли я что-то ещё сделать, чтобы показать, что существует проблема, требующая внимания? В следующем сообщении я объясню, что, по моему мнению, является корневой причиной.