предисловие
Почему мне вдруг захотелось написать резюме?Вообще-то меня оскорбили. В начале марта этого года наш торговый центр получил акцию на закупку одной точки от ХХ банка (грубо говоря, это была шерсть).На тот момент это был первый этап активности.Я никогда не думал, что когда вход активности был открыт, трафик мог напрямую загрузить ЦП на 100%, что привело к короткому 502 для службы. . В течение периода был принят аварийный план до конца события, но я никогда не думал, что будет вторая фаза события, и третья фаза события, которое было запущено на прошлой неделе. Думая о том, что я сделал недавно, и о некоторых подводных камнях, с которыми я столкнулся, я воспользуюсь этой возможностью, чтобы не полениться и записать это.
Что делали с первой по третью фазу события?
Технический фон и узкие места
Проект основан на архитектуре Vue + SSR, и кеширование не выполняется.Основная причина отсутствия кеширования заключается в том, что исходное tps приложения относительно низкое, мощность преобразования невелика, а результаты рендеринга страницы включают пользовательские данные и время на стороне сервера. Невозможно напрямую перейти к кешу без модификации. Поэтому, когда на первую фазу приходится большое количество операций, легко загрузить ЦП на 100 % при высокой степени параллелизма.
На первом этапе при неизвестных обстоятельствах услуга не могла быть оказана напрямую.В то время для нормального выполнения действий первым решением было добавить машину, чтобы выдерживать некоторое давление, а затем добавить кеш.Там в настоящее время есть два решения для кэширования: кэширование страниц или кэширование компонентов. , но поскольку наши компоненты страницы сведений о продукте, которые необходимо кэшировать, включают в себя динамическую информацию, удобство сопровождения слишком низкое, а умственные затраты высоки, мы, наконец, выбрали первое. Мы разобрали информацию и данные о динамических изменениях (данные по времени/пользователям и т.д.) на странице бизнес-деталей, во время мероприятия срочно заблокировали некоторый динамический контент, не влияющий на работу, а затем поставили CDN на страница.
После мероприятия мы сделали обзор: поскольку приложение должно обеспечивать стабильную работу в условиях большого трафика, неизбежна обработка по оптимизации производительности. С этой целью мы сделали следующие четыре программы:
-
Делайте динамическое и статическое разделение данных:Мы можем классифицировать данные на две категории: динамические и статические.Статические данные — это период времени, который не меняется со временем/пользователем, тогда как динамические данные — это наоборот, часто меняющиеся, связанные со временем, связанные с пользователем и другие типы данных. можно отнести к динамическим данным. Самым большим препятствием для невозможности кэширования исходной страницы является то, что когда узел отображает шаблон, он будет получать пользовательские данные по умолчанию или вызывать пользовательские интерфейсы в asyncData; кроме того, будут установлены динамические данные, такие как время сервера. Таким образом, идея состоит в том, чтобы разместить статические данные на узле для получения и динамические данные на клиенте (браузер считывает asyncData, монтирует и т. д. в жизненном цикле браузера), чтобы обеспечить чистоту сервера.
-
Доступ к странице CDN:После преобразования динамического и статического разделения его путь можно добавить в cdn. Однако нужно обратить внимание на то, не повлияют ли на отрисовку такие параметры, как запрос по пути, если да, то нужно перенести логику на клиент. время (например, 10 минут) повлияет на бизнес.
-
Кэш приложения:Если в худшем случае cdn выйдет из строя и скорость возврата возрастет, само приложение все равно нужно подготовить. Это требует выбора кеша памяти/кеша Redis в соответствии с потребностями проекта.
-
Автоматический переход на более раннюю версию:В крайних случаях предыдущий кеш не блокирует трафик, и требуется окончательное решение: понижение уровня рендеринга. Так называемый деградированный рендеринг означает, что пустой шаблон возвращается напрямую, без входа в маршрут, и полностью передается браузеру для рендеринга. Самым большим преимуществом этого является то, что он полностью избегает нагрузки на узлы и превращает приложение ssr в статическое приложение. Недостаток тоже очевиден, пользователь видит пустой шаблон и ему нужно дождаться инициализации. Как автоматически перейти на более раннюю версию?Вы можете определить нагрузку на текущую машину, проверяя время от времени давление процессора, нагрузку и т. Д. Через таймер, чтобы решить, следует ли переходить на более раннюю версию; вы также можете явно решить, следует ли понижать перенося определенный идентификатор на запрос URL-адреса.
После того, как вышеописанная оптимизация производительности была проведена по плану проекта, следующим этапом стал стресс-тест, который был признан успешно запущенным. 🤪
Скоро снова наступит вторая фаза ивента, но как мы и ожидали, проект стабильно выдерживает нагрузки, за это время также был добавлен интерфейс трафика, а также добавлены такие оптимизации, как дружественные подсказки. Однако одной из болевых точек является необходимость сделать процесс копирайтинга для нескольких специальных продуктов, которые не возвращаются через интерфейс, а также представляют собой какие-то временные привлекающие внимание подсказки, и нет необходимости возвращать их в интерфейсе веб-сайта. страница подробностей. Так как время тоже очень срочное, мы не уверены, будет ли такое конкретное требование к копирайтингу в будущем (связанное с конкретными страницами и конкретными областями), поэтому мы решили временно написать какой-то низкий код: для определенного идентификатора продукта события, временно добавить копирайтинг, После оффлайн мероприятия удалить копию. При этом есть риск, ведь код временный, должен быть онлайн и оффлайн, и есть временная задержка. К счастью, конец мероприятия был выходным, и посещаемость в последний день была невелика.Была предоставлена соответствующая копия руководства и послепродажная обработка.После оценки влияние было небольшим и приемлемым.
Конкретная копия, которую необходимо добавить на страницу сведений о продукте и страницу покупки продукта следующих изображений:
Шерстяная активность действительно ароматная сцена?Продукт встретил меня в конце июня, сказав, что будет еще три фазы активности XX, но общий план остается таким же, как и второй этап. Мое сердце: все еще идет? ? ? (Шёпотом, что слишком тяжело работать рабочим), потому что окончательное время не установлено, и после второй фазы урока я также обсуждал с задними одноклассниками, и рассматривал активные товары в направлении конфигурации, и поместите их в фон нашей конфигурации.Китайский модуль сценария и это возможно. Для страницы сведений о продукте, учитывая, что динамическое и статическое разделение не будет нарушено, сначала убедитесь, что данные, возвращаемые интерфейсом конфигурации, являются статическими и могут быть получены с сервера. Выполняются следующие три конкретных действия:
- Внесите в конфигурацию копирайтинг продуктов, участвующих в мероприятии, получите его из интерфейса конфигурации и удалите лоу-код
- Организуйте интерфейсы страниц с высокой посещаемостью (например, страницы сведений о бизнесе), а интерфейс на клиенте должен быть ограничен по току.После того, как интерфейс достигнет определенного tps, он вернется к статусу 429, а фронт- end должен выполнять отказоустойчивую обработку.Доступ к функциям страницы осуществляется нормально, а интерфейс ограничения тока заблокирован.ошибка.
- Для покупки текущего ограничивающего интерфейса вам необходимо дать сообщение о занятости (активность слишком популярна, повторите попытку позже)
// 统一在 getResponseErrorInterceptor 处针对 429 状态做处理
export const getResponseErrorInterceptor = ({ errorCallback }) => (error) => {
if (!isClient) {
...
} else {
// 429 Code 服务报错需要支持不弹出错误提示
if (+error.response.status === 429) {
// 针对限流接口,且需要 busy 提示时增加 needBusyMsg 属性
errorCallback(error.config.needBusyMsg ? '活动太火爆了,请稍后再试' : null);
} else {
...
);
}
}
return throwError(error);
};
После напряженной недели стресс-тестирования и тестирования на прошлой неделе наконец-то был запущен третий этап. 👏👏👏👏
Чтобы узнать больше о решениях по оптимизации производительности Vue SSR, вы можете перейти сюда:Практика оптимизации производительности Vue SSR
Некоторые вопросы кодирования, возникающие в реальном процессе
- В локальном проекте (архитектура vue-ssr), когда динамический интерфейс размещается на сервере для получения, есть очень простой фрагмент кода: логотип участника, позволяющий отображать и скрывать кнопку участника. Код выглядит следующим образом (код упрощен):
<redirect
v-if="!isVip"
:link="link"
type="h5"
>
开通会员<ui-icon name="arrow-right" />
</redirect>
Хотя он работает нормально локально, будет следующее предупреждение:vue.esm.js:6428 Mismatching childNodes vs. VNodes: NodeList(2) [div, a.DetailVip-right.Redirect] (2) [VNode, VNode]
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
Но обновите тестовую среду, страница будет недействительной, клик недействителен и т. д. Будет сообщено о следующей ошибке:Failed to execute 'appendChild' on 'Node': This node type does not support this method
анализировать
Руководство по Vue SSR находится по адресуАктивация клиентаЯ только что упомянул о некоторых подводных камнях, на которые следует обратить внимание.При использовании «гибрида SSR + на стороне клиента» вам нужно понимать одну вещь: некоторые специальные структуры HTML, которые могут изменяться браузерами. Например, отсутствует запись в таблице<tbody>, следующие ситуации также приведут к несоответствию между статическим HTML, возвращаемым сервером, и содержимым, отображаемым браузером:
- Неверный
HTML(Например:<p><p>Text</p></p>) - Различные состояния сервера и клиента
- Влияние неопределенных переменных, таких как даты, временные метки и рандомизация
- Сторонние скрипты влияют на отрисовку компонентов
- Когда требуется аутентификация
Конечно, после определения причины и назначения правильного лекарства есть несколько способов решения этой проблемы:
- Проверьте соответствующий код, чтобы убедиться, что HTML действителен.
- Самый простой и грубый способ - использовать
v-showзаменитьv-if, чтобы знать, что время сборки сгенерировалоHTMLНе имеет состояния, все части приложения, связанные с проверкой подлинности, должны отображаться только на стороне клиента, что может быть изменено для получения данных и содержимого, представленных на сервере/клиенте, для устранения несоответствия состояния между сервером и клиентом. - Перед лицом сторонних скриптов вы можете избежать рендеринга компонентов на стороне сервера, заключив их в теги.
- ..... (Добро пожаловать, чтобы добавить)
Для таких проблем вы также можете увидеть эту статью:blog.Lichter.IO/posts/v UE - также…
2: Та же страница h5, конфигурация вступает в силу при открытии в браузере, но не работает при открытии в официальном аккаунте и апплете?
На третьем этапе мы сделали активный идентификатор продукта и соответствующую копию в процессе настройки. Конфигурация выглядит следующим образом:
После получения содержимого конфигурации продукта и выполнения JSON.stringify() вы, несомненно, получите следующую строку:
455164527672033280|龙支付 立减 10 元|满 40 立减 10(仅限 XX 卡)#\\n623841656577658880|龙支付 立减 10 元(仅限 XX 卡)|满 40 立减 10(仅限 XX 卡)#\\n350947143063699456|龙支付测试 立减 10 元(仅限 XX 卡)|满 40 立减 10 测试(仅限 XX 卡)#
Получите всю информацию о списке идентификаторов продуктов на странице сведений, мы используем#Чтобы отличить, напишите простой регуляр следующим образом:
activityItems() {
return this.getFieldValue('activity_item')?.split('#\\n');
},
Но открытие нашей ссылки h5 в официальном аккаунте будет#автоматически сбежал в\, содержимое станет:
455164527672033280|龙支付 立减 10 元(仅限 XX 卡)|满 40 立减 10(仅限 XX 卡)\\\n623841656577658880|龙支付 立减 10 元(仅限 XX 卡)|满 40 立减 10(仅限 XX 卡)\\\n350947143063699456|龙支付测试 立减 10 元(仅限 XX 卡)|满 40 立减 10 测试(仅限 XX 卡)\
Ах, это, не так ли? ? (чуть не рухнул, когда узнал) 😩 Решение сразу#символы заменены на символы, которые не переносятся;.
Кроме того, сбой при открытии в апплете произошел из-за того, что план второго этапа был расширен. В то время было принято ограниченное решение. Для эффективности его нужно открыть только на главной станции и в основном приложении. у апплета свой отдельный appid, а третья фаза имеет несколько входов, просто снимите это ограничение.
Суммировать
Я участвовал в третьей фазе, и у меня тоже накопился некоторый опыт, я наступил на некоторые ямы, я думаю, что прошло много времени с тех пор, как я ее писал.
Суммировать
- Предварительный просмотр Vue SSR:ssr.vuejs.org/zh/
- Практики производительности Vue SSR:Наггетс.Талант/пост/688788…
- Vur-hydration-error: blog.Lichter.IO/posts/v UE - также…