Pull to refresh

Comments 41

Платформа, сервисы, разработчиков 4000… а в реальности озон это вот это:

Попытка обращения в саппорт с очевидным вопросом

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

Hidden text

Уже год с лишним такая проблема в Firefox, в хроме работает. Ставлю те же браузеры на новый ноутбук — ни в одном уже не работает.


Кто сталкивался — подскажите, в какую сторону копать?

Что характерно - сообщить о проблеме невозможно, потому что чтобы написать в техподдержку, надо залогиниться

Выглядит это как сообщение


Заголовок спойлера
[ERROR] Error while rendering widget
e.log @ vendor-bxfelgr.f162537917cc738c.js:1
value @ vendor-bxfelgr.f162537917cc738c.js:1
n @ vendor-bxfelgr.f162537917cc738c.js:1
value @ vendor-bxfelgr.f162537917cc738c.js:1
(anonymous) @ vendor-bxfelgr.f162537917cc738c.js:1
e.log @ vendor-bxfelgr.f162537917cc738c.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
Promise.then (async)
t.platformLog @ main.1d1995958c69eff1.js:1
t.log @ main.1d1995958c69eff1.js:1
t.error @ main.1d1995958c69eff1.js:1
errorCaptured @ main.1d1995958c69eff1.js:1
ne @ vendor-core.e1b0f11de3063d4a.js:2
t._render @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
y @ vendor-core.e1b0f11de3063d4a.js:2
x @ vendor-core.e1b0f11de3063d4a.js:2
y @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
y @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
T @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
T @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An.run @ vendor-core.e1b0f11de3063d4a.js:2
jn @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
fe @ vendor-core.e1b0f11de3063d4a.js:2
Promise.then (async)
se @ vendor-core.e1b0f11de3063d4a.js:2
he @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
An.update @ vendor-core.e1b0f11de3063d4a.js:2
St.notify @ vendor-core.e1b0f11de3063d4a.js:2
set @ vendor-core.e1b0f11de3063d4a.js:2
Mn.kn.set @ vendor-core.e1b0f11de3063d4a.js:2
setWidgetState @ main.1d1995958c69eff1.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
v @ vendor-core.e1b0f11de3063d4a.js:17
_replaceAsyncState @ main.1d1995958c69eff1.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
f @ vendor-core.e1b0f11de3063d4a.js:17
Promise.then (async)
d @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
v @ vendor-core.e1b0f11de3063d4a.js:17
fetchAsyncState @ main.1d1995958c69eff1.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
v @ vendor-core.e1b0f11de3063d4a.js:17
_tryToLoadOnMount @ main.1d1995958c69eff1.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
v @ vendor-core.e1b0f11de3063d4a.js:17
mounted @ main.1d1995958c69eff1.js:1
re @ vendor-core.e1b0f11de3063d4a.js:2
bn @ vendor-core.e1b0f11de3063d4a.js:2
insert @ vendor-core.e1b0f11de3063d4a.js:2
P @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An.run @ vendor-core.e1b0f11de3063d4a.js:2
jn @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
fe @ vendor-core.e1b0f11de3063d4a.js:2
Promise.then (async)
se @ vendor-core.e1b0f11de3063d4a.js:2
he @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
An.update @ vendor-core.e1b0f11de3063d4a.js:2
t.$forceUpdate @ vendor-core.e1b0f11de3063d4a.js:2
y @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
Promise.then (async)
Qe.h @ vendor-core.e1b0f11de3063d4a.js:2
Qe @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
en @ vendor-core.e1b0f11de3063d4a.js:2
t._c @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ main.1d1995958c69eff1.js:1
t._render @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
init @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
N @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:2
t._update @ vendor-core.e1b0f11de3063d4a.js:2
r @ vendor-core.e1b0f11de3063d4a.js:2
An.get @ vendor-core.e1b0f11de3063d4a.js:2
An @ vendor-core.e1b0f11de3063d4a.js:2
t @ vendor-core.e1b0f11de3063d4a.js:2
Rn.$mount @ vendor-core.e1b0f11de3063d4a.js:2
(anonymous) @ main.1d1995958c69eff1.js:1
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
f @ vendor-core.e1b0f11de3063d4a.js:17
Promise.then (async)
d @ vendor-core.e1b0f11de3063d4a.js:17
f @ vendor-core.e1b0f11de3063d4a.js:17
Promise.then (async)
d @ vendor-core.e1b0f11de3063d4a.js:17
(anonymous) @ vendor-core.e1b0f11de3063d4a.js:17
v @ vendor-core.e1b0f11de3063d4a.js:17
We @ main.1d1995958c69eff1.js:1
(anonymous) @ main.1d1995958c69eff1.js:1
setTimeout (async)
edd6f @ main.1d1995958c69eff1.js:1
m @ runtime.bd95246eec31e407.js:1
t @ host.04c9b91d2c57cf26.js:1
(anonymous) @ host.04c9b91d2c57cf26.js:1
m.O @ runtime.bd95246eec31e407.js:1
(anonymous) @ host.04c9b91d2c57cf26.js:1
l @ runtime.bd95246eec31e407.js:1
(anonymous) @ host.04c9b91d2c57cf26.js:1

в консоли браузера. Воспроизводится на чистых Chrome, Safari, на настроенном Firefox. Все браузеры самых новых версий. Платформа MacOS, arm64/amd64.

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

