Русский
Русский
English
Статистика
Реклама

Блог компании deutsche telekom it solutions (ex t-systems)

Для нас главное это желание учиться и развиваться в DevOps преподаватели и менторы о том, как учат в DevOps-школе

01.10.2020 18:11:51 | Автор: admin

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

К счастью, учиться никогда не поздно. Особенно если вы захотели стать DevOps-инженером.

Этим летом наши коллеги запустили первый поток DevOps-школы и готовятся стартовать в ноябре второй. Если вы давно размышляете над тем, чтобы стать DevOps-инженером, добро пожаловать под кат!

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

- С чего началось создание DevOps-школы?

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

Алексей Шарапов, техлид, ведущий ментор: В прошлом году мы брали студентов на работу как интернов, воспитывали джунов. Студентам или выпускникам университетов тяжело найти работу, потому что требуют опыт, а опыт не получить,если на работу не берут - получается порочный круг. Поэтому мы давали ребятам возможность себя проявить, и сейчас успешно работают. Среди наших стажеров был один парень - инженер-конструктор на заводе, но умевший немного программировать и работать на линуксе. Да, у него не было какие-то крутых навыков, но у него горели глаза. Для меня в людях главное - это отношение, желание учиться и развиваться.Для нас каждый студент - это стартап, в который инвестируем свое время и опыт. Мы даем шанс каждому и готовы помогать, но студент сам должен взять на себя ответственность за свое будущее.

Лев Гончаров aka @ultral, ведущий инженер, евангелист рефакторинга инфраструктуры через тестирование: Около 2-3 лет назад я загорелся идей нести IaC в массы и сделал внутренний курс по Ansible. Уже тогда ходили разговоры, как объединить разрозненные курсы одной идей. Позже к этому добавилось потребность на проекте расширить инфраструктурную команду. Посмотрев на удачный опыт соседних команд по развитию выпускников Java School, сложно было отказаться от предложения Стаса по организации DevOps-школы. Как итог - на своем проекте мы закрыли потребность в специалистах после первого же выпуска.

- Что нужно для того, чтобы попасть в школу?

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

Лев Гончаров: Конкретные технический hard skill - это дело наживное. Главное, чтобы был инженерный подход к решению проблем. Совсем не будет лишним знать язык, ведь DevOps-инженер, как человек-клей, должен вылепливать процессы, а это, как ни крути, подразумевает коммуникацию и не всегда на русском языке. Но язык так же можно прокачать на курсах внутри компании.

- Обучение в DevOps-школе длится два месяца. Чему за это время смогут научиться слушатели?

Илья Кутузов, преподаватель, лидер DevOps-сообщества в Deutsche Telekom IT Solutions: Сейчас мы даем студентам только необходимые для работы hard skills:

  • DevOps basics

  • Development toolkit

  • Containers

  • CI/CD

  • Clouds & orchestration

  • Monitoring

  • Configuration management

  • Development

Лекции в DevOps-школе по ту сторону экранаЛекции в DevOps-школе по ту сторону экрана

- Что произойдет после того, как студент освоит программу курса?

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

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

Станислав Салангин:
Да, собрать команду и, главное, удержать ее, не дать разбежаться и продолжать мотивировать было поначалу очень тяжело. Но все преподаватели и менторы школы - наши сотрудники. Это DevOps-лиды в проектах, которые знают, как наши проекты работают изнутри, искренне болеют за свое дело и за компанию.Мы называемся школой, а не академией или курсами, потому что, как в настоящей школе, для нас огромное значение имеет близкое общение преподавателя со студентами. Мы планируем организовать со студентами свое комьюнити - не чатик в Телеграме, а сообщество единомышленников, которые встречаются лично, помогают друг другу и развиваются.

Дримтим преподавателей и менторов. Надеемся скоро встретиться и сделать общую фотографию лично!Дримтим преподавателей и менторов. Надеемся скоро встретиться и сделать общую фотографию лично!

- Чем вы занимаетесь в DevOps-школе?

Илья Кутузов, преподаватель, лидер DevOps-сообщества в Deutsche Telekom IT Solutions:

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

Почему DevOps-школа? Онлайн-курс не дает быстрого погружения и не дает практического навыка работы с технологией. Любая виртуальная школа не даст ощущения, что ты действительно умеешь решать практические задачи и сможешь разобраться с реальной проблемой на проекте. То, с чем студенты столкнутся во время обучения, с тем они и будут работать в проектах.

Алексей Шарапов, техлид, руководитель и ментор школы:

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

Игорь Ренькас, к.т.н., ментор, product owner:

Я занимаюсь менторингом студентом в школе, а также помогаю Станиславу в организации и развитии школы. Первый блин, на мой взгляд, не вышел комом и мы успешно стартовали, но сейчас мы, конечно же, работаем над тем, что можно улучшить в школе: думаем над модульным форматом, обучением по ступеням, хотим в будущем учить не только hard skills, но и soft skills. У нас не было проторенной дороги и готовых решений. Мы искали преподавателей среди коллег, продумывали лекции, курсовой проект, организовывали все с нуля. Но в этом и заключается наш главный челлендж и вся прелесть школы: мы идем по своему пути, делаем так, как нам кажется правильным и как лучше для наших студентов.

Лев Гончаров aka @ultral, ведущий инженер, евангелист рефакторинга инфраструктуры через тестирование:

Я учу студентов Configuration management и как с ним жить. Что будет недостаточно, что-то положить в git, необходимо изменить парадигму мышления и подходы. Что инфраструктура как код - это значит не только написать некий код, но сделать поддерживаемое, понятное решение. Если про технологии, то рассказываю в основном про Ansible и вскользь упоминаю, как его состыковать с Jenkins, Packer, Terraform.

- Коллеги, спасибо за интервью! Что скажете читателям напоследок?

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

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

DevOps-школа - это open source проект. Мы делаем это для сообщества, делимся знаниями, искренне хотим помочь ребятам, у которых есть желание развиваться в DevOps. Сейчас в нашей компании для джунов открыты все дороги. Главное - не бояться!

Подробнее..

Главное мотивированность и настойчивость как в Deutsche Telekom IT Solutions растят своих специалистов

25.05.2021 18:15:50 | Автор: admin

Как выглядит типичный процесс отбора на стажировку? Есть ли у выпускников гуманитарных вузов шансы на трудоустройство в IT? Как найти способного стажёра и вырастить из него настоящего специалиста? Сотрудники Т Дмитрий Балахонов и Сергей Морозов набирали ребят в свои команды, преследуя разные цели, но в итоге пришли к схожим выводам. Этими выводами, а также интересными историями из практики, коллеги готовы поделиться с читателями Хабра.

День карьеры на факультете прикладной математики и механики Воронежского госуниверситетаДень карьеры на факультете прикладной математики и механики Воронежского госуниверситета

Вы оба набирали стажёров. Почему возникла такая потребность?

Сергей: В компании я являюсь руководителем трайба Test Management SSC Russia. Одна из моих задач это поиск стажёров для различных проектов, не только для себя, но и для коллег. Часть стажёров приходит к нам непосредственно через HR-отдел. Например, они могут увидеть вакансию на корпоративном сайте или на HH.ru и откликнуться. Других мы находим через программу рекомендаций, в рамках которой действующие сотрудники могут предлагать кандидатуры своих знакомых. В случае прохождения стажировки и успешного трудойствойства кандидата такой сотрудник получает бонус. Наконец, кого-то мне приходилось искать и самостоятельно.

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

Дмитрий: У меня немного другая специфика. Сергей набирает людей про запас, чтобы сначала выучить, а уже потом выбрать для них проект. Мне нужны были стажёры в конкретную команду в проект Open Telekom Cloud. Задача была важная, требующая оперативного решения, поэтому я сам был замотивирован заниматься поиском.

По какой причине чаще всего отсеиваются кандидаты?

Сергей: Самый большой отсев происходит из-за английского. Причём у нас не такие уж высокие требования. В идеале, конечно, B2. Но на практике можно и чуть-чуть снизить планку. Если говорить о стажёрском уровне, то вполне достаточно, чтобы человек мог понять вопрос на чужом языке и ответить на него, пусть с ошибками, но чтобы основная мысль была понятна.

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

Дмитрий: Справедливо. Грубо говоря, проще взять выпускника или выпускницу факультета романо-германской филологии и помочь освоить тестирование, чем взять вроде бы продвинутого человека с факультета компьютерных наук, но с нуля учить его английскому или немецкому.

Сергей: Часто в резюме написано B2, С1, а человек этому уровню не соответствует. История из реальной практики. Приходит ко мне кандидат. В резюме указано, что уровень владения английским С1, т.е. продвинутый. Спрашиваю: Could you please briefly tell us about yourself?. Отвечает на русском: Извините, я сегодня рассказ о себе не готовил. То есть даже эту фразу произнести на английском он не смог.

Дмитрий: А есть и противоположное. Человек скромничает, мол, я на английском только вино у бармена в Турции заказывал, а когда предлагаешь ему пообщаться он раскрывается. Выясняется, что никаких проблем, никакого языкового барьера у него нет.

По каким ещё критериям проходит отбор?

Сергей МорозовСергей Морозов

Сергей: Если речь идёт именно о стажёрах, то завышенных требований мы не выдвигаем. Мы просто хотим увидеть, что у человека есть элементарная техническая база (SQL, REST, понимание протокола HTTP и т.п.). Можем давать простейшие задачи на программирование. Важно, чтобы человек, помимо упомянутого владения языком, просто обладал логическим мышлением и был способен к обучению.

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

А что важно указывать в CV?

Сергей: Я всегда говорю обязательно пишите ключевые слова по вашим компетенциям, даже если вы не очень глубоко в чём-то разбираетесь. Речь ведь идёт о стажировке, а не о полноценной занятости. Если читали книжку по профильной теме, проходили курс, даже видео на Youtube смотрели, пишите об этом в CV. Интервьюеру это позволит найти темы для разговора и в итоге максимально раскрыть кандидата. А так мы порой вынуждены сами буквально выуживать из человека информацию.

Дмитрий: Да, это очень типично. Как-то перед собеседованием я просматривал резюме девушки, которую мне рекомендовали как хорошего специалиста в Python. Так у неё ни разу слово Python в CV не мелькнуло. Если бы я изначально об этом её навыке не знал, то как должен был догадаться?

Такое ощущение, что сейчас бум платных курсов по программированию и тестированию. Часто их указывают в CV?

Сергей: Да, они встречаются. Но у меня к ним скептическое отношение. Конечно, если платные курсы есть в CV, это лучше, чем ничего. Но при прочих равных условиях я бы предпочёл видеть там стажировку в конкурирующей IT-компании. Обучение в таких компаниях, как ни крути, выгоднее для человека, чем платные курсы. Во-первых, не нужно платить деньги. Во-вторых, IT-компании реально заинтересованы в том, чтобы вырастить специалиста и устроить его в свой проект, а не заработать на обучении. А платные школы это всё-таки коммерческая история, и нередко бывает так, что за красивой картинкой там ничего не стоит. Не буду обвинять всех подряд, но такое действительно бывает. Поэтому важно читать отзывы о школах и образовательных курсах, общаться с теми, кто их уже проходил, чтобы иметь релевантную информацию.

Но если человек прошёл стажировку в другой компании и его не взяли на младшего инженера, значит, он недостаточно хорош. Разве не так?

Сергей: Не совсем. Возможно, в другой компании были очень высокие требования в конкретном проекте, на который набирали стажёров. И у нас бывают проекты разного уровня, в том числе сложные для освоения начинающими специалистами. В 2018 году у меня была группа из пяти стажёров. По окончании стажировки трёх забрали проекты, а двоих не взяли. В итоге один из стажёров устроился к нам на следующий год, а другой нашёл работу у конкурента. Так что всё относительно, целеустремлённый человек рано или поздно найдёт себя.

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

Как проходит стажировка? Ваши подходы чем-то отличаются?

Сергей: На стажировке к человеку прикрепляется ментор или несколько менторов, каждый из которых покрывает какую-то тему. Кто-то может о Java рассказывать, кто-то преподавать теорию тестирования и т.д. Сама программа обучения составляется так: мы смотрим, в каких проектах в ближайшем будущем готовы взять младших инженеров и какие требования есть в этих проектах по технологиям. Исходя из этого находим менторов с нужными скиллами.

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

Дмитрий: Я уже говорил, что мы берём людей в конкретный проект. Люди сразу работают над реальными задачами. Что касается подбора менторов, то здесь есть два варианта развития событий. В каких-то командах Open Telekom Cloud много специалистов из России, а в каких-то единицы. Может сложиться, что стажёр попадёт в команду, где вообще никого из России нет. Ментором тогда станет иностранец и задания будут исходить от него. Но в таком случае мы всё равно подыскиваем и русскоязычного наставника. Его можно найти в другой команде, которая выполняет похожие задачи.

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

Сергей: В моей практике есть несколько успешных кейсов. В основном они связаны с тестированием. Например, у нас стажировалась девушка, которая окончила строительный университет и до этого восемь лет работала архитектором. Сейчас успешно влилась в IT, более двух лет работает в нашей компании. Или был молодой человек, который десять лет трудился в ресторанном бизнесе: барменом, менеджером и т.д. Потом он вдруг решил переквалифицироваться в QA. Тоже работает сейчас у нас и прекрасно справляется.