Отписка "Начните принимать куку сайта". Мда...

Прячьте такие сообщения под спойлер, если не сложно, пожалуйста

А разгадка проста — это так вот работает "защита" от Cloudflare для не-РФ-ных IP-шников.


Залогиниваешься с IP РФ, после этого тебя перестаёт перенаправлять на CF, и начинает работать и с других IP.

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

Привет, спасибо за рассказ. Возникла пара вопросов:
  1. 4000 разработчиков в штате — пугающая цифра. Есть ли возможность немного описать разбиение людей по каким-то продуктам/группам? Или это не только Озон, но и какие-то другие проекты вашей фирмы?
  2. Платформенные команды забрали к себе все вкусные задачи, позволив продуктовым командам только разрабатывать бизнесовые фичи. Как вы боритесь с выгоранием людей в продуктовых командах, где нет никаких технологических челленджей, и нужно просто использовать готовые managed сервисы?

Могу ответить на 2 вопрос.

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

Платформа не придумывает алгоритмы для логистики, складов, для сервисов типа стоков и информации о товарах и т.п. Платформа не пишет оптимальные sql запросы в шардированном окружении. Платформа не занимается анализом hotpath и не ищет утечки памяти. Платформа не оптимизирует выделения памяти, не уменьшает потребление CPU и т.п. Этим всем занимаются именно продуктовые команды. Но да! Платформы дает больше средств для диагностики своих сервисов и, конечно, помогает командам, если у них возникают проблемы, для решения которых у них вдруг не хватает экспертизы.

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

А я попробую немного ответить на первый. Есть десять крупных направлений, которые расписаны здесь: https://tech.ozon.ru/#rec424970919

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

Ага, и отдавать начальству вот такую туфту: 5 млн RPS

Ну или у вас действительно столько RPS, но из них реально обслуживают бизнес хорошо если 5 000 RPS, но скорее всего меньше. А остальное - ну надо же чем-то загрузить 4000 разработчиков.

Некоторые команды были бы даже рады, если бы им приходилось бы обслуживать всего 5к, а не сотни тысяч запросов во время высокого сезона :)

Похоже ,что вы не знаете, как расшифровывается буква S в использованной вами аббревиатуре. Обычно это расшифровывается так - requests per second. А у вас, видимо, per day.

похоже, вы настолько боитесь больших чисел, что не в состоянии поверить в то, что вам говорят. если приглядеться на первый же скрин графаны, то можно увидеть там avg 26.1k req/s - и что-то мне подсказывает, что это далеко не самый нагруженный сервис и скрин сделан не в период пиковой нагрузки.

Похоже, что вы одинаково воспринимаете две очень разные цифры: 5 000 000 и 26 100.

На текущий момент Warden — большая сложная система

Выглядит так, что для эффективного управления работой 3500 микросервисов понадобился монолит? Надеюсь ошибся ;)

Нет, Warden - не монолит :) Он сам состоит уже из нескольких компонентов. Больше и сложнее он стал по сравнению с той самой первой версией, которую мы запустили в 20 году и которая умела работать только с кубером.

Интересно узнать адопшен? какой процент сервисов используют эти фичи?

Этот процент близок к 100%, потому что в большинстве случаев у команд просто нет никакой альтернативы, да она в целом и не нужна: зачем пытаться самому создавать кластер базы или чего-то еще, если можно сделать пару кликов и получить тоже самое.

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

5 миллионов RPS, то есть 432 миллиарда запросов в сутки, на 32.7 миллионов активных покупателей (официальная статистика компании) - это как-то ну прямо очень много. Либо вы выдаете пиковую нагрузку за типовую, либо у вас очень много паразитной нагрузки

еще не забываем про ботов и парсеров

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

Помимо запросов от пользователей, есть также и огромная офлайн часть компании: WMS (система управления складом), логистика и другие внутренние системы.

По описанию warden, вобрал некоторые идеи от linkerd, он кстати уже на go+rust переписан, и Twitter (Finagle), на котором тот базировался.

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

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

Очень интересно, спасибо!

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

И сколько это все отъедает ресурсов? хотя бы верхнеуровнево. Может вместо огромного paas дешевле было б просто нанять 100500 админов для обработки всех тасок?)

Спасибо за статью, одна из самых интересных на мой взгляд за последнее время. Подскажите, не планируете компоненты платформы, например, тот же warden опенсорсить? )

Ваша компания выкладывает что-нибудь в Open Source? Контрибутит куда-нибудь?

отвечу за рука, раз пока никто не ответил. У Озона есть проекты в Open source в Github: https://github.com/orgs/ozontech/repositories

Ещё описание всех проектов есть на сайте Ozon Tech: https://tech.ozon.ru/#rec424929921

Из проектов к Платформе точно относится file.d — супер быстрый инструмент для создания конвейеров данных

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

Полностью поддерживаю)

Ждём в или CE , или уже полностью сорцы ( хотя это нагло наверное)

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

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

Ха-ха-ха-ха.

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

Больше никакого Delphi — только современные технологии.

Питон появился в 1991 году, Делфи в 1995.

Просто оставлю это здесь.

Много проектов используют Delphi сейчас?)

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

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

Sign up to leave a comment.