А какой вообще процент стажёров в итоге становится специалистами?

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

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

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

Сергей: Преимущества стажировок для компании налицо. Найти стажёра проще, чем синьора. Его легче интегрировать в корпоративную культуру. А при наличии способностей он будет быстро продвигаться внутри команды. Если при этом и другие специалисты не останавливаются в развитии, система начинает работать по-настоящему эффективно. Ведь можно же и мидла развить до уровня синьора, ставя перед ним чёткие цели. А когда он достигнет нужного уровня, то в свою очередь освободит место для бывшего стажёра. Это прекрасный путь, который позволяет развивать команду и давать людям возможности для роста.

Подробнее..

Ребёнок всё время в планшете. Отбираем и прячем или вместе развиваем цифровой интеллект?

25.01.2021 16:17:27 | Автор: admin

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

Матчасть. Термин и цифры

Эксперты прогнозируют, что 90% населения будет подключено к интернету в течение ближайших 10 лет. В статье Стефани Томпсон (редактора журнала Всемирного экономического форума) был проведен опрос 800 экспертов и руководителей в ИТ-отрасли, чтобы понять, как выглядит наше цифровое будущее. Более подробно можно посмотреть здесь

Статистика опроса

С каждым годом становится всё труднее справляться с быстрым ростом технологий и адаптироваться к ним. Поэтому человечеству необходимо приспосабливаться к изменяющимся условиям окружающего мира. Для того, чтобы приспособиться к новым ситуациям выживания, природа снабдила человека интеллектом. Существует теория Множественного интеллекта Гарварда Гарднера, согласно которой у человека существует несколько видов интеллекта: лингвистический, логикоматематический, пространственный, музыкальный, телеснокинестетический, личностный модуль. На сегодняшний день в такую классификацию добавлен эмоциональный и социальный интеллект. Каждый вид интеллекта развивается по-разному.

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

Да, такой интеллект существует и недавно ученые выделили такое понятие как Digital quotient (DQ) Цифровой интеллект. Термин Цифровой интеллект это абсолютно новое понятие, которое не стоит путать с искусственным интеллектом и машинным обучением. Например, профессор Yuhyun Park в своих исследованиях дает следующее определение цифрового интеллекта:

Цифровой интеллект (DQ) это комплексный набор технических, когнитивных и социально эмоциональных компетенций, которые позволяют людям решать задачи цифровой жизни и адаптироваться к ним.

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

И вот более наглядно:

Развитие цифрового интеллекта: практическое применение

Итак, в нашем могучем человеческом мозге появилось место для еще одного вида интеллекта. Это прекрасно! Но для чего мы можем применить его развитие на практике?

Одно из главных борьба с киберпреступностью!

Статистика киберпреступности

По результатам ежегодного исследования Norton Cybercrime Report, одного из крупнейших в мире исследований в сфере киберпреступлений в отношении пользователей, ущерб от киберпреступности за 2021 год будет оценивать в 6 триллионов долларов. Согласно результатам исследования, каждую секунду 18 пользователей старше восемнадцати лет становятся жертвами киберпреступности, ежедневно это более полутора миллионов жертв в мире. Средний ущерб от кибератаки на одного среднестатистического пользователясоставляет $197. За последний год примерно 556 миллионов пользователей старше 18 лет во всем мире пострадали от киберпреступности, это больше, чем все население Европейского Союза. Полную статистику можно найти, например вот тут. Цифры выглядят не очень, правда? К сожалению, жертвами мошенников становятся не только пожилые люди, но и молодежь, которая игнорирует правила безопасности в Интернете. Именно поэтому необходимо начинать прививать цифровую грамотность еще с детства.

Развиваем DQ у детей

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

Тем более, что гаджеты это не всегда вселенское зло для детей. Кроме доступа к актуальным сейчас онлайн-занятиям, существует много интересных приложений которые развивают критическое мышление, интеллект и многие другие навыки: например, Меморадо, Mekorama, Minecraft, в котором можно постигать азы программирования и т.д.

Метод Помидоро

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

Жулик, не воруй

Когда фундамент обращения с гаджетами заложен, можно начинать рассказывать ребенку о безопасности в Сети. Эта задача оказалась сложнее: для моей дочки мошенник в интернете, в отличие от того же незнакомца на улице, это что-то совсем абстрактное и мифическое. Здесь помогает проговаривание и сказки, особенно сказки про жуликов в интернете. У Л.Петрановской есть хороший цикл книг Что делать если? это про трудные моменты в реальной жизни и как с ними справляться ребенку. Вот если бы кто-то ещё написал такую книгу для детей про киберпреступность

Следующий момент, который мы стали прорабатывать это приватность. Как и многим детям, в один прекрасный момент нашей дочери захотелось снимать и выкладывать всю свою жизнь в Instagram, Youtube, Likee, TikTok и так далее. Вначале мы поддались самому простому и неправильному способу: забили на объяснение и просто сказали: Нет и все. Но в какой-то момент все-таки пришлось выйти на разговор. И мы стали объяснять на довольно понятных терминах ребенку о том, что нужно думать о том, что ты хочешь разместить в интернете, рассказали историю про мошенников, которые могут воспользоваться информацией, полученной из этих видео и как они могут навредить ей. И она нас услышала! В таких разговорах хорошо помогает метод коучинга и вопросов: например, Для чего тебе это? и Что ты хочешь показать людям?, чтобы ребенок мог сам смог задуматься, насколько это ему необходимо. На своем опыте я поняла, что дети готовы к серьезным разговорам. Чаще всего не готовы взрослые, потому что не всегда понимают, как объяснить и донести свою мысль до ребенка.

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

Есть ли у вас опыт обучения ребенка тому, как использовать гаджеты и находиться в Сети? Буду рада, если вы поделитесь им в комментариях!

Подробнее..

Как я делал свой самолёт

14.11.2020 16:05:59 | Автор: admin
image

Здравствуйте, дорогие Хабровчане!

Меня зовут Константин Томаревский. Я инженер компании Deutsche Telekom IT Sotutions. Хотел поделиться с Вами своей давней задумкой, которую пытаюсь воплотить в железе.

По образованию я авиационный инженер. Когда я поступал в Университет СПбГПУ, я мечтал о том, что буду конструировать самолёты (ну или космические ракеты), буду работать в каком-нибудь конструкторском бюро и проводить рабочие дни за математическими расчётами, лабораторными стендами и полевыми испытаниями. Я закончил Университет, получив там очень много теоретических знаний, но ни разу не прикоснувшись к настоящей практике. Прошло уже много времени, но мысль о том, что мои знания так и остались знаниями, и не воплотились в практической плоскости, не покидала меня и я решил попробовать сделать пусть и совсем не большой, но реально функционирующий по всем правилам летательный аппарат.

image

Первоначальная идея


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

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

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

Развитие идеи


Когда-то давно, ещё в школьные времена, я ходил на радиокружок. Рядом с ним на этаже располагались также судомодельный и авиамодельный. Я иногда заходил к авиамоделистам и смотрел как они работают. Когда начал заниматься этим проектом, прошерстил Интернет на предмет технологии создания авиамоделей, пересмотрел много роликов на YouTube и понял, что этого мне мало. Я не хочу создавать одиночную модель из чего попало. Нужна была настоящая технология, с помощью которой, воспользовавшись ей единожды, я смогу делать одинаково точные модели в любом количестве. Как на конвейере. Выбор незамедлительно пал на 3D-моделирование и 3D-печать. Эти технологии позволяют создавать самые разнообразные формы аэродинамических поверхностей с большой точностью.

Расчёт планера


Та ещё задачка. Прежде всего нужно было определиться с размерами. Забегая вперёд, от этого зависело то, как придётся резать модель для того, чтобы её можно было напечатать на 3D принтере область печати не резиновая. Я принял решение, что это будет узкофюзеляжный низкоплан с классическим хвостовым оперением. Я задал следующие параметры:

  • длина корпуса: 90 см

Параметры крыла:

  • размах: 130 см
  • удлинение: 7,8
  • сужение 2,5
  • площадь: 2160 кв. см
  • геометрическая крутка 4 градуса
  • аэродинамическая крутка нет
  • поперечное V 5 градусов
  • профиль крыла ЦАГИ-718 14%

Двигатель:

  • электрический бесколлекторный
  • заявленная тяга двигателя ~ 10Н
  • Двухлопастной винт 10 Х 7

Трёхопорное шасси с основными стойками под крыльями и носовой стойкой. Все шасси убирающиеся, переднее шасси может поворачиваться. При массе всей конструкции со всеми силовыми и управляющими компонентами и электроникой 1,8 кг расчётная скорость взлёта при угле атаки 12 градусов примерно 10 м/с.

Проектирование


На первом курсе университета у нас была инженерная графика на компьютере в среде Компас. Поэтому и сейчас выбор среды моделирования пал именно на него. Только тогда 3D мы не проходили, поэтому пришлось эту область осваивать самому. И это оказалось безумно интересно! Вот что получилось:

image

Ну или так:

image

3D печать


Для печати был приобретён один из самых простых 3D принтеров. На самом деле, расчёт планера, проектирование и печать были тесно переплетены. Дойдя на определённом этапе до проектирования и печати, приходилось часто возвращаться назад и пересматривать расчёты, первоначальные параметры. Что-то было слишком сложно реализовать с учётом ограниченной области печати принтера и особенностей печати, что-то просто отбросилось за ненадобностью. Некоторые части (например крылья), пришлось перепроектировать с учётом прочности пластика (утолщать стенки). Ещё одной из задач было сделать так, чтобы не было ни одного клееного или паянного соединения. Я старался проектировать модель таким образом, чтобы некоторые части можно было перепроектировать и перепечатать, не затрагивая всю модель. После долгих усилий и примерно 230 часов печати и перепечатывания получилось следующее:

image

Я начинал проектирование модели с хвоста. Первым печатался также хвост. От этого качество печати хвоста не лучшее. Постепенно осваивая печать, я довёл её до довольно высокого качества. Масса всей конструкции получилась чуть больше 2 кг что оказалось несколько больше проектной.

Вид с хвоста:

image

Передняя стойка шасси:

image

Расположение двигателя:

image

Промежуточный итог


Что мы имеем по внутреннему оснащению:

  • Двигатель
  • Литий-полимерный аккумулятор на 6000 миллиампер-часов
  • 6 сервоприводов
  • 3 стойки шасси

Лётных испытаний ещё не проводилось. Надо ещё много чего доделать. Кроме того, я ещё не определился с выбором пульта управления. Об этом буду рассказывать в следующих постах.

Вспомним старый добрый спор, всколыхнувший в своё время многие форумы в Интернете взлетит или не взлетит?
Подробнее..

Как сделать так, чтобы умные лампочки не глупели при перебоях питания

10.12.2020 10:23:48 | Автор: admin

Если вы когда-либо обзаведётесь технологиями умного дома, то скорее всего, в числе первых купленных устройств у вас окажутся именно умные лампочки. Они действительно удобны. Включение-выключение света при движении. По таймеру. Плавное нарастание яркости для более комфортного пробуждения. Разные цветовые температуры. И так далее.

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

Я говорю о том, как умные лампочки реагируют на кратковременный перебой в подаче электроэнергии.

Глупые умные лампочки

Не та лампочка умная, что включается по желанию твоему, а та, что НЕ включается, когда ты не хочешь того народная мудрость

Для начала позвольте вопрос: как думаете, что произойдёт с погашенной умной лампочкой, если в квартире вдруг мигнёт электричество? Она включится. Если это произойдёт ночью, а лампочка установлена неподалёку от кровати, то сами понимаете, ощущения будут не из приятных. Спросонок даже не сразу сообразишь, что произошло и почему вокруг так светло.

Почему при скачке напряжения они включаются? Есть мнение, что это сделано для обратной совместимости с обычными глупыми лампочками. Если вы вкрутите умную лампочку в патрон, управляемый обычным выключателем, она должна работать. Появляется питание -> лампочка включается. Именно это и приводит нас к неприятному побочному эффекту при нештатном исчезновении и повторной подаче питания. К сожалению, умные лампочки недостаточно умные, чтобы такое поведение было настраиваемо. Есть, впрочем, исключения, о которых ниже.

Когда я впервые столкнулся с этим, то был удивлён. Вернее я сначала был разбужен светом в глаза, а удивление пришло секундой позже. Заглянув за решением в Интернет я нашёл много товарищей по несчастью, задающих извечный вопрос что делать. А вот с ответами было негусто. Они варьировались от замены умных лампочек умными же розетками до примеров скриптов в логику умного дома, которые при обнаружении горящей посреди ночи лампочки посылали бы команду на выключение.

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

Умные технологии, ага.

Решение

По щучьему веленью, по моемухотенью Народная мудрость

Идеальный конечный результат, в моём понимании, был бы таким умная лампочка может быть настроена на умное поведение при перебое питания. А именно: при подаче питания вместо включения на максимальную яркость, лампочку можно заставить оставаться выключенной или, скажем, восстанавливать предыдущее состояние (к примеру, если в момент перебоя с электричеством лампочка была включена на 30% яркости, то восстанавливается тот же самый режим).

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

И вот однажды я натыкаюсь на такую запись на странице замечательного проекта zigbee2MQTT

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

Описания обновлений прошивок (ссылка) и приложения iOS (ссылка). Упоминание функции power-on behavior.

Уж не знаю, чем вызвана такая застенчивость по отношению к функциональности, которую они сами описывают как долгожданную (вольный перевод фразы long awaited). Что же касается других производителей, то я не смог найти аналогичную настройку. Возможно, они стесняются ещё сильнее (хотя казалось бы, куда сильнее-то). Если вам такие известны, пожалуйста, напишите в комментарии.

решение доступное всем, но неполное

В теории нет разницы между теорией и практикой. А на практике есть

Итак, лампочки с нужной заявленной функцией есть, остаётся только купить и спать спокойно. Но где там. Самое интересное всегда начинается, как только дело доходит до реального использования. А практика показала, что через официальное приложение лампочки можно настроить только следующим образом.

Интерфейс приложения Philips Hue Bluetooth. Я привожу настройки на русском и английском, т.к. перевод с английского хромает и вводит в заблуждение.Интерфейс приложения Philips Hue Bluetooth. Я привожу настройки на русском и английском, т.к. перевод с английского хромает и вводит в заблуждение.

Нас интересует настройка со значком молнии. Именно она оставит лампу в выключенном состоянии если она была выключена и произошёл перебой в подаче питания. Вот оно решение! Однако, тут как в том анекдоте, есть нюанс. Если свет мигнёт дважды в течение 15 секунд, то лампочка включится принудительно причём на максимальную яркость и мы снова проснёмся посреди ночи в поисках выключателя. Об этом даже написано в приложении. Интервал в 15 секунд проверен мной на лампочке с артикулом 9290023349 и прошивкой 1.65.11_hB798F2BF от 11 мая 2020.

Конечно, шанс получить двойной перебой питания питания с интервалом в 15 секунд ниже чем получить одиночный. Но он всё-таки есть.

Если бы я не увлекался умными устройствами с интерфейсом ZigBee и не наткнулся на эту функциональность именно на сайте проекта zigbee2MQTT, я бы тут же бросил эту затею. Да и статью на Хабр писать не стоило бы

и решение полное, но не для всех

Если долго мучиться, Что-нибудь получится

Оказывается, что по протоколу ZigBee доступна ещё одна возможность настройки, до которой не добраться из приложения. Она позволяет настроить умную лампочку на режим всегда выключена. То есть как бы быстро напряжение ни мигало, или как бы яростно вы ни щёлкали выключателем, лампочка не включится. Включить её можно только через сопряжённые устройства умного дома (ZigBee-координатор или всё ту же Bluetooth-приложеньку от производителя).

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

В моём случае (у меня есть ZigBee-координатор CC26X2R1 и zigbee2mqtt) окончательное решение выглядит так:

  1. лампочку нужно сопрячь с координатором

  2. в логах найти её уникальный номер (к примеру 0x0017880108fe7a41)

  3. и послать через zigbee2mqtt MQTT-сообщение.
    Topic: zigbee2mqtt/[FRIENDLYNAME]/set/hue_poweron_behavior
    Data: off

Только после этого мы получим по-настоящему умную лампочку, которая горит, когда нужно и не горит, когда не нужно.


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

Подробнее..

Как отлаживать код в RStudio и создавать новый проект на R

22.03.2021 12:19:24 | Автор: admin
Новогодним подарком в этом году стали для меня новая команда и проект на языке R, о котором в тот момент я знал немного. Поначалу было трудно и не понятно, но время шло, картинка прояснялась. С чем-то удалось разобраться, что-то пришлось принять как есть. И вот, спустя два с половиной месяца работы на R, я решил поделиться опытом и рассказать о своих первых шагах в этом проекте. Я не буду описывать все свои душевные муки и эмоции, которые переполняли меня в процессе освоения этого очень интересного языка, а сосредоточусь на технической стороне вопроса. Цель моей статьи рассказать о том, как отлаживать код в RStudio и создавать новый проект на R.

Первое с чем пришлось мне столкнуться это отладка приложения. В RStudio есть возможность выделить отдельные участки кода и запустить их. Это очень помогает при работе с R markdown, так как в них, в режиме Debug, нельзя поставить точку останова. А выделить строчки и запустить их можно где угодно.

запуск строчки кода

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

панель глобального окружения

Создают или меняют значения этих переменных через Console.

Console

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

кнопка Source

Есть в RStudio и классический Debug режим. В нем присутствует возможность ставить Break Points, с возможностью запуска в режиме отладки и функция browser(), встретив которую R прерывает выполнение кода, позволяя отладить приложение. Но в нашем проекте это не получило широкого распространения из-за работы с R markdown.

Следующее с чем я столкнулся в R это два типа проектов: обычный проект (New Project) и проект типа package (R Package). Когда я пришёл в команду, там был некий микс из этих 2-х. Вроде был Package, но он не собирался и запускали его через RScrtipt. Сейчас, благодаря усилиям моих коллег, у нас работающий R Package.

image

Обычный проект (New Project) предлагает написать R-скрипт файлы, где один файл подключается к другому через функцию source(). Таким образом, при запуске скрипта получается как бы один очень большой файл, в который включены все файлы проекта. Это не всегда удобно и не очень гибко.

кнопка Source

В отличие от обычного проекта, проект типа R Package предлагает нам написать библиотеку функций на R, которую потом можно будет установить на любую машину и вызывать эти функции внутри своего R-скрипт файла. Есть правда один нюанс. Функции доступны только из R-скрипта. Поэтому, прежде чем начать с ними работать, нужно будет создать такой скрипт и уже в нем прописать вызовы этих функций. Запускается он в консоли с помощью команды: Rscript. Чтобы это работало нужно в переменных окружения прописать путь к файлу Rscript.exe. На моей машине этот путь выглядит так: C:\Program Files\R\R-4.0.3\bin. При создании своих функций в проекте типа Package, в режиме разработки, следует пользоваться функцией load_all(), которая подтягивает все изменения в память. Если ей не пользоваться, то при всяком изменении кода в проекте, для того чтобы эти изменения вступили в силу, надо запустить процесс инсталляции, что R делает не быстро.

Теперь о проекте R-Package: В отличие от простого проекта, он содержит некую обязательную структуру и специальные файлы. Это:

  • файл DESCRIPTION с описанием пакета,
  • папка man для описания функций,
  • файл NAMESPACE со списком доступных функций создаваемого пакета,
  • папка с названием R, в которой должен лежать ваш код на языке R
  • файл .Rbuildignore со списком того, что не входит в пакет при его сборке
  • файл .Rhistory, который хранит историю команд в консоли
  • .RData хранит содержимое вкладки Environment, точнее данные которые были загружены в память при работе с проектом

.Rhistory и .RData присутствуют как в проекте типа Package, так и в обычном проекте. Ещё можно создать папку inst для дополнительных ресурсов и папку test для unit тестов. Более детально с тем, как устроен R package и почему именно так он работает вы можете ознакомиться по ссылке.

При создании проекта типа R Package используют утилиту roxygen2. Она помогает создать документацию для вашего пакета. Идея в том, что вы описываете каждую функцию прямо в коде, а утилита уже сама переносит это описание в папку man, конвертируя в необходимый формат и добавляет информацию о функциях в файл NAMESPACE. Подробнее о roxygen2 тут.

Ещё есть полезные пакеты для настройки проекта, которые используют практически во всех инструкциях по его созданию, как минимум во всех тех, что я нашёл в Интернет:

  • devtools основной пакет, в котором собранно большинство команд для работы с проектом в их упрощенном виде
  • usethis пакет помощник, упрощающий выполнение многих рутинных операций
  • testthat пакет для написания Unit тестов
  • covr пакет для проверки кода на покрытие unit тестами

Все общедоступные пакеты с их описанием и с документацией к языку R хранятся в CRAN The Comprehensive R Archive Network (http://personeltest.ru/aways/cran.r-project.org/ )

Для удобства работы, в RStudio уже встроены средства проверки вновь создаваемого проекта (Check Package) и его тестирования (Test Package).

Build меню

Вроде бы всё, что хотел, рассказал, но лучше один раз увидеть, чем сто раз прочитать. Ниже видео о том, как начать работать с R:

  1. Начало работы с R на RStudio. Проект на языке R или пакет на языке R
  2. Создание проекта R package вместе с Unit tests и documentation
  3. Запуск и отладка R кода для проекта R Package

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

Как мы провели международную онлайн-конференцию для 1000 человек

23.10.2020 14:16:54 | Автор: admin
Полгода назад мы писали о том, как перенести все внутренние коммуникации в компании в виртуальное пространство. Но тогда мы еще не знали, что всего за пару месяцев нам предстоит подготовить международную онлайн-конференцию Innovation Day 2020. Как впервые сделать масштабное мероприятие в онлайне и выжить читайте под катом.

image

Innovation Day традиционное ежегодное мероприятие для Deutsche Telekom IT Solutions Russia. В апреле коллеги со всех уголков Deutsche Telekom приезжают в Санкт-Петербург, чтобы послушать доклады об инновациях, познакомиться, в общем, прекрасно провести время, наслаждаясь апрельским питерским солнышком и видом на Неву с Васильевского острова.

В этом году все должно было пройти по плану: мероприятие было назначено на 28 апреля, подготовка началась чуть ли не за полгода, была арендована площадка, а некоторые иностранные коллеги уже делали визу и покупали билеты в Россию. Но когда за месяц до дня Х мы сели по домам, стало понятно, что проект придется поставить на стоп. Первое время мы наивно надеялись на май или июнь, но статистика только росла, никакого намека на открытие границ не было. Поэтому, чтобы совсем не отказываться от мероприятия, мы решили: да будет онлайн, и запланировали Innovation Day на сентябрь.

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


Так проходил Innovation Day в 2019 году

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

Как это работало

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

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

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





Две соседние переговорки также оборудовали под маленькие студии, где находились модераторы сцен.



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

Было решено сделать отдельный лендинг, где доклады были разделены на три стрима (три сцены), и участник, выбрав тему доклад из интерактивного расписания, проваливался в нужный поток. Спикеры подключались к трансляции через Cisco Webex привычный в нашей компании инструмент конференц-связи, а в качестве плеера использовался Facecast.



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

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

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

Одной из задач, которые мы ставили перед собой вначале, было зацепить зрителей и не дать им забить и уйти на кухню резать салат. В течение всего мероприятия количество зрителей держалось примерно на одном уровне, что, конечно, не значит, что все участники были на 100% вовлечены, но дает на это надежду!

В заключение хотелось бы отметить...

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

Это были слова, а вот Innovation Day в цифрах:

2,5 месяца подготовки
17 докладов
28 спикеров со всего Deutsche Telekom
16 стран от Америки до Азии
1000 участников от Чикаго до Куала-Лумпур
5 часов прямого эфира


Если вы хотите поделиться опытом организации онлайн-мероприятий или задать вопросы жду вас в комментариях!
Подробнее..

Микросервисы VS монолит баттл адептов

09.02.2021 10:17:03 | Автор: admin

Монолитная и микросервисная архитектуры два диаметрально разных подхода. Во время круглого стола на конференции DevOps Live 2020 столкнулись адепты этих архитектур, которые в формате баттла искали ответы на самые актуальные вопросы. Избыточны ли ресурсы на каждый микросервис? Есть ли необходимость в постоянном рефакторинге? И как грамотно организовать рабочее место?

Адвокатом микросервисов выступил Алексей Шарапов, а обвинительную речь зачитал Андрей Булов. Оба сотрудники Deutsche Telekom IT Solutions стратегического подразделения крупнейшей в Европе телекоммуникационной компании Deutsche Telekom и не новички в обсуждаемом вопросе.

Андрей Булов: Я работаю в довольно крупном энтерпрайзе, в котором берут свое начало молодые стартапы. Побывал в разных ролях: архитектора, девелопера. С 2016 года начал писать на микросервисах.

С тех пор я невзлюбил паттерн Microservice as a goal, которым грешат многие энтерпрайзы, и стал пропагандировать здравый смысл. Честно говоря, я считаю, что микросервис и текущая разработка это что-то типа Spotify в Agile: все хотят внедрить, но не все понимают, зачем это нужно.

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

А еще я люблю лямбды, и считаю, что микросервис это некое переходное звено.

Алексей Шарапов: На данный момент я являюсь DevOps евангелистом. То есть хожу и очень громко всем говорю: Давайте делать DevOps!. Я в разработке с 2010 года. Занимался разработкой фронтенда и немного бэкенда. С 2015 года влюбился в DevOps и DevOps-практики. Стараюсь заниматься ими ежедневно и приносить счастье нашим разработчикам.

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

Андрей Булов: Начнем с меня. Почему микросервисы это плохо? Во-первых, потому что это очень дорого. Почему-то считается, что у всех, как у Google, есть куча намаринованных маленьких серверов, в которые можно засунуть маленькие сервисы, и все будет прекрасно работать.

На самом деле, вам придется купить облако и Кубер, и во всей этой виртуализации будет работать Docker, в котором зашиты ОС Java-машина, Application Server и микросервис, раздающий три строчки. А вы будете греть воздух всей этой чудесной инфраструктурой.

С точки зрения программной оптимизации, микросервис это постоянная перегонка из строк в строки. Это съедает массу памяти, и возникает нагрузка и на сеть, и на программистов. Микросервисы дорого имплементировать, и не всегда понятно, зачем люди их выбирают.

Тот же монолит или мелкая галька прекрасно выполняются на Bare Metal, не требуют особых ресурсов, Application Server JVM. И внутри себя они общаются по бинарным внутренним протоколам, байтики бегают по серверу: все прекрасно и довольно быстро работает.

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

Алексей Шарапов: На все это могу ответить, как человек, занимающийся инфраструктурой в крупных компаниях последние несколько лет, что мы можем делать очень много классных вещей. В первую очередь, ограничивать минимум. Если на наш сервис нет нагрузки в спокойном состоянии, можем сделать ему минимальные ресурсы. Мы должны содержать Kubernetes-кластер, какие-то дополнительные сущности, но запуском внутренних компонентов можем управлять очень-очень тонко. И если в какой-то момент нам на определенное время нужны сущности, мы можем использовать CronJob. А еще Openfaas, о чем часто забывают. Мы не греем наш кластер ненужными сущностями, а запускаем только то, что необходимо.

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

Например, можно использовать те же самые AWS лямбды и запускать в них какой-то код да, может быть, это будет не в кластере, а отдельно. Кроме того, не стоит забывать, что у нас есть Kubernetes-кластер. Мы можем не иметь его у себя, а запускать где-то на стороне. Такую возможность предоставляет облачный провайдер.

Не стоит забывать и о том, что когда мы запускаем на Bare Metal, нужно какое-то общее окружение, с которым мы работаем. Если все это учесть, получается даже чуть больше, чем в кластере Kubernetes.

Андрей Булов: Микросервисы это штука, которая требует некоей Java-команды и постепенного обучения. То есть вы девелопите какой-то микросервис, и в нем может постепенно меняться его бизнес-контекст. Многие забывают, что помимо обычного советского рефакторинга, который нужно делать практически каждый день, микросервисы еще требуют бизнес-рефакторинга. Если в монолите вы можете просто порефачить модули и сделать git push force, как тимлид или девелопер, то в микросервисах вам придется договориться с другими командами, с другими людьми и, например, перенести функционал из одного микросервиса в другой.

Мой личный опыт: когда разрастается какой-нибудь важный микросервис типа Order-микросервиса, или Booking-микросервиса, который выполнял 90% функционала приложения, по-моему, немного теряется смысл. Нам требовался временный рефакторинг в заказной разработке или в бизнесе. Довольно трудно продать людям, которые заведуют деньгами, что нам нужно еще пару спринтов, чтобы перекроить бизнес boundaries наших микросервисов. Потому что с первого раза (и со второго, и с третьего) мы не смогли понять этот контекст, зато теперь научились.

Я это лично продавал продуктоунерам. Это занимательно. Если уж вы отважились на микросервисы, всегда помните о том, что рефакторинг не закончится никогда. Он как ремонт, и вам нужно будет всегда со всеми договариваться. Закладывайте хотя бы процентов 20 времени исключительно на это.

Алексей Шарапов: С мыслями о рефакторинге я не согласен. Если API меняется от версии к версии, возможно, это включает в себя несколько проблем, которые больше на совести девелопера, разрабатывающего эту часть. Либо нужно запланировать, что не стоит вводить постоянные изменения, включая новый функционал микросервисов.

С другой стороны, если это все сложно переписать, может быть это уже и не микросервис вовсе? И огромный микросервис, который выполняет большое количество бизнес-логики, превращается в мини-монолит. Да, это сервис, но не микросервис. В моем идеальном восприятии и я стараюсь работать именно так микросервис должен держать минимальную бизнес-логику. Он небольшая сущность, которую Java-команда может написать и переписать за спринт. И это не должно задеть какой-то другой функционал. Именно тогда речь идет о микросервисе.

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

Как всегда, когда собрались архитекторы, происходит рефакторинг ради рефакторинга. Но нужен ли он здесь на самом деле, или хочется впихнуть то, что в формат микросервиса впихивать не нужно? В монолите мы привыкли к тому, что можно что-то переписать, поменять модуль, и все классно! Но чтобы отрефакторить монолит, которому 20 лет (а я с таким сталкивался в реальном мире, это не сказки), только для того, чтобы разобраться, как это сделать, нужно полгода. И это без учета времени на необходимые изменения.

Андрей Булов: Микросервисы copy & paste driven development. Согласно идеологии микросервисов, в них не должно быть общих зависимостей, кроме какого-нибудь спринга, или общих либ. Но почему-то все забывают о том, что когда микросервисы пишутся для энтерпрайза, пусть и не очень кровавого, у него есть enterprise-specific вещи. А есть еще базовые, типа общей аутентификации, общего логирования, общих доменных объектов.

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

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

Поэтому от идеологии всегда приходится отступать, и делать либы. Но тогда это уже перестает быть микросервисом.

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

За это я микросервисы не очень люблю.

Алексей Шарапов: В этом моменте я с тобой согласен, но не во всем. Мне нравится подход, когда библиотека выносится отдельно, и все ее куски делаются при помощи CTRL-C CTRL-V. С июля мы начали новый проект, в котором изначально используется микросервисный подход. И я слышал что-то подобное от наших архитекторов: либо мы копируем, либо выносим в библиотеки.

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

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

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

Андрей Булов: Собственно, именно поэтому: в микросервисах нет единого хорошего стандарта, а есть набор практик и адепты, каждый из которых агитирует за свое. Если микросервис разрабатывает программист или команда программистов, вы получите свой уникальный стиль микросервиса с такими вещами, как POST vs PUT (холивар на кухне), и рассуждениями о том, какие ошибки мы возвращаем при валидации, какое возвращаем время и в каком стиле мы возвращаем API.

Это требует либо постоянного ревью: чтобы пришел архитектор или лид-девелопер и вставил руки в нужное место, либо нужен общий гайдлайн на проект. Но опять же, общих best practices для микросервисов, к сожалению, нет. Адепты спорят друг с другом. И ты думаешь: Хм, разработчик Василий так любит двухсотый код возвращать, надо учесть эту специфику. А этот, наверное, 404 бросит. Ведь тут не сервер упал, просто у него код ошибки такой. Либо требуется централизованное управление, и тогда теряется весь смысл микросервисов. У тебя получается команда с многими модулями, которые просто деплоятся отдельно, и архитектор ходит и пишет для них гайдлайны.

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

Алексей Шарапов: А как вообще жить без документации? Я бы начал с этого, потому что я себе такого не представляю. Да, мысль, может быть, чуть-чуть испорчена энтерпрайз-сложным миром, большим и тяжелым. Но даже несмотря на микросервисную инфраструктуру и архитектуру, мне нравится документация. Под ней можно понимать не подробный талмуд о том, как мы должны написать микросервис, а описание общих частей.

Сейчас мы что-то подобное подготавливаем для наших команд. И я не вижу в этом ничего плохого. Там просто написано о том, что нужно использовать классические коды ошибок, как это описано в интернете.

По поводу всего остального. Во-первых, инфраструктура as a code становится проще. То есть деплой становится everything as a code, а все части деплоя, инфраструктуры и самого кода вы можете посмотреть в Гите. Разработчику проще, когда он деплоит какое-то количество микросервисов, и отлавливает эти ошибки быстрее. Ему не нужно лезть в тяжелый монолит, рассматривать его и пытаться понять, что происходит. Он понимает, что происходит от написания первой строчки до попадания на ProdStage, и на каждой отдельной части.

Плюс выпуск происходит намного быстрее, и ему легче свериться с документацией. Ему не нужно разбираться с внутренними взаимодействиями, с тем, как работает система. Он написал свою часть. Видит, с чем это все вместе работает, и может выпускать этот кусочек. С Андреем я согласен в одном: в команде должны быть люди, которые понимают, что они делают. Даже несмотря на кровавый энтерпрайз, они должны понять, что они создают микросервис по определенным законам. И все будет круто до тех пор, пока люди соблюдают установленные правила, хотя бы из взаимоуважения.

Андрей Булов: Да, давайте наймем команду космонавтов, которая нам все хорошо сделает.

О, мое любимое.

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

На деве все хорошо. Значит, мне нужно поднять у себя Docker, кучу микросервисов с базой, учесть взаимодействие этого всего. А потом сидеть, как обезьянка, переключаться между PyCharm и смотреть, куда приведет тот или иной breakpoint. Потому что проблема очень скользкая, и просто логами ее вычислить невозможно.

С точки зрения вычислительных мощностей, поднять у себя такое количество докеров, конечно, можно, но тогда тормозить будет зверски. Если мы подключаемся к какому-нибудь Куберу и удаленно пробрасываем порты, конечно, оно может сработать. Но тогда получается, что один девелопер блокирует все девовское окружение, а другие сидят, курят бамбук или девелопят локально. Либо нам нужно много-много окружения, иначе необходимо много-много серверов. Что возвращает нас к первому вопросу: все это совсем не дешево.

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

Поэтому дебажить микросервисы я люблю очень сильно!

Алексей Шарапов: Андрей прямо по больному прошелся. Конечно, дебажить микросервисы довольно-таки сложно. Но, на самом деле, команда должна просто привыкнуть к освоению новых инструментов.

В мыслях о port forwarding я с Андреем абсолютно не согласен. Если приходится пробрасывать огромное количество каких-то сущностей в единицу времени, наверное, мы опять говорим о том, что у нас слишком большое количество взаимодействий. Нужно вообще прекратить это дебажить, поднимая какие-то локальные контейнеры. Либо, необходимо иметь достаточное количество неймспейсов. Понимайте изначально, во что вы вписываетесь. Да, это может быть дорого. Вы можете поднять какой-нибудь свой minikube.

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

Кроме того, можно прекратить создавать костыли, и позвать человека. Можно окружить все трассировкой, например использовать Jaeger, посмотреть, собирать логи с каждого момента. Логов не хватает: значит нужно посмотреть, как микросервисы взаимодействуют между собой. При нормальной трассировке можно обнаружить, где происходят падения. Придется поднять буквально несколько сервисов. И это займет не так много времени и ресурсов. И жизнь твоя улучшится.

К этому просто надо привыкнуть. Очень сложно осознать, что все поменялось извините, теперь будет так. Но когда привыкнешь, станет легче.

Андрей Булов: Видимо, я морально устарел в микросервисах.

Есть еще вот такой интересненький кейс:

У нас есть микросервис со своими бизнес-контекстами, сервис, который делает Order, сервис, хранящий в себе Vehicle. Есть API GW, есть GUI. К нам приходит продактоунер и говорит: Эй, ребята, мы принимаем заказы на машины, и теперь занимаемся отделкой салона.

И начинается парад независимости. Это когда команды внедряют у себя один параметр и проносят его через все независимо друг от друга.

А потом начинается игра: давайте все это дело проинтегрируем! Мы возвращаемся к предыдущему слайду: как это дебажить?

Очень тяжело и с первого, и с десятого раза определить реальный бизнес-контекст микросервиса и приложения. И во всяких крупных энтерпрайзах часто получается, что flow идет как бы через все микросервисы. Все они, вроде бы, независимые, но друг без друга не могут, и все должно работать вместе.

Это абсолютно реальный пример: нам никуда не деться от того, что придется пронести бедный параметр VehicleCover через все микросервисы и базы. Давайте это сделаем и помолимся, чтобы все программисты микросервисов назвали это правильно, соблюли чудесный capital letter, сделали везде одинаковый тип, воркчар был правильным, все это прошло ревью архитектора и т.д.

В монолите это сделать довольно легко: открываем идею, смотрим, даем кому надо по рукам профит! В микросервисах придется побегать между командами.

Алексей Шарапов: Я согласен с тем, что это будет боль. Но самое главное не создавать SOA в этом случае. Это же не микросервис: протаскиваешь через распределенные данные монолита из кусков какое-то значение, которое ты должен везде обработать. Почему твое значение не может быть отдельным микросервисом, из которого все берут данные? Или который это обрабатывает отдельно от всех, чтобы не нарушать состояние остального. Если такие требования появились, как их вписать со стороны идеологии? А если это вам не подходит, зачем вы вообще начали делать микросервисы?

По поводу зависимостей. Хочу вернуться к прошлому вопросу про копипаст, где нужно вставлять и описывать одну часть. Ты говоришь: не факт, что они правильно дадут название во всех своих сервисах. Именно для этого и нужна если не документация, то хотя бы минимальное описание, как с этим работать. Нужно просто предложить определенный алгоритм с этого дня: есть такие-то требования и проект может быть такого-то характера. А еще существует вероятность того, что этот проект изначально не был подготовлен для микросервисов.

Я такое видел: берут какой-то проект, для которого не нужны микросервисы. Но нет, мы просто обязаны сделать классно и красиво, ведь решение о необходимости микросервисов спустили сверху. Но ведь главное не применять технологии там, где они не нужны. Плохо делать что-то просто потому, что так захотелось.

Больше по этому поводу мне нечего сказать. Наверное, это вопрос ко все участникам разработки.

Андрей Булов: О, я тебя заразил здравым смыслом!

Тестирование.

Мой любимый вопрос на Lead Test Engineer или Test Manager. Я рисую такую картинку и говорю:

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

На этот вопрос, к сожалению, пока мало, кто ответил. Все почему-то говорят про модульные тесты, про то, что нам нужно окружение, еще одно окружение, еще одно окружение.

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

Ни технически, ни организационно идеальных практик пока, к сожалению, нет. В общем, тяжело это работает. С монолитом проще: взяли Selenium, все протестировалось, смоками покрыли, выкатываемся в прод все работает. Мы красавцы, мы восхитительны!

Алексей Шарапов: А как же без проблем, Андрей? Может быть, в том, что касается тестирования, я с тобой согласен. Я не то чтобы заразился здравым смыслом. Просто не так глубоко погружался в проблемы тестирования.

И я еще раз призываю прекратить думать о микросервисе, как о монолите. Мы привыкли тестить так, чтобы было красиво, но теперь условия изменились. Мы, например, во время тестирования очень активно используем testcontainers. И это решает часть проблем.

Я все время говорю о том, что нужно иметь достаточное количество стендов. Я хожу в свои команды и напоминаю: Ребят, поднимите нормальное количество стендов, прекратите страдать на одном, который упал, после чего все сломалось, и вы мучаетесь. Распределите запросы, и страдания закончатся. Человек, который у вас близко работает с инфраструктурой, как мне кажется, должен взаимодействовать и с и с девелопмент командой. Хотя бы для того, чтобы подойти и сказать им: Поднимите стенды, все пробросьте к себе на машину, используйте testcontainers, прекратите тестить это, как монолит, и все будет хорошо.

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

Частично, Андрей, я с тобой согласен, но и монолит не отменяет множества стендов. Я не могу себе представить отчаянных людей, которые запустили монолит на одной машине, чтобы сэкономить свои ресурсы, и сказали: Все классно! Мы никогда не падали, а во время деплоя там огромный downtime.

Андрей Булов: Уел!

Хочу рассказать про каждому разработчику по своему Куберу. CI/CD моя любимая тема.

Во-первых, чтобы это все собрать, нам нужен очень хороший Jenkins с кучей слейвов. В разработке возникает несколько вопросов:

  • Мы пересобираем все сервисы каждый коммит?

  • Сколько нужно слейвов на сборку?

Приходит бизнес и говорит:

А сколько нам нужно заплатить за сборку? Сколько-сколько? Нет, вон там стоит под столом сервер, давайте его использовать.

  • А почему все так медленно работает?

У меня пять разработчиков сделали коммиты, и пять раз подряд пересобирается весь этот зоопарк.

Помимо очень мощного окружения нужен очень мощный CI/CD.

  • Можем ли мы считать, что у нас работает система, когда собралось 60 микросервисов, и 61, который мы не релизим, упал?

У меня вопрос: можем мы зарелизиться, или нет?

Тот сервис, конечно, релизить не будем, остальные зарелизим. Какая радость от того, что мы в проде упадем?

А нужно ли вообще смотреть, что с этим микросервисом? Мы его уже 100 лет не трогали, что-то упало.

Ну, не знаю. Может быть, сам заработает.

С continuous delivery отдельная песня, когда нам нужно заделиверить что-то. Мы деливерим, деливерим, деливерим это в прод бах! падает какая-нибудь джоба, нам это нужно пересобирать все по новой, и т.д. В общем, это гораздо больнее, чем собрать один Maven clean install, прогнать все тесты все работает, мы великолепны.

Алексей Шарапов: А как жить без CI/CD? Попробую описать, что я имею в виду.

Мне кажется, что CI и CD необходимы для любого проекта. Ты используешь CI в проекте с монолитом, с микросервисами. Почему появляется необходимость на каждый коммит пересобирать все-все-все микросервисы? Здесь стоит опять задуматься о независимости. Возможно, разговор тут идет не про инструменты. Однако, предположим, какой-нибудь GitLab CI с его Docker runners сильно сэкономили бы тебе ресурсы. Мы не говорим про этот страшный Jenkins, который перегружен, огромную Java-машину. Мы можем использовать что-то более легковесное.

Может быть, каждый CI/CD должен заканчиваться на том моменте, где это на самом деле необходимо. Если речь идет об огромном монолите, который работает в нашем энтерпрайзе, скажу честно, CD у нас поскольку постольку, просто потому что есть такие условия. Однако же мы предоставляем и такой инструмент. И мы не берем jenkins , как мы привыкли, а находим необходимый инструмент легковесный, удобный. Именно с его помощью мы что-то делаем, и это классно работает.

Я просто не могу себе представить, как можно жить без CI/CD. У нас микросервисы это огромный проект, все они собирались отдельно. Был микросервис, который жил с самой первой версии, никогда не менялся, мы его не пересобирали, однако же он всегда работал. Вот она независимость.

Андрей Булов: О, вот это мой любимый вопрос на собеседовании отдельные DevOps команды.

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

Мой любимый вопрос DevOpsам: как написать такую чудесную синюю кнопку, которую жмешь, все базы в один момент с каким-то снепшотом бэкапятся. А еще все это можно потом либо восстановить одной зеленой кнопкой, либо слить разработчикам на дев-окружение. Причем мне нужно не ощущение: Ну, в принципе, нормально! Вроде, все закончилось, а что-то более доказательное. Если бизнес говорит: Ребята, это какая-то фигня, что мы ему можем возразить в ответ? Что, по нашим ощущениям, все должно работать?

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

Алексей Шарапов: Нет, потому что это один из самых сложных вопросов касательно микросервисов.

Есть разные подходы на данный момент. Предположим, что существует сложная система с балансировкой через Patroni. Мы в наших реалиях никому не можем передать имеющиеся snapshot базы, просто потому что это невозможно.

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

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

Андрей Булов:

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

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

Получается, все то, про что я говорил: все выливается в эти проблемы. Используйте паттерн мудро и только там, где это необходимо. Аминь.

Алексей Шарапов: Абсолютно согласен не нужно применять микросервисы там, где этого не требуется. Я хочу привести пример того, как я это представляю. Мы не можем запустить проект в продакшен, пока не будет написано большое количество бизнес-логики. Но мы можем посмотреть на это с другой стороны: у нас есть простой бизнес. Предположим, я сейчас делаю автоматическое создание ресурсов внутри нашей сети.

Крошечный скейтбордик это первый маленький микросервис, который дергает по REST какой-нибудь AWX и запускает создание первой машины: класс, продукт уже есть, и я могу пользоваться этим каждый день. Потом я хочу сделать самокат. Прикручиваю туда базу данных, чтобы ходить в стейты. Дальше велосипед, мотоцикл, в конце машина это уже AWX плюс Terraform, Cloud, которые взаимодействуют между собой через разные микросервисы, Kafka. Я могу создавать какие-то вещи уже с первой улыбающейся рожицы, которая на меня смотрит (LIKE THIS).

Или возьмем другой бизнес-кейс. Предположим, у вас магазин с напитками. Сегодня вы принимаете заказ с одним напитком, но когда у вас есть автомобиль, это уже огромная сеть ресторанов.

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

Профессиональная конференция по интеграции процессов разработки, тестирования и эксплуатации DevOpsConf 2021 пройдет 30 и 31 мая 2021. Но билеты на нее вы можете приобрести уже сейчас, успев сделать это до повышения цены.

А еще вы можете сами стать героями конференции, подав доклад.

Хотите бесплатно получить материалы предыдущей конференции по DevOps? Подписывайтесь на рассылку.

Подробнее..

Как оптимизировать работу аэропортов с помощью машинного обучения

05.11.2020 18:21:17 | Автор: admin

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

Наша команда более десяти лет разрабатывает приложения, которые управляют работой крупнейших аэропортов: Франкфурт, Дублин, Манила, Джакарта, Майами, Пекин. Аэропорты используют приложения для оптимального управления ресурсами, организации работы и контроля за потоками информации аэропортов, координации расписания рейсов.

Аэропорты, использующие наши приложенияАэропорты, использующие наши приложения

Крупные аэропорты обслуживают сотни тысяч пассажиров, тысячи тонн грузов и сотни самолётов в день. Так, за 2019 год аэропорт Франкфурта обслужил более 70 миллионов пассажиров, более двух миллионов тонн грузов и более пятисот тысяч самолётов. То есть, в день аэропорт обслуживал порядка 190 тысяч пассажиров, более пяти тысяч тонн грузов, более тысячи самолётов. Такие показатели связаны с огромным количеством человеческих и материальных ресурсов. Для типичного пассажира внутренняя работа аэропорта представляется чёрным ящиком. Мы проходим набор рутинных процедур: собственную регистрацию, регистрацию или получение багажа, трансфер до самолёта и полёт. Кажется, всё достаточно просто, однако, это лишь вершина айсберга. Каждый видимый нами процесс включает в себя десятки подпроцессов, в которых задействованы сотни людей. Логично, что задачей менеджеров аэропорта является оптимизация процессов для снижения затрат на привлечение сотрудников и других ресурсов. Мы попытались решить это задачу.

Идея звучит достаточно просто: Если вы знаете, сколько пассажиров обслуживает аэропорт в конкретный день вы знаете, какой набор ресурсов для этого потребуется: сколько сотрудников должно выйти на работу, сколько автобусов будет использовано для доставки пассажиров к самолётам, сколько горючего этим автобусам потребуется. Таким образом, задача сводится к определению количества пассажиров в аэропорту в конкретный день в будущем. Это позволит менеджменту привлекать заранее известное количество ресурсов, а значит, точнее рассчитывать расходы. Поставленная задача является задачей регрессии, в которой необходимо установить зависимость количества пассажиров от других параметров.

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

  • Время года. Туристические сезоны отчётливо прослеживаются и вносят существенный вклад в количество пассажиров. В авиации принято использовать астрономические сезоны, поэтому и мы опирались именно на них.

  • День недели. От дня недели зависит как количество туристических рейсов, так и количество рабочих перелётов.

  • Праздник и его характер. Информация о том, является ли день праздничным, продолжительность праздника, характер праздника (религиозный или общественный). Череда праздников, как правило общественных, может мотивировать людей совершать перелёты.

Важнейшим же шагом на пути к решению задачи стало предположение о влияние экономической ситуации в стране на пассажиропоток. А именно о том, что экономической рост стимулирует пассажиропоток, и между двумя этими величинами существует зависимость. Для динамической оценки состояния экономики мы решили использовать DAX, а также уровень занятости населения.

DAX

Deutscher Aktienindex German stock index важнейший фондовый индекс Германии. Индекс вычисляется как среднее взвешенное по капитализации значение цен акций крупнейших акционерных компаний Германии.

Ежедневные значения DAX, а также процент работающих граждан Германии были взяты с Yahoo Finance. Для обучения модели использовались данные о ежедневном количестве пассажиров в аэропорте за 2018 и 2019 год, взятые на kaggle. Сезонность, день недели и характер праздничности дня мы посчитали вручную. На подготовительном этапе были использованы исключительно открытые источники, данные из которых были сгруппированы в единый датасет.

Влияние состояния экономики на пассажиропоток не носит молниеносный характер. Должно пройти время для того, чтобы люди ощутили изменения на себе. Поэтому судить о текущем дне по текущему DAX не совсем справедливо. Нужно было найти оптимальный сдвиг DAX от текущей даты по величине коэффициента корреляции между DAX и количеством пассажиров. Такой поиск обозначил 5 различных сдвигов со схожим результатом: от 15 до 19 дней относительно текущей даты.

Следующим шагом был выбор используемой модели. Нашей целью было получение минимального значения MAE, которое говорило бы об ошибке в (количество людей / день). Были испробованы различные варианты разбиения датасета на тест и трейн, различные сдвиги DAX относительно текущего дня, различные модели и их параметры. Конкретно были рассмотрены Linear Regressor, Random Forest, Gradient Boosting, SGDRegressor. Параметры для моделей подбирались с помощью GridSearchCV.

MAE

Mean Average Error

Расчёт ошибки и точности предсказания происходил отдельно для каждого сдвига DAX для каждой модели. Результатом каждого прогона были графики как на картинке ниже. На каждом из таких графиков изображено реальное количества пассажиров из данных теста (синим) и график предсказаний модели на данных того же тестового датасета (оранжевым). Для уверенности в правильном обучении модели и недопущении её переобучения также сравниваются показатели MAE для теста и трейна. Их близость говорит о корректности обучения. Решение о компетентности модели и выборе данных принимались на основе MAE, однако привычный показатель score модели для каждого набора (сдвиг DAX + модель) тоже принимался во внимание.

Графики для Linear Regression со сдвигом DAX в 15 дней Графики для Linear Regression со сдвигом DAX в 15 дней

При построении всех возможных комбинаций стало понятно, что с использованием любой модели наилучший результат достигается при использовании DAX со сдвигом в 15 дней. Как говорилось выше, при выборе модели, мы ориентировались на минимальность MAE. На основе этого критерия была выбрана модель Gradient Boosting с ошибкой в 297 человек. Это означает, что ошибка в день в среднем составляет вместительность одного самолёта.

Следующим шагом стало сохранение обученной модели с помощью pickle, использование REST API для взаимодействия с моделью и создание Docker-образа. После контейнеризации получаем готовое приложение, которое отвечает на вопрос о количестве пассажиров в аэропорту через 15 дней, исходя из DAX, уровня безработицы и информации о том, является ли день праздничным. Данное решение может быть встроено в инфраструктуру любого аэропорта при наличии данных о пассажиропотоке в прошлом. Необходимо лишь переобучить модель на данных конкретного аэропорта.

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

Подробнее..

Управление инфраструктурой Open Telekom Cloud с помощью Ansible

06.05.2021 10:07:53 | Автор: admin

Open Telekom Cloud

В этой статье расскажу о нашем опыте работы над развитием инструментов управления инфраструктурой облачного сервиса Open Telekom Cloud, как мы столкнулись с особенностями этого облака, какие решения принимали и какие инструменты использовали.

Open Telekom Cloud международная публичная облачная платформа, основанная на OpenStack. Платформа идеально подходит для компаний или стартапов, которые работают с европейскими пользователями, чьи персональные данные должны храниться в пределах Евросоюза: сервис разработан Deutsche Telekom и соответствует стандартам защиты данных GDPR (Генеральный регламент о защите персональных данных) EC.

С чего все начиналось

Почти два года назад в поисках специалистов в Россию пришел проект Open Telekom Cloud. Требовалось много людей на автоматизированное тестирование и несколько человек в спецотряд под названием Ecosystems, требования были очень расплывчатые: Ну, надо знать Python и понимать, как работать с облачными сервисами

В то время, по удачному стечению обстоятельств, завершалось несколько проектов в Воронеже, и около 10 человек были готовы к взятию новых барьеров. Самых опытных из них отправили в команду Ecosystems, остальные отправились в QA.

Команда Ecosystems занималась API мониторингом, мониторингом сервисов, созданием модулей для Ansible, разработкой и поддержкой инструментов управления инфраструктурой Open Telekom Cloud. На данный момент она участвует еще и в разработке Terraform Provider, OpenStack SDK, OpenStack Ansible Collections. Во всех наших инструментах (OTC Extensions, Terraform Provider, Ansible Collections) мы стараемся максимально соответствовать OpenStack и переиспользовать существующие решения для него.

С самого начала с Open Telekom Cloud все оказалось довольно интересно. Разработка находится на стороне Huawei, декларировалось, что облако основано полностью на технологии OpenStack. Но Huawei внесли множество своих решений в сервисы. Многие из них были полностью написаны китайскими коллегами, были заметные отличия нашего API от OpenStack API.

Но тогда это нас не сильно волновало. Первой нашей задачей в Ecosystems было создание мониторингов, которые помогут определить качество работы тех или иных сервисов, в сложных сценариях. Например, использовать балансировщик нагрузки для хостов в разных AZ (availability zone), наблюдать за распределением запросов по каждому из хостов. Или следить за отказоустойчивостью того же балансировщика нагрузки в сценарии, когда один или несколько хостов за ним выключаются по тем или иным причинам.

В качестве инструментов для реализации задачи был выбран Ansible и Terraform, провайдер для Terraform уже существовал, и Huawei его в какой-то степени поддерживал. При создании мониторинга начали изучать и использовать Go для различных задач. Например, нужен был быстрый сервер, который не загнется от потока запросов, что в будущем открыло нам новое направление с поддержкой провайдера Terraform. Во время создания мониторинга находились баги в Terraform провайдере, и казалось, что дождаться их решения будет невозможно, никто их исправлять не спешил.

Что ж, раз Terraform стал для нас критичным инструментом, мы отправились в репозиторий с провайдером и начали исправлять баги. В какой-то момент поддержка провайдера со стороны Huawei прекратилась, да и через некоторое время HashiCorp решили всех сторонних провайдеров убрать из своего репозитория.

Тогда мы решили перетащить провайдер в свою организацию на Github, форкаем golangsdk, называем его gophertelekomcloud и переносим провайдер на него (после всех преобразований gophertelekomcloud в итоге стал самостоятельным проектом, указания, что это форк, больше нет). Но это уже другая история

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

Ansible и коллекции

Опустив некоторые детали, первоначально мониторинг работал примерно так:

Точкой входа был AWX, он вызывал плейбуки с ролью Terraform, результат выполнения Terraform снова передавался в Ansible, и далее выполнялись какие-то сценарии.

Кажется, что все отлично, есть базовый .tf модуль, который создает сетевую часть, и отдельные модули на каждый сценарий, .state всех модулей хранится в s3. Все удобно, работает как часы.

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

Был только Python и Ansible

Учитывая, что Open Telekom Cloud не является решением, на 100% совместимым с OpenStack, в нем присутствуют сервисы собственной разработки, например, RDS (Relational Database Service). С помощью Ansible мы не можем построить все необходимые нам ресурсы используя OpenStack SDK и ansible-collections-openstack, в таком виде, чтобы это было легко поддерживать.

Что ж, надо расширять возможности OpenStack SDK, адаптировать под наш проект и писать собственные коллекции. Для коллекций необходимо описание ресурсов, которых нет в OpenStack SDK, для таких ресурсов был создан проект OTC Extensions.

OTC Extensions

Этот проект дополняет и расширяет функции OpenStack SDK для работы с Open Telekom Cloud, так же если он установлен в качестве python package, в OpenStack Client добавляются дополнительные плагины для работы с облаком.

Взаимодействует с:

python-openstacksdk

python-openstackclient

Структура проекта близка к OpenStack SDK:

otcextensions/    sdk/        compute/            v2/                server.py                _proxy.py    tests/        unit/            sdk/                compute/                    v2/                        test_server.py

Все дополнительные ресурсы унаследованы от базового openstack.resource.Resource, или если мы хотим изменить существующий объект то нужно наследование от него базового класса этого объекта, например, если у openstack.compute.v2.server нет поддержки тэгов или они реализованы иначе:

class Server(server.Server):    def add_tag(self, session, tag):        """Adds a single tag to the resource."""    def remove_tag(self, session, tag):        """Removes a single tag from the specified server."""

И далее патчим Connection в методе load (otcextensions/sdk/__init__.py):

openstack.compute.v2.server.Server.add_tag = server.Server.add_tagopenstack.compute.v2.server.Server.remove_tag = server.Server.remove_tag

В итоге наш connection теперь будет работать с кастомными тегами.

Для нового ресурса:

otcextensions/    sdk/        elb/            v2/                elb_certificate.py                _proxy.py

В файле elb_certificate.py создаем класс, указываем его url, какие методы поддерживает, какие параметры принимает

class Certificate(resource.Resource):resources_key = 'certificates'base_path = ('/lbaas/certificates')# capabilitiesallow_create = Trueallow_fetch = Trueallow_commit = Trueallow_delete = Trueallow_list = True_query_mapping = resource.QueryParameters(    'id', 'name', 'description',    'type', 'domain', 'content',    'private_key', 'marker', 'limit',)# Properties#: Namename = resource.Body('name')#: Idid = resource.Body('id')#: Descriptiondescription = resource.Body('description')#: Certificate type.type = resource.Body('type')#: Domain name associated with the server certificate.domain = resource.Body('domain')#: Private key of the server certificate. *Type: string*private_key = resource.Body('private_key')#: Public key of the server certificate or CA certificate. *Type: string*content = resource.Body('certificate')#: Administrative status of the certificate.admin_state_up = resource.Body('admin_state_up')#: Creation timecreate_time = resource.Body('create_time')#: Specifies the project ID.project_id = resource.Body('tenant_id')#: Time when the certificate expires.expire_time = resource.Body('expire_time')#: Time when the certificate was updated.update_time = resource.Body('update_time')

Рядом обязательно должен быть файл _proxy.py, этот класс адаптер предоставляет интерфейс для работы с инстансом Connection, в нем мы описываем методы ресурса:

class Proxy(_proxy.Proxy):    skip_discovery = True    # ======== Certificate ========    def create_certificate(self, **attrs):        return self._create(_certificate.Certificate, **attrs)    def certificates(self, **query):        return self._list(_certificate.Certificate, **query)    def delete_certificate(self, certificate, ignore_missing=True):        return self._delete(_certificate.Certificate, certificate,                            ignore_missing=ignore_missing)    def get_certificate(self, certificate):        return self._get(_certificate.Certificate, certificate)    def update_certificate(self, certificate, **attrs):        return self._update(_certificate.Certificate, certificate, **attrs)    def find_certificate(self, name_or_id, ignore_missing=False):        return self._find(_certificate.Certificate, name_or_id,                          ignore_missing=ignore_missing)

В otcextensions/sdk/__init__.py eсть структура со всеми нестандартными ресурсами - OTC_SERVICES, добавляем наш ресурс по имени папки в которой он находится:

'elb': {    'service_type': 'elb',    'replace_system': True}

OTC_SERVICES так же в методе load, добавляются в Connection:

for (service_name, service) in OTC_SERVICES.items():    if service.get('replace_system', False):        if service['service_type'] in conn._proxies:            del conn._proxies[service['service_type']]    sd = _get_descriptor(service_name)    conn.add_service(sd)

На этом добавление сервиса завершено, мы можем его использовать через OpenStack SDK.

cfg = openstack.config.get_cloud_region(cloud=TEST_CLOUD_NAME)conn = connection.Connection(config=cfg)sdk.register_otc_extensions(conn)cert = conn.elb.create_certificate(    private_key=PRIVATE_KEY,    content=CERTIFICATE,    name=NAME )

Ansible collections

Окей, ресурсы теперь есть, осталось разобраться как их использовать, есть отличный вариант, создать коллекцию своих модулей и хранить ее в ansible-galaxy, по аналогии с ansible-collections-openstack создаем коллекцию ansible-collection-cloud, которая основана на OTC extensions.

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

Делаем все по гайду (developing-collections):

ansible-collection-cloud/    plugins/        module_utils/            otc.py        modules/            elb_certificate.py            elb_certificate_info.py

В module_utils, храним базовый для всех модулей класс:

class OTCModule:    """Openstack Module is a base class for all Openstack Module classes.    The class has `run` function that should be overriden in child classes,    the provided methods include:    """

В нем создается инстанс Connection, и патчится через OTC extensions, чтобы мы могли использовать кастомные ресурсы.

Все модули делятся на два типа с постфиксом _info возвращают информацию о существующем ресурсе, без него создают/изменяют/удаляют ресурсы.

Например, lb_certificate_info:

from ansible_collections.opentelekomcloud.cloud.plugins.module_utils.otc import OTCModuleclass LoadBalancerCertificateInfoModule(OTCModule):    argument_spec = dict(        name=dict(required=False)    )    otce_min_version = '0.10.0'    def run(self):        data = []        if self.params['name']:            raw = self.conn.elb.find_certificate(name_or_id=self.params['name'], ignore_missing=True)            if raw:                dt = raw.to_dict()                dt.pop('location')                data.append(dt)        else:            for raw in self.conn.elb.certificates():                dt = raw.to_dict()                dt.pop('location')                data.append(dt)        self.exit_json(            changed=False,            elb_certificates=data        )def main():    module = LoadBalancerCertificateInfoModule()    module()if __name__ == '__main__':    main()

аналогично выполнен и lb_certificate.

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

Установка коллекций

Для начала работы необходимо установить коллекции в окружение, для примера используем venv (venv использовать необязательно, но такой подход имеет свои плюсы):

/$ cd ~~$ python3 -m venv ansiblevenv

Активируем окружение:

~$ source ansiblevenv/bin/activate(ansiblevenv) ~$

Установим OpenStack Client, otcextensions и wheel (необязательно):

(ansiblevenv) ~$ pip install wheel(ansiblevenv) ~$ pip install openstackclient(ansiblevenv) ~$ pip install otcextensions

Для работы с коллекциями далее необходимо установить их из Ansible-Galaxy (Ansible-Galaxy содержит множество свободно распространяемых ролей и коллекций, разрабатываемых сообществом). Дополнительно ставим OpenStack коллекцию для нативных ресурсов:

(ansiblevenv) $ ansible-galaxy collection install opentelekomcloud.cloud(ansiblevenv) $ ansible-galaxy collection install openstack.cloud

В принципе все для работы с облаком готово, осталось разобраться с авторизацией. OpenStackподдерживает несколько способов авторизации.

Авторизация

clouds.yaml

OpenStack client/sdk самостоятельно ищет файл для авторизации в следующих местах:

  1. system-wide (/etc/openstack/{clouds,secure}.yaml)

  2. Home directory / user space (~/.config/openstack/{clouds,secure}.yaml)

  3. Current directory (./{clouds,secure}.yaml)

clouds:  otc:    profile: otc    auth:      username: '<USER_NAME>'      password: '<PASSWORD>'      project_name: '<eu-de_project>'      # or project_id: '<123456_PROJECT_ID>'      user_domain_name: 'OTC00000000001000000xxx'      # or user_domain_id: '<123456_DOMAIN_ID>'    account_key: '<AK_VALUE>' # AK/SK pair for access to OBS    secret_key: '<SK_VALUE>'

После того, как файл создан, указываем переменной окружения OS_CLOUD имя конфигурации, в данном случае:

~$ export OS_CLOUD=otc

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

Чтобы проверить, что все сделано правильно, можно запустить любую команду OpenStack клиента:

~$ openstack server list

Если авторизация успешна, то мы получим список серверов:

Чтобы повысить безопасность, можно вынести чувствительную информацию из clouds.yaml. Рядом с файлом clouds.yaml создаем secure.yaml и помещаем туда все, что хотим скрыть:

clouds:  otc:    auth:      password: '<PASSWORD>'

Переменные окружения

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

# .ostackrc fileexport OS_USERNAME="<USER_NAME>"export OS_USER_DOMAIN_NAME=<OTC00000000001000000XYZ>export OS_PASSWORD=<PASSWORD> # optionalexport OS_TENANT_NAME=eu-deexport OS_PROJECT_NAME=<eu-de_PROJECT_NAME>export OS_AUTH_URL=https://iam.eu-de.otc.t-systems.com:443/v3export NOVA_ENDPOINT_TYPE=publicURLexport OS_ENDPOINT_TYPE=publicURLexport CINDER_ENDPOINT_TYPE=publicURLexport OS_VOLUME_API_VERSION=2export OS_IDENTITY_API_VERSION=3export OS_IMAGE_API_VERSION=2

Создаем переменные:

~$ source .ostackrc

С авторизацией разобрались! Теперь можно полноценно использовать коллекции.

Использование коллекции

Как мы знаем в коллекции два типа модулей: с постфиксом info возвращают информацию о существующем ресурсе, без него создают/изменяют/удаляют ресурсы. Все модули вызываются по полному имени: opentelekom.cloud.*

Все info модули поддерживают поиск как по имени, так и по id ресурса, например:

- name: Get loadbalancer info  opentelekomcloud.cloud.loadbalancer_info:    name: "{{ lb_name_or_id }}"  register: result

Если передано имя ресурса, то в ответе вернется dict с параметрами ресурса, если имя не указано, то появится список всех доступных в проекте ресурсов. Не инфо модули также возвращают dict.

Пример сценария

Для примера использования коллекций создадим файл example.yaml и будем там описывать различные ресурсы. Создадим небольшую инфраструктуру: сеть, сервер и балансировщик нагрузки.

Для создания нативных ресурсов всегда используются OpenStack модули, например, сеть:

---- name: Create main network  openstack.cloud.network:    name: my_network  register: net- name: Getting info about external network  openstack.cloud.networks_info:    name: admin_external_net  register: ext_net- name: Create subnet  openstack.cloud.subnet:    name: my_subnet    network_name: "{{ net.network.name }}"    cidr: 192.168.0.0/16    dns_nameservers:          - 100.125.4.25          - 100.125.129.199  register: subnet- name: Create router  openstack.cloud.router:    name: "{{ public_router_scenario }}_router"    enable_snat: true    network: "{{ ext_net.openstack_networks[0].id }}"    interfaces:      - "{{ subnet.subnet.name }}"  register: router

Для сервера нам нужен ключ:

- name: Create key pair  openstack.cloud.keypair:    name: bastion_key_pair    public_key_file: "/tmp/keys/public.pub"  register: keypair

Создадим security group, откроем порты 80, 443 и 22 для ssh, также откроем icmp:

- name: Create security group  openstack.cloud.security_group:    name: bastion_secgroup    description: Allow external connections to ssh, http, https and icmp  register: sec_group- name: Add rules for tcp connection to the security group  openstack.cloud.security_group_rule:    security_group: "{{ sec_group.secgroup.name }}"    protocol: tcp    port_range_min: "{{ item }}"    port_range_max: "{{ item }}"    remote_ip_prefix: 0.0.0.0/0  loop:     - 22    - 80    - 443- name: Add a rule for icmp connection to the security group  openstack.cloud.security_group_rule:    security_group: "{{ secur_group.secgroup.name }}"    protocol: icmp    port_range_min: -1    port_range_max: -1    remote_ip_prefix: 0.0.0.0/0

Для подключения сервера к сети необходимо создать порт:

- name: Create a port for a bastion  openstack.cloud.port:    name: bastion_port    network: net.network.id    security_groups:      - "{{ sec_group.secgroup.name }}"     fixed_ips:       - ip_address: 192.168.200.10  register: port

Для создания сервера тоже используются нативные модули. Например, создадим bastion (это те хосты, которые принято использовать как jump для доступа в недоступные снаружи сети). Здесь также представлен пример инъекции команд при создании сервера через userdata:

- name: Getting information about a current image  openstack.cloud.image_info:    image: Standard_Debian_10_latest  register: image- name: Create a new instance  openstack.cloud.server:    state: present    name: bastion    flavor: s2.medium.2    key_name: bastion_key_pair    availability_zone: eu-de-01    security_groups:     - "{{ sec_group.secgroup.name }}"    timeout: 200    userdata: |      {%- raw -%}#!/usr/bin/env bash                 #setup ssh service config                 file=/etc/ssh/sshd_config                 cp -p $file $file.old &&                     while read key other; do                         case $key in                         GatewayPorts) other=yes ;;                         AllowTcpForwarding) other=yes ;;                         PubkeyAuthentication) other=yes ;;                         PermitTunnel) other=yes ;;                         esac                         echo "$key $other"                     done <$file.old > $file                 sudo service sshd restart                 mkdir -p /etc/sslcerts/live                 #generate Diffie-Hellman for TLS                 sudo openssl dhparam -out /etc/sslcerts/live/dhparams.pem 2048      {% endraw %}    nics:      - port-name: "{{ port.port.name }}"    boot_from_volume: true    volume_size: 5    image: "{{ image.openstack_image.id }}"    terminate_volume: true    delete_fip: true    auto_ip: true  register: bastion

Для динамической регистрации хоста используем add_host:

- name: Register nodes  add_host:    name: "{{ bastion.openstack.name }}"    groups: bastions    ansible_host: "{{ bastion.openstack.interface_ip }}"    ansible_ssh_user: linux    ansible_ssh_private_key_file: "/path/to/key"

После создания сервера можно проверить подключение:

- name: Wait for nodes to be up  hosts: bastions  gather_facts: no  tasks:    - name: Wait for nodes to be up      wait_for_connection:        timeout: 250

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

После того, как у нас создана сеть и есть хотя бы один сервер, мы можем создать loadbalancer:

- name: Create loadbalancer  opentelekomcloud.cloud.loadbalancer:    name: my_elastic_loadbalancer    state: present    vip_subnet: "{{ subnet.subet.id }}"    vip_address: 192.168.200.100    auto_public_ip: true  register: loadbalancer

Далее для loadbalancer создаем listener, если протокол https, то сразу можем создать сертификат:

- name: Create listener http  opentelekomcloud.cloud.lb_listener:    state: present    name: my_listener_http    protocol: http    protocol_port: 80    loadbalancer: "{{ loadbalancer.loadbalancer.id }}"  register: listener_http- name: Create Server certificate  opentelekomcloud.cloud.lb_certificate:    name: my_https_cetificate    content: "{{ some_https_certificate }}"    private_key: "{{ some_loadbalancer_https_key }}"  register: certificate- name: Create listener https  opentelekomcloud.cloud.lb_listener:    state: present    name: my_listener_https    protocol: terminated_https    protocol_port: 443    loadbalancer: "{{ loadbalancer.loadbalancer.id }}"    default_tls_container_ref: "{{certificate.elb_certificate.id }}"  register: listener_https

Чтобы добавить к балансировщику сервер, необходимо создать пул серверов. Для каждого listener создается отдельный пул:

- name: Create lb pool http  opentelekomcloud.cloud.lb_pool:    state: present    name: my_pool_http    protocol: http    lb_algorithm: round_robin    listener: "{{ listener_http.listener.id }}"  register: lb_pool_http- name: Create lb pool https  opentelekomcloud.cloud.lb_pool:    state: present    name: my_pool_https    protocol: http    lb_algorithm: round_robin    listener: "{{ listener_https.listener.id }}"  register: lb_pool_https

Добавляем сервер в пул:

- name: Create members for a http pool in the load balancer  opentelekomcloud.cloud.lb_member:    state: present    name: my_member_http    pool: "{{ lb_pool_http.server_group.id }}"    address: 192.168.200.10    protocol_port: http    subnet: "{{ subnet.subet.id }}"  register: members_http- name: Create members for a https pool in the load balancer  opentelekomcloud.cloud.lb_member:    state: present    name: my_member_https    pool: "{{ lb_pool_https.server_group.id }}"    address: 192.168.200.10    protocol_port: http    subnet: "{{ subnet.subet.id }}"  register: members_https

И, наконец, добавим healthmonitor для каждого пула, чтобы наблюдать за статусом хостов:

- name: Enable health check for http members  opentelekomcloud.cloud.lb_healthmonitor:    state: present    name: http_healthcheck    pool: "{{ lb_pool_http.server_group.id }}"    delay: 1    max_retries: 2    monitor_timeout: 1    type: http- name: Enable health check for https members  opentelekomcloud.cloud.lb_healthmonitor:    state: present    name: https_healthcheck    pool: "{{ lb_pool_https.server_group.id }}"    delay: 1    max_retries: 2    monitor_timeout: 1    type: http

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

В результате на консоли можно увидеть наш сервер, балансировщик нагрузки и все остальные ресурсы:

Таким образом мы перевели инфраструктуру наших мониторингов полностью на Ansible.

Насколько мне известно, в России не одна компания пользуется услугами Huawei для создания собственных облачных сервисов, было бы интересно увидеть в комментариях, приходилось ли им решать подобные вопросы касаемо расширения ванильного OpenStack SDK и как они к этому подходили.

Весь код находится в публичном доступе и хранится на Github:

Если тема интересна, то буду рад поделиться своим опытом по работе с другими инструментами. Пишите в комментариях, готов ответить на ваши вопросы!

Подробнее..

Cucumber и BDD, пишем ui авто тесты на iOS

08.10.2020 12:16:26 | Автор: admin

Предисловие

Привет, Хабр! В данной статье-мануале я хочу рассказать о базовых функциях такого фреймворка как Cucumber и его применение для создания ui авто тестов на мобильных iOS устройствах.

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

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

Несколько слов о Gherkin, Cucumber и BDD

Gherkin представляет из себя структурированную манеру написания документации для PO, бизнес-аналитиков и тестировщиков. Академическое определение Gherkinговорит, что это человеко-читаемый язык для описания поведения системы, каждая строчка начинается с одного из ключевых слов (Given-When-Then-And) и описывает одно из предусловий/шагов/результатов.

Cucumber - это инструмент, используемый для выполнения behavior driven (BDD) сценариев, написанных на языке Gherkin.

BDD (behavior driven development) - методология разработки ПО, основной идеей которой является составление требований к продукту в формате понятых не-специалисту поведенческих сценариев. Пример BDD сценария:

Scenario: Login with PINGiven the app is runningAnd I'am registered userAnd I see Login screenWhen I enter 4-digits PINThen I am logged in

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

Разворачиваем Cucumber

На сайте Cucumber поддержка iOS находится в любопытном статусе semi-official (полу-официальный?) поэтому процесс установки и настройки фреймворка местами весьма нетривиален.

  • Cucumber - это СocoaPod библиотека, поэтому начинаем с нее. Открываем терминал и устанавливаем CocoaPod

    sudo gem install cocoa pods

  • переходим в свой проект и создаем подфайл

    pod init

  • заходим в созданный подфайл. Проверяем, что в нем есть следующее:

source 'https://github.com/CocoaPods/Specs.git'platform :ios, '11.0'use_frameworks!inhibit_all_warnings!def test_pods  pod 'Cucumberish'endtarget НАЗВАНИЕ_ВАШЕГО_ПРОЕКТАCucumberTests do  test_podsend

Если этой записи нет - добавляем её руками, предварительно удалив всё из файла. Обратите внимание, что в таргете фигурирует название вашего проекта

  • устанавливаем XCFit

    sudo gem install xcfit

  • открываем Xcode, добавляем к проекту новый таргет, используя появившийся шаблон cucumberish bundle. В проекте появятся папка НазваниеВашегоПроектаCucumberTests с дефолтными файлами. Там же необходимо самостоятельно создать папку Features

  • идем в build phases таргета CucumberTests, удаляем дубликаты Copy Bundle Resources, Compile Sources и Link Binary With Libraries

  • закрываем Xcode, устанавливаем поды

    pod install

  • в проекте появится .xcworkspace файл, открываем его. Зачастую на этом шаге отваливаются стандартные файлы из папок Screens, Step Definitions и Supporting Files. Если это произошло - добавляем их обратно руками через Add Files to.

    Почти готово, мы в шаге от завершения установки Cucumber!

  • на момент написания этой статьи (осень 2020) из коробки фреймворк не собирается из-за нескольких ошибок в коде. Возможно, эти проблемы будут неактуальны. Через поиск в Xcode находим и правим следующие строки:

    • добавляем @objc перед class func CucumberishSwiftInit()

    • зменяем var elementQurey на var elementQuery

    • заменяем expectedMenuCount: uInt = uInt(menuCount)! на expectedMenuCount: Int = Int(menuCount)!

    • заменяем expectedCellCount: uInt = uInt(cellCount)! на expectedCellCount: Int = Int(cellCount)!

Вот теперь все. Жмем +U для запуска тестов. Если все сделано правильно, проект соберется, а в логе мы увидим сообщение Tests successfully executed 0 from 0. Это значит, что фреймворк успешно отработал, но не запустил ни одного теста, что не удивительно, так как мы еще не написали ни одного сценария.

Фреймворк "из коробки"

По умолчанию Cucumber имеют следующую структуру:

  • папка Features - в ней хранятся файлы с разрешением .feature, они содержат в себе один или несколько BDD сценариев. Каждый сценарий, написанный на Gherkin, состоит из набора строк, последовательно выполняемых при работе теста

  • <название проекта>CucumberTests.swift файл в корне фреймворка. Содержащий код, выполняемый для Given шагов, задает предусловия каждого теста. По умолчанию файл будет содержать шаг для запуска приложения. Также файл содержит ряд настроек, к примеру, управление тэгами, но о них чуть позже

  • папка Screens - в ней хранятся .swift файлы, содержащие локаторы, по которым можно обращаться к инспектируемым элементам приложения

  • папка Step Definitions - в ней хранятся .swift файлы содержащие код, выполняемый в шагах тестов

  • папка Common - в ней хранится commonStepDefinitions.swift файл, содержащий в себе код, который может выполняться для простых проверок типовых элементов (наличие объектов на экране, нажимаемость кнопок и т.п.)

Для удобства организации шагов и сценариев в соответствующих папках фреймворка можно создавать дополнительные файлы. Все .feature файлы, помещенные в папку Features, будут подтягиваться в тестовые наборы автоматически, а файлы с шагамипотребуется дополнительно вызывать в beforeStart функции CucumberishSwiftInit()

Что происходит при запуске теста?

Фреймворк установлен, теперь мы хотим создать свой первый тест. Для того, чтобы это было проще сделать, надо понимать, что будет происходить c Xcode после того, как вы нажмете +U.

А происходить будет следующее:

  • фреймворк соберет проект на выбранном девайсе/эмуляторе

  • фреймворк построчно распарсит первый сценарий из первого фича-файла

  • все первые Given и And строки будут рассматриваться как предусловия теста. Они могут быть как совсем простыми и состоять из единственного Given условия, так и комплексными Given-And-And- наборами строк

Простой шаг-предусловиеПростой шаг-предусловие
  • фреймворк отправится в корневой swift файл за кодом, выполняемым в этих шагах. Если точнее, то для простого предусловия выше будет выполнен следующий код:

Шаг The app is running является первым и обязательным почти для любого сценария, так как в нем происходит запуск трестируемого приложения.

  • как только будут пройдены все Given шаги и дело дойдет до первой When или Then строки, предусловия будут считаться выполненными. За кодом для выполнения последующих строк фреймворк будет обращаться в .swift файлы из папки Step Definitions

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

Пишем свой первый тест

Итак, имея базовое представление о том, как работает фреймворк мы понимаем, что именно должно быть сделано для создания нашего первого теста:

  • создаем feature файл в папке Features. В начале файла обязательно должна быть общая информация описывающая функционал по шаблону:

Feature:In order to As a I want to 
  • пишем тестовый сценарий в feature файле, используя синтаксис Gerkin

  • в корневом swift файле раскрываем Given шаги этого сценария

  • в step definition файле раскрываем остальные шаги

Особенности написания Given шагов

Упомянутого выше предусловия the app is running самого по себе почти всегда будет недостаточно. Если точка входа в тест находится не на стартовой страничке, а где-то глубже, то удобно использовать комплексные Given-And-And- предусловия. При помощи еще одной или нескольких строк, мы можем привести приложение к нужному для конкретного теста состоянию.

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

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

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

  • запускаем приложение

  • если после запуска мы видим страницу регистрации, то регистрируемся, нажав на кнопку Get started. Ждем, пока прогрузится экран для установки пинкода, задаем пин 0000, вводим его повторно для подтверждения регистрации

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

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

  • Проверяем, что после регистрации/логина приложение прогрузилось, и мы находимся на экране My credentials. Простой ассерт, в котором мы ожидаем экран

  • Проверяем, что на экране в табличке credentialList нет сущностей, если они остались с предыдущих тестов, удаляем их одну за одной. Для этого тапаем по первой ячейке в таблице, вызываем меню действий, тапаем по кнопке "Delete" и подтверждаем кнопкой "Delete credential". Повторяем эти действия пока первая ячейка в таблице не перестанет существовать

В результате предусловия выполнены. Мы имеем запущенное приложение, ожидающее дальнейших шагов на пустом экране My credentials.

Несколько слов о тестовых шагах и CommonStepDefinitions

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

Отдельно хочется рассказать про CommonStepDefinitions.swift. Он создается по умолчанию в папке Common и содержит в себе набор проверок, которые могут быть использованы для тестирования стандартных, типовых элементов.

Допустим, в вашем приложении есть условный объект Menu, на нем находятся две стандартные кнопки Confirm и Deny, а также текст Please confirm. Для того, чтобы проверить отображение этого объекта, кнопок и текста, не обязательно в step definitions детализировать код для четырех разных шагов. Достаточно просто в сценарии написать эти шаги в подходящем под CommonStep формате:

And I see the "Menu" viewAnd I see "Confirm" buttonAnd I see "Deny" buttonAnd I see "Please confirm" text

При выполнении теста все эти строки будут определены как common шаги, а точнее, как один единственный шаг:

Использование common шагов позволяет здорово сократить количество кода, необходимого для простых проверок или действий. Но надо понимать, что этот метод не всегда подходит для тестирования кастомных элементов из-за сложных путей их обнаружения. В этом случае удобнее всего пользоваться обычными step definitions и обращаться к этим элементам через accessibility identifier.

Запускаем тесты

После того, как один или несколько BDD сценариев написаны и ко всем их строкам существует definition, можно запускать тестовый прогон комбинацией +U. В случае, если необходимо запустить только часть тестов, можно воспользоваться тегами, отметив ими желаемые сценарии в фича файлах (или фича файлы целиком) и перечислив теги для запуска в executeFeatures корневого .swift файла.

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

Из этого можно извлечь пользу. К примеру, на нашем проекте из общего количества авто-тестов в 50+ штук необходимо всего 5 тестов на регистрацию. После прохождения этих 5-и тестов состояние регистрации сохраняется и последующие 45 тестов начинаются уже с логина, минуя десяток тапов по кнопкам и пару экранов. Тем самым, мы экономим примерно 10 секунд времени от каждого теста, не выполняя одни и те же действия, уже протестированные ранее.

Обратная сторона медали - периодически требуется очищать приложение от различных сущностей в предусловиях тестов (как было показано выше на примере шага I have no credentials). Для этого приходится писать довольно объемные шаги, но в моем случае такой существенный выигрыш времени стоит того.

Отчет

После выполнения всех тестов будет сформирован стандартный Xcode отчет. Тесты в нем группируются по фича файлам. Для любого шага можно просмотреть детализацию вплоть до вызываемых методов.

В случае падения теста тут же можно будет увидеть подробный лог и скриншоты. Этот инструмент очень удобен при написании и отладке тестов на новые фичи.

Когда начинается магия?

Сперва создание и поддержка cucumber тестов казались мне довольно трудоёмким занятием, фреймворк выглядел медленным и неудобным, а BDD сценарии излишне формализованными. Но после десятка внедренных тестов я полностью изменил свое мнение.

Одна из самых полезных фишек кукумбера - переиспользование отдельно взятых шагов в любом месте, где это допустимо. Максимальное дробление сценариев на мельчайшие части, так раздражавшее поначалу, спустя 3-4 спринта привели к формированию внутри фреймворка большого пула разных шагов. Все эти предусловия, действия и результаты при грамотном написании должны работать независимо друг от друга и иметь одинаковые точки входа-выхода, в этом случае их можно переиспользовать, комбинировать и на лету собирать из них новые авто-тесты просто написав BDD-сценарий. В моей текущей работе бывали случаи, когда создание авто-тестов на новый функционал просто сводилось к написанию BDD сценария из уже существующих шагов. Новый авто-тест без программирования? Фантастика? Так вот с cucumber это действительно возможно.

Если добавить к этому то, что при разработке по BDD методологии сценарии для вас пишет PO и пишет их точь-в-точь как вам надо, то получается совсем утопическая вселенная, где тестировщику остается только скопипастить текст из Jira в фича-файл и получить работающий автотест.

Естественно, реальность всё-таки вносит свои корректировки, и PO будет иметь отличный от тестировщика взгляд на описание фичи, чаще всего, сценарии приходится глубоко редактировать, дополняя деталями или пропущенными шагами, примерять на них стандартные техники тест дизайна. И без добавления кода в step definitions тоже никак не обойтись.

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

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

Подробнее..

Масштабируем продакт-менеджмент, часть 2 продукт

01.03.2021 16:18:41 | Автор: admin

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

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

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

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

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

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

Чем это грозит?

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

Как же тогда определить, что такое продукт?

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

Ценность понятие субъективное. В процессе взаимодействия с решением у покупателя возникнет некоторое собственное ощущение того, насколько простым, приятным, удобным и полезным это взаимодействие. Именно за это покупатель и платит.

Оплата в свою очередь это самый просто маркер для выделения продукта. То, за что пользователь готов платить, и называется продуктом. В данном случае это некоторый набор из систем, людей и процессов, обеспечивающий поток ценности пользователю (operational value stream).

В таком случае владельцу продукта с методологической точки зрения более правильно было бы реализовать разработку сразу нескольких систем, участвующих в потоке ценности. Такие команды разработки называются продуктовыми или функциональными (feature teams или cross-component teams).

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

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

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

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

И еще раз о том, зачем выделять продукт.

В случае, когда продукт выделен правильно, владелец продукта имеет возможность:

  1. Влиять на все компоненты, составляющие поток ценности;

  2. Видеть реальные метрики продукта, а не косвенные, отраженные в компоненте;

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

  4. В ворохе заявок в поддержку выявлять наиболее критические, а не только те, которые относятся к его компоненте;

  5. Фокусировать усилия команды на наиболее проблемных местах, "расшивая" одно "бутылочное горлышко" за другим.

Спасибо за внимание, в следующей статье поговорим про метрики.

Подробнее..

Перебраться через забор или история о том, как стать командой за три часа

25.11.2020 22:06:19 | Автор: admin
Существуют разные мнения о том, как команды становятся командами. Есть несколько наиболее популярных моделей, которые говорят о невозможности стать командой быстро. Это может быть долгий процесс со своей динамикой.

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

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

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


Ну, вы поняли.

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

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

Так впервые мы все увидели друг друга только на первом планировании. И поскольку это было не просто планирование, а PIP (Product Increment Planning мероприятие в SAFe, посвященное высокоуровневому планированию работы команд на следующие несколько спринтов), то нам предстояло разобраться со многими вещами за ограниченный отрезок времени.

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

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


Кстати, наш Product Increment Planning, будь он в оффлайне, мог бы выглядеть так.

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

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

Отвечая, один из разработчиков сделал паузу и просто озвучил все то, что беспокоило каждого из присутствующих. Неуверенность, неловкость, высокий уровень неопределенности Да, все это есть, и мы все это чувствуем. Но помешает ли это нам выполнить то, ради чего мы собрались сейчас? Это вы скажите мне!

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

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

Робкий костер разгорелся в уверенное яркое пламя.

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

Это было удивительно следить за тем, как они за считанные минуты открыли для себя, что все они часть команды.

Выступление на TED на эту тему мне попалось намного позже.

Между тем Продукт Оунер тоже работал вовсю, несмотря на то, что приличная доля работы была выполнена им еще до этой встречи: ведь это он подготовил все требования. Он объяснял высокоуровневые цели, на которые команде нужно было ориентироваться, актуализировал бэклог, отвечал на вопросы, прояснил все, что было возможно прояснить.

Я же, как Скрам Мастер, направляла движение дискуссии, когда это было необходимо, предупреждая возникновение чувства, что сама дискуссия заходит в тупик.

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

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

Нам всем удалось это сделать, действуя сообща. Помогая друг другу, мы получили наш первый успешный совместный опыт еще до начала работы над задачами. На этом планировании наша команда обрела общее достижение (конечно, первое из многих). Мы стали покорителями PI планнинга, и это вселило в нас чувство, что мы безусловно способны успешно реализовать все остальные части нашего сложного проекта.

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

А что именно он может для этого сделать, звучит, как тема для следующей статьи :)
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru