-Поиск по дневнику

Поиск сообщений в comdersrek

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 10.12.2014
Записей:
Комментариев:
Написано: 99





[recovery mode] Ханойские башни — теоретическое решение без рекурсии

Пятница, 06 Января 2017 г. 07:38 + в цитатник
Задача Ханойских башен — одна из самых первых задач, которые предлагаются начинающим программистам, в основном, чтобы проиллюстрировать концепцию рекурсивных решений. В этой статье приводится метод, который позволяет теоретическим путем, без рекурсии, указывать оптимальное решение для текущего хода. "Ханойская башня" является одной из популярных головоломок XIX века. Даны три стержня, на один из которых нанизаны восемь колец, причем кольца отличаются размером и лежат меньшее на большем. Задача состоит в том, чтобы перенести пирамиду из восьми колец за наименьшее число ходов на другой стержень. За один раз разрешается переносить только одно кольцо, причём нельзя класть большее кольцо на меньшее. Классическое решение данной задачи с тремя стержнями предполагает, что для заданного количества колец n количество перекладываний вычисляется по формуле . Дополнительную привлекательность данной задаче придаёт и сопровождающая её легенда: В Великом храме города Бенарес, под собором, отмечающим середину мира, находится бронзовый диск, на котором укреплены 3 алмазных стержня, высотой в один локоть и толщиной с пчелу. Давным-давно, в самом начале времён, монахи этого монастыря провинились перед богом Брахмой. Разгневанный Брахма воздвиг три высоких стержня и на один из них возложил 64 диска, сделанных из чистого золота. Причем так, что каждый меньший диск лежит на большем. Как только все 64 диска будут переложены со стержня, на который Брахма сложил их при создании мира, на другой стержень, башня вместе с храмом обратятся в пыль и под громовые раскаты погибнет мир. Между делом новичку предлагается оценить сложность данного решения, чтобы впечатлить результатом: число перемещений дисков, которые должны совершить монахи, равно 18 446 744 073 709 551 615. Если бы монахи, работая день и ночь, делали каждую секунду одно перемещение диска, их работа продолжалась бы 584 миллиарда лет. Суть решения сводится к пониманию того, что для перемещения текущего диска необходимо решить задачу по переносу всех предыдущих дисков на свободный стержень, перемещению требуемого диска и последующему обратному перемещению всех предыдущих дисков меньшего размера на нужный стержень. Таким образом, решение задачи сводится к предыдущим решениям, что и иллюстрирует механизм рекурсии. Александр Бусаров MrShoor написал очень информативный пост, отлично дополняющий соответствующую статью в Википедии, с очень подробным программным кодом, рекомендую ознакомиться с его реализацией рекурсии. В том же посте имеется описание фрактальной природы алгоритма. Я попытаюсь продолжить это направление, раскрыв применение кода Грея для данной конкретной задачи. Приведу цитату из соответствующей статьи в Википедии: Коды Грея применяются в решении задачи о Ханойских башнях. Пусть N — количество дисков. Начнём с кода Грея длины N, состоящего из одних нулей (то есть G(0)), и будем двигаться по кодам Грея (от G(i) переходить к G(i+1)). Поставим в соответствие каждому I-ому биту текущего кода Грея I-ый диск (причём самому младшему биту соответствует наименьший по размеру диск, а самому старшему биту — наибольший). Поскольку на каждом шаге изменяется ровно один бит, то мы можем понимать изменение бита I как перемещение I-го диска. Заметим, что для всех дисков, кроме наименьшего, на каждом шаге имеется ровно один вариант хода (за исключением стартовой и финальной позиций). Для наименьшего диска всегда имеется два варианта хода, однако имеется стратегия выбора хода, всегда приводящая к ответу: если N нечётно, то последовательность перемещений наименьшего диска имеет вид f->t->r->f->t->r->… (где f-стартовый стержень, t-финальный стержень, r-оставшийся стержень), а если N чётно, то f->r->t->f->r->t->...Оптимальное решение задачи сводится к определению положения дисков после очередного хода. В самом начале (при нулевом ходе) все диски находятся на одном и том же стартовом стержне f. Нумерация весов дисков осуществляется с номера 1 по возрастанию. Требуется описать положение дисков на ходе с номером m. Очевидно, что при оптимальном решении после хода m количество перемещаемых дисков n будет не более (1). Остальные диски большего размера можно не брать в расчёт, что очень удобно при более общем предположении о бесконечном количестве дисков в начальной задаче с тремя стержнями. Далее, определившись с количеством перемещенных дисков, определимся с их положением. Ввиду фрактальности решения, которое описывалось в упомянутых выше источниках, становится очевидным, что благодаря "вложенности" решений друг в друга просматривается связь между двоичным кодом номера хода и номером перемещаемого диска. В частности, во время данного хода перемещается тот диск, чей "вес" i коррелирует с максимальной степенью двойки в двоичном разложении номера m текущего хода минус единицу: (2). В той же нотации Pascal/Delphi, которую использует MrShoor в своем коде, это может быть записано следующим образом: Таким образом, для каждого из дисков с весом i мы можем определить тот ход j, на котором диск данного веса был перемещен последний раз: . Код для определения номера хода num_move последнего перемещения диска с весом i может выглядеть подобным образом (с условием включения модуля Math): Стоит обратить внимание на тот факт, что попутно в переменной q_move получено количество перемещений диска с весом i с начала игры. Итак, в промежуточном итоге, мы знаем, сколько раз каждый диск был перемещен в течение игры после каждого хода. Теперь определимся с тем, куда перемещался каждый из дисков. Как отмечено в Википедии, перемещение верхнего диска циклично и, при выборе определенного стержня назначения t, если N нечётно, то последовательность перемещений наименьшего диска имеет вид f->t->r->f->t->r->… (где f-стартовый стержень, t-финальный стержень, r-оставшийся стержень), а если N чётно, то f->r->t->f->r->t->… Вспоминая о фрактальности, можно заметить, что если отбросить верхнюю часть предшествующих дисков, то текущий диск также совершает подобное циклическое движение во время своих собственных ходов. Учитывая этот факт, становится очевидным, что в зависимости от четности номера диска, цикл перемещения нечетного диска совпадает с циклом перемещения первого диска, а цикл перемещения четных дисков разнится очередностью стержней t и r. В частности, зная количество перемещения q_move и четность номера текущего диска, можно простым делением на 3 по остатку определить последний стержень, куда был перемещен данный диск. Следовательно, имея на входе общее количество дисков N, выбранный стержень назначения t и номер текущего хода m, можно восстановить положение всех дисков при оптимальном решении без обращения к рекурсивным алгоритмам. Для тех, кому интересны вариации задачи Ханойских башен, в частности, случаи 4 и более стержней, предлагаю ознакомиться с опытом PapaBubaDiop, развивающего данное направление в виде игр, попутно пытаясь монетизировать некоторые версии на различных платформах. Надеюсь, что тем из читателей, которым интересны теоретические решения, более оптимизированные для подобных задач с большим количеством входных данных и затрачиваемых вычислительных ресурсов, эта публикация пригодится в дальнейшем в качестве базиса для собственных результатов. Стиль и язык немного суховаты и годятся скорее для академических работ, потому прошу не судить особо строго, особенно с учетом попытки выправить карму и выбраться из минуса. Всем всего наилучшего и светлого, с Новым 2017 Годом: успехов и удач во всем хорошем!

Метки:  

DEV Labs 2016. Онлайн конференция для C++ разработчиков. 10 декабря

Среда, 07 Декабря 2016 г. 01:39 + в цитатник
Приглашаем всех C++ разработчиков принять участие в финальной конференции Soft Labs в 2016 году, которая состоится в субботу 10 декабря. По традиции, мы стараемся не растягивать предновогодние мероприятия. Минимум «воды», максимум практических наработок, которые будут полезны разработчикам в их повседневной работе. В программе мероприятия три выступления: • Павел Цытович расскажет про библиотеку wallaroo для реализации модульной архитектуры С++ приложений; • Владимир Прус покажет возможности применения системы сборки Boost.Build для самых разных проектов на C++; • Дмитрий Одинцов расскажет о том, зачем нужна многопоточность, когда её следует и когда не следует применять. Уровень всех докладов – regular. Конференция стартует 10 декабря в 11:00 по московскому времени. Для участия в конференции необходимо зарегистрироваться. Участие – бесплатное. Для того, чтобы принять участие в любой конференции серии Soft Labs, достаточно иметь компьютер или мобильное устройство, подключённые к интернету. Никакого специального программного обеспечения устанавливать не нужно. Плагин платформы загрузится за несколько секунд. Для проведения наших мероприятий мы используем платформу zoom.us. Помимо отличного качества звука и картинки, данный инструмент позволяет подключаться к мероприятиям с помощью смартфонов и планшетов. > Более подробно

Метки:  

Мнения экспертов об ушедшем в историю «правиле 20%» Google

Воскресенье, 11 Сентября 2016 г. 00:15 + в цитатник
В ИТ-сфере производительность труда напрямую зависит от разработчиков. Поэтому компании ищут и порой находят весьма парадоксальные способы мотивации, компенсации и прочей оптимизации труда рыцарей интеллектуального ордена. Однако находят их не все, а только наиболее рьяные первопроходцы. А после этого общественность увлеченно наблюдает за тем, что происходит в том же Google. Кто-то мечтает применить программы наподобие «правила 20%» у себя в компании, а кто-то настроен скептически. Единого мнения обычно не бывает. Мы попросили экспертов высказаться на эту тему. Насколько эффективно такое правило? Для каких компаний лучше всего работают такие нововведения? Готовы ли крупные российские компании к такому эксперименту? В каких российских ИТ-компаниях это уже реализовано? «В Google запускаются тысячи мини-проектов, которым самим предоставлено доказать свою рентабельность. Из сотни запущенных проектов только единицы окажутся действительно стоящими, а 2-3 зададут новое веянье. Это похоже на два типа добычи ресурсов: интенсивный (вглубь) и экстенсивный (вширь). Google копает вширь и нет-нет, да и наткнется на пару алмазов высшего качества. Надо понимать, что далеко не каждая компания может себе позволить похоронить сотни проектов, чтобы найти несколько стоящих», – писал в 2014 году пользователь Geektimes, проходивший стажировку в Google. «Правило 20%» когда-то приводилось в пример как эффективный подход к инновациям в Google. Каждый сотрудник Google имел право 20% рабочего времени, то есть один день в неделю, посвящать сторонним проектам. Благодаря правилу 20% в своё время появились на свет такие проекты как Gmail и AdSense, Google Cardboard, а также сотни мелких проектов, многие из которых ушли в Open Source. «В Google тьма маленьких команд, которые образовались из 20-процентных проектов. С таким огромным количеством маленьких стартапов внутри компании тяжело всем находить логичное место в иерархии. Кроме того, суть и назначение некоторых команд меняется с течением времени. Отсюда и небольшой беспорядок», – добавляет пользователь. Максим Нальский, CEO Pyrus В правиле 20% компании Google речь идет не совсем о сторонних проектах, ведь результаты работ принадлежат корпорации. В нашей компании есть другое правило: разработчики сами планируют 100% своих задач. У нас итеративная разработка. По понедельникам мы встречаемся, и каждый разработчик обязан прийти со своим планом на неделю. Все знают глобальные планы компании: когда релиз и что в него войдет. Но не менеджеры должны говорить разработчикам, что им делать, а они сами должны прийти и сказать: «Я сделаю вот это». На совещаниях мы модерируем и корректируем планы и приоритеты. Почему у нас так и почему в Google сделали «правило 20%»? Причина в том, что компании конкурируют за лучшие кадры. Реально сильный разработчик делает на порядок больше, чем в среднем по индустрии. Разница действительно на порядок – х10. Просто есть вещи, которые один разработчик может сделать, а 10 разработчиков не сделают никогда. Бывают такие таланты, и за них борются работодатели. Google привлекает лучших разработчиков со всего мира. Творческих людей невозможно заставить делать то, что им неинтересно. Им нужно давать определенную свободу. Что касается самого правила, то есть разные мнения. Считается, что в Google этим правилом пользуются только 10% сотрудников. Когда Марисса Мейер пришла в Yahoo!, ее спрашивали: «Когда вы сделаете в Yahoo это правило 20%?». Она ответила: «Я вам открою страшный секрет про Google. Это правило не 20%. Это правило 120%». Лично я убежден, что ничего стоящего, работая 20% времени, за год сделать невозможно. Когда ты создаешь новый продукт, ты выкладываешься на 200%, живешь этой идеей и делаешь с утра до вечера. Поэтому за эти 20% времени можно только нащупать какую-то идею и убедить свое руководство выделить ресурсы. Йован Савович, Футурико Мне кажется, у нас в компании все распоряжаются всеми 100% своего времени, по крайней мере, мы к этому стремимся и в последнее время сознательно, как часть механики процесса. И я не знаю, правильно ли это в смысле эффективности, и не уверен про другие компании, как бы им пошло. Но мы стараемся, чтобы сами за себя решали, что важно, все. Илья Сачков, Group-IB Я думаю, такое правило в Google появилось не с первого дня существования компании. И думаю, что оно появилось в тот день, когда компания находилась в устойчивом состоянии, и ей нужен был рост, и она была готова привлекать стартапы. Конечно же, лучшие стартапы могут рождать в том числе внутренние сотрудники. Но, для нас, например, в текущий момент гораздо важнее совершенствовать собственные продукты, которые ещё не полностью захватили рынок. Некоторые из них находятся на совсем ранней стадии. Поэтому для нашего этапа развития компании сотрудникам важнее совершенствовать существующие продукты, расширять их функционал. Для таких компаний как Mail.ru или «Яндекс» такая стратегия и такие проекты, наверное, возможны. Я о подобном в России не слышал, но подобная культура напоминает именно «Яндекс». Алексей Крайнов, Riot Games Russia Director Могу только за Riot Games сказать: мы работаем на Free Schedule — время работы, количество отпусков и отгулов — на усмотрение сотрудника. Глобально и локально в московском офисе. Нужно понимать, что это возможно только среди реально сильных профи и ответственных людей. Они уже могут распорядиться этим подходом с ценностью и для себя, и для компании. Владислав Кочетков, ФИНАМ В финансовой компании сотрудники, как правило, работают в условиях жёстких временных ограничений. И даже если им приказным порядком выделять 20% времени для творчества, большинство предпочтёт использовать это время для решения текущих задач. Зато у нас есть экономисты, стратеги и аналитики, которые занимаются исследованиями и разработками концепций, дизайном новых продуктов и тому подобным креативом. Такое правило теоретически эффективно для компаний с организационной структурой типа «ad hoc», как её называют Камерон и Квин. То есть для молодых, быстро развивающихся компаний, где KPI часто меняются. Если бы KPI были жёсткими, то сотрудники вместо реализации собственных идей старались бы повышать показатели, заданные менеджерами (не важно, насколько эти показатели адекватны рыночной ситуации). На практике это правило проявило себя, в основном, в крупных прибыльных IT-компаниях, которые снимают так называемую «инновационную ренту», т.е. получают прибыль благодаря тому, что оказались первыми в каком-то направлении. Подобные крупные IT-компании зачастую служили кладбищами идей своих сотрудников и источником кадров для конкурентов. Обычно в качестве примера приводят историю Xerox, где изобретено было множество полезных нововведений, но до внедрения довели лишь малую её часть. В мелких рыночно-ориентированных компаниях редко ведутся НИОКР, поэтому такое правило нежизнеспособно. Небольшие компании не настолько маржинальны (как Google или Яндекс), чтобы часто идти на риск изобретения новых вещей. Они чаще копируют. А для клонирования и адаптации идей гигантов нужно не столько снабжать сотрудников рабочим временем, сколько, наоборот, следить за его целевым использованием. Что касается стартапов, то им, тем более, важно, чтобы команда была сфокусирована на одной цели. В России подобная программа [по типу 20%] реализована в компании «Яндекс». В частности, насколько мне известно, так появился проект «Школа вебмастеров». Артур Сахаров, Redmadrobot Химчистка, спортзал, детский сад, автосервис — инфраструктура, которой обрастают ИТ-гиганты, чтобы сотрудники как можно больше времени проводили в офисе компании. Эрик Шмидт, кстати, говорит о «правиле 120%» — 100% времени разработчики посвящают работе, 20% — своим проектам, которые за счет сформированной в ИТ-компании среды отнимают сильно меньше ресурсов. В реальности инженеры Google проводят еще больше времени, занимаясь разработкой, потому что им просто не нужно разбираться с домашними ежедневными проблемами. В Redmadrobot разработчики занимаются не только коммерческими проектами и не только кодингом. Они участвуют в R&D активностях, в автоматизации процессов, оптимизации разработки, выступают на конференциях, пишут статьи на Хабр — на все это выделяется время. У нас нет четкого правила 20% потому, что на самом деле нигде его нет. Мы стараемся построить структуру и спланировать работы так, чтобы сотрудники делали то, что приносит компании пользу, без сильных ограничений. Естественным образом получается, что начинающие разработчики почти полностью заняты на проектах и прокачиваются на них, а самые крутые отводят до 60% времени на активности, направленные на развитие и перспективу. Иначе быть не может, компания является полигоном для развития своих сотрудников, для освоения ими новых технологий, из которых потом возникают новые продукты и решения, и задача построенной системы управления — способствовать этому развитию. Руслан Фазлыев, Ecwid Бизнес требует 100%. Google де-факто закрыл инициативу «20%». Только абсолютный фокус делает возможным победы. Насколько эффективным это было бы, если бы мы ввели у себя? А мы вводили. У X-Cart, PHP платформы электронной коммерции, была возможность сотрудникам инкубировать свои проекты. Никто не смог. Проекты, которые реально успешно инкубировались X-Cart — Ecwid, Tittygram, делались более чем одним сотрудником, и компания давала на них ресурсы. Одиночка может провести разведку, но победа происходит только когда компания начинает воспринимать проект всерьез. В маленькой компании правило 20% — это катастрофа, стартапы не могут позволить себе терять 20% продуктивности. И если люди хотят пилить какие-то еще продукты, кроме основного, это повод задуматься: а таким ли интересным является основной, не пора ли «встряхнуть все». В большой компании полезный выхлоп от 20% может происходить только когда она всерьез начинает поддерживать единичные начинания. Будет поддерживать все — размоется. В результате получается, что «система 20%» де-факто не может работать: сотрудники пилят свои проекты на выброс. Что действительно работает — тематические хакатоны время от времени, и мы их устраиваем. В 2004 году Ларри Пейдж и Сергей Брин впервые заявили, что в компании используется «правило 20%». В 2013 году СМИ писали, что сотрудников лишили права открывать собственные проекты по «правилу 20%». С приходом в главное кресло корпорации Ларри Пейджа политика резко изменилась. Был взят новый курс на максимальную эффективность разработок при малом количестве направлений, а не на диверсификацию проектов. Отмена «правила 20%» началась с того, что в 2012 году разработчиков обязали получать специальное разрешение на сторонние проекты у менеджера. Вот что по этому поводу писал директор по разработке Google+ Джеймс Виттекер в 2012 году, объясняя причину своего ухода: «Под Эриком Шмидтом реклама была всегда в фоновом режиме. Google управлялась как фабрика инноваций, поощряя работников к предпринимательству с помощью наград учредителей, бонусов и 20% времени. Доход от рекламы давал нам запас для размышлений, изобретательства и созидания. Форумы вроде App Engine, Google Labs и опенсорса были плацдармом для наших изобретений. До нас не доходил тот факт, что это все оплачивалось банкоматом, набитым добычей от рекламы. Наверное, до инженеров, разрабатывающих конкретно рекламу, это и доходило, но все остальные были убеждены, что Google была в первую очередь технологической компанией; компанией, нанявшей умных людей и поставившей крупную ставку на их способность к инновациям. Из этой машины для инноваций вышли стратегически важные продукты вроде Gmail и Chrome: продукты, которые были результатом инициативы на самых нижних уровнях компании. Конечно, столь неудержимый новаторский дух иногда приводит к неудачам. Были такие и у Google, но компания всегда знала, как быстро упасть, встать и сделать выводы. В таких условиях вы не должны быть частью какого-нибудь особенного «внутреннего круга» для успеха. Вам не должно везти с получением крутого проекта, на котором можно сделать карьеру. Любой с идеями или умением сотрудничать может внести свою долю. За это время у меня было несколько возможностей уйти из Google, но я не мог себе представить лучшего места для работы. Но, как говорится, это было тогда, а сейчас — это сейчас». Потом в компании Google сформировали мощный аналитический отдел, который анализировал производительность персонала. Чтобы работать с максимальной эффективностью, сотрудникам нужно уделять основному проекту 100% своего времени. Поэтому желающих подать заявку на открытие проекта по «правилу 20%» становилось все меньше. Формально это правило продолжает существовать в компании, но на деле его применение не одобряется.

Метки:  

[Перевод] GitLab 8.11: канбан-доска и разрешение конфликтов одним кликом

Воскресенье, 28 Августа 2016 г. 02:22 + в цитатник
Эта статья — перевод релизной статьи компании GitLab. Релизы выходят каждый месяц 22 числа. Если вы пропустили предыдущие, вот ссылки: 8.10, 8.9, 8.8 В новом GitLab 8.11 столько всего интересного, что мы с трудом сдерживаем себя в рамках конструктивного повествования! Итак, в новой версии появились: принципиально новый новый способ представления и работы с тикетами (issues); слеш-команды (/command) для работы с тикетами; возможность создавать шаблоны тикетов (в неограниченном количестве); онлайн-среда разработки; возможность разрешать конфликты мержа не выходя из GitLab; настройка прав на пуш в ветку для отдельных участников и групп (только в ЕЕ); … и много других фич, о которых мы тоже расскажем. MVP этого месяца — Clement Ho. Спасибо ему за мерж-реквесты и отзывчивость в работе над задачами. Доска тикетов (Issue Board) Тикеты (issues) в GitLab — очень гибкий инструмент. Они могут содержать ссылки друг на друга, можно обозначить их приоритеты, можно отсортировать по популярности. Доска тикетов добавляет новый способ работы с ними. Теперь можно настраивать рабочие процессы (workflows) и быстро получать информацию о состоянии тикетов. Всё это доступно на простой и приятной глазу доске, похожей на те, что используются в Канбане или Скраме. Доска создается для каждого проекта автоматически. По умолчанию все открытые тикеты формируют список-бэклог (Backlog), а все закрытые появляются в списке завершённых (Done list). Добавляя новые списки, вы создаёте новые рабочие процессы. Принадлежность тикета к списку определяется меткой. При добавлении тикета в список к ней добавляется соответствующая метка, при удалении из списка — метка удаляется. Если у вас раньше были метки вроде фронтенд, бэкенд и дизайн — самое время сделать из них списки. Тикеты появятся в них автоматически. И, конечно, тикет может принадлежать более чем одному списку. Если хотите посмотреть на эту фичу в действии, загляните на доску GitLab CE версии 8.12. Документация по доскам тикетов Разрешение конфликтов при мерже Мержи в крупных и активно разрабатываемых проектах обычно вызывают много проблем. Мы хотим, чтобы у вас был встроенный инструмент для разрешения конфликтов. Поэтому теперь можно это делать прямо в интерфейсе GitLab. Когда мерж блокируется конфликтом, можно просто нажать кнопку "Resolve these conflicts" и перейти в интерфейс разрешения. Там можно выбрать нужные строки и закоммитить полученный результат. Разумеется, так получится разрешить далеко не все конфликты. Но мы надеемся, что в большинстве случаев этот инструмент поможет вам ускорить прохождение мерж-реквестов. Документация по разрешению конфликтов Разрешения на работу с ветками для конкретных пользователей (только EE) Теперь в Enterprise Edition можно настраивать разрешения на пуш или мерж в ветку не только для подгрупп пользователей (как developers или owners), но и для конкретных пользователей. Новые настройки можно совмещать с другой функциональностью, в том числе с разрешениями для подгрупп. Например, можно разрешить пушить непосредственно в ветку только тимлидам Пете и Маше, но подтверждать мерж-реквесты в эту ветку — всем членам группы уровня developer и выше. Для каждого действия (пуш и мерж) можно настроить любое количество авторизованных пользователей. Документация по разрешениям на работу с ветками «Закрытие» комментариев в мерж-реквестах. В мерж-реквестах бывают длинные ветки комментариев, в которых можно запутаться. Но каждый из них важен. Мы добавили возможность отметить комментарий или целую ветку как обработанную и закрыть её. В мерж-реквестах теперь также есть счётчик незакрытых обсуждений и удобная кнопка перехода к к следующему открытому обсуждению. Документация по закрытию обсуждений в мерж-реквестах Схемы конвейеров. Конвейеры в GitLab могут иметь достаточно сложную структуру с множеством последовательных и параллельных сборок. Теперь можно посмотреть на схему конкретного конвейера, отображающую его строение и состояние. Такая схема наглядно показывает происходящие в нём процессы. Просто кликните на конвейере на странице мерж-реквеста или в списке конвейеров. Вы увидите схему этого конвейера с отображением выполненных, проваленных, активных и ожидающих сборок. Шаблоны тикетов и мерж-реквестов. Возможность стандартизировать тикеты и мерж-реквесты с помощью шаблонов уже была в GitLab Enterprise Edition. Начиная с GitLab 8.11 шаблонов может быть много — например, один для ошибок, а другой для предложений. А сама возможность есть во всех версиях: GitLab.com, GitLab CE/EE. Шаблоны пишутся в разметке Markdown и лежат в вашем репозитории соответственно в папках .gitlab/issue_templates и .gitlab/merge_request_templates: Цель этой фичи — улучшить внешний вид и полноту предложений, сообщений об ошибках и мерж-реквестов. Документация по шаблонам Слеш-команды Теперь в GitLab есть слеш-команды (/command) — так же, как в IRC, HipChat, Mattermost или Slack. Они позволяют менять метки, назначать исполнителей, подписываться и отписываться от тикетов и делать многое другое — быстро и не отрывая рук от клавиатуры. Команды работают в описании тикета или мерж-реквеста, а также в комментариях. Как ими пользоваться: Вы вводите текст, содержащий команду (с клавиатуры, из шаблона, через API, как угодно). Подтверждаете отправку комментария, сохранение тикета или реквеста. Команды выполняются и больше не показываются в тексте. Если комментарий состоял только из команд, он будет выполнен, но не опубликован. Можно использовать слеш-команды даже при создании нового тикета или реквеста: Если последовательно указать несколько команд, то все они будут выполнены. Несколько идей, как можно использовать слеш-команды: В письме в ответ на оповещение из тикета или мерж-реквеста (текст письма становится комментарием). В шаблоне тикета или мерж-реквеста. Через notes API. Мы сами с нетерпением ждём ваших рассказов о том, какие ещё способы использования вы изобретёте. Документация по слеш-командам Интеграция с Koding Koding позволяет запускать среду разработки в облаке, использовать единые настройки этой среды для всей команды и даже использовать локальный редактор. Благодаря этому не нужно тратить время на установку и настройку стека для каждого нового компьютера и при любом изменении. Начиная с версии 8.11 GitLab поддерживает интеграцию с Koding. Теперь одним нажатием кнопки можно выкачать проект целиком или отдельный мерж-реквест и открыть его в полноценной облачной IDE. (обратите внимание, что на GitLab.com интеграция с Koding пока не добавлена). Включите поддержку Koding в Admin > Application settings Настройте Koding для работы с вашим проектом: И все! Теперь вы можете быстро выкачать любой мерж-реквест, ветку и коммит проекта в полноценную IDE. Мы подготовили небольшое видео, показывающее процесс работы связки Koding + GitLab: Для того, чтобы узнать больше о Koding в GitLab, обратитесь к нашей документации. Конвейеры в мерж-реквестах Теперь конвейеры отображаются в мерж-реквестах: Нажмите на конвейер, чтобы увидеть его схему и билды, относящиеся к нему. Отображение статуса развертывания для мерж-реквестов Теперь вы можете указывать URL для своих сред развертывания (environments): Благодаря этому GitLab показывает статус развертывания для мерж-реквестов в случаях, когда развертывание происходит автоматически при мерже: После успешного мержа GitLab покажет вам ссылку на среду развертывания, что позволяет увидеть результат мерж-реквеста в один клик. Веб-хуки для конвейеров (pipelines) Для упрощения интеграции с конвейерами GitLab мы добавили веб-хуки для них. Они срабатывают при создании, запуске или завершении работы конвейера. Для того, чтобы добавить веб-хук, выберите Webhooks в меню Settings вашего проекта. Подсветка и скрытие кода Теперь редактор GitLab поддерживает подсветку и позволяет скрывать блоки кода. Ссылки на мерж-реквесты при пуше Теперь при пуше на GitLab появляются ссылки на создание мерж-реквеста, а также на все мерж-реквесты, имеющие отношение к текущему. Значок покрытия тестами (test coverage) Появилась возможность создавать значки, показывающие покрытие тестами вашего проекта: Если вы не использовали отображение покрытия в GitLab, подключите его в настройках конвейеров: pipelines/settings. Документация по значкам покрытия тестами Временные ограничения на доступ к проекту При выдаче доступа к проекту одиночному пользователю, либо группе, теперь можно установить определенную дату, после которой доступ к проекту будет для них закрыт. Это упрощает работу с правами доступа для временных членов команды. Перемещение проектов между шардами (только EE) В GitLab 8.10 были добавлены множественные точки монтирования (mount points). В GitLab 8.11 появилась возможность перемещать проекты между шардами (shards) при помощи команды rake. Эта функциональность не предполагается для частого использования, однако она может оказаться полезной в случаях, когда вы хотите протестировать новый шард или переместить часто используемый проект на хранилище с быстрым доступом. Улучшения производительности В данном релизе был введен ряд изменений направленных на повышение производительности — мерж-реквесты и их диффы стали еще быстрее! Ниже приведены графики, показывающие разницу в производительности после развертывания GitLab 8.11 RC2 на GitLab.com (падение в производительности попадает на развертывание). Время загрузки диффов для мерж-реквестов: Количество выполненных SQL-запросов при отображении диффов: Время, потраченное на выполнение SQL-запросов при отображении диффов: Также значительно повысилась производительность конвейеров: Ниже приведен детальный список проведенных улучшений и соответствующих мерж-реквестов: Улучшения Улучшен процесс проверки на возможность пользователю просматривать несколько тикетов: !5370 Улучшена процесс проверки максимального уровня доступа пользователя: !5412 Уменьшено количество SQL-запросов для отображения CI графиков: !5502 Добавлены улучшения для работы GitLab’а с Git, направленные на уменьшение количества используемых команд и более быструю сортировку номеров версий: !5536, !5375 Информация об авторах коммитов теперь кешируется для каждой Sidekiq-транзакции во избежание дополнительных выборок: !5537 Уменьшено количество запросов, используемых для отображения диффов мерж-реквестов: !5551 Улучшена итерация по наборам диффов: !5564 Повышена производительность методов, зависящих исключительно от статистики диффов: !5568 Повышена производительность создания диффов путем удаления излишних проверок на текстовые блобы: !5575 Удалены ненужные вызовы методов при создании диффов: !5591 Улучшена проверка на активность diff note: !5597 Улучшен процесс создания ссылок на трекер тикетов: !5608 Повышена производительность парсинга ссылок в документах Markdown: !5629 Повышена производительность синтаксической подсветки блоков кода в документах Markdown: !5643 Улучшен процесс генерации ключей кеша для документов Markdown: !5715 Улучшен процесс сортировки тегов Git: !5723 Удалены триграммные индексы для таблицы ci_runners (только для PostgreSQL): !5755 Удалены выборки коммитов в DiffHelper: !5756 Удалены 45 избыточных индексов для баз данных: !5759 Обратно добавлено кеширование todo-счетчиков: !5789 Уменьшено количество проектов, используемых в запросах на получение списка todo: !5791 Более не отображаются SVG-изображения размером более 2 мегабайт, благодаря чему уменьшено время загрузки и использование памяти: !5794 Решена проблема с утечкой памяти в sanitization-фильтре Markdown: !5808 Изменено отображение выпадающего меню, показывающего список проектов, в которые можно переместить тикет — теперь используется постраничный вывод вместо отображения полного списка: !5828, !5686 Удалены вызовы методов, ответственных за поиск ненужных блобов Git: !5848 Добавлена асинхронная загрузка выпадающих меню для веток в диалогах cherry pick и revert: !5607 Улучшены запросы, используемые для отметки todo как завершенных: !5832 Проведен апдейт gitlab_git до версии 10.4.7 для использования улучшений, появившихся в этой версии библиотеки: !5851 Улучшены проверки доступа Git в Enterprise Edition: !647 Удален ненужный индекс таблицы geo_nodes: !639 Ace Editor теперь загружается только по необходимости, что уменьшает размер используемого JavaScript почти на 100 килобайт: !4914 Новые фичи Sidekiq теперь кеширует некоторые объекты транзакций. Эта опция включена по умолчанию, ее можно отключить через переменную окружения: !5054 Теперь GitLab может использовать ruby-prof при обработке запросов, сохраняя данные профилировки на диск для дальнейшего просмотра. Для использования этой фичи нужно определить токен в заголовке: !5281 Добавлена возможность отслеживания кастомных событий с помощью GitLab Performance Monitoring. Например, количество пушей, форков проектов и т. д.: !5830 Инструментирование Проведено инструментирование Nokogiri: !5470 Уменьшена ненужная нагрузка на инструментирование вызовов методов: !5550 Проведено инструментирование класса Repository: !5621 Проведено инструментирование Gitlab::Highlight: !5644 Проведено повторное интсрументирование Project.visible_to_user: !5793 GitLab Mattermost 3.3 GitLab 8.11 поставляется с Mattermost 3.3, открытым аналогом Slack. В Mattermost 3.3 добавлены локализации на китайский, корейский и голландский языки, бот на Go, возможность помечать (flag) посты, упоминания вида @here и многое другое. Кроме того, в этоу версию Mattermost вошли несколько security updates, поэтому мы настоятельно рекомендуем обновиться на нее. Поддержка Redis Sentinel В GitLab теперь еть экспериментальная поддержка Redis Sentinel. Все подробности в документации Прочие изменения Этот релиз включает в себя и многие другие улучшения, включая различные security fixes. Полный список изменений доступен в Changelog. Upgrade-барометр Обновление до GitLab 8.11 потребует даунтайма из-за миграций баз данных Даунтайм для сайта GitLab.com (самый крупный из известных нам инстансов GitLab) составил 15-30 минут. В зависимости от количества данных на вашем инстансе ваш даунтайм может быть меньше. Одна из миграций удаляет несколько столбцов в нескольких таблицах (и инстанс GitLab нужно свернуть, чтобы эти данные не пропали в процессе доступа к ним). Две другие миграции создают новые таблицы и наполняют их информацией на основе уже существующих в системе данных: в этом случае даунтайм нужен, чтобы добавляемые данные не поменялись в процессе работы миграции (и оставались неизменными, пока развертывание 8.11 не завершено полностью). Наконец, еще одна миграция добавляет два внешних ключа (foreign keys), и здесь даунтайм нужен для гарантии отсутствия одновременного доступа к изменяемым данным. Устаревание (deprecation) Ruby 2.1 С этим релизом мы обновили Ruby до версии 2.3. Для ручных установок мы настоятельно рекомендуем вам обновить Ruby до 2.3. Установки GitLab, сделанные через Omnibus, автоматически будут использовать Ruby 2.3. Поддержка Ruby 2.1 и 2.2 будет полностью прекращена в GitLab версии 8.13. Для тех, кто обновился раньше остальных Если вы обновились до 8.11 сразу после релиза и в процессе reconfigure получили ошибку undefined method merge! for nil:NilClass, то скачайте более новый пакет с младшей версией .1: 8.11.0-ce.1. Просто запустите apt-get update and apt-get install gitlab-ce / apt-get install gitlab-ee, и всё должно починиться само. Форсированная двухфакторная аутентификация при использоваии GitLab API и Git поверх HTTP Если у вас включена двухфакторная аутентификация и вы пытаетесь получить API-токен через метод /sessions или Resource Owner Password Credentials flow provided в OAuth2, то вы не сможете залогиниться. Для успешного логина в этих случаях вам нужно будет использовать Personal Access Token. Подробнее о personal access tokens Реиндексирование Elasticsearch (только для EE) Мы изменили структуру индексов Elasticsearch и теперь они используют взаимоотношения типа «родитель-ребенок». Это повышает производительность, но требует полной перестройки всех индексов Elasticsearch. После обновления до 8.11 вам надо будет вручную удалить старые индексы и построить новые. Для удаления старых индексов сделайте вот такой запрос к Elasticsearch: curl -XDELETE 'http://localhost:9200/_all/' Для перестройки индексов выполните действия описанные в документации по интеграции с Elasticsearch Внимание Описанное выше применимо только если вы обновляетесь с предыдущей версии (8.10). Если вы обновляетесь с более ранних версий, проверьте разделы «Upgrade-барометр» для всех промежуточных версий. Если вы обновляетесь с версии GitLab, меньшей, чем 8.0 и при этом у вас включен CI, вам нужно сначала обновиться до 8.0. По умолчанию в процессе обновления все пакеты Omnibus будут остановлены, потом будут прогнаны все их миграции, и только потом они будут запущены снова. Это поведение не зависит от «размера» обновления. Изменить это поведение можно, создав файл /etc/gitlab/skip-auto-migrations. Установка Если вы устанавливаете GitLab с «нуля», прочитайте соответствующий раздел: https://about.gitlab.com/installation/ Обновление Инструкции по обновлению: https://about.gitlab.com/update/ Enterprise Edition GitLab Enterprise Edition включает в себя дополнительные функции типа поддержки LDAP-групп. Подробную информацию можно посмотреть в описании GitLab EE. GitLab EE доступен только по подписке, подробности и цены можно посмотреть вот тут. Не хватает времени на установку и настройку нового инструмента? В стоимость подписки входят услуги по установке и обновлению GitLab на ваших серверах. P.S. Если будете обновляться, обновляйтесь сразу на 8.11.2

Метки:  

Mikrotik QOS в распределенных системах или умные шейперы

Воскресенье, 07 Августа 2016 г. 12:27 + в цитатник
А что бы вы со своей стороны могли предложить? — Да что тут предлагать… А то пишут, пишут… конгресс, немцы какие-то… Голова пухнет. Взять все, да и поделить. — Так я и думал, — воскликнул Филипп Филиппович, шлепнув ладонью по скатерти, — именно так и полагал. М. Булгаков, «Собачье сердце» Про разделение скорости, приоритезацию, работу шейпера и всего остального уже много всего написано и нарисовано. Есть множество статей, мануалов, схем и прочего, в том числе и написанных мной материалов. Но судя по возрастающим потокам писем и сообщений, пересматривая предыдущие материалы, я понял — что часть информации изложена не так подробно как это необходимо, другая часть просто морально устарела и просто путает новичков. На самом деле QOS на микротике не так сложен, как кажется, а кажется он сложным из-за большого количества взаимосвязанных нюансов. Кроме этого можно подчеркнуть, что крайне тяжело освоить данную тему руководствуясь только теорией, только практикой и только прочтением теории и примеров. Основным костылем в этом деле является отсутствие в Mikrotik визуального представления того, что происходит внутри очереди PCQ, а то, что нельзя увидеть и пощупать приходится вообразить. Но воображение у всех развито индивидуально в той или иной степени. Поэтому я решил написать еще один материал, в котором я смешаю теорию с практикой, визуальными примерами и разобью данный материал на блоки от простого, к сложному. С каждым новым примером я буду добавлять необходимую информацию, и в самом конце вы получите полное представление, как это все работает. Думаю, так будет значительно проще понять основные принципы построения шейпера на микротике. В данном материале я буду рассматривать только Queue Tree очереди с использованием PCQ. Уж извиняйте, Simple Queues для меня это — несколько не тот уровень возможностей. Так же не будет описан устаревший материал, который применим только для пятых версий ROS, хотя в некоторых моментах я буду на него ссылаться для сравнения. Начнем с простого примера Имеем микротик: WAN интерфейс с белым адресом (1.1.1.1) и входящей скоростью 32 мегабита в секунду LAN — c подсетью 192.168.0.0/24 Задача нарезать входящую в различных комбинациях (Download) скорость для подсети 192.168.0.0/24. Исходящую скорость (Upload) пока трогать не будем, но отмечу, что ее реализация почти ничем не отличается от реализации входящей скорости. Для того чтобы что то нарезать на микротике мы должны определится с критериями отбора нужного нам трафика и выделить его. Для этого нам понадобится /ip firewall mangle. Мангл можно представить в виде своеобразного фильтра, способного отбирать из общего потока пакеты и соединения по определенным критериям и выполнять с ними определенные действия. Наш единственный критерий известен: нам из общего потока нужны только пакеты, которые идут в подсеть 192.168.0.0/24. В качестве действия с этими пакетами мы выберем — назначение пакету маркировки, впоследствии на основе этой маркировки пакеты можно будет обработать в Queue Tree. Чтобы правильно промаркировать пакет — нужно знать по каким цепочкам в Mangle он проходит. Для этого нужно знать диаграммы движения пакетов (Packet Flow) причем не абы какие, а именно свежие диаграммы т.к. в шестой версии ROS схема немного изменилась. И естественно, посмотрев на эти диаграммы впервые, у вас на устах ничего кроме матерных слов не будет. Опять же не все так сложно как кажется, данные диаграммы показывают, как ходит трафик во всех случаях, нам же для работы с шейпером понадобится лишь малая их часть. Исходя из данной диаграммы, можно понять, что интересующий нас трафик идет по пути: Input Interface > PREROUTING ->FORWARD ->POSTROUTING -> Output Interface Схема при включенном NAT будет чуть пожирнее: Input Interface > PREROUTING > DST-NAT >FORWARD > POSTROUTING > SRC-NAT > Output Interface Какую из цепочек выбрать? В пятых версиях ROS кроме того где находится NAT, нужно было еще знать где находится обработка очередей global-in, global-out и global-total. В шестой версии стало все проще, т.к. вышеуказанные обработки упразднили и заменили одним global. И находится этот global в самом конце POSTROUTING, после него обрабатываются очереди SimleQueue и пакет отпускается на волю. Исходя из этого — нам неважно, где он теперь, т.к. все обработки по маркировке производятся до него. А раз так, то единственное ограничение нам создает только NAT и выбор будет зависеть от направления трафика, который мы хотим промаркировать. По этому случаю накидал свою диаграмму: Как видно из диаграммы, для маркировки полученных пакетов, нам нужны цепочки, в которых доступны серые адреса подсети 192.168.0.0/24 (dst-address). А видно их только в FORWARD и POSTROUTING. Для того чтобы промаркировать Upload пакеты нужны цепочки со второй половины диаграммы, в которых доступны серые адреса подсети 192.168.0.0/24 (src-address). А доступны они во всех трех цепочках PREROUTING, FORWARD, POSTROUTING. Я рад, что не поленился и написал так много лишних букаф. И все для того, чтобы донести до вас информацию о том, что независимо от направления, которое мы хотим промаркировать, можно выбрать цепочку FORWARD в обоих случаях. Но так нельзя делать в пятых версиях ROS. С цепочкой определились, теперь нужно определиться с тем, как мы будем помечать пакеты. Сначала пометить соединения, а уже потом в них пометить нужные пакеты? Или просто пометим пакеты и все взлетит? Как то давно во времена первых версий из шестой линейки, мне написал один хороший человек (за что ему огромное спасибо!), и сказал, что у него в системе интересный глюк. Дал он мне соединение на TeamViewer и показал, как обычная маркировка пакетов помечает на треть (треть! Карл!) пакетов больше, чем маркировка при тех же параметрах но в пределах соединений. Соответственно и скорости в дереве были в норме, а вот на интерфейсах были на треть выше. Ковырялся долго, ничего не нашел. Делал повторую маркировку по тем же критериям вне коннекшена, предварительно отключив дальнейшие передачи уже помеченных пакетов в вышестоящих правилах. Все это с занесением в лог. Нормальные обычные пакеты, почему они не попали в коннекшен так и не понял. Поставил ту же версию себе на тестовый стенд (один WAN, один LAN и все это под двойной NAT) настроил правила и поймал тот же глюк у себя. На протяжении четырех-пяти (уже не помню) версий я ловил данный глюк. Потом тупо сделал нагрузочный тест и понял — не такое уж и великое снижение нагрузки на камень, чтобы использовать маркировку в соединениях. С тех пор, на маркировку пакетов в соединениях — я забил. Как руки дойдут — проверю, а пока маркирую пакеты так. Ну, с этим закончили. Правило в студию! Данным правилом мы помечаем все пакеты, у которых dst-address равен адрес листу «LAN» ну и назначаем им packet-mark тоже «LAN» /ip firewall mangle add > Так же добавим и сам адрес лист: /ip firewall address-list add > На этом маркировка в одном направлении закончена, чтобы промаркировать исходящий трафик, нам нужна копия правила, где заменен на > Но как я уже писал, для примера мы возьмем только входящий трафик. Ловим трафик в Queue Tree Для того чтобы создать очередь PCQ в данном случае требуется одно правило и профиль в Queue Type. Но я создам два правила, чтобы на одном примере показать как в том, или ином случае ведет себя очередь при установке лимитов. Родительская очередь /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 > Тут стоит прояснить несколько моментов: — В данном параметре можно указать либо «global» либо имя интерфейса. Имя интерфейса тут играет роль определенного фильтра направления трафика и используется в сложных конфигурациях для исключения всех направлений кроме указанного интерфейса и действует только для этой очереди и ее потомков. Всегда указывайте в данном параметре «global» эффект будет тот же, а проблем меньше. — в условии задачи указано что канал у нас выдает 32 метра, но прописывать нужно чуть меньше доступной скорости. В противном случае вы упретесь в шейпер своего провайдера, ваш же просто не будет работать. burst-limit=0 burst-threshold=0 — отключены т.к. их использование мало чего дает при PCQ, но в профиле они имеют достаточную актуальность для использования. > — приоритет очереди, 1 — высший приоритет, 8 — низший приоритет. НЕ РАБОТАЕТ если очередь имеет потомков. Приоритеты работают только у потомков, причем конкурируют они друг с другом не только в пределах своего родителя, но и с потомками других родителей и только в случае общего дедушки, который лимитирует этим дармоедам скорость. При одинаковых приоритетах они распределят между собой всю доступную дедушкой скорость. При разных — сначала из общей дедушкиной миски едят высокоприоритетные, потом едят те у кого приоритет пониже и то только если что-то осталось, ну или родители развели дедушку на Limit-at. Хотя и родители могут устроить битву титанов среди своих потомков, если у них установлен не только Limit-at, но и Max-limit. Это будет в стиле: «не сжирайте все, у деда есть и другие дети с внуками от первого брака!» Ну да постебались и хватит! Про лимиты и приоритеты расскажу более наглядно чуть позже. В общем, мы создали родителя, теперь ему нужен потомок. Но для добавления потомка (конечной очереди) сначала необходимо добавить профиль. Добавляем. /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 pcq-rate=0 > — Указываем что очередь которая использует данный профиль является инициатором подочередей PCQ pcq-burst-rate=0 pcq-burst-threshold=0 — Настройки Burst Скоростей, об этом чуть позже. — Данный параметр указывает по какому классификатору будут создаваться PCQ очереди. В данном случае по адресу назначения (входящий трафик) и — задают количество адресов в одной очереди. > > — Устанавливает верхний лимит скорости для одной PCQ очереди (в нашем случае для одного ip адреса) Если указан ноль — скорость не ограничена и будет разделена поровну между очередями (ip адресами). В нашем случае 30 мегабит будут разделены поровну между активными очередями (ip адресами). — лимит размера одной очереди (для одного ip адреса) Все данные в этой очереди при достижении лимитов задерживаются, все что в нее не влезло — уничтожается. > — лимит размера всех очередей. Теперь, когда у нас есть родительская очередь и профиль под потомка, мы добавим самого потомка: /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=8 > — вот тут мы ловим в очередь поток промаркированных в мангле пакетов. — указали родителя, который ограничил нам скорость. > Ну, вот и закончили с правилами. Посмотрим на визуальную диаграмму. Все что происходит наверху, вы уже знаете, далее смешанные промаркированные пакеты в хаотичном порядке, кучей подхватываются очередью потомком. И тут начинается самое интересное. Допустим, у нас сейчас в подсети работают три машины: 192.168.0.1, 192.168.0.2 и 192.168.0.3. В связи с тем, что потомок привязан к профилю с именем «PCQ_DOWNLOAD_LAN», профиль ему сообщил: что нужно создать под каждый встреченный в промаркированном потоке dst-ip адрес отдельную PCQ очередь. У нас внутри Queue Tree очереди будет создано три PCQ очереди (потока) с одинаковыми параметрами pcq-rate, pcq-limit и настройками Burst скоростей. В данном случае очередь сработала как своеобразный сортировщик пакетов. И для каждого пользователя создала индивидуальную очередь. Каждая очередь проходит через pcq-rate, именно эта штука и задерживает пакеты в индивидуальных очередях. Далее пакеты смешиваются и поступают во вторую часть Queue Tree очереди c именем «LAN», где проходят проверку на суммарную скорость по Max-Limit, если он есть и исчерпан, то этот Max-limit будет поделен поровну между PCQ-очередями (потоками), задержка производится на уровне pcq-rate, какие-то очереди ускоряются, какие-то притормаживаются. Все что не влезло в pcq-limit — уничтожается. Но у нас этого параметра в очереди «LAN» не установлено и поэтому трафик ползет вверх к родительской очереди (DOWNLOAD). Там все происходит по аналогии, проверяется Max-Limit и если он достигнут — родительская очередь пинает pcq-rate на закрытие дышла. Скорости потоков выравниваются, и все приходит в норму. Представим на секунду, что мы не установили Max-Limit в родительской очереди. Так вот, если нигде по пути трафика при > Многих мучает вопрос, если в данном случае > А что будет, если проснется еще один и тоже начнет качать? — Будет произведено перестроение и выравнивание скоростей. 30 мегабит они поделят поровну. Единственный нюанс — на это требуется время, второй пользователь будет немного медленнее набирать скорость, чем обычно. Суть механизма заключается в задержке и уничтожении пакетов, которые не влезли в лимит. Протокол TCP устроен таким образом, что в рамках соединения — сервер который отправляет данные клиенту, проверяет как они дошли до него, если у пакетов выросла задержка или пакет потерялся (нарушение последовательности) сервер снижает скорость отправки чтобы увеличить стабильность. pcq-limit и pcq-total-limit задаются экспериментально, чем больше лимит — тем больше задержка и больше занято оперативной памяти роутера. Чем меньше лимит — тем больше пакетов будет уничтожено. Что будет, если задать > Каждый пользователь получит не более 5 мегабит. 3 активных пользователя * 5 мегабит =15 мегабит. Три активных пользователя, все качают по полной, > Скорость упрется в Max-limit родительской очереди (30M) и данная скорость будет поделена между пользователями равномерно по 10 мегабит. Если один из них уйдет с закачки или снизит свою скорость минимум до 8 мегабит, двое остальных разгонятся до 11 мегабит. Я очень надеюсь, что по данному примеру все понятно, если непонятно — прочтите еще раз и еще раз, далее будет сложнее. Burst Технология Burst предназначена для подачи увеличенной скорости при назначенном лимите на короткое время. Использовать данную функцию целесообразно на небольших по скорости тарифах, для ускорения веб-серфинга или быстрой подгрузки данных в приложения. Данная функция работает только в случае если pcq-rate не равен нулю. Не буду до посинения грузить вас графиками и формулами расчета, лучше накидаю пример. > > > Максимальная скорость работы пользователя равна 2 мегабитам. Если скорость его работы в данный момент менее 1 мегабита (pcq-burst-threshold), ему станет доступна скорость в 4 мегабита (pcq-burst-rate) на 10 секунд (на практике меньше) это pcq-burst-time. Счетчик начинает тикать с того момента как будет превышен порог в 1 мегабит (pcq-burst-threshold), по истечении времени скорость упадет до pcq-rate, чтобы Burst снова стал доступен — скорость пользователя должна упасть ниже 1 мегабита и находится там не менее 10 секунд (pcq-burst-time) Понятно, что это очень грубое объяснение, на самом деле время доступности burst рассчитывается по непростому алгоритму — время делится на 16 отрезков и учитывая почти все переменные скорости и лимитов рассчитывается время действия. Данная функция потребляет значительное количество ресурсов, используйте ее с умом. Для справки: При внесении любых изменений, в любую очередь и в любом ее проявлении (Tree или Simple) — все счетчики обнуляются в т.ч. и счетчики Burst. Если вы используете скрипты для автоматической коррекции значений Max-Limit типа QOSEvxController — будьте готовы отказаться от Burst или использовать циклы проверки очередей в QOSEvxController не так часто. Ведро с болтами (Bucket) Так же с недавнего времени в шестой версии ROS для очередей появился новый параметр bucket-size (размер ведра). Данный параметр может быть изменен в пределах от 0.1 до 10 и используется для задания емкости ведра с токенами. Емкость ведра рассчитывается по форумуле: Емкость в > Над каждой очередью нависает ведро с гомном токенами, пока трафик в данной очереди не превышает лимит (max-limit) токены накапливаются в данном ведре. При переполнении ведра токен падающий в полное ведро уничтожается. На что тратятся токены. /queue tree add > В данном примере, емкость ведра будет равна: () * > Если пользователь или пользователи потока пакетов с маркировкой «PC1-traffic» до недавнего времени ничего не качали на полной скорости — ведро с токенами в данной очереди будет полным, а это целых сто мегабайт трафика. И вот решили они дружно, что то качнуть, так вот, первых 100 мегабайт трафика они получат без ограничения скорости по max-limit, когда 100 мегабайт будет скачано очередь начнет ограничивать скорость согласно заданному . Кроме этого, если у очереди есть родитель с более жирным max-limit, то после того как потомок выжрет все свои токены, из своего ведра, он начнет забирать токены у родительской очереди. Для чего это нужно? Bucket-size это как своеобразный Burst, только не по скорости а по объему трафика. Применение его совместно с PCQ очередями даст лишь сомнительную пользу. В одиночных сеялках типа pfifo, red и sfq может быть крайне полезен. Для PCQ очередей — единственное, что приходит в голову, это то, что мы лимитируем родительскими очередями скорость, которая чуть ниже реальной скорости канала. Грамотное использование данной функции может кратковременно более полно эксплуатировать всю доступную скорость канала и сглаживать пики активности пользователей. Более подробная диаграмма работы ведра: Эквиваленты маркировки трафика В данном примере я указал, что у нас одна подсеть (192.168.0.0/24) с тремя пользователями (192.168.0.1, 192.168.0.2, 192.168.0.3). Мы пометили трафик к данным адресам одним правилом в mangle и одним адрес-листом. На всякий случай скажу, что для mangle нет разницы, как мы ему скормим адреса для пометки — обработаны они будут одинаково. Подсеть целиком: /ip firewall address-list add > Диапазон адресов: /ip firewall address-list add > Отдельные адреса: /ip firewall address-list add > /ip firewall address-list add > /ip firewall address-list add > Аналогично обстоит дело и с PCQ очередями. PCQ очередь без проблем разбирает один поток пакетов, помеченный одним правилом, состоящий из адресов разных подсетей на подочереди. Допустим, что мы подмешали еще трех пользователей из другой подсети (192.168.1.1, 192.168.1.2, 192.168.1.3). Просто добавив нужные записи в адрес-лист. Тогда получим такую картину: Исходя из всего вышеперечисленного, можно сделать вывод, что оперируем мы не подсетями, а группами ip адресов, которые создаем с помощью адрес-листов В данном случае нет смысла раздельно маркировать трафик, делать два профиля и две очереди. Такой подход необходим только в следующих случаях: Когда требуется задать индивидуальный Max-Limit для выбранной группы адресов. Когда требуется различный приоритет для групп адресов или типа трафика. Когда требуется реализация различных тарифных планов для группы адресов. (pcq-rate) И во всех возможных комбинациях вышеперечисленных случаев. А вот пример того, как делать не надо: Полный листинг примера: /ip firewall mangle add > /ip firewall address-list add > /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 pcq-rate=0 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=8 > Пример второй. Приоритет одних, над другими. Допустим, что мы администратор организации с небольшим количеством сотрудников. Имеем исходные данные: WAN интерфейс с белым адресом (1.1.1.1) и входящей скоростью 32 мегабита в секунду LAN — c подсетью 192.168.0.0/24 (Рабочие станции Директоров) LAN2 — c подсетью 192.168.1.0/24 (Рабочие станции Менеджеров) В данном примере мы как раз, имеем один канал и две группы потребителей с разными приоритетами. Где директора имеют приоритет над менеджерами. Именно в этом случае для реализации данной схемы потребуется раздельная маркировка пакетов и раздельные очереди для групп пользователей. Правила для маркировки: /ip firewall mangle add > /ip firewall mangle add > Два правила для маркировки трафика с разными packet-mark и два списка для присвоения адресам принадлежности к группам. /ip firewall address-list add > /ip firewall address-list add > Пришло время создать профили PCQ для очередей. Сколько нужно профилей? По идее на загрузку хватит и одного профиля, но я всегда создаю по отдельному профилю на каждую группу и на каждое направление. Это позволяет иметь гибкие настройки на будущее, без дополнительного вмешательства в уже созданные правила и очереди /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 pcq-rate=0 > /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 pcq-rate=0 > Создаем дерево очередей: Родительская очередь: /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 > Потомки: /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=7 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=8 > В данном примере нет ничего сложного, разница между очередями лишь в разных маркировках пакетов и разных приоритетах. При низких скоростях данная схема будет прозрачно пропускать трафик через себя и любой из потребителей может получить все 30М указанных в родительской очереди. При нехватке скорости в родительской очереди скорость начнет перераспределяться между потребителями по следующей схеме: Группа с адресами GROUP-A_DW имеет более высокий приоритет > Если данная группа не утилизировала весь доступный лимит скорости (30М), остатки этого лимита будут переданы в очередь с более низким приоритетом GROUP-B_DW > Если группа GROUP-A_DW утилизировала весь доступный лимит в 30 мегабит, группа GROUP-B_DW не получит вообще никакой скорости и никакой возможности передавать и получать пакеты из сети. Для того чтобы группе с низким приоритетом оставалось хотя бы некоторое количество скорости, можно задать в очереди параметр > И вторая очередь после правок будет выглядеть так: /queue tree add burst-limit=0 burst-threshold=0 priority=8 > В таком случае при нехватке скорости в родительской очереди, очередь с низким приоритетом будет всегда получать минимум 5 мегабит, которые сможет равномерно разделить между активными потребителями в пределах этой очереди. Пример третий. Реализация тарифных планов с разделением на группы с разными приоритетами В данном примере будет рассмотрен своеобразный гибрид, который включает реализации из первых двух примеров. Предположим, что мы субпровайдер с ограниченными финансовыми и техническими возможностями. У нас есть узкий канал в интернет, пара тарифных планов и две категории абонентов (физ.лица и юр.лица). Чаще всего, при предоставлении услуг юридическим лицам мы получаем от них большую выгоду, чем от физических лиц на тех же показателях скорости. Вместе с этим, мы предоставляем юридическим лицам некоторые дополнительные гарантии в виде гарантированной скорости и более оперативной технической поддержки. Ну и как чаще всего бывает — мы немного увлеклись и подключили чуть больше абонентов, чем может вытянуть наш канал в интернет. По правильному — нужно расширить канал или подключить дополнительный с последующей балансировкой нагрузки. Но как уже было сказано, на это пока нет возможностей. Но скорости в прайм-тайм не хватает, юридические лица начинают звонить и жаловаться на несоответствующую тарифному плану скорость, задержки пакетов, заикания телефонии и пр. Частично облегчить данную ситуацию поможет шейпер с приоритетами как во втором примере, единственные отличия в том, что в данном примере скорость на одного абонента строго лимитирована и присутствует несколько тарифных планов. Так же как и в предыдущих примерах, мы рассмотрим только входящую скорость. Однако во избежание путаницы в комментариях, именах маркировок и именах очередей будет присутствовать upload скорость. Сокращения: FIZ — физическое лицо. UR — юридическое лицо. 1024K-1024K — Скорости по тарифу: Download-Upload DW- Download UL — Upload Маркировка пакетов: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Четыре правила маркировки, которые выдадут нам четыре потока помеченных пакетов, рассортированных по четырем тарифным планам (Два для физ.лиц и два для юр.лиц.) Чтобы привязать абонента к определенному тарифному плану, нужно поместить его ip адрес в нужный адрес-лист: /ip firewall address-list add > /ip firewall address-list add > /ip firewall address-list add > /ip firewall address-list add > /ip firewall address-list add > И т.д. Теперь необходимо добавить необходимые профили для очередей: /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 > /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 > /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 > /queue type add pcq-burst-rate=0 pcq-burst-threshold=0 > Опять же я создал четыре профиля вместо двух, для сохранения гибкости настроек на будущее. Далее построим дерево очередей: Родительская очередь: /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 > Потомки: /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=8 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=8 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=7 > /queue tree add burst-limit=0 burst-threshold=0 limit-at=0 max-limit=0 priority=7 > При реализации данного примера все будет работать следующим образом: При низких скоростях абоненты без проблем получают свою тарифную скорость, которая ограничена параметром pcq-rate. Но самое интересное, начинается, когда активных абонентов больше чем может выдать канал. Родительская очередь ограничена 30 мегабитами. Тарифные планы физических лиц и сами физические лица между собой равноправны. Тарифные планы юридических лиц и сами юридические лица тоже между собой равноправны. Но в связи с тем, что очередь юридических лиц имеет более высокий приоритет, отсюда следует, что и сами юридические лица с их тарифными планами тоже имеют более высокий приоритет — и они будут обрабатываться первыми. Вся доступная скорость отдается в тарифы для юридических лиц, каждый такой абонент ограничен скоростью тарифа заданной в параметре pcq-rate. Тем не менее, если данные абоненты интенсивно работают и их потребление трафика превышает в сумме 30 мегабит, то получим такую картину: 30 мегабит будут разделены поровну между юридическими лицами, на основании текущего количества пакетов в каждой PCQ очереди. На самом деле объяснить данную ситуацию не так просто, но я попробую. Предположим, что у нас все перечисленные юридические лица качают «по полной». В данный момент есть четыре абонента с тарифом в 1 мегабит и двенадцать абонентов с тарифом в 3 мегабита. 4 * 1М = 4 мегабита 12 * 3M = 36 мегабит 4М + 36М = 40 мегабит требуется абонентам с одинаковым приоритетом. Но у нас всего 30 мегабит. Все бы было просто в случае одинаковых тарифных планов: 30 мегабит поровну поделились бы между абонентами и все. Но как будет распределена скорость, если тарифы у нас разные в пределах одной приоритетной группы. Как распределится недостаток скорости? В голову приходит два варианта развития событий, но лишь один из них верный. Недостаток скорости будет распределен в процентном соотношении исходя из скорости тарифного плана. Примерно как то так: (100% / 40 мегабит которые требуются) = 2.5 30 мегабит которые есть * 2.5 = 75% от того что требуется мы имеем. (1 мегабит / 100%) * 75% = 0.75 мегабита (3 мегабита / 100%) * 75% = 2.25 мегабита Проверяем: 4 абонента с тарифом в 1М (4 * 0.75) = 3 мегабита. 12 абонентов с тарифом в 3М (12 * 2.25) = 27 мегабит. 27+3 = 30 мегабит. В принципе логично и относительно честно, только вот к сожалению данный сценарий будет обработан несколько иначе, а именно: Вся доступная скорость (30 мегабит) будет распределятся равномерно, между участниками в равные единицы времени. Представьте чан с 30 литрами воды, из которого отходят трубки одинакового сечения и N- количество стаканов разных размеров на столе, в которые одновременно разливают ограниченный объем воды одинаковыми струйками. В нашем примере самый маленький стакан имеет объем один литр, стакан побольше — три литра. (Три литра! Карл!) Как только мелкие стаканы будут наполнены — в них перестают лить воду. Вся оставшаяся вода будет продолжать разливаться в более крупные стаканы. Если и после этого вода в чане останется — она будет разлита в стаканы на другом низкоприоритетном столе. Но воды, то у нас не хватает даже на один стол. Сложные вычисления: Первый этап, первый временной промежуток: 4 стакана по литру = 4 литра 12 стаканов по три литра, но данном промежутке времени в них залит только литр = 12 литров. 30 литров — (4+12) =14 литров воды осталось в чане. Второй этап, второй временной промежуток: В связи с тем, что стаканов более трех литров в примере нет — просто разделим остатки воды между трехлитровыми стаканами. 14 литров / 12 > Итог вычислений: Пользователь на тарифе 1 мегабит получит весь мегабит целиком. Пользователь на тарифе 3 мегабита получит 1+ 1,16 = 2,16 мегабита Тоже самое если использовать простые вычисления: (30 литров — 1 литр * 4) / 12 =2,16 Если внимательно посмотреть на оба примера (неправильный и верный) можно увидеть что в первом примере общая нехватка скорости по тарифу у всех ровно четверть от заявленной скорости и пострадали все тарифы одинаково. Во втором случае мелкие тарифные планы не почувствовали нехватки и получили заявленную скорость, однако тарифы с более высокой скоростью ощутили нехватку почти на треть. Исходя из излишне-изложенной и не самой удачной метафоры, можно условно сказать, что тарифы с низкими скоростями имеют некий приоритет над тарифами с более высокими скоростями, при нехватке скорости, даже с одинаковым приоритетом. Да это не совсем честно, но, к сожалению, данное поведение шейпера никак нельзя изменить. Вот на этом моменте точка зрения господина Шарикова резко ушла в аут. Страдать будут не все равномерно, а лишь те, кто имеет более веселый тарифный план. Ну и как водится чем больше скорость — тем больше платит абонент. Если данная ситуация еще более-менее допустима с физ.лицами, то с юр.лицами это даже досадным недоразумением назвать нельзя. Ну да вернемся к дальнейшему обсуждению… При данных условиях видно, что канала в 30 мегабит не хватает даже для обслуживания тарифных планов юридических лиц. Следовательно, пока юридические лица интенсивно получают данные, физические лица не получают вообще никакой скорости. Эту проблему можно решить заданием параметра limit-at, но в данном случае это еще сильнее снизит доступную скорость для юридических лиц. Понятное дело, что подобная ситуация в реальности будет равна катастрофе. Но отодвинем катастрофу подальше и представим что юридических лиц не так много. А именно: 2 с тарифами в 1 мегабит и два с тарифами в 3 мегабита. И качают они «по полной». Путем нехитрых вычислений (2*1 + 2*3 = 8, > Но как бы, ни хватало скорости физическим лицам, юридические лица будут обслужены первыми. Пример четвертый. Приоритет одного типа трафика над другим Дополнительно к классической системе приоритетов, когда поток разделен на несколько групп абонентов с разными приоритетами можно прикрутить дополнительные критерии разделения на приоритеты. На эту тему можно спорить часами. Одни люди скажут, что при особых обстоятельствах, безусловно, стоит использовать приоритеты. И, конечно же, предоставят весомые аргументы в пользу данных решений. Другие начнут кричать про производительность и как бы этичность данного решения — мол, кто мы такие, чтобы решать за пользователя или абонента какой тип трафика ему важнее. Я в этот дурацкий холивар никогда не влезал. Просто в виду большого опыта у меня своя точка зрения на этот счет. Все зависит от каждого конкретного случая и типа применения данной технологии. Есть системы, в которых применение приоритетов только вредит общей работе — напрасно нагружает оборудование, следовательно, жрет электричество, мешает конечному пользователю самостоятельно определить какие либо проблемы с сетью (прим. — высокий приоритет icmp). Так же встречались системы на мыльницах с полностью загруженным маршрутизацией процессором, на который еще навешали приоритезацию и удивлялись, почему упала скорость. Так же есть масса примеров, где данные решения нашли свое место и значительно улучшили работу сети и репутацию данных субпровайдеров. В некоторых случаях казалось, что применение приоритезации в каком-то конкретном случае было неоправданно (широкие каналы, всем всего хватает и данная фича просто нагружает процессор) тем не менее, при отвале сразу четырех аплинков из шести, скорости стало катастрофически не хватать. И эта якобы ненужная фича очень сильно снизила количество звонков в техническую поддержку. Да, существенно просела скорость загрузки торрентов тем не менее жалоб от «танкистов» на длинный пинг и лаги в игре не поступало. Кроме всего этого, те люди у кого больше опыта знают, что под словом приоритезация понимается очень обширная тема и различные области применения. Думаю, что стоит перечислить основные типы: Приоритезация по типу пользовательского трафика Пользовательский поток делится на два, с разными приоритетами. Критериями разделения могут быть порты, протоколы, адреса назначения, адреса источники и целые подсети. Производительность для высокого приоритета достигается за счет выделения дополнительной полосы скорости сверх тарифа абонента и более высокого приоритета очереди. Таким образом, абонент получает скорость тарифа под высокий приоритет + скорость тарифа под остальной трафик. По факту: абонент получает скорость тарифа умноженную на два. На практике, при свободном аплинке и полном использовании абонентом своей скорости по тарифу, абонент в среднем использует скорость тарифа+20%. При нехватке аплинка, низкоприоритетный трафик задерживается (полоса сужается), высокоприоритетный пропускается (отдельная полоса с более высоким приоритетом). Приоритезация по направлению внешний <-> внутренний Пользовательский поток делится на два, с разными приоритетами. Критериями разделения обычно служат подсети. В одном потоке идет внешний трафик в мир, во втором внутренний или межабонентский трафик. Используется крайне редко, обычно в распределенных системах, состоящих из нескольких маршрутизаторов. Приоритезация по направлению внешнего трафика Download <-> Upload Почти не используется в проводных сетях. Администраторы беспроводных сетей знают, что при односторонней передаче данных через радиооборудование (симплекс), скорость в разы выше чем при наличии встречного трафика (дуплекс). Чаще всего при наличии встречного трафика более 30% линк сильно деградирует Для примера: UDP тест на мостах UBNT через AirOS симплекс ~130-160 мегабит/c. Дуплекс ~40-50 мегабит/c. В шестой версии ROS с ее изменениями (корневая очередь global и пометка в forward) появилась возможность контролировать дуплексный трафик с ограничением и снижением приоритета исходящего трафика от абонентов. Данная теория в основном относится к B/G/N, при использовании оборудования работающего в AC режиме встречный трафик уже не так страшен. Суровая практика Ну, хорошо, теория и основы понятны. Стоит реальная задача сделать некий умный шейпер. С чего начать? Какие факторы нужно учесть, чтобы не собрать все грабли и впоследствии не переделывать все сначала? Перед тем, как создать некоторую конструкцию шейпера необходимо в первую очередь определится с множеством параметров, которые имеет ваша сеть, или будет иметь в будущем. Если вы не сделаете этого сейчас, то в будущем могут возникнуть проблемы, которые заставят вас переделывать конструкцию с нуля. Так же стоит помнить, что каждая новая функция, требование или критерий будет стоить процессорного времени. Чаще всего эта стоимость будет возрастать в геометрической прогрессии. Поэтому дважды подумайте, на сколько критична и уместна данная функция в вашей конфигурации. Первое с чего мы начинаем — это каналы в интернет. Первое на что нужно обратить внимание — это число каналов. Если у вас несколько каналов в интернет или только планируется использовать несколько каналов в будущем, то, скорее всего, вам понадобится делать под каждый канал уникальный шейпер. Сейчас объясню почему. При создании общего шейпера, в кореневой очереди нужно будет прописать значение max-limit, которое будет равно сумме скоростей ваших каналов. В теории это будет работать, но на практике не все так сказочно как кажется. Во первых, какой бы крутой у вас не стоял балансировщик нагрузки между каналами — всегда будет определенный дисбаланс. Разная нагрузка на каналы хотя бы в 1% нарушит стабильную работу шейпера и минимум 1 абонент на каждом канале будет недополучать тарифной скорости. Во вторых, скорость некоторых каналов время от времени может «плыть» и в составе балансировки это приведет к краху т.к. ни балансировщик, ни шейпер не будут знать о реальных скоростях аплинков. И даже искусственно созданный запас по емкости в данном случае не спасет. В третьих, при падении одного из каналов общая емкость изменится, и значение max-limit в очереди станет неактуальным. В результате этого шейпер будет прозрачно пропускать трафик, соблюдая лишь pcq-rate. Кто-то из абонентов будет получать полную скорость, а кто-то вообще ничего. Исходя из вышеперечисленного — если у вас несколько каналов, считайте данный функционал обязательным, даже при условии что цена ему довольно высока. А цена данного функционала — умножение нагрузки процессора от шейпера и числа его правил на количество обслуживаемых каналов. Второе на что нужно обратить внимание — это гарантированная скорость каналов. Если скорость на канале плавает в пределах более 20% это очень плохо. Выходов из данной ситуации несколько: 1. Использовать только гарантированные каналы. Это почти миф. Такие каналы предоставляют в основном юр.лицам со всеми вытекающими. Во вторых, если канал приходит в роутер по радио — толку от этого будет мало. 2. Использование не всей емкости канала. Достигается путем длительных тестов и вычисления его средней скорости. Думаю, что вас не сильно порадует фиксированное использование только половины потенциала канала. Зато стабильность значительно возрастет. 3. Использование коммерческих (QOSEvxController) или самописных скриптов для актуализации значения max-limit на канале. Данное решение чуть лучше второго варианта и позволяет получать с канала чуть больше его средней скорости. Цена вопроса — Договор на юр.лицо или внешние скрипты и некоторые ресурсы процессора. Третье и последнее по каналам — Тип подключения аплинков. Да, я имею ввиду подключение по радио, со всеми вытекающими. При встречном трафике производительность данного канала снижается, и скорость значительно плывет. Решение тоже, что и выше, плюс добавление в конструкцию различных приоритетов для Download/Upload трафика. Данный функционал не добавляет существенной нагрузки на ЦП Второе на что мы обратим внимание это число тарифных планов в сетке. Тут можно сказать одно — соблюдайте золотую середину. Не стоит прописывать только те тарифы которые у вас есть сейчас, сетку тарифных планов нужно продумать заранее т.к. значительно проще поднять их на этапе создания, чем добавлять их в будущем совершая ошибки и путаясь в тысячах правил mangle. Но также не увлекайтесь, каждый лишний тарифный план умножает нагрузку на процессор. Третий вопрос для обсуждения — это: «Нужно ли выделять какому либо типу трафика более высокий приоритет?» Безусловно, стоит хорошо задуматься о внедрении в конструкцию данного функционала. Разделение потока пакетов хотя бы на два приоритета приведет к увеличению нагрузки на процессор вдвое, а при использовании регулярных выражений хотя бы в одном правиле mangle в десятки раз. Поэтому использовать данную фишку стоит только владельцам роутеров серии CCR, CHR, X86 с достаточным количеством свободных мегагерц на ядрах процессоров. Однако полезность данной функции тоже очень положительно влияет на работу сети. Во первых, многое зависит от того, кому вы предоставляете интернет. Есть абоненты, которые с компьютером строго на «вы» и это самая болезненная для технической поддержки группа. Они собирают все тизеры на страницах интернета, соответственно на их компьютере просто зоопарк из вирусов, троянов и загрузчиков, да еще центр обновления у них сам качает, что захочет и когда захочет. А после школы возвращается их ребенок, запускает танки, ловит лаги и начинаются звонки в техническую поддержку. Вы вежливо объясняете, что у них проблемы с компьютером и чаще всего получаете ответ что им «все починили и настроили две недели назад» и что у них проблем быть не может. Ведь папины веселые картинки на весь экран, которые просили положить денег на какой-то номер телефона, удалил мамин знакомый программист с работы. И чаще всего до таких абонентов трудно достучатся и найти нужные слова для убеждения. Увы, но это так! При выделении в более высокий приоритет (отдельная полоса) к примеру, тех же танкистов, подобные проблемы переходят из разряда «острые» в разряд «вялотекущие». И очень часто со временем решаются сами собой (машина начинает тупить, Winlocker-ы портят папе настроение, шифровальщики добивают файлы) и это все как бы намекает, что специалиста все-таки придется пригласить для решения этих проблем. Абоненты, которые с компьютером на «ты» обычно не звонят по пустякам в техподдержку, сначала проверяют свою машину, потом скорость, а потом уже набирают вас. И боже упаси вас, сказать им, что у них с машиной или сетевой картой, что-то не так, они вам горло перегрызут. Хотя в некоторых, из таких случаев провайдер действительно прав, т.к. человеческий фактор никто не отменял, мы все ошибаемся, забываем про роутер, про ноутбук который качает торренты на кухне и т.д. Во втором случае, когда нас выручает приоритезация по типу трафика — это некоторые проблемы с нашим оборудованием или каналами в интернет. Когда суммарной полосы наших каналов существенно не хватает, низкоприоритетный трафик равноправных абонентов прижимается чтобы пропустить высокоприоритетный. Тут тот же бонус, геймеры а тем более танкисты в разгар игровых баталий — очень нервный народ и пока вы занимаетесь решением проблемы вам будет значительно легче пережить эту неисправность если в это время вам не так сильно будут обрывать телефон как при падении всех сервисов в целом. Четвертый вопрос для обсуждения коснется только тех, у кого локальный трафик от абонентов превышает возможности внутренних линков до сегмента сети. Наиболее остро вопрос стоит у тех субпровайдеров, кто раздает интернет по радио на распространенном оборудовании. Для примера возьмем базовую станцию Ubiquiti Rocket M5 c хорошей панельной антенной, установленной по всем правилам и работающей на свободной частоте без помех. К данной базе подключено максимальное число абонентов (30 устройств) и для чистоты теории они все находятся на одинаковом расстоянии и с одинаковыми сигналами. И вот мы создали тепличные условия для красивой коробочки внутри которой китайское г… Не скажу что у других производителей все супер внутри корпуса, но данный производитель очень тщательно скрывает очень важный параметр — пакетную производительность данного устройства. По своему опыту скажу, что для данного устройства она лежит в пределах 16000-20000. Для Rocket M5 Titatium в районе 20000-25000. И что это нам дает? При закачке торрентов скоростью 1 мегабит в секунду (не самые мелкие пакеты, если что) генерируется порядка 800-1100 пакетов в секунду. Это говорит нам, что при самом плохом положении вещей максимальная производительность базы равна 15 мегабитам в секунду. А не 300 мегабит как пишут многие продаваны и не 150 как пишут более честные. А агрегация в суперфрейм тут пустой звук. Но это самое плохое развитие событий, не все же абоненты качают только торренты, кто-то серфит, кто-то в скайпе сидит, кто-то фильм смотрит и т.д. Количество пакетов снижается, но скорость растет. Так вот, средняя пропускная способность данной базовой станции в реальных условиях составляет порядка 35-45 мегабит. Ее максимум 70-80 мегабит на крупных пакетах при TCP трафике. К чему я собственно веду: при 30 абонентах с тарифами в 5 мегабит, данная база не справится в глобальный прайм-тайм, который случается не так уж редко. (Выход ожидаемых фильмов, трансляции спортивных событий и пр. Даже 20*5 это уже сто мегабит, понятное дело, что на базе есть свои очереди, таймслоты при использовании TDMA и прочее, база как бы обязана раздавать трафик честно и поровну. Но в реальных условиях, когда она явно перегружена по пакетам или радио, при наличии помех, разности расстояний и сигналов, равномерное деление по TDMA просто невозможно. Если ближе к теме, назовем базовую станцию сегментом, т.к. у нормальных провайдеров сети сегментированы и броадкаст по ним без разрешения не гуляет. И на каждый сегмент сделаем дополнительное разделение и ограничение скорости, чтобы в случае нехватки ресурсов базы скорость делилась бы равномерно между теми, кому она нужна. Легко сказать, но очень дорого сделать. Ведь каждый сегмент (VLAN). Будет умножать нагрузку от шейпера на количество введенных в шейпер сегментов. Данный функционал, несомненно, нужен беспроводным субпровайдерам, но он приводит к огромному количеству правил и гигантской трате системных ресурсов. Но его все, же используют, просто данный функционал легко настраивается на терминирующем роутере, из двух роутеров получается распределенная система. Первый роутер следит за скоростями каналов в интернет, приоритезацией и нарезкой скоростей. Далее трафик проходит во второй роутер, на котором шейпер следит за нагрузкой на сегменты сети. А так же за межабонентским трафиком, о котором я и расскажу. Последний вопрос: «Зачем нужен межабонентский трафик и как больно грабли ударят по лбу?» Межабонентский трафик нужен в первую очередь для снижения нагрузки на интернет каналы. В сети может быть поднят локальный ретрекер, либо другие различные сервисы, либо совсем без них. Суть заключается в том, чтобы при закачке какого либо торрента, торрент-клиент обращался в первую очередь к другим абонентам и в случае наличия у них запрашиваемых частей или файлов целиком получал их внутри сети на максимальной скорости. Так же возможна реализация внутренних серверов и сервисов самим провайдером. Ну, тут я уже предвижу: «Да кому нужны ваши внутренние серваки и ретрекеры? Тут у каждого второго оптика» У меня есть клиент, официальный провайдер. У него три канала по 4 мегабита от спутниковых модемов и около 400 абонентов. В радиусе 700км нет ни оптики, ни кабеля, ни файфая, ни жопорезов с 3-4g. В общем, ничего нет. Пинг 700мс. А вы тут как сырки в масле, с оптикой и 21 веком. Еще будут вопросы, зачем субпровайдерам кеширующие прокси, ретрекеры и прочие примочки? Так что межабонентскому трафику быть! Как бы это хорошо не звучало, это единственная вещь, которую ROS шестой версии не в силах победить. Связано это с тем, что при замене global-in, global-out и global-total которые были в пятой версии, на global который теперь есть в шестой, пропала возможность дважды помечать трафик и дважды прогонять его через HTB. Проблема в том, что мы физически не сможем пометить трафик от одного абонента до другого в пределах одного роутера, т.к. для одного абонента пакет будет помечен как исходящий, а для второго он является входящим. Для mangle это пакет соответствующий критериям двух правил, сначала он получит одну метку, а потом будет переразмечен другим правилом. И все бы получилось, если бы между маркировками можно было бы принудительно отправить пакет в обработку очередей. Но чудес не бывает. Кто-то скажет или спросит: «В пятой же версии все получится?» Да, конечно. Проверял, работает на ура! Только вот пятая версия имеет свои минусы и уже не подходит под те задачи, которые требуются от этого роутера. Как же быть? Есть некоторые варианты решения подобной задачи, трафик будет зарегистрирован лишь в одном направлении и с более низким приоритетом, интернет трафик будет иметь более высокий приоритет. Кроме этого данный поток полезно лимитировать. Схема довольно сложная и создается под отдельно взятые конфигурации. Если кто-то из специалистов сейчас прочитал это и понял, о чем я говорю — свяжитесь со мной, возможно, вместе мы придумаем что-то более продвинутое. Кроме всего этого межабонентский трафик нельзя маркировать на одном роутере с контролем нагрузки на интернет аплинки. Даже если вы решили рискнуть производительностью роутера и сделать комбаин «все в одном» (Контроль нагрузки на каналы+нарезка скорости по тарифам+приоритеты+контроль внутренних сегментов+маркировка межабонентского трафика) то вы через некоторое время заметите, что в корневых очередях каналов в интернет регистрируется нагрузка, которой на самом деле не существует. Это межабонентский трафик маркируется, попадает в очередь, передается в корневую очередь сегмента, а оттуда попадает в очередь канала. Изменение родителя у очереди канала или сегмента не даст никакого положительного результата. По факту получится, что канал свободен, но шейпер будет думать, что нагрузка на нем есть. Решение данной проблемы — распределенная система. Ну, вот как бы и решилось что к чему, естественно если есть биллинг, то он должен поддерживать работу с адрес-листами для сообщения микротику какому ip адресу и сколько скорости выдать. Тоже самое относится к скрипту балансировки, он должен сообщать своими списками какой ip адрес, к какому каналу привязан в данный момент времени. Кроме этого если вы создаете распределенную систему на двух роутерах, вам потребуется синхронизация адрес листов между роутерами, реализовать ее можно написав скрипт, либо внешний обработчик на api. Так же в скором времени такой скрипт можно будет приобрести (EvxListSync). Практическая и заключительная часть: Думаю что после того как мы определились с необходимыми параметрами, следует приступить от слов к делу. В данном примере я опишу основную конструкцию, в которую можно добавить некоторый функционал по своему вкусу или удалить лишний. Предположим, что у нас есть два канала в интернет и балансировщик, который раскидывает абонентов по каналам и формирует динамически нужные адрес листы ISP1 и ISP2. Для каждого канала будет создан индивидуальный шейпер. В примере будут рассмотрены четыре тарифных плана, два для физ.лиц и два для юр.лиц. Если есть биллинг — он должен добавлять ip адреса пользователей в соответствующие списки для привязки абонента к нужному тарифному плану. Если биллинга нет — заполнять данные адрес листы потребуется вручную. Кроме всего этого мы разделим трафик по типу на два приоритета. Разметка Маркируем весь входящий трафик к адресам из списка «SHAPER_TARGET» назначая пакетам метку «CLASS-B-DL» /ip firewall mangle add > Далее отлавливаем пакеты с меткой «CLASS-B-DL» и переразмечаем их, назначая метку более приоритетного класса. В более выскокий приоритет попадут: ICMP, DNS, SSH, TELNET, RDP и пакеты у которых в качестве адреса источника указан любой адрес из списка CLASS-A-SITES. /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Выполняем аналогичную процедуру для исходящего трафика: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > После этих действий мы получаем четыре потока промаркированных пакетов: CLASS-A-DL CLASS-B-DL CLASS-A-UL CLASS-B-UL Ищем в данных потоках пакеты принадлежащие абонентам, которые в данный момент работают на первом канале и переразмечаем их: /ip firewall mangle add > /ip firewall mangle add ; /ip firewall mangle add > /ip firewall mangle add ; После переразметки получим еще четыре дополнительных потока: ISP1-CLASS-A-DL ISP1-CLASS-B-DL ISP1-CLASS-A-UL ISP1-CLASS-B-UL Теперь нужно разобрать эти четыре потока на тарифные планы: Адрес лист «1024-1024-8» в формате «Входящая скорость-Исходящая скорость-Приоритет». Приоритет равен 8 если физ.лицо и 7 если юр.лицо. Так удобнее управлять листами из биллинга. Выделяем четыре потока для тарифного плана «1024-1024-8» два под загрузку, два под отдачу: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Повторяем действия для трех оставшихся тарифных планов: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > После данных действий мы получили 16 потоков промаркированных пакетов. Потоки канала: ISP1-CLASS-A-DL ISP1-CLASS-B-DL ISP1-CLASS-A-UL ISP1-CLASS-B-UL Потеряли актуальность т.к. все пакеты с данными маркировками были переразмечены. Но общие потоки: ISP1-CLASS-A-DL ISP1-CLASS-B-DL ISP1-CLASS-A-UL ISP1-CLASS-B-UL еще содержат пакеты других каналов, в нашем случае: канала ISP2. Далее нужно произвести переразметку для второго канала, аналогично первому: /ip firewall mangle add > /ip firewall mangle add ; /ip firewall mangle add > /ip firewall mangle add ; /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Получаем еще 16 потоков для второго канала. Итого у нас 32 потока, общие потоки классов и потоки каналов стали неактуальны т.к. все пакеты в них были переразмечены и образовали новые 32 потока. На этом маркировка закончена. Профили Перед тем как начинать работу с деревом необходимо создать профили очередей их число не влияет на производительность, число профилей обычно соответствует числу тарифных планов, но для гибкости я делаю по отдельному профилю на загрузку/отдачу. /queue type add > /queue type add > /queue type add > /queue type add > /queue type add > /queue type add > /queue type add > /queue type add > После того как профили созданы, можно приступать к созданию дерева. Дерево Ранее я упоминал о проблемах, которые возникнут при получении интернет каналов по радио, так же вполне вероятно, что провайдер вам выдаст не симметричный канал, либо вы будете использовать adsl или 3-4g. Исходя из этого, сразу закладываем в конструкцию: родительскую дуплексную очередь и подочереди для симплекса. Родительская очередь для первого канала: /queue tree add > Подочереди для симплекса: /queue tree add > /queue tree add > После этого можем добавлять конечных потомков, в этих очередях и будут заданы приоритеты. Тарифный план 1024-1024 для физ.лиц на два приоритета+приоритет входящего трафика: /queue tree add _1024-1024-8_CLASS-A priority=5 > /queue tree add _1024-1024-8_CLASS-B priority=6 > /queue tree add _1024-1024-8_CLASS-A priority=7 > /queue tree add _1024-1024-8_CLASS-B priority=8 > Остальные три тарифных плана: /queue tree add _2048-2048-8_CLASS-A priority=5 > /queue tree add _2048-2048-8_CLASS-B priority=6 > /queue tree add _2048-2048-8_CLASS-A priority=7 > /queue tree add _2048-2048-8_CLASS-B priority=8 > /queue tree add _1024-1024-7_CLASS-A priority=3 > /queue tree add _1024-1024-7_CLASS-B priority=4 > /queue tree add _1024-1024-7_CLASS-A priority=5 > /queue tree add _1024-1024-7_CLASS-B priority=6 > /queue tree add _2048-2048-7_CLASS-A priority=3 > /queue tree add _2048-2048-7_CLASS-B priority=4 > /queue tree add _2048-2048-7_CLASS-A priority=5 > /queue tree add _2048-2048-7_CLASS-B priority=6 > С первым каналом закончили, добавляем очереди второго канала по аналогии с первым: /queue tree add > /queue tree add > /queue tree add > /queue tree add _1024-1024-8_CLASS-A priority=5 > /queue tree add _1024-1024-8_CLASS-B priority=6 > /queue tree add _1024-1024-8_CLASS-A priority=7 > /queue tree add _1024-1024-8_CLASS-B priority=8 > /queue tree add _2048-2048-8_CLASS-A priority=5 > /queue tree add _2048-2048-8_CLASS-B priority=6 > /queue tree add _2048-2048-8_CLASS-A priority=7 > /queue tree add _2048-2048-8_CLASS-B priority=8 > /queue tree add _1024-1024-7_CLASS-A priority=3 > /queue tree add _1024-1024-7_CLASS-B priority=4 > /queue tree add _1024-1024-7_CLASS-A priority=5 > /queue tree add _1024-1024-7_CLASS-B priority=6 > /queue tree add _2048-2048-7_CLASS-A priority=3 > /queue tree add _2048-2048-7_CLASS-B priority=4 > /queue tree add _2048-2048-7_CLASS-A priority=5 > /queue tree add _2048-2048-7_CLASS-B priority=6 > После этого нужно внести в адрес лист «SHAPER_TARGET» диапазоны подсетей с абонентами, проследить, что биллинг добавляет адреса абонентов в нужные списки, проверить вносит ли балансировщик адреса абонентов в списки каналов. Так же требуется задать значения max-limit в корневых очередях, эти значения должны быть на 5-20% ниже реальной скорости, которую вам выдает провайдер. Итого получилось: 52 правила в Mangle, 8 профилей, 38 очередей Но если приблизится к более реальным условиям, получаются огромные числа. Возьмем для примера 5 каналов и 12 тарифных планов. 16 правил в Mangle для определения типов трафика. 5 каналов * 4 правила для разделения = 20 правил в Mangle 5 каналов * (4 правила на тариф* 12 > Итого правил в mangle = 276 (260 зависят от числа тарифов и каналов) Профили > Дерево 5 каналов на 3 корневые очереди =15 очередей 5 каналов * (4 очереди на тариф * 12 тарифов) = 240 очередей Итого: 255 очередей И данные цифры вполне нормально уживутся на CCR, CHR, X86 если не баловаться с регулярными выражениями. Если хочется добавить еще одну ступень для определения типа трафика — умножайте число очередей и правил на два. Для тех, кто вопреки убеждениям хочет прикрутить к данной схеме еще и контроль внутренних сегментов сети на этом же роутере — число правил и очередей умножайте на число сегментов и к полученному значению прибавляйте количество сегментов умноженное на два. В данном примере, при десяти сегментах количество правил в mangle станет около 2610, а количество очередей примерно 2580. К тому же если в сети будет присутствовать межабонентский трафик — по лбу очень больно ударят грабли, о которых я писал ранее. Для этих целей нужен второй шейпер на втором промежуточном роутере, кроме того что это все можно относительно просто реализовать, второй роутер дает еще много полезных преимуществ. Тем более владельцам гипервизоров поднятие второго экземпляра ничего не стоит. Думаю, что теперь многим станет понятно, почему на SOHO мыльницах с 680 мегагерцами на борту можно реализовать только простую сеялку на две группы пользователей и не более. Ну, раз уж я начал говорить про второй роутер и про контроль сегментов, грех будет не рассказать, как это все делается. Распределенный шейпер Первым делом нужно разметить трафик на втором роутере. Маркируем внешний входящий трафик, назначая метку: «EXT_CLASS-B_DL» /ip firewall mangle add > Далее отлавливаем пакеты с меткой «EXT_CLASS-B_DL» и переразмечаем их, назначая метку более приоритетного класса. Делаем по аналогии как на первом роутере. /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > После этого мы получили два потока промаркированных пакетов внешнего входящего трафика: EXT_CLASS-A_DL EXT_CLASS-B_DL Далее нам нужно их преобразовать в четыре потока, два потока для физ.лиц и два для юр.лиц, делать мы это будем перемаркировкой согласно адрес листам тарифных планов. /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; /ip firewall mangle add ; Теперь у нас есть в распоряжении четыре потока: EXT_CLASS-A-FL_DL EXT_CLASS-B-FL_DL EXT_CLASS-A-UR_DL EXT_CLASS-B-UR_DL Аналогичную процедуру производим с исходящим наружу трафиком: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > После того как мы добавили правила для маркировки исходящего трафика получаем уже восемь потоков: EXT_CLASS-A-FL_DL EXT_CLASS-B-FL_DL EXT_CLASS-A-UR_DL EXT_CLASS-B-UR_DL EXT_CLASS-A-FL_UL EXT_CLASS-B-FL_UL EXT_CLASS-A-UR_UL EXT_CLASS-B-UR_UL Для обработки межабонентского трафика так же потребуется добавить еще один поток, но на данном этапе в нем будет сразу два направления т.к. для одного абонента трафик является входящим, а для другого исходящим. /ip firewall mangle add > Теперь мы дошли до финальной стадии маркировки. С помощью разделенных адрес листов сегментов, мы сможем определить, откуда и куда идут пакеты. В данном примере у нас всего два сегмента VID30 и VID40. Входящий трафик: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Исходящий трафик, по аналогии: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Повторяем то же самое для второго сегмента: Входящий трафик: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > Исходящий трафик: /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > /ip firewall mangle add > На этом маркировка завершена. Профили Тут ничего особенного, два профиля по дефолту /queue type add pcq-rate=0 ; /queue type add pcq-rate=0 ; Дерево Корневая очередь, в которой можно задать max-limit (скорость соединения с первым роутером) /queue tree add > Дуплексная подочередь на сегмент сети: /queue tree add > Симплекс сегмента на загрузку: /queue tree add > Очереди потомки: /queue tree add _EXT_CLASS-A-FL_DL priority=5 > /queue tree add _EXT_CLASS-B-FL_DL priority=6 > /queue tree add _EXT_CLASS-A-UR_DL priority=4 > /queue tree add _EXT_CLASS-B-UR_DL priority=5 > /queue tree add _INT_DL priority=7 > Почти, то же самое для исходящего трафика: Симплекс сегмента на отдачу: /queue tree add > Очереди потомки: /queue tree add _EXT_CLASS-A-FL_UL priority=6 > /queue tree add _EXT_CLASS-B-FL_UL priority=7 > /queue tree add _EXT_CLASS-A-UR_UL priority=5 > /queue tree add _EXT_CLASS-B-UR_UL priority=6 > /queue tree add _INT_UL priority=8 > Повторяем дерево для второго сегмента (VID40) Очередь сегмента: /queue tree add > Загрузка: /queue tree add > /queue tree add _EXT_CLASS-A-FL_DL priority=5 > /queue tree add _EXT_CLASS-B-FL_DL priority=6 > /queue tree add _EXT_CLASS-A-UR_DL priority=4 > /queue tree add _EXT_CLASS-B-UR_DL priority=5 > /queue tree add _INT_DL priority=7 > Отдача: /queue tree add > /queue tree add _EXT_CLASS-A-FL_UL priority=6 > /queue tree add _EXT_CLASS-B-FL_UL priority=7 > /queue tree add _EXT_CLASS-A-UR_UL priority=5 > /queue tree add _EXT_CLASS-B-UR_UL priority=6 > /queue tree add _INT_UL priority=8 > На этом все. Естественно, что в адрес лист SHAPER_TARGET нужно вписать все диапазоны сегментов, а в списки VID30 и VID40 диапазоны сегментов которые на них находятся. Теперь расскажу, как это работает. Шейпер прозрачно пропускает через себя весь трафик до тех пор, пока не будет достигнут лимит, какой либо из родительских очередей. Простыми словами — пока хватает пропускной способности сегментов шейпер не работает, если же по сегменту идет большой трафик и превышает лимит — скорость режется в соответствии с приоритетами. Как только лимит достигнут, приоритеты будут обработаны так: > Пропускается внешний трафик высокого приоритета на загрузку для юр.лиц. > Пропускается внешний трафик низкого приоритета на загрузку для юр.лиц. + Пропускается внешний трафик высокого приоритета на отдачу для юр.лиц. + Пропускается внешний трафик высокого приоритета на загрузку для физ.лиц. > Пропускается внешний трафик низкого приоритета на загрузку для физ.лиц + Пропускается внешний трафик высокого приоритета на отдачу для физ.лиц + Пропускается внешний

Метки:  


Процитировано 1 раз

Go глазами java программиста

Воскресенье, 31 Июля 2016 г. 16:37 + в цитатник
Эта статья не для тех, кто уже пишет на go. Она для программистов на других языках, которым инетересно, стоит ли тратить время на go. Чем отличается go, например, от java и чем может быть полезен. Принципы go Когда-то можно было просто взять и создать новый язык программирования. Сейчас язык имеет шанс занять какое-то место только если у него есть четкие принципы, которым следуют его создатели. Другими словами — собственное лицо. Принципы go — это простота и продуктивность. Принцип простоты звучит так: Если без чего-то можно обойтись, без этого нужно обойтись. Принцип продуктивности: Самое ценное — это время, затрачиваемое разработчиком. Его надо минимизировать всеми доступными способами. Проиллюстрирую принцип простоты: В go очень мало языковых конструкций. Например, только один цикл. Go можно выучить за два вечера. В go отказались от динамической загрузки библиотек — результат компиляции один большой исполняемый файл В go нет warning-ов при компиляции. Любая некорректность или «многословие» — это ошибка компиляции. В go встроен автоформат кода на уровне самого языка. Есть только один каноничный вид кода на go Теперь несколько примеров продуктивности: Код на go на 20-30 процентов короче аналогичного на яве (там просто не лишних слов, например, нет точки с запятой в конце каждого предложения, нет круглых скобок в операторах условия или цикла etc) В go очень быстрый компилятор (несколько секунд на компиляцию большого проекта) Продуктивности служит не только сам язык, но и стандартные инструменты с ним поставляемые. Инструменты повышения производительности Профилировщики начну с небольшого отступления о том как я, программист java, пришел к использованию go. Я делал игровой проект — многопользовательский космический шутер. Изначально я написал серверную часть на java. Она работала. Но очень быстро все уперлось в производительность. На одном сервере можно было запустить не более 300 клиентов. Это слишком мало, чтобы игра стала рентабельной. Что я мог сделать с этим, как программист java? На самом деле немногое: 1) Используя метод пристального взгляда искать в коде неэффективные места, пробовать их исправлять и, после каждого изменения, вновь запускать нагрузочные тесты. Этот способ очевидно неэффективен. 2) Погрузиться в изучение альтернативных серверных библиотек, пробовать разные варианты. Это тоже не дает никаких гарантий — возможно проблемы в моём собственном коде, или вообще в самом языке java. 3) Наконец, я мог купить один или несколько платных профилировщиков и попробовать получить какую-то информацию от них. Но и тут есть проблемы. Если использовать локальный сервер, стоящий у нас в офисе, я не мог создать нужной нагрузки, поскольку у нас в офисе нет нужного количества свободных машин, чтобы запустить несколько тысяч клиентов. Если же использовать внешний сервер, то требовалась довольно сложная конфигурация, чтобы запустить там профилировщик. Наконец, выбор профилировщика сам по себе является нетривиальной задачей. В go эта проблема решена очень удобно. Профилировщик там является частью языка. Включить его можно на любом сервере, а результатом его работы является файл, который можно скачать на свою машину и не спеша изучить при помощи очень удобных инструментов. Эти инструменты покажут какие именно строчки кода тратят более всего памяти и процессорных циклов. Их использование дает возможность быстро и эффективно найти и исправить все проблемные места. (Которые, кстати, почти всегда оказываются не там, где ожидаешь их найти) В моем проекте сервер, переписанный на go изначально «тянул» только 20 клиентов (много хуже, чем на яве). После работы с профилировщиками эта цифра выросла до 2500. Race detector Другая головная боль всех писателей многопоточных приложений — race conditions. Это такие трудноуловимые баги, которые возникают только если звезды сошлись определенным образом. То есть, если потоки запустились в одном порядке, баг есть, если в другом — нет. А порядок непредсказуем. В go для решения этой проблемы есть стандартный инструмент — race detector. Если его включить, программа на go будет писать в лог обо всех небезопасных обращениях к общей памяти из разных потоков. Используя race detector можно быстро, целенаправленно найти и устранить все проблемные места. Интересные конструкции Я не имею целью научить программировать на go и не стану разбирать все его конструкции. Хочу остановиться только на трех, наиболее интересных. Все они описывают парадигмы, которых в яве в чистом виде нет. И эти парадигмы очень полезны. Это интерфейсы, горутины и каналы. Интерфейсы Интерфейс в go похож на интерфейс в яве или c#. Это — набор сигнатур методов, но без реализаций. Основная разница в том, что go не требует объявлять, что какая-то сущность имплементирует какой-то интерфейс. Достаточно, чтобы у сущности просто были все нужные методы. Что это даёт? Decoupling. Вы можете взять чужую библиотеку. Найти там сущность с каким-то набором методов, создать у себя интерфейс с тем же набором и использовать эту сущность, как этот интерфейс. Вам не надо изменять чужой код, не надо завязывать свой код на чужие сущности и не надо писать адаптеров, которые являются классическим boilerplate кодом. Еще одна иллюстрация принципа продуктивности. Горутины Сначала для многозадачных приложений в языках программирования были придуманы процессы. Они были тяжеловесными, имели собственное адресное пространство и быстро «жрали» ресурсы системы. Потом появились треды (или нитки). Они были гораздо легче и работали в одном адресном пространстве. Если процессов обычно запускали единицы или десятки, то тредов можно было иметь уже сотни. Однако, при неаккуратном использовании и они могли отнять все ресурсы системы. Каждый тред всё-таки занимал какие-то ресурсы, даже если был заблокирован. Чтобы ограничить число тредов, начали использовать тред пулы. Горутины можно мыслить как задачи, выполняемые одним общим большим тред пулом. В Go горутины крайне дешевы. Вы можете запустить миллионы горутин без проблем для производительности. Единственное требование — горутины должны быть «маленькие». То есть горутина должна быстро сделать свою работу и либо выйти, либо заблокироваться (что с точки зрения планировщика горутин одно и тоже) Каналы Каналы являются расово правильным средством коммуникаций между горутинами. В go есть важное правило: Don't communicate by shared state. Share state by communication. Его смысл — не пользуйтесь переменными, к которым имеет доступ более одной горутины. Вместо этого заставьте горутины пересылать данные друг другу. Эта пересылка данных как раз и делается через каналы. Канал в go это очередь (буфер) в один конец которого можно писать, а из другого читать. При этом, горутина блокируется при попытке писать в переполненный канал или читать из пустого канала. Но самое интересное — go имеет конструкцию для одновременного чтения из нескольких каналов. Горутина может перечислить несколько каналов, на которых она будет сидеть и ждать появления сообщения в одном из них. Получив это сообщение, горутина разблокируется, обрабатывает его и (обычно) снова ждет следующего сообщения. Так, например, в чат сервере горутина может ждать как сообщение от пользователя так и сигнала о выходе из чата. Одновременно. Управление зависимостями Такие инструменты управления зависимостями, как maven или gradle сегодня существуют для всех серьезных языков. В go пошли дальше и сделали поддержку управления зависимостями на уровне самого языка. При импорте пакета (конструкцией, аналогичной import в яве) можно указать как локальное имя, так и адрес пакета в любой современной системе контроля версий (например, в git). Например, «github.com/gorilla/websocket» Go самостоятельно скачает нужный пакет и включит его в ваш проект. Если какой-то пакет уже был ранее скачан, то он просто будет использован. Вы также можете попросить go обновить все пакеты до их последних версий. Здесь, впрочем есть один неприятный момент — go всегда скачивает последнюю версию пакета. Если над проектом работает несколько человек, это может привести к различным версиям пакетов у разных разработчиков. Для решения этой проблемы используются внешние инструменты — менеджеры пакетов. Один из лучших на сегодняшний день — glide. В основе glide – два действия: 1) Найти все зависимости проекта, и записать их в файл 2) Cкачать эти зависимости При этом файл можно редактировать вручную, указывая, при необходимости, другие версии пакетов (отличные от последней). В качестве идентификатора версии в GIT используется идентификатор коммита (в других системах контроля версий используются специфичные для них идентификаторы) Слабые стороны go Любой принцип имеет не только сильные стороны, но и слабые. В go, на мой взгляд, есть одна плохая и одна ужасная вещь, которые проистекают из принципа простоты. Плохая — это отсутствие generic-ов. Ужасная — обработка ошибок путем проверки возвращаемого функцией кода. Без generic-ов приходится отказываться от строгой типизации. А обработка ошибок приводит к большому количеству однотипного кода. Который, к тому же, можно вовсе забыть написать и оставить ошибку необработанной. Кроме этого, следуя принципу продуктивности, было решено ввести в go garbage collector. Само по себе это неплохо. Но важно понимать, что этот самый коллектор будет запускаться каждые несколько секунд и заметно притормаживать систему. С этим, впрочем, можно успешно бороться. Выводы Стоит ли ява программисту полностью переходить на go? Нет. Во всяком случае, пока. Ява в среднем быстрее. В ней больше полезных библиотек и наработанных способов создания приложений. Стоит ли использовать go для решения определенных задач? Однозначно, стоит. Какие задачи лучше всего решать на go? Создание многопоточных высоконагруженных серверных решений, в которых потоки много коммуницируют между собой. Какой язык лучше учить новичку — go или яву? Однозначного ответа нет, но со временем аргументов в пользу go будет все больше. Возраст языка играет роль. Более старый язык обрастает «историческими» вещами. Что-то было добавлено давно, теперь никому не нужно, но выбросить нельзя, поскольку нарушится обратная совместимость. Какие-то конструкции языка или стандартных библиотек, ранее актуальные, сейчас выглядят неуместно, кажется, логичнее делать эти невостребованные вещи вне стандарта языка. Для каких-то стандартных проблем накопилось множество альтернативных решений разного качества. Для новичка всё это — большое количество бесполезных но необходимых знаний в стиле: «Здесь нужно быть особенно осторожным. Здесь у нас ЛУЖА» Go создавался гораздо позже и на сегодня в нем присутствует все, что востребовано сейчас и ничего лишнего.

Метки:  

Промышленные системы управления — 2016: уязвимость и доступность

Суббота, 23 Июля 2016 г. 16:45 + в цитатник
Автоматизированные системы управления технологическими процессами (АСУ ТП, ICS) используются в наши дни повсеместно — от «умных домов» до атомных электростанций. Однако сложная организация таких систем, требование непрерывности технологического процесса и возможность доступа к АСУ ТП через всеобщий Интернет делают их легкоуязвимыми для хакерских атак. При этом количество уязвимых компонентов АСУ ТП из года в год не снижается. Практически половина выявленных в 2015 году уязвимостей имеет высокую степень риска, причем наибольшее количество уязвимостей найдено в продуктах самых известных производителей. В частности, повсеместно в АСУ ТП используются словарные пароли и пароли по умолчанию, что позволяет без труда получить к ним доступ и перехватить управление. Такие выводы содержатся в исследовании компании Positive Technologies, в котором проанализированы данные об уязвимостях АСУ ТП за период с 2012 по 2015 год, а также данные о доступности компонентов АСУ ТП через Интернет в 2015 году. Ниже представлены основные результаты этого исследования. Методика исследования В качестве основы для исследования была использована информация из общедоступных источников, таких как базы знаний уязвимостей (ICS-CERT, NVD, CVE, Siemens Product CERT, Positive Research Center), уведомления производителей, сборники эксплойтов, доклады научных конференций, публикации на специализированных сайтах и в блогах. Степень риска уязвимости компонентов АСУ ТП мы определяли на основе значения CVSS второй версии. Сбор данных о доступности компонентов АСУ ТП в сети Интернет осуществлялся путем сканирования портов ресурсов, доступных в сети Интернет, с помощью общедоступных поисковых систем: Google, Shodan, Censys. После сбора данных был проведен дополнительный анализ на предмет взаимосвязи с АСУ ТП. Специалисты Positive Technologies составили базу данных идентификаторов АСУ ТП, состоящую примерно из 800 записей, позволяющих на основе баннера сделать заключение об используемом продукте и его производителе. Результаты В рамках исследования были рассмотрены уязвимости компонентов порядка 500 производителей автоматизированных систем управления. В итоге выявлено 743 уязвимости в АСУ ТП. Эксперты Positive Technologies в 2015 году самостоятельно обнаружили 7 новых уязвимостей (две из них имеют высокую степень риска), подробная информация о которых была направлена производителю. Напомним, что согласно нашему предыдущему исследованию «Безопасность промышленных систем в цифрах», с 2009 по 2012 год количество обнаруженных уязвимостей АСУ ТП выросло в 20 раз (с 9 до 192). В последние годы (2012—2015) количество обнаруживаемых ежегодно уязвимостей остается стабильным (около 200). Это можно объяснить возросшим интересом производителей оборудования к своевременному выявлению и устранению уязвимостей и взаимодействию с исследователями. Общее количество уязвимостей, обнаруженных в компонентах АСУ ТП Лидерами в рейтинге наиболее уязвимых компонентов АСУ ТП являются продукты Siemens, Schneider Electric и Advantech. Однако количество обнаруженных уязвимостей зависит от распространенности продукта и от того, придерживается ли производитель политики ответственного разглашения. Как следствие, данный рейтинг не свидетельствует напрямую о защищенности конкретных решений того или иного производителя. Количество уязвимостей в компонентах АСУ ТП различных производителей Наибольшее количество уязвимостей было выявлено в SCADA-компонентах и программируемых логических контроллерах, сетевых устройствах промышленного назначения и инженерном ПО, а также в компонентах человеко-машинных интерфейсов и терминалах удаленного доступа и управления, что соответствует данным предыдущего отчета за 2012 год. Основная доля уязвимостей имеет высокую и среднюю (по 47%) степень риска. При этом, если оценивать уровень опасности уязвимости исходя из возможности реализации главных угроз информационной безопасности (нарушения конфиденциальности, целостности и доступности), то больше половины выявленных уязвимостей имеют высокую метрику по такому важному показателю, как нарушение доступности. В совокупности с возможностью удаленной эксплуатации уязвимостей и слабыми механизмами аутентификации это значительно повышает риск проведения атак на АСУ ТП. Распределение уязвимостей по степени риска Поскольку данные о процессе устранения уязвимостей не публикуются, в исследовании использованы данные, полученные экспертами Positive Technologies непосредственно от производителей. Подробная информация о выявленных уязвимостях, которые уже устранены производителями, представлена на сайте компании. По данным 2015 года, лишь 14% уязвимостей устранены в течение трех месяцев, 34% устранялись более трех месяцев, а оставшиеся 52% ошибок — либо вовсе не исправлены, либо производитель не сообщает о времени устранения. Доля устраненных уязвимостей в компонентах АСУ ТП Вместе с тем в настоящее время только для 5% известных уязвимостей имеются опубликованные эксплойты. Данный показатель значительно снизился по сравнению с 2012 годом: тогда можно было найти эксплойты для 35% уязвимостей. Наибольшее количество уязвимостей относятся к таким типам, как отказ в обслуживании (DoS), удаленное выполнение кода (Code Execution) и переполнение буфера (Overflow). Эксплуатация таких уязвимостей злоумышленником может привести к отказу в работе какого-либо оборудования или к его несанкционированной эксплуатации, что, учитывая требования к штатной работе АСУ ТП, недопустимо. Распространенные типы уязвимостей компонентов АСУ ТП По состоянию на март 2016 года обнаружено 158 087 компонентов АСУ ТП, доступных в сети Интернет. Наибольшее количество компонентов АСУ ТП доступно по протоколам HTTP, Fox, Modbus и BACnet, и в большинстве случаев для авторизации в таких системах используется словарный пароль. Наибольшее число доступных компонентов АСУ ТП было найдено в США (43%), Германии (12%), Франции, Италии и Канаде (примерно по 5%). Низкое количество АСУ ТП, обнаруженных в Азии, связано с использованием локальных и малоизвестных на мировом рынке решений. Россия занимает 31 место с 600 доступными компонентами (это менее 1% общего числа найденных компонентов). Число компонентов АСУ ТП, доступных в сети Интернет (по странам) По распространенности компонентов АСУ ТП лидируют компании Honeywell (17%), SMA Solar Technology (11%), Beck IPC (7%). Самыми распространенными компонентами в сети Интернет являются системы для автоматизации зданий компании Tridium (25 264), входящей в состав группы компаний Honeywell, а также системы мониторинга и управления электроэнергией, в том числе на основе технологий солнечных батарей компании SMA Solar Technology (17 275). В ходе исследования были также найдены автоматизированные системы, управляющие производственными процессами различных предприятий, транспортом и водоснабжением. Во многих случаях злоумышленнику не обязательно обладать какими-то специальными знаниями, чтобы получить к ним доступ: среди найденных в сети Интернет компонентов АСУ ТП только две трети можно условно назвать защищенными. Доля уязвимых и безопасных компонентов АСУ ТП, доступных через Интернет Полученные данные говорят об отсутствии адекватной защиты АСУ ТП от кибератак в 2016 году. Даже минимальные превентивные меры, такие как использование сложных паролей и отключение компонентов АСУ ТП от сети Интернет, позволят в значительной степени снизить вероятность проведения атак, несущих заметные последствия. Полный текст исследования «Безопасность АСУ ТП в цифрах — 2016» можно найти на www.ptsecurity.ru/research/analytics

Метки:  

[Перевод] Agile API — возможно ли?

Вторник, 19 Июля 2016 г. 20:32 + в цитатник
Множество статей и книг посвящено тому, как правильно проектировать API, но едва ли кто-то затрагивал тему постоянно меняющихся (гибких) API. Динамично развивающаяся компания зачастую выпускает по несколько релизов в неделю, а иногда и в день. При этом для добавления новых функций необходимо постоянно вносить изменения в существующее API. В этой статье мы расскажем о том, как мы в Badoo решаем эту задачу, какие подходы и идеи мы используем в своей работе. Для начала я должен немного подробнее рассказать о Badoo, чтобы вы понимали, кто работает с нашим API и почему оно так часто меняется. Наше внутреннее API и его использование Наш Badoo API (протокол обмена сообщениями) представляет собой набор структур данных (сообщений) и значений (enums), которыми обмениваются клиенты и сервер. Структура протокола у нас задаётся на основе определений Google protobuf и хранится в отдельном репозитории git. На основе этих определений генерируются классы моделей для различных платформ. Он используется для шести платформ — сервера и пяти клиентов: Android, iOS, Windows Phone, Mobile Web и Desktop Web. Кроме того, тот же самый API используется в нескольких самостоятельных приложениях на каждой платформе. Чтобы все эти приложения и сервер могли обмениваться требуемой информацией, наш API “вырос” достаточно большим. Немного цифр: 450 сообщений, 2665 полей. 135 enum’ов, 2096 значений. 125 флагов фич, которыми можно управлять на стороне сервера. 165 флагов клиентского поведения, которые сообщают серверу особенности поведения клиента и поддерживаемого клиентом протокола. Когда это нужно сделать? Вчера! В Badoo мы стараемся реализовывать новые функции как можно быстрее. Логика проста: чем скорее появится версия с новыми возможностями, тем быстрее пользователи смогут ими воспользоваться. Кроме того, параллельно мы проводим A/B-тестирование, но в этой статье мы не станем подробно останавливаться на нем. Время реализации фичи — от идеи до релиза — иногда всего лишь неделя, включая написание требований, изменение API и технической документации, имплементация и релиз новой версии. В среднем же на все уходит около месяца. Однако это не означает, что мы добавляем по одной фиче в приложение в месяц. Мы работаем параллельно над множеством новых фич. Для того, чтобы быть способными на такие подвиги, нам пришлось разработать процесс, который позволяет нам двигаться с нужной скоростью. С какой стороны подойти? К примеру, владелец продукта предлагает новую идею и просит разработчиков API расширить протокол, чтобы реализовать новые возможности на стороне клиентов. Прежде всего необходимо понимать, что над реализацией новой функции работает множество людей: Product Owner; дизайнеры; разработчики серверных решений; разработчики API разработчики клиентских приложений для разных платформ; QA; аналитики данных. Как можно гарантировать, что все они понимают друг друга и говорят на одном языке? Нам нужен документ с описанием требований к функциональности (PRD).Обычно такой документ готовит Product Owner. Он создает вики-страницу с перечнем требований, вариантами использования, описанием флоу, эскизами дизайна и т. д. На основе PRD мы можем приступать к планированию и реализации необходимых изменений в API. Тут опять не всё так просто. Подходы к проектированию протокола Существует много подходов к «распределению обязанностей» между сервером и клиентом. Подходы варьируются от «вся логика реализована на сервере» до «вся логика реализована в клиенте». Обсудим «за» и «против» каждого подхода: Вариант 1. Вся логика реализована на сервере (клиент работает как View из шаблона MVC). Плюсы: Новые функциональные возможности для всех платформ достаточно реализовать только один раз — на сервере. Можно обновить только серверную логику и лексемы, нет нужды вносить изменения в клиентские приложения и готовить новый релиз (очень большой плюс, когда речь идет о нативных приложениях). Минусы: Более сложный протокол (часто фича требует несколько последовательных действий, которые легко реализовать на клиенте, а добавление этих шагов в протокол сильно все усложняет). Если что-то работает по-разному на разных клиентских приложениях, необходимо иметь на сервере отдельную реализацию функционала для каждого клиентского приложения и каждой поддерживаемой версии приложения. Может негативно повлиять на удобство использования приложения через медленное или нестабильное соединение. Если бизнес-логика реализована на стороне сервера, некоторые функции будет очень сложно или вовсе невозможно реализовать при отсутствии соединения с сервером. Вариант 2. Вся логика реализована в клиенте — клиентское приложение содержит всю логику и использует сервер как источник данных (характерно для большинства публичных API). Плюсы: Количество запросов к серверу меньше, пользователю приходится меньше ждать ответов. Лучше работает в автономном режиме и через медленную или нестабильную сеть. Значительно упрощается кэширование. При необходимости гораздо проще реализовать различающееся поведение для разных платформ и версий клиентов. Проще взаимодействие с сервером — команды могут работать без оглядки друг на друга. Минусы: Занимает больше времени. Всю логику необходимо реализовать на каждом из клиентов, а не один раз на сервере. Для реализации даже самых незначительных изменений необходимо релизить каждое клиентское приложение. Выше вероятность ошибок в коде, поскольку у каждого приложения отдельная реализация логики. С одной стороны, первый подход позволяет реализовать бизнес-логику только один раз на сервере, и затем она будет использоваться на всех клиентах. С другой стороны, для разных платформ характерны свои особенности, своя структура лексем, разный набор фич, а сами фичи нередко реализуются в разное время. В большинстве случаем проще делать протокол более ориентированным на данные, чтобы клиентские приложения получили некоторую свободу и могли работать по-своему. Но, как всегда, единственно верного решения нет, поэтому мы постоянно балансируем между этими двумя подходами. Техническая документация Несколько лет назад, когда наша компания была меньше, только два клиента (Android и iOS) использовали протокол. Разработчиков было мало, все рабочие моменты мы обсуждали устно, поэтому документация на протокол содержала лишь описание общей логики в комментариях для определений protobuf. Обычно это выглядело так: Затем появились еще три клиентские платформы: Windows Phone, Mobile Web и Desktop Web, да количество разработчиков в Android и iOS командах выросло в три раза. Устное обсуждение стало обходиться все дороже, и мы решили, что настало время тщательно все документировать. Теперь эта документация включает намного больше, чем просто комментарии о полях. Например, мы добавляем краткое описание фичи, sequence-диаграммы, скриншоты и примеры сообщений. В простейшем случае документация может выглядеть так: Разработчики приложений и QA для всех шести платформах, используют эту документацию и PRD в качестве основных источников знания. Эта документация помогает не только реализации новых функций, но и при значительном редизайне и рефакторинге приложений, когда требуется знать как работает уже имплементированный функционал. Теперь мы можем с легкостью сказать разработчикам «RTFM», что экономит нам массу времени. Кроме того, такой подход помогает новичкам понять, как все устроено, и быстро включиться в процесс разработки. Сервируем документацию Мы готовим техническую документацию в формате reStructuredText и храним ее в репозитории git вместе с определениями протокола, а с помощью Sphinx мы генерируем HTML-версию, которая доступна во внутренней сети работникам компании. Документация разделена на ряд основных разделов, посвященных различным аспектам реализации протокола и другим вопросам: Протокол – документация, созданная на основе комментариев для определений protobuf. Функции продукта – техническая документация по вопросам реализации функций. (диаграмма конвейера и т. д.). Общее — документы о протоколе и флоу, не относящаяся к конкретным фичам продукта. Особенности приложений — поскольку у нас несколько различных приложений, в этом разделе описаны различия между ними. Как уже говорилось выше, протокол используется общий. Статистика — общее описание протокола и процессов, связанных со сбором статистики и информации о производительности приложений. Нотификации — документация о различных типах уведомлений, которые могу приходить нашим пользователям. Архитектура и инфраструктура — структура нижнего уровня для протокола, двоичные форматы протокола, фреймворк для A/B-тестирования и т. д. Итак, мы внесли изменения в API. Что дальше? После внесения изменений в протокол и документация на основе PRD, и PRD и API проходят две стадии ревью. Сначала внутри команды, отвечающей за протокол, затем у разработчиков приложений тех платформ, где будет реализована эта фича. На этом этапе мы получаем обратную связь по следующим вопросам: Достаточность — достаточно ли данных изменений API для реализации фичи на каждой платформе. Совместимость — совместимы ли изменения с кодом приложений на платформах. Может быть можно немного подправить протокол и сэкономить одной-двум платформам кучу времени и ресурсов? Понятность После обсуждения и утверждения всех изменений серверные и клиентские команды могу приступать к реализации фичи. Закончить на данном этапе было бы слишком хорошо. Часто у ProductOwner’а уже есть дальнейшие планы по улучшению данной фичи, но при этом он все же хочет выпустить приложение сейчас в текущем виде. Или еще интереснее. Иногда нас просят внести изменения для одной платформы, а для остальных оставить все как есть. Фича как ребенок, она растет и развивается Фичи развиваются. Мы проводим A/B-тесты и (или) анализируем обратную связь после выпуска новых фич. Иногда анализ показывает, что фича нуждается в доработке. Тогда Product Owner'ы вносят изменения в PRD. И тут возникает «проблема». Теперь PRD не соответствует формату протокола и документации. Более того, может получиться так, что для одной платформы изменения уже внесены, а другая команда только приступает к работе. Чтобы предотвратить возможные противоречия, мы используем версионирование PRD. К примеру, для одной платформы фича может быть реализована в соответствии с версией R3. Через некоторое время Product Owner решает доработать новый функционал и обновляет PRD до версии R5. И мы должны обновить протокол и техническую документацию с учетом новой версии PRD. Для мониторинга обновлений PRD мы используем историю изменений в Confluence (вики от компании Atlassian). В технической документации на протокол мы добавляем ссылки на конкретную версию PRD, просто указывая > Все изменения в PRD рассматриваются как новый функционал. Product Owner’ы накапливают изменения (R1, R2…) до тех пор, пока не решат, что настала пора отправить их в разработку. Они готовят задание для разработчиков API с описанием требуемых изменений в протоколе, а затем такие же задания получают все команды разработчиков, отвечающие за разные платформы. Когда для фичи готов следующий набор изменений, создается еще один тикет на доработку API, затем аналогичным образом реализуются изменения для всех платформ: Получив перечень изменений в PRD, мы возвращаемся в начало этого процесса, то есть вносим изменения в протокол и так далее. Конечно, это осложняет нам жизнь, поскольку никто не отменял необходимость поддержки реализованных ранее функций и клиентских приложений, которые были основаны на версии R3. Для решения этой проблемы мы используем несколько инструментов управления изменениями в протоколе. Управление изменениями в протоколе В предыдущем разделе мы обсудили контроль версий PRD. Чтобы реализовать эти изменения в API, мы должны рассмотреть варианты управления версиями протокола. Для простоты можно сказать, что существует три варианта (уровня) со своими преимуществами и недостатками. Уровень протокола Такой подход широко используется для медленно меняющихся публичных API. Когда выходит новая версия протокола, все клиенты должны начать использовать ее вместо старой. Мы не можем использовать этот вариант, поскольку у нас набор фич и время их реализации очень сильно отличаются на разных платформах. Например, у нас есть несколько версий протокола: V1. Поддерживает функции A, B, C. V2. Поддерживает функции B’, C и D, где B’ — это обновленная функция B (требующая другой последовательности команд). Поэтому, если в приложении нужно реализовать фичу D, придется также обновить фичу B до версии B’, хотя, возможно, сейчас это не требуется. Мы в Badoo никогда не применяли такой подход к контролю версий. В нашем случае больше подходят два следующих варианта. Контроль версий на основе сообщений При этом подходе после внесения изменений в функцию создается новое сообщение (структура данных в protobuf) с новым набором полей. Такой подход хорошо работает, если требования меняются значительно. Например, в компании Badoo у каждого пользователя есть альбомы. Раньше пользователи могли создавать собственные альбомы и помещать в них фотографии: AddPhotoToAlbumV1 { required string album_id = 1; required string photo_id = 2; } Затем Product Owner решил, что достаточно будет трех заранее определенных типов альбомов: my photos (мои фотографии), other photos (прочие фотографии) и private photos (личные фотографии). Чтобы клиенты могли различать эти три типа, нужно было добавить enum; соответственно, следующая версия сообщения будет выглядеть следующим образом: AddPhotoToAlbumV2 { required AlbumType album_type = 1; required string photo_id = 2; } Такой подход иногда вполне оправдан, но нужно действовать осторожно. Если изменение не будет быстро реализовано на всех платформах, придётся поддерживать (добавляя новые изменения) как старые, так и для новые версии, то есть хаос будет нарастать. Уровень полей/значений По возможности мы используем то же самое сообщение или перечисление, удаляя некоторые поля/значения или добавляя новые. Это, пожалуй, самый распространенный подход в нашей практике. Пример: AddPhotoToAlbum { optional string album_id = 1 > optional string photo_id = 2; optional AlbumType album_type = 3; } В данном случае клиентские приложения продолжают использовать старое сообщение, а новые версии приложений могут использовать album_type вместо album_id. Кстати, мы всегда используем необязательные поля. Это позволяет удалять поля в случае необходимости (разработчики Google пришли к такому же выводу). Поддержка изменений протокола Как уже говорилось ранее, наше API используется сервером и пятью клиентскими платформами. Новые версии наших клиентских приложений выпускаются каждую неделю (всего около 20 версий приложений в месяц, которые могут работать по-разному и использовать разные части протокола), поэтому мы не можем просто создавать новую версию протокола для каждой новой версии приложения. Такой подход к управлению версиями протокола потребует, чтобы сервер поддерживал тысячи различных комбинаций работы приложений. Это решение далеко от идеального. Поэтому мы остановились на варианте, когда каждое приложение сразу передает серверу сведения о том, какие версии протокола оно поддерживает. В этом случае сервер может взаимодействовать с любым клиентским приложением, просто полагаясь на список поддерживаемых фич, предоставленный самим приложением. Например, недавно мы реализовали функцию «What’s New» (Что нового). Таким образом мы информируем наших пользователей о новых функциях в приложении. Приложения, поддерживающие эту функцию, отправляют серверу флаг SUPPORTS_WHATS_NEW. В результате сервер знает, что клиенту можно отправлять сообщения о новых функциях и они будут нормально отображаться. Как поддерживать порядок в API? Если это общедоступный API, то обычно определяется конкретная дата, после наступления которой старая часть перестает работать. Для Badoo это практически невозможно, поскольку нам важнее реализовать новые функции, чем убирать поддержку старых. В подобной ситуации мы следуем процедуре, состоящей из трех этапов. На первом этапе, как только мы окончательно определились, что часть протокола должна быть удалена, она помечается как «устаревшая», и разработчики приложений для всех клиентских платформ получают задачу на удаление соответствующего кода. На втором этапе устаревшая часть протокола должно быть удалена из кода всех клиентов, но на сервере нельзя удалять этот код ещё достаточно долго — не все пользователи обновляют свои приложения быстро. На последнем этапе, когда из всех клиентских приложений удален устаревший код, и ни одна из версий, в которой используется эта часть протокола, больше не используется, она может быть удалена из серверного кода и из API. Общение В этой статье мы описали несколько технических и организационных подходов, которые мы позаимствовали или создали сами. Однако мы совсем не затронули вопросы общения. А ведь общение составляет 80 % нашей работы. Часто необходимо обсудить саму фичу и возможные пути реализации с большим количеством людей, прежде чем удается понять как эта фича может быть реализована на уровне протокола. В основе любого успешного проекта лежит упорная работа слаженной команды. К счастью, большинство разработчиков поддерживают нас, поскольку хорошо знают, как сложно работать с решениями для различных платформ без стандартизации. Мы поняли, что хорошо документированный API также помогает людям, которые не являются разработчиками, понять сам API и процесс его разработки. Тестировщики обращаются к документации в ходе тестирования, а Product Owner’ы используют ее для того, чтобы продумать варианты решения поставленных задач с минимальными изменениями в протоколе (да, у нас такие крутые Product Owner’ы!). Заключение При разработке гибких API и связанных с ним процессов необходимо быть терпеливыми и прагматичными. Протокол и процесс должны работать с различными комбинациями команд, версий ПО и платформ, устаревшими версиями приложения, а также учитывать многие другие факторы. Тем не менее, это очень интересная задача, по которой на данный момент опубликовано крайне мало информации. Поэтому мы были очень рады поделиться нашими наработками в данном направлении. Спасибо за внимание!

Улучшаем цвета в вебе (для эплофилов)

Понедельник, 18 Июля 2016 г. 21:21 + в цитатник
Последние несколько лет наблюдается значительное улучшение технологии производства дисплеев. Сначала это было обновление до экранов с более высоким разрешением, начавшееся с мобильных устройств, а затем перешедшее на настольные компьютеры и ноутбуки. Веб-разработчики должны были понять, что значит для них высокое значение в DPI, и знать, как разрабатывать страницы, использующие такое высокое разрешение. Следующее революционное улучшение дисплеев происходит прямо сейчас: улучшение цветопередачи. В настоящей статье я хотел бы разъяснить, что это значит, и как вы, разработчики, можете выявлять такие дисплеи и обеспечивать лучшее взаимодействие для ваших пользователей. Возьмём типичный компьютерный монитор — тип, который вы используете уже более десяти лет, — дисплей sRGB. Последние разработки Apple, включая Retina iMac (конец 2015 г.) и iPad Pro (начало 2016 г.), могут показывать больше цветов, чем дисплей sRGB. Такие дисплеи называются дисплеями с широким цветовым охватом (разъяснение терминов «sRGB» и «цветовой охват» будет дано далее). Почему это полезно? Система с широким цветовым охватом часто обеспечивает более точное воспроизведение оригинального цвета. Например, у моего коллеги по имени Хобер есть броские кроссовки. Ярко-оранжевые кроссовки Хобера К сожалению, то, что вы видите выше, не передаёт, насколько на самом деле впечатляющие эти кроссовки! Проблема в том, что цвет материала кроссовок не может быть представлен на дисплее sRGB. Камера, которой сделана эта фотография (Sony a6300), имеет матрицу, воспринимающую более точно цветовую информацию, и соответствующие данные имеются в оригинальном файле, однако дисплей не может показать их. Здесь показан вариант фотографии, на которой каждый пиксель, имеющий цвет, выходящий за границу типичного дисплея, заменён светло-голубым: Те же ярко-оранжевые кроссовки Хобера, но здесь все пиксели, выходящие за границу цветового охвата, заменены голубыми Как можно видеть, цвет материала кроссовок и значительной части травы выходит за границу дисплея sRGB. Фактически, точно представлены цвета лишь менее чем у половины пикселей. Будучи веб-разработчиком, вам необходимо считаться с этим. Предположите, что продаёте такие кроссовки через онлайн-магазин. Ваши клиенты не будут точно знать, какой цвет они заказали, и могут быть удивлены, когда их покупка придёт к ним. Эта проблема уменьшается при использовании дисплея с широким цветовым охватом. Если у вас есть одно из устройств, упомянутых выше, или подобное, то вот вариант фотографии, которая покажет вам больше цветов: Те же ярко-оранжевые кроссовки Хобера, но добавлен цветовой профиль На дисплее с широким цветовым охватом можно видеть кроссовки более яркого оранжевого цвета, зелёная трава также более разнообразная по цвету. Если у вас, к сожалению, не такой дисплей, то вы, скорее всего, видите что-то очень близкое по цвету к первой фотографии. В этом случае лучшее, что я могу предложить, это окрасить изображение, выделив его теряемые вами по цвету участки. Во всяком случае, это хорошая новость! Дисплеи с широким цветовым охватом являются более яркими и обеспечивают более точное отображение реальности. Очевидно, есть желание убедиться, что вы сможете предоставить вашим пользователям такое формирование изображений, в котором данная технология будет полезна. Ниже представлен следующий пример, на этот раз со сгенерированным изображением. Пользователи на дисплее sRGB видят внизу однородный по цвету красный квадрат. Однако это, в некотором роде, трюк. На самом деле, на изображении даны два оттенка красного, один из которых можно увидеть только на дисплеях с широким цветовым охватом. На таком дисплее вы увидите бледный логотип WebKit внутри красного квадрата. Красный квадрат с бледным логотипом WebKit Иногда различие между нормальным изображением и изображением с широким цветовым охватом очень тонкое. Иногда оно выражено значительно более резко. Демоизображения На странице примеров можно сравнивать разные варианты изображений, а также видеть, где на изображении находятся пиксели, выходящие за цветовую границу дисплея sRGB. Имеется также и более интерактивный вариант, показывающий рядом различные изображения. Определения Ниже дано краткое объяснение терминов, часто используемых при обсуждении цвета. Цветовое пространство. Цветовое пространство — это то окружение, в котором можно задавать и сравнивать цвета. Имеется несколько типов цветового пространства, каждый из которых использует разный набор параметров для описания цветов. Например, серое цветовое пространство имеет только один параметр, управляющий уровнем яркости при переходе от чёрного к белому. Вы, вероятно, знакомы с цветовыми пространствами типа RGB, которые используют красный, зелёный и синий цвета в качестве параметров, складываемых вместе на дисплее для создания требуемого цвета. Процессы печати часто используют цветовые пространства типа CMYK, где цвет чернил составляется из голубого, пурпурного, жёлтого и чёрного цветов. Цветовой профиль. В 1993 году группа поставщиков образовала Международный консорциум по средствам обработки цветных изображений (ICC), чтобы задать стандарт, описывающий цветовые пространства. Цветовой профиль представляет собой данные, определяющие цветовое пространство устройства, и может быть использован для перехода между различными цветовыми пространствами. Наиболее распространённые получили имена, как, например, sRGB (или более формально, IEC 61966-2-1). Моё использование выше названия sRGB теперь приобрело больше смысла: такой дисплей может показывать цвета, соответствующие цветовому пространству sRGB. Цветовой профиль может быть записан в некоторый файл или встроен непосредственно в изображение, что позволяет компьютеру понимать, что на самом деле означают значения для цвета в изображении. Цветовой охват. Цветовой охват представляет собой спектр цветов, который может обрабатывать устройство или который может задать цветовое пространство. Цветовой охват для дисплея компьютера — это все цвета, которые дисплей можно точно показывать. Понятие визуализации цветового охвата представляется несколько более трудным, но это немного похоже на цветоподборщики, имеющиеся в ПО разработчика. Представьте себе палитру всех возможных цветов, наложенную на поверхность, с первичными цветами в нескольких точках экстремумов. При движении к красному экстремуму цвет становится более красным. При движении к синему — более синим и т.д. Цветовой охват — это область на рассматриваемой воображаемой поверхности, показывающая, насколько цвет у данного устройства может быть сдвинут в том или ином направлении. Цветовой охват можно понять на основе диаграммы, представленной ниже; здесь цветная поверхность показывает палитру цветов, воспринимаемых человеческим глазом. Белый треугольник — область цветового пространства sRGB (как можно видеть, она существенно меньше той, что видит глаз). Диаграмма, показывающая цветовой охват sRGB Эти диаграммы могут немного дезориентировать, потому что они показывают вам цвета, которые вы можете явно видеть, а затем сообщают вам, что цветовой охват не содержит те цвета. Тем не менее, они дают хороший способ сравнивать размер различных цветовых охватов. Отметим также, что здесь вы видите двумерное представление поверхности цветового охвата, когда в действительности она расположена в трёх- или четырёхмерном пространстве (всё это довольно сложно — мы сейчас пытаемся дать простое введение в тему). Широкий цветовой охват. Этот термин неформально действует в промышленности для описания устройств или цветовых пространств, имеющих цветовой охват, превышающий таковой у sRGB (которым обладают почти все компьютерные дисплеи, используемые в последние примерно десять лет). Дисплеи с более широким цветовым охватом уже имеются на рынке некоторое время, но они были ограничены, в основном, профессиональным применением. Теперь они становятся доступными для обычных потребителей, а это значит, что появляется больше доступных цветов. Иногда широкий цветовой охват называют расширенной цветопередачей. Современные дисплеи Apple поддерживают цветовое пространство Display P3, которое примерно на 25% шире sRGB. Глубина цвета. Компьютеры могут использовать различные уровни точности или глубины для представления цвета. Это не то же самое, что цветовой охват, описывающий палитру цветов. Скорее это количество отдельных цветов внутри цветового охвата, которое может быть задано. Веб-разработчики, как правило, знают синтаксис CSS rgb(), имеющий 0-255 значений для красного, зелёного и синего. Это даёт глубину 8 бит на канал — всего 16 777 216 цветов. Если добавить четвёртый компонент цвета / степень прозрачности, то можно сохранить цвет в 32 битах. Если используется глубина 8 битов на канал, то можно воспроизвести всегда только одно и то же количество цветов, независимо от используемого цветового пространства — будет просто другой набор цветов. При выборе 16 бит на канал пространство будет более глубоким, и можно получить больше цветов внутри того же цветового охвата. Хорошим примером является проведение градиента между схожими цветами: можно увидеть полосчатость, когда компьютер и дисплей не имеют требуемую глубину, чтобы показать плавный диапазон цветов между конечными точками. Пример ниже показывает, как недостаточная глубина цвета порождает полосчатость, хотя все цвета между конечными точками находятся в пределах цветового охвата (это несколько искусственный пример, чтобы усилить эффект). Сниженная глубина цвета демонстрирует отчётливые переходы между схожими цветами. Градиент от светло-красного к тёмно-красному с отчётливыми полосами При увеличении глубины цвета переходы становятся намного менее заметными. Градиент от светло-красного к тёмно-красному без выраженных полос После такого введения рассмотрим более детально цвет в сети и последние усовершенствования в WebKit, помогающие разрабатывать контент с улучшенным пониманием вопросов, связанных с цветом. Мы также дадим информацию о некоторых особенностях, введённых нами в W3C, которые позволят вам получить ещё больше полезного от этой новой технологии для дисплеев. Цвета в вебе Сеть часто пытается изо всех сил обрабатывать цвета правильно. Я уверен, среди читающих есть те, кто с болью вспоминает безопасные веб-цвета! Поскольку мы шли от этого, у нас всё ещё есть ограничения, такие как работа HTML и CSS только в цветовом пространстве sRGB. Как в примере с кроссовками Хобера выше, это значит, что имеется много цветов, которые ваши CSS, изображения и холсты не могут воспроизвести. Это — проблема, если вы пытаетесь показать вашей семье весенние цветы, цветущие в вашем саду, или покупки для ярко-красного спортивного автомобиля, помогающие, несомненно, разрешению вашего кризиса середины жизни. Так, когда мы показываем фотографию кроссовок выше, дисплей sRGB сжимает все цвета за пределами цветового охвата sRGB в цвета, которые он может показать. Но дисплей с расширенным цветовым охватом, такой как Display P3, не производит такой сдвиг в палитру sRGB. На рисунке ниже можно видеть разницу между цветовым пространством sRGB и Display P3. Сравнение цветового охвата sRGB и P3 Окрашенный треугольник представляет собой пространство sRGB. Белый треугольник показывает пространство Display P3. Оно значительно больше, чем у sRGB, особенно на участках наиболее насыщенных цветов — красного, жёлтого, фиолетового и зелёного. Чёрный контур показывает возможности типичного человеческого глаза. Помните красный квадрат с бледным логотипом WebKit? Изображение было создано в цветовом пространстве Display P3, заполнено 100%-но красным rgb(255, 0, 0), а затем был введён логотип с немного отличным красным цветом rgb(241, 0, 0). На дисплее sRGB логотип не виден, поскольку все значения красного выше 241 в Display P3 находятся выше самой верхней границы красного в sRGB; красный 241 и красный 255 воспринимаются как один цвет. Примечание. Я видел в Твиттере, что здесь возникает небольшое недопонимание, поэтому попробуем альтернативное объяснение. Принципиально все полностью красные значения между 241/255 и 255/255 в цветовом пространстве Display P3 не различаются при просмотре их в sRGB. Это не означает, что красный 241 у Display P3 такой же, что красный 255 у sRGB, — к сожалению, здесь не так просто, и я не хотел бы вдаваться в детали в данной вводной статье. Для тех, кому это интересно: в macOS имеется приложение Color Sync Utility, которое позволяет различными путями преобразовывать цветовые пространства, а также сравнивать цветовые охваты. Итак, теперь вы понимаете, почему надо знать глубже ситуацию с цветом и что эту технологию следует использовать для обеспечения пользователям лучшего взаимодействия. Сказанное выше является основой — теперь поговорим, что это значит для WebKit. Согласованные по цвету изображения Выше было упомянуто, что сеть «заточена» под использование sRGB. WebKit/Safari на Mac работают в этом цветовом пространстве многие годы, обеспечивая пользователю согласованные цвета на различных дисплеях (ко времени написания настоящей статьи большинство других ядер браузеров работает в т.н. цветовом пространстве прибора, т.е. они не обрабатывают значения цвета, пока те не пройдут через аппаратное обеспечение дисплея). WebKit согласовывает по цвету все изображения как в iOS, так и в macOS. Это значит, что для изображения, имеющего цветовой профиль, можно быть уверенным в правильности представления цвета на дисплее, независимо от того, обычный это дисплей или дисплей с широким цифровым охватом. Это полезно, поскольку многие цифровые камеры не используют sRGB в своём исходном формате, из-за чего просто интерпретация значений красного, зелёного и синего, как таковых, вряд ли, даст правильный цвет. Обычно пользователь не желает делать что-либо для получения этого согласования цвета. Почти всё программное обеспечение для обработки изображений позволяет вставлять в изображение цветовой профиль; многие программы делают это по умолчанию. На примерах, показанных выше, можно видеть это действие согласования по цвету на Safari от OS X 10.11.3 и выше, а также на iOS 9.3 и выше (устройства Retina). Всё, что я должен был сделать, это убедиться, что изображения содержали соответствующий цветовой профиль. Если изображение не несёт с собой профиль, то WebKit принимает, что имеет место sRGB. Это позволяет легко в вашей создаваемой иллюстрации (например, рамка или фоновые изображения) согласовать то, что было задано вами в CSS. Это значит, что CSS-значение rgb(255, 0, 0) будет соответствовать соответствующему значению для полного красного цвета в sRGB. Примечание. Предположение, что изображение, не несущее соответствующих тегов (о цветовом профиле), не следует обязательно относить к sRGB, требует некоторого комментария. Причина, по которой мы делаем это, объяснена выше: такой подход позволяет обеспечить согласование цветов в изображении с CSS-цветами на странице. Ситуация является нормальной для технологии дисплеев, используемой последние десять лет. Но сейчас, когда появились дисплеи, поддерживающие расширенный цветовой охват, возникает желание более полно управлять тем, в каком виде предстаёт ваш контент. Обнаружение дисплея Выше было пояснено, почему предпочтительнее изображения с широким цветовым охватом подавать на такой же дисплей. Если изображение с широким цветовым охватом поступает на обычный дисплей, то WebKit, согласовывая цвета изображений, покажет его в пространстве sRGB. Однако это преобразование в sRGB может быть выполнено несколькими способами, и нет гарантии, что оно пройдёт одинаково на разных браузерах или платформах. У опытного веб-разработчика есть желание иметь возможность преобразовывать изображения офлайн, чтобы лучше контролировать то, что будет видеть конечный пользователь. К тому же встраивание цветового профиля немного увеличивает размер файла. Не всегда есть желание отправлять эти специальные данные, если они не требуются. Наилучшим решением является предоставлять изображение с широким цветовым охватом, когда у пользователя есть такой дисплей, и sRGB-изображение — при ином дисплее. Эта ситуация является одним из направлений адаптивных изображений и точно показывает, что должны обрабатывать элементные и медиа-запросы. WebKit теперь поддерживает (новый по отношению к CSS Color Level 4) медиа-запрос на цветовой охват. Ниже показано, как следует использовать его: <picture> <source src="photo-srgb.jpg"> </picture> Этот запрос можно использовать также внутри таблицы стилей: .main { background-image: url("photo-srgb.jpg"); } @media (color-gamut: p3) { .main { background-image: url("photo-wide.jpg"); } } Или как скрипт: if (window.matchMedia("(color-gamut: p3)").matches) { // Do especially colorful stuff here. } Запрос на цветовой охват принимает значения р3 и rec2020 как значения, которые являются намеренно неточными терминами, чтобы задать палитру цветов, поддерживаемых системой, включая ядро браузера и аппаратное обеспечение дисплея. По умолчанию, поскольку почти все дисплеи поддерживают sRGB, нет необходимости проверять на такую функциональность. Но типичный современный дисплей с широким цветовым охватом может поддерживать всю или почти всю палитру цветов, входящую в пространство DCI P3, и будет соответствовать медиа-запросу. Например, пространство Display P3, упомянутое выше, является одним из вариантов DCI P3. Значение rec2020 показывает, что система имеет дисплей, поддерживающий даже более широкий цветовой охват, как, например, определяемый пространством Rec. 2020 (в настоящее время довольно редко можно встретиться в сети с аппаратным обеспечением, которое, на самом деле, поддерживает Rec. 2020, — не стоит пока беспокоиться об этом). Поскольку медиа-запросы имеют надёжную систему восстановления, можно начать использовать цветовой охват сразу же, чтобы дать пользователям широкого цветового охвата более хорошие цвета, позволяя работать и пользователям, у которых ещё нет соответствующих браузеров или аппаратных средств. Будущие направления Предоставление и визуализация изображений с широким цветовым охватом являются относительно простыми процессами, но что, если необходимо объединить какое-то изображение с другими элементами страницы, как, например, цвет фона, или ввести изображение в элемент холста? Это — некоторые из проблем, с которыми сталкиваются органы стандартизации, и я хотел бы поговорить о том, чего здесь можно ожидать. Широкий цветовой охват в CSS Выше было показано, что rgb(241, 0, 0) в Display P3 — то же самое, что rgb(255, 0, 0) в sRGB. Что необходимо сделать, если требуется цвет, заданный в CSS, ввести как-то в изображение с широким цветовым охватом? Мы ведь не можем задать эти цвета в CSS. Ниже описано то, что участники проекта WebKit предложили для CSS. Идея состоит в добавлении новой функции, называемой color(), которая может содержать цветовой профиль, а также параметры, определяющие цвет: /* NOTE: Proposed syntax. Not yet implemented. */ strong { color: color(p3 1.0 0 0); /* 100% red in the P3 color space */ } На практике её, вероятно, использовали бы с правилом @supports: strong { color: rgb(255, 0, 0); /* 100% red in the sRGB color space */ } @supports (color: color(p3 0 0 0)) { strong { color: color(p3 1.0 0 0); /* 100% red in the P3 color space */ } } Примечание. Я первоначально допустил опечатку, показав синтаксис как color(p3, 255, 0, 0). Это является одним из неудобств существующей функции rgb(). Новая функция color() будет принимать числа с плавающей запятой в качестве параметров, а не 8-разрядные целые числа. CSS будет задавать некоторые известные названия цветовых профилей, благодаря чему можно будет легко найти требуемые значения цвета. Идёт ещё некоторая дискуссия о разрешении авторам ссылаться на внешние профили или, возможно, указывать изображение, которое имеет встроенный профиль. Дополнительно CSS может принять решение, позволяющее определять значения за пределами 0-255 (или 0-100%) в существующей функции rgb(). Например, rgb(102.34%, -0.1%, 4%) будет означать цвет немного более красный, немного менее зелёный и чуточку более синий. Трудность здесь состоит в том, что понимание этих значений может быть непростым делом (например, что значит отрицательный зелёный цвет?). Другое предложение состоит в задании цветового пространства для всего документа и интерпретации в нём регулярных CSS-значений цвета. Для внешних изображений со встроенными профилями будет, соответственно, происходить согласование цвета. Эти обсуждения идут в рабочей группе W3C CSS в настоящее время. Ваше мнение интересует нас — группе надо знать больше, что думают веб-разработчики. Если вы заинтересованы в участии, то обратите внимание на сообщения электронной почты с темой, начинающейся с "[css-color]", в списке адресов электронной почты WWW-стиля. WebKit надеется реализовать эти свойства, когда мы будем уверены, что они оправдывают себя. Широкий цветовой охват в HTML Хотя CSS работает с большинством представлений HTML-документов, имеется одна важная область, в которой это цветовое пространство не действует: элемент холста. Как 2D-, так и WebGL-холсты принимают, что они работают в цветовом пространстве sRGB. Это значит, что даже на дисплеях с широким цветовым охватом невозможно создать полноцветовой холст. Как решение предлагается добавление опционального флажка к функции getContext, задающего то цветовое пространство, на которое должен быть настроен по цвету холст. Например: // NOTE: Proposed syntax. Not yet implemented. canvas.getContext("2d", { colorSpace: "p3" }); При этом появляются некоторые моменты, подлежащие рассмотрению, например, как создавать холсты, имеющие повышенную глубину цвета. Например, в WebGL можно использовать half-float-текстуры, дающие точность 16 бит на один цветовой канал. Однако даже если такие более глубокие текстуры использованы в WebGL, вы будете ограничены точностью 8 бит, встраивая это WebGL-изображение в документ. Необходимо дать разработчику метод задания глубины цветового буфера для элемента холста. Этого достигают более сложным способом, комбинируя функции getImageData/putImageData (или эквивалент readPixels в WebGL). При сегодняшних 8 битах на каждый буфер канала не происходит потеря точности при вводе в холст и выводе из него. Преобразование также может происходить эффективно, как по производительности, так и по памяти, поскольку данные холста и программы имеют один тип. Если глубина цвета разная, то это может оказаться уже невозможным. Например, half-float-буфер WebGL не имеет эквивалентного типа в JavaScript, что означает либо вынужденное некоторое преобразование данных при чтении или записи, а также использование дополнительной памяти при их хранении, либо необходимость работы с исходным буфером массива и выполнения громоздких математических операций с битовыми масками. Такие обсуждения идут в настоящее время на сайте WhatWG и будут продолжены скоро в W3C. И снова приглашаем вас присоединяться. Выводы Дисплеи с широким цветовым охватом вышли на рынок и являются будущим вычислительных устройств. По мере роста количества пользователей этих великолепных дисплеев разработчики будут всё более заинтересованы в освоении ошеломляющей палитры предлагаемых цветов и в предоставлении пользователям всё более привлекательного взаимодействия с сетью. Программное обеспечение WebKit даёт разработчикам большие возможности по улучшению цветовых характеристик путём согласования цвета и обнаружения цветового охвата, имеющихся сегодня у Safari Technology Preview, а также у macOS Sierra и iOS 10 betas. Мы также заинтересованы в начале реализации более совершенных цветовых характеристик, таких как задание широкого цветового охвата в CSS, введение профилей в элементы холста и использование увеличенной цветовой глубины.

Метки:  

[Из песочницы] Шлюз для почтового сервера

Воскресенье, 17 Июля 2016 г. 14:48 + в цитатник
Не так давно посчастливилось сменить место работы. Попал в компанию, которая, в принципе, заслуживает отдельной статьи по ряду причин и, возможно, появится здесь позже. Если совсем вкратце о структуре нашего отдела: заниматься чем-то, кроме своей основной деятельности, не возбраняется, так что взор мой упал на наш почтовый сервер, доставляющий много хлопот. У компании имеются удаленные партнерские филиалы, равномерно распределенные по всей Западной Европе, использующие один почтовый сервер. К сожалению, бюджет IT-отдела не очень большой, а пользователей достаточно много (около 700 почтовых аккаунтов). Использовался, да и сейчас используется для почты Exchange 2010 с последними обновлениями и более-менее настроенными правилами фильтрации спама, а вот с антивирусом как-то не заладилось. Купленное решение отказывалось нормально работать, раздувая очередь входящей корреспонденции до неприличных размеров и вешая намертво всю почту. (Да, я знаю, что все best practice говорят о необходимости и edge-сервера, и отдельно сервера архивации, но что было на тот момент, то и было.) Берем инициативу в свои руки. К большому своему удивлению, найти развернутый мануал по решению такой проблемы сходу не удалось, так что возникла идея поделиться своими пробами и ошибками в рунете. Из того, что было в конечном итоге протестировано и опробовано: Zentyal, ASSP и Xeams. Подробно описывать их не буду, но пару слов стоит сказатьНачнем по порядку. Zentyal отпал достаточно быстро, потому что цели менять всю инфраструктуру Active Directory и переезжать на open-source решение не стояло, да и вообще, он скорее представляет из себя эдакий комбайн из всего, что только возможно. Как мне кажется, он прекрасно подошел бы SMB до 50 пользователей. Перейдем ко второму нашему кандидату. Anti-Spam SMTP Proxy. Весь набор для проксирования почтового трафика в нем есть, т.е. и Байесовская фильтрация спама, и пенальти очки, и черные/белые списки, и ClamAV и куча-куча всего еще. Есть единственный недостаток: юзабельность. Т.е. веб-интерфейс ASSP это обернутые в какой-то ад конфиги, которые лично мне проще править через консоль. Штука эта простояла у нас около 2х месяцев в продакшене, а потом какой-то из админов что-то поменял в конфигах и все заверте… В общем, мы поймали пару раза .locky и в последний раз актуального бэкапа не нашлось, потому человек ушел в отпуск, а когда пришел уже было поздно. Это заставило нас пересмотреть нашу политику резервного копирования, но об этом в другой раз. К огромному сожалению, отдельного Linux-администратора у нас нет, т.к. почти вся инфраструктура на Microsoft, поэтому ковырять монструозные награмождения через веб-интерфейс для админов была реальная пытка. После усиленного гугления и пробы еще нескольких продуктов, я остановил свой выбор на Xeams. Да, к большому сожалению, это не OpenSource, а закрытый продукт, однако, он очень дружелюбен к тем администраторам, у которых нет большого опыта в связках Linux&Dovecot&Postfix&etc. Кроме того, он кросплатформенный, так что не возникнет проблем даже у тех, кто с линкусом на вы. Работать он может в трех режимах: Stand alone server — да, xeams умееть быть и просто почтовым сервером. На сколько хорошим не могу сказать, потому что эта функция интересовала меня в последнюю очередь. Spam firewall — в этом режими xeams только принимает весь почтовый трафик на себя и дальше распределяет на корпоративные почтовые сервера. Hybrid mode — Гибридный режим. Объединяет два других, рекомендую ставить его, поскольку полноценно фильтровать спам он не сможет без пропуска исходящего трафика через себя. Так как у нас уже был почтовый сервер, то использовался вариант SMTP-Proxy Установка производилась на чистую машину с Ubuntu 14.04. Единственное, что необходимо было доставить, так это Java, на которой, собственно, работает движок Xeams. sudo apt-get update && upgrade sudo apt-get install libc6-i386 sudo update-alternatives --config java sudo apt-get install default-jre java -version Xeams использует ClamAV, правда, рекомендует ставить его на отдельную машину, но в процессе использования на одной машине никаких проблем замечено не было. Если необходимо позже переконфигурировать настройки ClamAV, то это тоже можно сделать без проблем. sudo apt-get install clamav-daemon Качаем архив с инсталлятором отсюда. Распаковываем, даем права и выполняем. wget http://www.xeams.com/files/XeamsLinux64.tar tar -xf ./XeamsLinux64.tar chmod +x ./Install.sh ./Install.sh Если все прошло успешно, Web-Interface будет доступен по 5272 порту. Главная страница содержит отчеты, графики и основные параметры потребления ресурсов. Мы дали машине 8Гб RAM, пиковая нагрузка несколько раз достигала 6, так что такие цифры вполне оправданы. Переходим к самой настройке. На Firewall весь трафик на 25 порт заворачиваем на IP нашего Xeams на порт 2525. Это сделано потому, что у нас Xeams не только получает, но через него и отправляется почта, так что входящая приходит на 2525й порт, а исходящая на 25й порт. В целом, настройка Xeams простая и достаточно удобная. На которые моменты все-таки, хотелось бы обратить внимание: Server Configuration > Server Configuration > Basic Указываем порт для http/https web-доступа. DNS, если указан в настройках самой машины, то можно не указывать И адрес, для ежедневных отчетов. Server Configuration > Server Configuration > Advanced На вкладке Advanced необходимо указать HELO (как правило, можно просто скопировать из настроек имеющегося почтового сервера), чтобы самим не попасть в СпамЛисты. Server Configuration > SMTP Configuration > Relaying Используйте только Closing relay и пропишите адреса и хосты, с которых можно будет отправлять почту без аутентификации. Со стороны Exchange это выглядит вот так, где закрашенным прописан адрес smtp-relay Server Configuration > SMTP Proxy Server Configuration Здесь все просто, указываем порты, на которые принимается почта, указываем адрес пересылки и порт. В нашем случае, это адрес корпоративного Exchange GreylistingОтдельно хотелось бы сказать о <a href=«ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%80%D1%8B%D0%B9_%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA»>Грейлистинге. Настоятельно рекомендую прописать туда все домены публичной почты и белого списка, потому что задержка письма на 10 часов из-за неправильно настройки на стороне отправляющего почтового сервера, увы, не редкость. Server Configuration > Active Directory Integration Если у Вас поднят Active Directory, то его без проблем можно интегрировать в Xeams. Зачем? Хотя бы для того, чтобы пользователи не мучали Вас в первое время, что у них не доходит почта. Пользователь без проблем сможет зайти и проверить свой почтовый ящик, просмотреть свой спам и прописать свои black/whitelist: Кроме этого, это предоставляет возможность использовать SMTP только аутентифицированным пользователям. В общем, удобно. ClamAVЕсли Вы, также, как и я установили ClamAV на тот же сервер, что и Xeams, то страница настройки будет приглядеть примерно вот так: чуть ниже я расскажу о некоторых нюансах его использования. Спамфильтры. У Xeams достаточно большой набор спамфильтров: Real-time Black-hole servers (RBL). Каждому списку можно выставить свои очки значимости, на основе которых, Xeams определяет благонадежность письма. Из адаптивных фильтров используется Bayesian Analysis, которая вполне справляется с возложенными на нее функциями. Были опасения, что работать он будет плохо, из-за большого количества языков переписки (русский, немецкий, английский, испанский, итальянский, польский, греческий), однако, процент ложных срабатываний достаточно низок. Auto Learn Sender. Отличная вещь, именно из-за него мы пропускаем весь исходящий почтовый трафик через Xeams, который анализирует адреса получателей и принимает их во внимание, когда выносит окончательную оценку благонадежности письма. Остальные фильтры страндартны и я не думаю, что их необходимо описывать в этой статье, которая и так уже получилась раздутой. Теперь несколько слов хотелось бы уделить не совсем очевидным нюансам: После нескольких дней использования, мы изменили стандартные настройки фильтров и конфигурацию очков: Градация писем по очкам и Bayesian Score подняли до 115. Самым распрастраненнным ложным срабатыванием являлась проблема правильной кодировки, так как, все-таки, Xeams заточен на английский язык, решилась отключением этой настройки. По умолчанию, ClamAV НЕ проверяет вложения макросов в документах Ofiice, т.е. новомодный .locky может спокойно пройти, исправить это можно одной строчкой: echo 'ScanOLE2 true' >> /etc/clamav/clamd.conf Если кому интересно, то вот конфиг, который используется у нас сейчасcat /etc/clamav/clamd.conf #Automatically Generated by clamav-base postinst #To reconfigure clamd run #dpkg-reconfigure clamav-base #Please read /usr/share/doc/clamav-base/README.Debian.gz for details TCPSocket 3310 # TemporaryDirectory is not set to its default /tmp here to make overriding # the default with environment variables TMPDIR/TMP/TEMP possible User clamav AllowSupplementaryGroups true ScanMail true ScanArchive true ArchiveBlockEncrypted false MaxDirectoryRecursion 15 FollowDirectorySymlinks false FollowFileSymlinks false ReadTimeout 180 MaxThreads 12 MaxConnectionQueueLength 15 LogSyslog true LogRotate true LogFacility LOG_LOCAL6 LogClean false LogVerbose false PidFile /var/run/clamav/clamd.pid DatabaseDirectory /var/lib/clamav SelfCheck 3600 Foreground false Debug false ScanPE true MaxEmbeddedPE 10M ScanOLE2 true ScanPDF true ScanHTML true MaxHTMLNormalize 10M MaxHTMLNoTags 2M MaxScriptNormalize 5M MaxZipTypeRcg 1M ScanSWF true DetectBrokenExecutables false ExitOnOOM false LeaveTemporaryFiles false AlgorithmicDetection true ScanELF true IdleTimeout 30 PhishingSignatures true PhishingScanURLs true PhishingAlwaysBlockSSLMismatch false PhishingAlwaysBlockCloak false PartitionIntersection false DetectPUA false ScanPartialMessages false HeuristicScanPrecedence false StructuredDataDetection false CommandReadTimeout 5 SendBufTimeout 200 MaxQueue 100 ExtendedDetectionInfo true OLE2BlockMacros false ScanOnAccess false AllowAllMatchScan true ForceToDisk false DisableCertCheck false DisableCache false MaxScanSize 100M MaxFileSize 25M MaxRecursion 10 MaxFiles 10000 MaxPartitions 50 MaxIconsPE 100 StatsEnabled false StatsPEDisabled true StatsHostID auto StatsTimeout 10 StreamMaxLength 25M LogFile /var/log/clamav/clamav.log LogTime true LogFileUnlock false LogFileMaxSize 0 Bytecode true BytecodeSecurity TrustSigned BytecodeTimeout 60000 OfficialDatabaseOnly false CrossFilesystems true OnAccessMaxFileSize 25M В целом, через две недели после использования и анализа спама, возможного спама, можно сказать, что 98% спама действительно не проходит. Буду рад предложениям, комментариям и критике в комментах.

Метки:  

Уязвимости корпоративных информационных систем — 2015: внутри хуже, чем снаружи

Вторник, 05 Июля 2016 г. 21:15 + в цитатник
Максимальный уровень риска уязвимостей, связанных с отсутствием обновлений безопасности (доля уязвимых систем) В 2015 году сетевые инфраструктуры компаний оказались лучше защищены от внешнего злоумышленника, чем в предыдущие годы, однако уровень защищенности от внутреннего нарушителя остался крайне низким. Лидер уязвимостей сетевого периметра — старые версии ПО, во внутренних сетях — недостатки управления учетными записями и паролями. Увеличилось число сотрудников, которые переходят по внешним ссылкам, а уровень защищенности каждой третьей из беспроводных сетей оценивается «ниже среднего». Такие наблюдения сделаны в исследовании компании Positive Technologies на основе тестов на проникновение, проводившихся в 2015 году. Ниже мы представляем основные результаты исследования. Исходные данные В исследовании использованы результаты тестирования 17 информационных систем крупных российских и зарубежных компаний. Наибольшую долю составляют компании финансового сектора (35%). В равных долях представлены промышленные, телекоммуникационные и IT-компании (по 18%), также среди протестированных — одна транспортная компания и одна госорганизация. Большинство исследованных предприятий включали множество дочерних компаний и филиалов, расположенных в разных городах и странах; количество активных узлов, доступных на их сетевом периметре, исчислялось сотнями. Помимо тестирования на проникновение, в 24% проектов проводилась оценка осведомленности сотрудников в вопросах информационной безопасности. Общие результаты В 76% исследованных систем выявлена возможность получения злоумышленником полного контроля над отдельными критически важными ресурсами. При этом в 35% систем такой уровень привилегий может быть получен от лица любого внешнего нарушителя. Не удалось получить контроль над какими-либо критически важными ресурсами в 24% проектов. В целом видна тенденция к повышению общего уровня защищенности критически важных ресурсов, по сравнению с 2013 и 2014 годами. В половине исследованных систем возможно получение полного контроля над всей корпоративной инфраструктурой. При этом в 19% случаев такие привилегии могут быть получены со стороны внешнего нарушителя, а еще в 31% компаний — от лица внутреннего нарушителя из пользовательского сегмента сети. Минимальный уровень доступа, необходимый нарушителю для получения полного контроля над отдельными критически важными ресурсами Как и в предыдущие годы, практически в каждой корпоративной инфраструктуре были обнаружены уязвимости высокой степени риска. С 2013 года сохраняется тенденция к росту доли организаций, корпоративная инфраструктура которых подвержена критически опасным уязвимостям, связанным с использованием устаревших версий ПО и с отсутствием обновлений безопасности. Средний возраст наиболее устаревших неустановленных обновлений — 73 месяца (более шести лет). Недостатки защиты сетевого периметра По сравнению с 2014 годом общий уровень защищенности сетевого периметра повысился: в рамках почти половины проектов, где проводились работы, не было выявлено недостатков, которые позволили бы получить доступ к критически важным ресурсам из внешних сетей. Сложность осуществления атак также возросла: для получения доступа к ресурсам внутренней сети внешнему нарушителю лишь в 46% случаев достаточно обладать низкой квалификацией (против 61% в 2014 году). Сложность преодоления периметра В 54% проектов, где проводились работы по внешнему тестированию на проникновение, были получены максимальные привилегии в каких-либо критически важных для бизнеса системах, в 27% случаев — полный контроль над всей инфраструктурой компании. В 55% систем для преодоления сетевого периметра без использования методов социальной инженерии требовалась средняя либо низкая квалификация, либо вовсе тривиальные действия нарушителя. В среднем для получения доступа к ресурсам внутренней сети, как и в 2014 году, требовалась эксплуатация двух различных уязвимостей. При преодолении сетевого периметра в 47% случаев вектор атаки основывался на эксплуатации уязвимостей веб-приложений. В целом уязвимости различного уровня риска в коде веб-приложений были обнаружены в 69% исследованных систем. Например, уязвимость «Загрузка произвольных файлов» была выявлена в 56% проектов, а «Внедрение операторов SQL» оказалось возможно в 44%. Другие 53% атак, в результате которых был получен доступ к ресурсам внутренней сети, пришлись на использование словарных учетных данных. Данная уязвимость была наиболее распространенной в 2014 году, а в 2015 году выявлена на сетевом периметре 78% систем. Во всех этих системах были обнаружены простые пароли привилегированных пользователей. В 44% компаний словарные учетные данные использовались для доступа к общедоступным веб-приложениям. Во всех исследованных системах были выявлены недостатки, связанные с использованием на сетевом периметре уязвимых версий ПО; главным образом это устаревшие версии веб-серверов (78%) и прикладного ПО (67%). Наиболее распространенные уязвимости на сетевом периметре Недостатки защиты внутренней сети Как и в предыдущие годы, в рамках всех проектов удалось получить максимальные привилегии в критически важных системах при тестировании от лица внутреннего злоумышленника (например, рядового сотрудника, находящегося в пользовательском сегменте сети). При этом полный контроль над инфраструктурой был получен в 71% случаев. Полученные результаты совпадают с показателями 2013 года. В среднем при наличии доступа во внутреннюю сеть для контроля над критически важными ресурсами злоумышленнику требуется эксплуатация четырех различных уязвимостей, что на один шаг больше, чем в предыдущем году, и на один шаг меньше, чем в 2013 году. Однако сложность реализации атак существенно снизилась — в 82% случаев для доступа к критически важным ресурсам нарушителю достаточно было обладать квалификацией низкого уровня; аналогичный показатель в 2014 году составлял лишь 56%. Самой распространенной уязвимостью ресурсов внутренней сети остается использование словарных паролей. Данный недостаток обнаружен в рамках всех без исключения проектов. При этом в 91% случаев было выявлено использование слабых паролей для привилегированных учетных записей. Словарные пароли во внутренней сети Во всех системах также были выявлены недостатки защиты служебных протоколов, которые могут привести к перехвату и перенаправлению сетевого трафика. Недостаточный уровень защиты привилегированных учетных записей и недостатки антивирусной защиты по-прежнему распространены во внутренней сети компаний: уязвимости каждой из этих категорий были обнаружены в 91% систем. Уровень защищенности внутренних сетей по-прежнему остается крайне низким. Несмотря на отдельные улучшения (например, повысился средний уровень криптографической защиты, повысилась осведомленность пользователей в вопросах информационной безопасности), применяемых мер защиты все так же недостаточно для противодействия злоумышленникам. Наиболее распространенный сценарий развития атаки во внутренней сети практически не изменился с 2014 года и состоит всего из трех основных этапов. Как и прежде, для успешной атаки достаточно использовать широко распространенные и давно известные типы уязвимостей. Наиболее распространенные уязвимости внутренней сети Недостатки осведомленности сотрудников в вопросах ИБ В целом уровень осведомленности сотрудников в вопросах информационной безопасности оценивается выше, чем в 2014 году, но по-прежнему остается достаточно низким: ни в одной из протестированных систем он не был оценен как приемлемый, хотя вдвое снизилась доля компаний, для которых уровень осведомленности сотрудников был оценен как крайне низкий (25% против 50% в 2014 году). В 2015 году в среднем 24% пользователей осуществили переход по поддельной ссылке (в 2014 году было 20%). Не изменилась доля испытуемых, которые ввели свои учетные данные в заведомо ложную форму аутентификации или загрузили исполняемый файл: показатель остался на уровне 15%. Доля зафиксированных событий относительно общего количества отправленных сообщений Недостатки защиты беспроводных сетей В рамках данных работ проводится поиск недостатков в использовании точек доступа и клиентских устройств Wi-Fi для диапазонов 2,4 и 5 ГГц с использованием технологий 802.11a/b/g/n, а также недостатков в архитектуре и организации беспроводного доступа. Лишь для 33% систем уровень защищенности беспроводных сетей был оценен как «приемлемый». Среди выявленных недостатков стоит отметить использование механизма WPS для упрощения процесса настройки беспроводной сети. Для подключения к точке доступа используется специальный PIN-код, состоящий только из цифр. Нарушитель может подобрать PIN-код и подключиться к точке доступа. Также выявлены факты использования несанкционированных точек доступа; в случае их подключения к локальной вычислительной сети злоумышленник имеет возможность получить доступ к внутренним сетям. В ряде систем обнаружено отсутствие защиты отдельных беспроводных сетей, что может привести к перехвату важной информации. К распространенным уязвимостям можно также отнести использование стандартных учетных записей для доступа к веб-интерфейсу управления сетевым оборудованием. В рамках одного из проектов было установлено, что почти все беспроводные сети компании доступны за пределами контролируемой зоны, при этом на общедоступных ресурсах сетевого периметра в открытом виде хранились учетные данные пользователя домена. Таким образом любой внешний нарушитель может подключиться к беспроводной сети и проводить атаки на ресурсы ЛВС. Заключение Для снижения рисков компрометации критически важных систем со стороны внешних нарушителей рекомендуется особое внимание уделять ресурсам, доступным из внешних сетей. Как показывает практика, подавляющее большинство успешных атак основаны на эксплуатации уязвимостей не официальных сайтов организаций и их серверов, а каких-либо других ресурсов компании, которые не должны быть доступны на сетевом периметре (например, СУБД, неиспользуемых отладочных интерфейсов, интерфейсов удаленного доступа или управления, интерфейсов инфраструктурных служб, таких как LDAP). Интерфейсы для доступа к таким ресурсам могут быть открыты для подключения по ошибке администраторов; зачастую представители крупных компаний, отвечающие за безопасность, не могут точно сказать — сколько и каких ресурсов организации доступны из внешних сетей. Для защиты от атак на веб-приложения рекомендуется применять межсетевые экраны уровня приложения с эффективными настройками правил корреляции. Для контроля за ресурсами на сетевом периметре рекомендуется обеспечить регулярное сканирование ресурсов, доступных из внешних сетей (к примеру, раз в месяц). Для своевременного выявления и устранения уязвимостей в коде критически важных веб-приложений необходимо регулярно проводить работы по анализу их защищенности, как методом черного или серого ящика, так и методом белого ящика с подробным анализом исходных кодов. Такие работы важно проводить не только на каждом этапе разработки приложения, но и в отношении систем, принятых в эксплуатацию, с последующим контролем устранения выявленных уязвимостей. Что касается защиты корпоративных систем от атак со стороны внутреннего нарушителя, необходимо ввести парольную политику, запрещающую использование простых паролей, предусматривающую обязательную двухфакторную аутентификацию для привилегированных пользователей критически важных систем, а также требования к регулярной смене паролей (например, раз в 60 дней). Также необходимо обратить особое внимание на устаревшие версии ПО, на открытые протоколы передачи данных и на хранение важной информации в открытом виде на серверах и рабочих станциях сотрудников. Кроме базовых мер защиты информации, следует на регулярной основе проводить аудит безопасности информационных систем и тестирование на проникновение со стороны внешнего и внутреннего нарушителя. Полный текст исследования читайте на www.ptsecurity.ru/research/analytics Авторы: Дмитрий Каталков, Евгений Гнедин, отдел аналитики информационной безопасности Positive Technologies

Метки:  

Security Week 25: уязвимости в Windows, libarchive и Wordpress, новые старые трюки криптолокеров

Воскресенье, 26 Июня 2016 г. 11:05 + в цитатник
Поговорим о тренировке. Вместе с криптолокерами в наш уютный ландшафт угроз пришли казалось бы давно забытые трюки: от «албанского вируса» (набор для самостоятельной зашифровки данных) до макросов в офисных документах. По меркам тех угроз, про которые действительно интересно читать, это прошлый век и детский сад, но вот проблема — работают ведь. В случае макросов от пользователей требуется сделать пару лишних кликов, в процессе выводятся предупреждения (опасно!), но нет, все кликается, загружается и приводит к реальным убыткам и потере данных, хорошо если только на одном компьютере. По нашим данным, число криптоатак на пользователей за последние два года выросло в пять раз — и этот тот случай, когда количество рано или поздно переходит в качество. Подавляющее большинство криптолокеров, а особенно такие трояны начального уровня, по-прежнему без проблем блокируются стандартным защитным софтом. Увы, это не исключает заражение полностью — и дело не в том, что стопроцентной защиты не бывает. Недавно я ссылался на пример, когда к неплохо защищенной инфраструктуре подключается внешний фрилансер с ноутбуком без антивируса и устраивает локальный армагеддон. Недавно к арсеналу древних трюков добавился еще один. Вместо макросов в офисные документы внедряют ссылки на внешние объекты с помощью технологии OLE (новость, исследование Microsoft). В документе этот хитрый маневр выглядит примерно как на картинке. В одном из случаев использовалась довольно топорная социнженерия: «Нажмите, чтобы разблокировать этот контент и доказать, что вы не робот». В Ворде такая конструкция выглядит чрезвычайно подозрительно, но ведь работает. И что с этим делать? Все выпуски дайджеста доступны по тегу. В случае с обычными пользователями понятно что делать — антивирус надо ставить. В случае компаний все сложнее, выше я уже привел пример, почему не всегда получается заблокировать все и везде. Сотрудников надо обучать. Желательно, чтобы тренинги по тому, что мы называем security awareness, отличались от росписи в журнале за инструктаж на случай пожара. Обучение должно быть регулярным, цели его должны быть понятны всем — именно поэтому мои коллеги, отвечающие за тренинги, говорят, что надо обязательно включать в программу не только обычных сотрудников, но и начальство, вплоть до топ-менеджеров. С точки зрения технаря это решение возможно выглядит немного странным, ну а куда деваться? Одним из качественных изменений в индустрии ИБ является именно расширение понятия безопасности за пределы борьбы хорошего кода с плохим. Безопасность — это люди, их запрограммировать не получится, и гневным циркуляром проблему не решить. Но пробовать надо: не будучи алгоритмизируемым решением, тренинги дают вполне измеряемую эффективность. Неделя патчей: Windows, Wordpress, libarchive Обнаружение уязвимостей в софте и выпуск патчей — это такой регулярный элемент новостного фона по теме безопасности. Настолько привычный, что в список самых посещаемых такие новости выбиваются нечасто: в моем еженедельном сериале это происходит примерно раз в квартал. Вот и настал такой момент: на повестке дня сразу три важных патча. В Microsoft залатали уязвимость в протоколе Web Proxy Auto Discovery (новость, бюллетень MS). И Microsoft, и первооткрыватель, исследователь из китайской компании Tencent, много деталей не раскрывают. В схеме работы протокола обнаружили возможность отката к уязвимому «процессу обнаружения прокси-сервера», конкретно эксплуатируется «предсказуемость идентификаторов транзакций при работе с Netbios». В списке подверженных — все версии Windows, начиная с 7, но по факту дыра присутствует даже в Windows 95, и, естественно, в неподдерживаемой более XP. Возможно причиной малого количества деталей является универсальность атаки. По словам исследователя, эксплойт может прилететь и в виде URL в браузере, и в виде вредоносного офисного документа, и даже на флешке (например с помощью вредоносного шортката). Дальнейшее развитие атаки нельзя назвать простым делом, но в итоге появляется возможность перехвата трафика или подмены доверенных сетевых устройств. Исследователи из Cisco нашли три уязвимости в опенсорсной библиотеке libarchive (новость, исследование). В случае с открытым софтом важнее даже не характер уязвимости, а понимание — кто подвержен. В этом может помочь список зависимого софта на сайте библиотеки. Все три уязвимости могут эксплуатироваться с помощью подготовленного архива определенного формата, конкретно подвержены 7-Zip и RAR. Кроме того, теоретически можно эксплуатировать уязвимость, когда библиотека работает с данными mtree, штатной утилиты в FreeBSD. Все три уязвимости позволяют выполнять произвольный код. Наконец, очередной апдейт Wordpress до версии 4.5.3 закрывает 24 уязвимости (новость, анонс Wordpress). Большая часть уязвимостей позволяет получить контроль над веб-сайтом. Дополнительно были исправлены 17 багов — причем все относительно свежие, они были «добавлены» в последних трех релизах открытой CMS. Что еще произошло: Проект Let's Encrypt сообщает о выпуске пятимиллионного бесплатного сертификата HTTPS. Одновременно с этим выяснилось, что компания Comodo, продающая SSL за деньги, зачем-то пытается зарегистрировать на себя торговую марку Let's Encrypt в США. Фу таким быть. Индийскую рекламную фирму inMobi, зарабатывающую в том числе на баннерах в мобильных приложениях, оштрафовали в США на почти миллион долларов за отслеживание пользователей без их ведома. Рекламная сеть этой компании предположительно «накрывает» больше миллиарда устройств. Древности: «Tired-1740» Резидентный опасный вирус, стандартно записывается в COM-, EXE- и OVL-файлы при их загрузке в память для выполнения. Периодически расшифровывает и выводит на экран фразу: «I think you're too tired to the bone. You'd better go home», а затем перезагружает компьютер. Перехватывает int 21h. Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 85. Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.

Метки:  

[Перевод] Модуль PowerShell для Intel IoT Gateway

Воскресенье, 26 Июня 2016 г. 09:15 + в цитатник
Шлюзы Intel для интернета вещей могут работать под управлением различных операционных систем. Одна из них – Windows 10 IoT. Сегодня мы поговорим о модуле для PowerShell IntelIoTGatewaySetup, который создан специально для поддержки IoT-шлюзов в среде Microsoft Windows. Официально этот модуль называется «Intel IoT Gateway Module for Microsoft Windows PowerShell». Он помогает настроить операционную систему шлюза на заданный уровень безопасности (Security SKU). Основные сведения Модуль входит в состав пакета Windows Configuration Software for Intel IoT Gateway. Пакет можно найти по вышеприведённому названию и скачать в Центре загрузки Intel. В настоящее время поддерживаются операционные системы Windows 10 IoT Enterprise и Windows 10 IoT Core. IntelIoTGatewaySetup позволяет настраивать следующие функции безопасности Windows, указанные в описании уровней безопасности. Предусмотрено три уровня безопасности. В частности, это, в порядке возрастания обеспечиваемого уровня защиты, Basic SKU, Medium SKU, и High SKU. Каждый следующий уровень расширяет возможности предыдущего. Итак, вот список настраиваемых функций. Windows Update, Windows Defender, Windows Firewall, Windows User Account Control, USB Removable Media Lockdown, Virtualization Based Security, App Locker, Code Integrity. BitLocker с поддержкой модуля TPM для Windows 10 IoT Enterprise. Хотя в определениях уровней безопасности упомянуто использование TPM и сетевой разблокировки (Network Unlock) для среднего и высокого уровней, модуль PowerShell настраивает лишь BitLocker с поддержкой TPM, так как Network Unlock требует дополнительной сетевой инфраструктуры. Хотя модуль IntelIoTGatewaySetup и настраивает множество параметров в соответствии с заданным уровнем безопасности, он не касается следующих возможностей: UEFI, Secure Boot и TPM. Всё это является частью аппаратных требований и требований к микропрограммам для шлюзов Intel. Таким образом, эти функции на шлюзе будут уже включены. Уровни привилегий учётных записей. Можно создать, в зависимости от особенностей использования системы, учётную запись с ролью администратора или обычную учётную запись со стандартным набором прав. ASLR. Эта возможность по умолчанию поддерживается и включена в ОС Windows, таким образом, в дополнительной настройке она не нуждается. Measured Boot. Эта функция реализуется благодаря прошивке UEFI, TPM и Windows. Она так же не нуждается в дополнительной настройке. Remote Attestation. Эта функция нуждается в настройке дополнительной сетевой инфраструктуры и в дополнительном программном обеспечении. BitLocker + Network Unlock. Технология Network Unlock требует настройки дополнительной сетевой инфраструктуры и возможностей DHCP-драйвера в UEFI. В результате модуль PowerShell способен настроить лишь BitLocker с поддержкой TPM. USB Filter. Для настройки этой функции в соответствии с особенностями использования шлюза, применяйте групповые политики для того, чтобы управлять USB-устройствами, основываясь на Device ID или Class ID. Keyboard Filter. Для настройки этого фильтра воспользуйтесь инструментом Windows ICD. В папке IntelIoTGatewaySetup находятся следующие основные компоненты: Readme.rtf. Обычный сопроводительный файл с инструкциями по началу работы. ModuleInstallation.ps1. Вспомогательный скрипт для установки модуля IntelIoTGatewaySetup. Папка IntelIoTGatewaySetup. Здесь содержится сам модуль. Установка модуля Если у вас имеется шлюз, оснащённый дисплеем и клавиатурой, команды PowerShell, необходимые для установки модуля, можно исполнять непосредственно на шлюзе. После установки команды PowerShell, которые предоставляет модуль, так же можно исполнять прямо на шлюзе. Мы называем это локальной установкой и локальным исполнением команд. Шлюз может быть расположен вне пределов физической досягаемости, кроме того, у него могут отсутствовать монитор и устройства ввода. В таком случае нужно воспользоваться другим компьютером, назовём его компьютером разработчика, который позволит организовать удалённое управление шлюзом и его настройку. Ниже мы будем рассматривать именно такой сценарий. Мы называем его удалённой установкой и удалённым исполнением команд. Для того, чтобы установить модуль PowerShell на шлюз с компьютера разработчика, эти две системы должны быть в одной и той же подсети. Кроме того, этот процесс включает в себя временное сопоставление сетевого диска на компьютере и шлюза. Итак, для удалённой установки модуля нужно выполнить следующие шаги. Для начала – вот список операций, которые нужно произвести на шлюзе для того, чтобы обеспечить удалённый доступ к PowerShell. Если на шлюзе установлена Windows IoT Core, то всё уже готово к работе, ничего больше делать не нужно. Если же шлюз оснащён Windows IoT Enterprise, нужно разрешить удалённое взаимодействие с PowerShell, используя эту и эту инструкции. Например, для того, чтобы включить удалённый доступ к PowerShell, воспользуйтесь нижеприведёнными командами. #Получим индекс NIC активного NIC Get-NetAdapter #$index – это полученный индекс. #Переключим целевое активное соединение в приватный режим. #В качестве разделителя в строке команды используется комбинация пробел + обратная галочка. Set-NetConnectionProfile -InterfaceIndex $index ` -NetworkCategory Private #Включим удалённый доступ Enable-PSRemoting -Force Теперь, когда шлюз готов к работе, займёмся компьютером, выполнив следующие шаги с использованием окружения PowerShell. 1. Убедитесь в том, что две следующих учётных записи, созданные на соответствующих устройствах, имеют административные полномочия. А именно: Учётная запись для компьютера разработчика, с которой осуществлён вход в систему. Учётная запись на шлюзе, которой мы воспользуемся позже. 2. Запустите интерпретатор командной строки PowerShell от имени администратора. 3. Для того, чтобы запустить скрипт ModuleInstallation.ps1 нужно, чтобы в PowerShell использовалась политика выполнения скриптов AllSigned или RemoteSigned. Взгляните на следующие командлеты: Get-ExecutionPolicy и Set-ExecutionPolicy. Они позволяют, соответственно, узнавать и задавать политику выполнения. Например, с помощью такой команды можно задать использование политики RemoteSigned. Set-ExecutionPolicy RemoteSigned 4. Воспользуйтесь точечной нотацией при вызове скрипта ModuleInstallation.ps1. Для того, чтобы это сделать, введите символ точки «.» и пробел перед путём к запускаемому скрипту. Этот подход позволяет запустить скрипт в текущей области действия. . .\ModuleInstallation.ps1 5. Затем взгляните на справку по модулю, о котором мы здесь говорим, ознакомьтесь с примерами его использования. Для этого воспользуйтесь такой командой Get-Help Install-IntelIoTGatewaySetup –Full 6. Выполните команду Install-IntelIoTGatewaySetup для установки модуля с компьютера разработчика на шлюз. Правила использования этой команды можно найти в справочных материалах из предыдущего шага. Например, можно воспользоваться следующей последовательностью действий: #$path это путь к папке, в которой находится загруженный модуль, # например: ‘C:\IntelIoTGatewaySetup’ #$remoteip это IP-адрес удалённого шлюза, #например: ‘192.168.2.5’ #$remoteaccount это учётная запись на шлюзе, #например, ‘Tester’ или ‘Domain\Tester’ #В качестве разделителя в строке команды используется комбинация пробел + обратная галочка. Install-IntelIoTGatewaySetup –ModuleLocalPath $path ` -RemoteGateway $remoteip ` -RemoteAccount $remoteaccount –Verbose Обратите внимание на то, что при локальной установке можно исполнить команду Install-IntelIoTGatewaySetup непосредственно на шлюзе. Для деинсталляции модуля предусмотрена команда Uninstall-IntelToTGatewaySetup. Подробности об этом можно найти в справочных материалах к модулю. 7. После установки воспользуйтесь PowerShell для выполнения команд нашего модуля на шлюзе. Об особенностях использования PowerShell на удалённых системах можно почитать здесь. Например, выполните, по порядку, нижеприведённые команды. Запустите службу WInRM, если она ещё не запущена. if ((Get-Service WinRM).Status.ToString() -ne 'Running') { # Запуск службы WinRM Write-Verbose "Start WinRM service." net start WinRM } Добавьте удалённый шлюз в список TrustedHosts. #Эта команда удалит исходный TrustedHosts и приведет к использованию $remoteip. #Кроме того, она может добавить новое значение к списку TrustedHosts. #Справку можно вызвать командой Get-Help Set-Item. #$remoteip это IP-адрес удалённого шлюза. #В качестве разделителя в строке команды используется комбинация пробел + обратная галочка. Set-Item WSMan:\localhost\Client\TrustedHosts ` -Value $remoteip –Force Создайте удалённую сессию PowerShell на удалённом шлюзе. #$remoteip это IP-адрес удалённого шлюза. #$remoteaccount это учётная запись с административными полномочиями #на удалённом шлюзе. #В качестве разделителя в строке команды используется комбинация пробел + обратная галочка. $s = New-PSSession -ComputerName $remoteip ` -Credential "localhost\$remoteaccount" Выполните эти команды на удалённом шлюзе. #Запустите удалённый скрипт для тестирования Invoke-Command -Session $s -ScriptBlock { #В этом блоке можете запустить желаемые команды PowerShell. #Эти команды будут запущены на удалённом шлюзе. #взглянем на сведения о нашем модуле Get-Command -Module IntelIoTGatewaySetup Get-Module IntelIoTGatewaySetup } Закройте удалённую сессию PowerShell после того, как выполните все необходимые команды. Remove-PSSession -Session $s Использование модуля Здесь мы, так же, как в предыдущем разделе, исходим из предположения, что для работы со шлюзом используется компьютер. Расскажем о том, как пользоваться модулем. Для начала, если вы этого ещё не сделали, включите использование удалённого PowerShell на шлюзе. Теперь, на компьютере разработчика, выполните следующие шаги. Воспользуйтесь той же процедурой, которая описана в п.7 предыдущего раздела. Все следующие примеры рассчитаны на то, что исполняемые на удалённом шлюзе команды будут помещены внутрь блока конструкции Invoke-Command. После установки модуля воспользуйтесь командой Get-Help с параметром –Full для того, чтобы узнать подробности о командах модуля. Например, выполните следующую команду для того, чтобы получить список всех команд, доступных в модуле: Get-Command -Module IntelIoTGatewaySetup Для настройки уровня безопасности служат команды Enable-IoTWinSecurities и Disable-IoTWinSecurities. Они, в свою очередь, вызывают другие команды модулей. Полезно будет взглянуть на справку по ним (Get-Help Enable-IoTWinSecurities –Full). Вот примеры работы с ними. Для того, чтобы включить базовый уровень безопасности («Basic» SKU) и задействовать приведённый в примере пароль восстановления BitLocker, выполните следующие команды. #$RecoveryPW это пароль восстановления для BitLocker, # который вы хотите использовать. #Например: $RecoveryPW = # '099825-222222-607607-626285-132319-115621-083204-229482' #В качестве разделителя в строке команды используется комбинация пробел + обратная галочка. Enable-IoTWinSecurities -SKU "Basic" ` -BitLockerRecoveryPW $RecoveryPW ` -AddPowerShellRemotingFirewallRule -ErrorLog –Verbose Взгляните на сообщения о результатах работы команд для того, чтобы выяснить, нет ли среди них предупреждений или сообщений об ошибках, которые касаются включаемых функций безопасности. Например, предупреждение может содержать рекомендацию о том, что сначала надо перезагрузить систему для того, чтобы завершить установку необходимых средств Windows, а потом снова выполнить команду установки. Для того, чтобы отключить / удалить настройки уровня безопасности, выполните следующую команду: Disable-IoTWinSecurities -ErrorLog -Verbose Отдельные команды, используемые в Enable-IoTWinSecurities и Disable-IoTWinSecurities, можно применять и самостоятельно, для настройки отдельных функций безопасности. Если TPM «не готов к использованию», его, сначала, нужно установить. В противном случае не получится включить BitLocker. Если AppLocker настроен в соответствии с высоким уровнем безопасности («High» SKU), пользователи не смогут использовать PowerShell для добавления новых функций Windows. В соответствии с архитектурой системы, файл DISMHOST.EXE, который используется PowerShell, находится во временной папке, в директории, соответствующей учётной записи пользователя, а этот файл окажется заблокированным. В результате пользователи не смогут использовать наши команды для включения VBS, так как эта команда попытается установить необходимую ей функцию Windows. При выполнении команды Enable-IoTWinSecurities мы сначала выполняем установку VBS. Если нужно установить функции Windows, выполните перезагрузку системы для того, чтобы завершить их установку, а затем снова запустите команду. Для функционирования системы User Mode Code Integrity нам нужно установить ключ реестра для того, чтобы разрешить размещению нашего модуля войти в режим Full Language Mode для Code Integrity Policy. В частности, рассматриваемый здесь модуль, по умолчанию, устанавливается по адресу %Program Files%\WindowsPowerShell\Module. Если это не так, соответствующий ключ реестра нужно настроить самостоятельно. Для этого нужно поместить путь, по которому установлен модуль (например, %Program Files%\WindowsPowerShell\Module) в запись типа REG_MULTI_SZ, которая называется «TestPath» и расположена в разделе реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CI\TRSData. Итоги Сегодня мы рассказали вам о новом средстве для настройки IoT-шлюзов Intel, которые работают под управлением Microsoft Windows. Рассмотренный здесь модуль для PowerShell, IntelIoTGatewaySetup, позволяет взаимодействовать со шлюзами как локально, так и удалённо, а собранные в нём команды помогают упростить и ускорить процедуры настройки шлюзов.

Метки:  

[Перевод] Язык Go, микросервисы и DevOps – хорошая компания?

Суббота, 25 Июня 2016 г. 17:53 + в цитатник
Привет, Хабр! Напоминаем, что все желающие по-прежнему могут приобрести отличную книгу Сэма Ньюмена "Создание микросервисов". Поскольку наши ожидания эта тема более чем оправдала, мы продолжаем искать связанную с ней литературу и не так давно обратили внимание на книгу о программировании микросервисов на языке Go Интересную статью с обоснованием этого подхода мы нашли в блоге Agile Maverick, и ее перевод размещаем под катом. Приятного чтения! Сейчас все говорят о микросервисах и DevOps. Поставьте эти словечки себе в профиль – и вас сразу начнут осаждать рекрутеры. Я побывал в Мюнхене на нескольких интересных митапах по микросервисам, и меня наиболее удивило, что эта тема пользуется наибольшим интересом в сообществах Java и Scala. Удивило потому, что Java и Scala – очень насыщенные языки, в которых есть из чего выбирать. Когда рассуждают о микросервисах, часто говорят, что сервисы должны быть маленькими ради уменьшения сложности и зависимостей при реализации. Но чем насыщеннее язык программирования, тем разнообразнее там зависимости. Это особенно актуально в Java, где наследуется масса кода. Я понимаю микросервисную архитектуру в более целостном ключе. Я бы сказал, что и вся экосистема должна быть проще и компактнее. Реализация – лишь одна сторона медали. Другая сторона – это время исполнения и сопутствующие фреймворки. Здесь мы подходим к теме DevOps – философии, стремящейся увязать друг с другом две эти стороны. Виртуальная машина Java оптимизирована для работы с долгоиграющими приложениями, в ней действует одна из наиболее выверенных и затейливых систем сборки мусора. Используется в боевых условиях уже более 10 лет. Тем не менее, когда мне доводится видеть современные высокодоступные архитектуры – сразу напрашивается вопрос: а нужны ли долгоиграющие приложения для реализации абсолютного большинства существующих сервисов? Приведу пример. Я участвовал в разработке приложения для кодировки видео, и это приложение как назло должно было работать круглосуточно с минимальными задержками. Мы думали, остановиться ли на стабильном языке программирования вроде Java или написать приложение на Go, где использовались бы имеющиеся библиотеки на C для кодирования и декодирования, однако такой проект мог обернуться утечками в памяти. Наконец, мы решили разделить приложение на различные процессы; статический бэкенд почти не изменился, поскольку передавал информацию по практически не изменившемуся протоколу, а еще у нас была функционально богатая клиентская часть, где существовал риск утечек. Обе части использовали разделяемую память. Оказалось, что вариант хороший. Поскольку Go стартует быстро, мы перезапускали клиентскую часть раз в десять секунд. Оказалось, что проблема – не в утечках памяти, а в оперативных обновлениях. За много лет в Java сложилось много нетривиальных решений – например, фреймворк log4j для логирования. На примере контейнерных решений вроде OpenShift можно убедиться, что теперь снова принято работать с stdout и stderr. Нет необходимости внедрять изощренные решения для логирования на уровне языка. Этот пример позволяет судить, как DevOps и новые среды времени выполнения меняют правила игры. Типичный docker-образ на Go docker имеет размер около 15 MB; сравните его с образом для JVM на Java, размер которого — около 300 MB. Разница 1 к 10. Java JVM оптимизирована под экономный расход памяти, но все равно требует примерно в 10 раз больше памяти, чем Go. В Go не так много унаследованных фреймворков, поэтому и зависимостей обычно мало, а код зависимостей входит в состав бинарного файла. Поэтому отпадает необходимость в таких сложных инструментах как Maven. В контейнерной среде релиз нового образа необходим всякий раз, когда меняется одна из зависимостей в цепочке. А значит, на Java Java мы должны обновлять такие контейнеры достаточно часто. Хуже того, зависимости обычно запрятаны где-то глубоко. Java и Scala – это языки для объектно-ориентированного программирования. Но при работе в сравнительно простых предметных областях такие решения кажутся мне довольно затратными. «Гибкий» аспект философии Go позволяет организовать разработку не только не хуже, но и гораздо понятнее. Java известен своим огромным конвейером и множеством инструментов для непрерывной интеграции вроде Jenkins, которые развились вокруг этого конвейера. В Go конвейеры получаются гораздо короче, проще и быстрее – ведь мы получаем бинарные файлы, уже готовые к исполнению. В 1990-е был настоящий бум серверов приложений Java – считалось, что они обеспечат независимость разработки от операционной системы и аппаратного обеспечения. Читая спецификацию JEE, мы также рассчитывали на простоту удаленных взаимодействий и компонент-ориентированную разработку. Когда я вижу контейнер docker, на котором работают Java-приложения, всегда вспоминаю о новой версии EJB. В принципе, стек Java не упростился, но теперь он упакован в контейнер. Такая упаковка даром не дается, поскольку добавляется еще один уровень сложности; вы с ним познакомитесь, как только попробуете отладить сеть такого docker-контейнера. Go docker – вариант для масштабирования сервисов, но сложную среду времени исполнения он не спасает. Если у вас всего один простой сервис, то простые бинарные файлы Go можно выполнять прямо на хосте. Если же речь идет о более сложном приложении, то сервисы можно положить, например, в контейнер и запускать их в PaaS-среде вроде OpenShift. Чтобы протестировать сервис на ноутбуке разработчика, контейнер не нужен, всяческая связанная с ним магия – тоже. Go прост, и обучаешься ему достаточно быстро. Основные концепции Go усваиваются всего за неделю-две. Поэтому новые коллеги могут с успехом изучить реализации сервисов, а разработчики или операторы могут быстрее фиксить баги, не отвлекаясь при этом от основной работы, даже если не они реализовывали эти сервисы. Автономные команды – дело хорошее, но если у вас всего трое коллег, то обеспечить круглосуточную доступность становится реально сложно. Go, где вариантов не так много, помогает быстрее освоиться с решением тем разработчикам, которые сами его не писали. Не требуется углубляться в философию разработки. Разумеется, всегда можно реализовывать сервисы и в более простом стиле на более насыщенных языках, например, на Java или Scala, но в данном случае нужно научиться самоограничению, обсуждать все детали с командой – соответственно, микросервисная архитектура обрастает огромной документацией. Мне кажется, Go идеально подходит для реализации микросервисов. Почему же этот язык так медленно усваивается в сообществе разработчиков? Думаю, просто никто не любит резких изменений. Мы попробовали изменить всего одно измерение в многомерном мире программирования. Это измерение – размер сервиса. По моему опыту, изменить одно измерение еще недостаточно, чтобы пошла эволюция. Поскольку все измерения взаимосвязаны, они влияют друг на друга. Решив упростить приложение, переделав его в виде микросервисов, мы должны также упростить и исполняющую среду, и язык программирования, с которым работаем. Иначе получим лишь новую головную боль – например, придется управлять сразу множеством JVM, которые занимают кучу места в памяти и запускаются довольно медленно. Либо получим множество мелких объектно-ориентированных решений, которые будут распределенными, а значит – более сложными. Наконец, мы просто запутаемся со множеством сервисов, образующих огромное дерево зависимостей. По-моему, не меняя всех измерений сразу, мы словно пересаживаемся с лошади на машину, но берем с собой седло и шпоры. Давайте не просто писать микросервисы, но и адаптировать под них всю архитектуру. Go отлично для этого подходит. Если предметная область сервиса расширится, вы всегда сможете дополнительно воспользоваться Java или Scala.

Метки:  

[Из песочницы] Тестирование. Ошибки при сертификации или ISTQB мне очень нужен

Суббота, 25 Июня 2016 г. 14:45 + в цитатник
Статья полезна тем, кому небезразлична их квалификация и хочется стать лучше. Учиться никогда не поздно. Любой тестировщик рано или поздно задумывается о качестве не только в рабочем процессе, но и в отношении себя, качестве своего образования и способностей. В данный момент далеко не все вузы способны подготовить такого специалиста. Остаются всяческие курсы, как правило, дистанционные, чтобы была возможность поучиться у людей из этой же области, добившихся успеха. Но есть и ещё один способ самоутвердиться. Это сертификаты. Их много, перечислять, смысла нет. Но практически во всех областях они есть и их получение, скорее плюс, чем минус. Мне бы хотелось написать о ISTQB, т.н. International Software Testing Qualifications Board. Это признанная во всём мире сертификация для тестировщика. Если ты такое получил, то по идее владеешь базовыми знаниями и теорией, то есть и плюсик тебе на собеседованиях добыть можешь, и в общем самоутверждаешься. В статье я бы поговорила об ошибках. О глупых и не очень. О тех, которые я лично совершила в таком тесте или могла. И не хотела бы, чтобы кто-то тоже так попался. Исчерпывающее тестирование Хотелось бы для начала, чтобы запомнили следующее, “исчерпывающее тестирование невозможно, независимо от того, сколько усилий затрачено на тестирование (т.н. Принцип # 2)”. Этот принцип запомнить придется. Много ссылок на материалы для подготовки кидать не буду, одну приведу в конце статьи. Пункт, в котором засомневалась я, был “При достаточных усилиях и инструментальной поддержке исчерпывающее тестирование возможно для любого программного обеспечения". Первые мысли были о том, что терпение и труд всё перетрут. Это верно только для тривиальных ситуаций, в любой реальной системе предусмотреть все ситуации не сможем, остается только свести к минимуму количество проблем. Стадии и задачи Информация для запоминания. Основной процесс тестирования можно поделить на этапы, направления деятельности: Планирование (Этап 1) Анализ и проектирование (Этап 2) Внедрение и реализация (Этап 3) Оценка критериев выхода и создание отчетов (Этап 4) Действия по завершению тестов (Этап 5) Эти все этапы стоит знать. Они выделены не случайно, все имеют особенности. Но это не значит, что они не могут накладываться друг на друга или происходить одновременно в конкретной ситуации. Вопрос, с которым я столкнулась, по сути, был таким, какие задачи мы выполняем на этапе анализа и проектирования. Были разные варианты ответов. Определение целей тестирования Рецензирование базиса тестирования Создание тестовых наборов из тестовых процедур Анализ накопленного опыта для улучшения процесса Ухватившись за слово проектирование, я предположила, что именно на этом этапе проектируются все тест планы, поэтому создание процедур и тестовых наборов казалось отличным ответом. Как я была не права. Поэтому кратко рассмотрю все этапы, чтобы прочитав мою статью можно было не читать огромные мануалы. Специально пронумеровала этапы для ссылки на каждый. Итак, этап номер 1, планирование. На этом этапе самое важное определить цель тестирования и описать для себя (или лицу вышестоящему) задачи, которые эту цель помогут достичь. Тут и объём, и риски, и подходы, и люди. Этот этап так же включает ещё и управление тестированием. Мы не только план составили, но и на протяжении всего процесса следим, что он выполняется, задача за задачей. Таким образом, не только ставили задачи, но и занимаемся их мониторингом. На втором — мы анализируем и занимаемся проектом. Что в это входит? Как раз рецензирование базиса тестирования. В него входит требования на целостность проекта, отчет об анализе рисков, архитектура, дизайн, тех. требования к интерфейсу. На этом этапе, по сути, составляем отчеты о рисках, оцениваем характеристики, расставляем приоритеты, у проекта вырисовывается архитектура. Выбираем тестовое окружение и устанавливаем все инструменты. Как раз на третьем этапе даётся воля для написания тестовых сценариев, тут же выполняется вся самая ответственная работа для выполнения их в ручном или автоматическом режиме. Этап внедрения и реализации я бы хотела отнести к самым главным в жизни тестировщика, в нем без сомнения проведётся больше всего времени, больше всего будет найдено проблем, которые, как не прискорбно признавать, нас воодушевляют для дальнейшей работы. На четвертом этапе в основном занимаемся отчетом, оцениваем характеристики, какие можем, смотрим найденные баги, анализируем какие бы ещё тесты могли бы провести, всё это формируем в отчет для заинтересованных лиц. И наконец, пятый этап, это скорее набор опыта. Смотрим, какие результаты мы получили, какие цели смогли достичь, анализируем данные для будущих релизов и используем дальше. На этом этапе тоже не обойтись без документации, которую надо сделать детально, чтобы отдать на этап сопровождения. Тестирование в период сопровождения В чём была моя ошибка, я предположила, что на этом этапе можно заниматься разбором жалоб по системе во время приёмочных процедур. И эта основная задача. На самом деле, к тестированию в период сопровождения относится работа системы после изменения окружения. То есть к этому пункту относится влияние этих изменений на действующую систему или какие-то дополнительные модификации. Например, смена платформы. Что будет являться тестированием сопровождения? Все эксплуатационные тесты, тестирование изменений, стоит так же добавить в список планов регрессионное тестирование тех областей, которые при этом не были затронуты. При этом основная проблема — это границы области, которую стоит включить в тестирование. Если позволяет время и ресурсы, то стоит включить их все. Но на это времени хватает далеко не всегда. Поэтому для принятия решения придется оценить риск и соотношение размера системы к размеру внесенных изменений. Системное и компонентное тестирование Главное помнить, что компонентное тестирование обычно является ответственностью разработчиков, в то время как системное тестирование — типичная ответственность тестировщиков. При компонентном тестировании занимаемся всё тем же поиском дефектов, только в разных кусочках системы, насколько возможно систему на эти части поделить. Важно, чтобы каждую из таких частей можно было тестировать изолированно. Есть множество способов и подходов, но это слишком широкая тема, которая уведет от самой сути, от разницы между видами тестирования. Ещё одной особенностью компонентного тестирования является то, что оно включает не только тестирование функциональное, но и проверяются нефункциональные характеристики. Например, к таким относится тестирование поведения ресурсов, отслеживаются утечки памяти. Как правило, при компонентном тестировании доступен код. Противоположным тестированием является системное. Если в компонентном мы рассматривали каждую часть, как отдельную, то тут мы смотрим на систему, как на единый объект. При тестах применяем множество методов, и исследуем как функциональные, так и не функциональные требования. Тут уже подходят для исследования тестовые описания, варианты использования системы и прочие всевозможные способы поиска багов, но сама система рассматривается в виде “черного ящика” без доступа к коду. Формальное рецензирование и его шаги Когда для системы сформировано множество требований к коду, требований к входным данных, какие-то юридические моменты должны быть учтены, и прочее, и прочее, то как этап тестированию добавляется рецензирование. По сути есть список, что мы должны учесть для завершения каждого модуля в системе. Возможно, что в этом процессе придется прибегать к экспертам в нужной нам области. Основные фазы формального рецензирования — это планирование, старт, индивидуальная подготовка, изучение/оценка/запись результатов, повторная обработка, отслеживание. Этапы на самом-то деле все последовательные и логичные. Спланировали, какие критерии нужны, и выбрали людей, при запуске поделились со всем своими планами, подготовились индивидуально, учитывая все особенности и требования именно этой системы. Далее получили результаты, которые показали нашим экспертам, и все проблемы, что всплывали, поправили. И дальше следим, чтобы нигде ничего не нарушалось. Заключение Данный материал не создан, чтобы решить все вопросы, связанные с предстоящей сертификацией. Надеюсь, хотя бы то немногое, что я успела осветить, уложится в голове наверняка. Если хоть в какой-то мере статья была полезна, то могу продолжить разбор самых, на мой взгляд, неочевидных ошибок, которых было просто избежать. Всегда готова к конструктивной критике. Если возникнут вопросы или в моих утверждениях найдется предмет для дискуссии, будет повод лишний раз вернуться к теории. Полезные ссылки Материалы для подготовки Хорошая статья о тестировании от Натальи Руколь

Метки:  

Учимся на ошибках в организации контроля качества

Пятница, 24 Июня 2016 г. 19:59 + в цитатник
Привет, Хабр! Меня зовут Илья Кудинов, и я работаю QA-инженером в компании Badoo. Три года назад я начал посещать различные IT-конференции и рассказывать о процессах и технологиях, применяемых нами при контроле качества. И конечно же, после каждого доклада я общался со слушателями, интересовался, как работают они. В этом деле меня всегда мотивировали отзывы вида «Раньше мы работали вот так, но, послушав твой доклад, мы увидели, как можно сделать лучше», а еще лучше — когда люди не копируют наши приемы, а придумывают что-то сами, иногда даже более интересные варианты. Таких историй у меня накопилось много, и я хочу поделиться с вами некоторыми из них (все имена и названия вымышлены, любые совпадения с реальными лицами являются случайностью). Может быть, что-то из этого поможет вам увидеть направление развития вашего собственного проекта — и это будет самой большой наградой для меня! Разумеется, буду рад после этого выслушать и ваши истории — в комментариях или личных сообщениях. Прежде всего давайте оговорим два момента. Первое: не для всех видов и масштабов разработки советы из этой статьи окажутся подходящими (для некоторых, я уверен, они будут даже очень вредными), поэтому для представителей разработчиков софта самолётов (а так же для тех гуру тестирования, кому мои советы кажутся очевидными) этот рассказ будет просто занимательным чтивом. Я в первую очередь ориентируюсь на быстроразвивающиеся продукты с плотным графиком релизов. Интереснее всего будет представителям тех компаний, где QA-отдел существует только в зародыше или пока не существует вообще. Второе: нет, «грустные» истории не выдуманы. И нет, они, возможно, не так ужасны в действии, как я их описываю, но свое мнение я буду стараться всегда максимально аргументировать. Визуализации мыслей и идей будут помогать вот эти три товарища, знакомьтесь: Итак, давайте начнем с того, что определимся, кто же мы, собственно такие. QA-инженеры? Тестировщики? Тестеры? Тестер — это такой прибор, использующийся для замера электрических характеристик цепи. Не надо нас так называть, мы обижаемся. Тестировщик — специалист, занимающийся тестированием. Тестирование — важный и незаменимый процесс при разработке чего бы то ни было, но в него входит исключительно процесс помещения системы в различные ситуации с целью изучения ее поведения и верификации поставленных на тестирование задач. QA-инженер — специалист, занимающийся контролем качества. В это понятие входят как тестирование, так и, например, последующий мониторинг, разработка и поддержка различных автотестов и прочих средств автоматизации и оптимизации процесса, релиз-инжиниринг. Впрочем, с целью упрощения речи, «тестировщик» тоже сойдет, но только если вы говорите это с должным уважением. Я гордо говорю, что я QA-инженер. Моя работа (и работа моих коллег как по компании, так и по сфере вообще) направлена на обеспечение максимально достижимого качества продукта — на то, в чем в любом случае заинтересованы все остальные участвующие в проекте стороны. Именно поэтому мне очень жаль, что во многих компаниях мои собратья зачастую рассматриваются как сугубо вспомогательный персонал, роль которого в проекте самая незначительная (уборщики хотя бы грязные кружки из-под кофе убирают за разработчиками). На самом деле роль тестировщика в проекте в конечном счете является ничуть не менее важной, чем роль разработчика. Бьёрн Страуструп (дат. Bjarne Stroustrup) в своей книге «Язык программирования C++» писал: «Программа, которая не прошла тестирование, не работает». Зачем вам нужны программисты, продукты которых никогда не будут работать? Тестировщик — не раб разработчика, великодушно выдающего задачи типа «проверь, пока я раскладываю на прод». Наоборот, разработчик и тестировщик совместными усилиями достигают поставленной цели — выпустить продукт к назначенному сроку в максимально высоком качестве. Именно для этого и создается отдел контроля качества. Но… как его организовать? QA-отдел Итак, компания «ФОЛИАНТ ЛИЦ» решила заниматься разработкой программного обеспечения. Она подошла к этому делу основательно, даже отважилась на создание QA-отдела! Сколько нужно набрать туда людей, если у нас уже есть 12 разработчиков? Классический подход подсказывает, что приблизительное соотношение рабочей силы должно быть таким: 1 QA-инженер на 3-4 разработчиков. Сказано — сделано! Нанимаем трех инженеров и считаем себя большими молодцами. Проект начинает развиваться, к QA-отделу предъявляются все новые и новые требования. Вот мы уже достаточно повзрослели, чтобы производить релизы не просто выкладкой gzip-архива на продакшен, а путем хорошо построенного и налаженного деплой-процесса. Кто будет этим заниматься? Отдадим это нашему специалисту в отдел контроля качества! Функционала становится все больше — тестировать регрессию все сложнее. Один из наших тестировщиков имеет опыт разработки? Отлично! Пусть он теперь занимается разработкой автотестов! Хорошо мы придумали, да? Что мы получили в итоге такого замечательного плана? Тестированием задач наших двенадцати разработчиков постоянно теперь занимается только один из QA-инженеров. Интересно, почему очередь на тестирование начала расти и наши отлично организованные релизы регулярно задерживаются? Урок: рассчитывая количество специалистов для QA-отдела, нужно принимать во внимание все сферы деятельности, которыми они будут заниматься помимо непосредственного тестирования, и нанимать при необходимости новые кадры, а не распределять новые обязанности между имеющимися. Разве не это подсказывает здравый смысл? Практика показывает, что не всегда. Смотрите, другая маленькая компания — «ЩЕБЕТАЛКА»! И у нее очень большие и серьезные планы. Начинают они с малого: четыре разработчика, пара менеджеров и один (очень гордый) тестировщик. Время проходит, бизнес идет в гору, количество заказов на разработку все увеличивается и увеличивается. Счастливые и довольные результатом руководители проекта объявляют расширение штата. Для начала наймем еще одного продакт-менеджера, пусть генерирует больше взрывных идей. Запросов на новые фичи становится все больше? Срочно набираем новых разработчиков! Ого, больше пользователей? Больше прибыли? Ребята, мы идем верной дорогой — нанимаем еще разработчиков, пусть засыпят наш проект фичами! Как же это все здорово! Но что же это? Почему стало больше багов? Почему пользователи недовольны? Мы ведь наняли больше людей, почему мы отстаем от графиков? Ах, наш несчастный тестировщик, мы совсем про него забыли! Урок: отдел контроля качества стоит развивать параллельно отделу разработки. Возможно, даже с опережением. Сложно бороться с конкурентами и доставлять пользователям новаторский функционал, если вы не можете обеспечить проекту должное качество. А вот у компании «ТЫНДУКС» все процессы уже давно поставлены. У нее немаленький отдел разработки и вполне соответствующий ему отдел тестирования. Разработчики и QA-инженеры сидят в разных помещениях, разделенных большим холлом, и недобро переглядываются через щели приоткрытых дверей. Завершив работу над задачей, разработчик со всей злостью, доступной при нажатии на кнопку Assign в Jira, кидает задачку на тестирование. Тестировщик недоверчиво смотрит на задачку, с отвращением открывает ее и спустя несколько секунд с достойной зависти яростью возвращает задачу на доработку с пояснением: «У вас опечатка в комментарии!» Казалось бы, при таком рвении к работе качество должно быть на высоте. Наверное, оно там и есть. Но мы этого никогда не узнаем, потому что при таком подходе задача доберется до продакшена примерно… никогда. Урок: отделы тестирования и разработки — не враги друг другу. Они не должны сидеть по разные стороны укрепрайонов, стараясь при первой же возможности свалить работу друг на друга. Как я уже говорил, их совместная цель — релиз задачи в поставленный срок, и их обязанностью является объединение усилий для достижения этой цели. Это вовсе не значит, что нужно закрывать глаза на ошибки: просто после обнаружения незначительного дефекта не обязательно сразу же отправлять задачу на доработку, вполне можно записать ее в сторонку, проверить, насколько это возможно, и отправить уже с полным списком ошибок, чтобы сэкономить горы времени на постоянно повторяющихся этапах разработки и тестирования. Здесь стоит заметить, что в некоторых случаях подобный подход все же уместен. В «промышленной» разработке (например, при поддержке софта использующегося на самолетах) качество и соответствие процессам может ставиться выше скорости, и это правильно. Наверное, я бы не хотел летать на самолетах, тестируемых и разрабатываемых работниками небольших «ультрасовременных и быстроразвивающихся» стартапов. QA-процесс И вот QA-отдел организован. Чем он будет заниматься? Правильно, контролем качества. Но как это процесс будет устроен? Любые QA-процессы всегда строятся вокруг балансирования между качеством и скоростью. Абсолютное качество недостижимо (если вы со мной будете спорить — надеюсь, вы разрабатываете самолеты), тестировать задачи мгновенно тоже невозможно. Где же найти это равновесие? Здесь каждая команда может придумать свое решение. Для кого-то это Continious Integration, кто-то отдает предпочтение строго регламентированным и спланированным релизам — и нельзя просто подсмотреть процессы, поставленные вашими соседями по гаражу. Как QA-процессы встраиваются в процессы развития проекта? Давайте поделим их на три этапа: продакт-дизайн, разработка и тестирование. Два молодых стартапа подошли к этому вопросу совершенно по-разному: компания «БОДУНЫ» плотно связала QA-инженеров с каждым из них, а «ПОЧТИ.РУ» оставила им только тестирование. Кто из них прав? Как говорится, истина может быть где-то посередине. Что мы получаем с каждым новым этапом QA-процесса? Качество. Что мы при этом теряем? Скорость. Какими же этапами контроля качества можно жертвовать? Тестированием? НЕТ. Контролем качества при разработке? Звучит важно. Нет, конечно не нужно чтобы тестировщик сидел за плечом у разработчика и больно щипал его каждый раз, когда тот забывает поставить точку с запятой. Есть много других способов помочь разработчикам соблюдать определенный уровень качества. Удачно настроенная система контроля версий, различные хуки и скрипты для проверки корректности кода, написание юнит-тестов (здесь, правда, QA может выступать только в роли надзирателя с кнутом и пряником), удобная система code review — все это в области ответственности отдела контроля качества. Контролем продакт-дизайна? Ну… В «промышленной» разработке существует целое направление контроля качества — тестирование и анализ ТЗ. Это помогает избежать логических и архитектурных ошибок на начальных этапах развития каждого проекта — и катастрофически отдаляет возможность начала разработки. Наверное, в молодом стартапе это излишние предосторожности. Высокая интеграция различных отделов друг с другом позволит всем участникам проекта (и разработчикам, и тестировщикам) увидеть подробности проекта, определить шероховатости и донести до менеджмента полезные (и не очень) идеи. К тому же, в нашем мире динамичных проектов и Agile-методологий ТЗ зачастую изменяется уже во время разработки (и даже после релиза, в конце концов), так что имеет смысл позволить продакт-менеджерам выражать себя бесконтрольно и уже потом вносить свои предложения и поправки. Урок: контроль качества на каждом этапе развития проекта положительно влияет на качество и катастрофически понижает скорость. Нужно строить процессы так, чтобы они соответствовали требованиям к вашему проекту, и не копировать бездумно чужие практики и статьи из книжек (и из Хабра, да-да). Смотрите, разработчик компании «БУБЛ» отдал свою задачу на тестирование и абсолютно уверен, что увидит ее снова только в случае возврата на доработку. И что же, в этапе тестирования участвуют только QA-инженеры? Вовсе не обязательно. Конечно, при обнаружении каждой неясности можно сразу же возвращать задачку, но это вполне может оказаться обычным недопониманием, а задача при этом повиснет в каких-то промежуточных статусах. Поэтому (и не только поэтому, конечно) общение и взаимодействие в процессе тестирования — бесценно. В случае обнаружения странных и непонятных моментов всегда можно сесть вместе с разработчиком и попробовать разобраться. С одной стороны, если это поведение ошибкой не является, то можно разобраться в алгоритме и избежать всех задержек с переходом статуса. А если это оказывается неожиданной ошибкой, то подобное изучение может помочь разработчику решить проблему с ходу, а не добраться до переоткрытой задачи спустя несколько дней и пытаться с нуля сообразить, что же там происходило. Урок: не стоит возвращать задачку при первом же непонятном моменте. Совместный с разработчиком дебаг — не только полезный и эффективный процесс, но и зачастую поучительное (оба участника могут глубже вникнуть в происходящее) и веселое занятие. В компании «НАЛИНИИ» прекрасно построен процесс разработки. У разработчиков есть полный набор инструментов для оптимизации процессов разработки и упрощения распределения работы. Они пользуются системами проджект-менеджмента и системами контроля версий: никто друг другу не мешает и вся их работа всегда в целостности и сохранности. А вот у их отдела контроля качества все давно не так безоблачно. Исторически сложилось так, что релизы на тестирование отправлялись им в качестве архивов, вложенных в почту. Ну, кто-то когда-то так придумал, и все привыкли. Они пишут свою документацию на бессчетных бумажках, разбросанных по всему отделу (некоторые особо хитрые инженеры завели самый настоящий совместный Google Doc, но очень боятся, что их рано или поздно поймают и заставят все переписать на бумажки). Очень жаль, что никто не может проявить инициативу и попробовать объединить используемые технические средства! Ведь можно было бы использовать общие репозитории, общие базы знаний, интегрировать друг в друга системы баг-трекинга, сборки приложений и сделать все таким красивым, автоматизированным и целостным… Но нет, к сожалению, разработчикам пришлось бы для этого отвыкать от привычного flow и даже (!) разрабатывать и настраивать что-то новое. Но нет, письмами как-то сподручнее… Урок: нужно стараться максимально интегрировать процессы и инструментарий отделов разработки и тестирования. Это поможет обоим отделам и проекту в целом. Иногда это требует небольших жертв от всех участвующих, но в конечном счете позволяет добиться куда больших успехов. Тестировщики компании «КРУПНОЖЕСТЬ» всегда работают по строгим тест-кейсам. Запрещена любая свобода действий — и не дай бог кто-то позволит себе пропустить хоть один пункт в тест-плане! Отсутствующая галочка в чек-листе равносильна преступлению и карается чтением «Войны и Мира» вслух перед всем отделом. Отдельные инженеры целыми днями занимались исключительно поддержкой этой документации, а каждый тестировщик был обязан составлять кейсы для каждого затронутого им функционала. Конечно, качество было на высоте! Поначалу… Выяснилось, что на продакшене начали появляться баги. Баги на продакшене, Карл! При проверке чек-листов выяснилось, что этот функционал проверялся, и ответственный тестировщик с самым невинным видом активно кивает головой: проверял, проверял! А затем выяснилось, что некоторые компоненты продукта не проверялись уже годами просто потому, что они не нашли себе места в тест-документах. Руководителя отдела заставили писать отчет и объяснительную относительно происходящего в четырех томах с оглавлением. Наверное, было бы лучше, если бы тестировщики при работе думали своей головой, а не следовали строгим инструкциям. Имели бы общий источник информации, но не в виде «Что делать», а в виде «Как это работает». Конечно, это может отрицательно повлиять на скорость тестирования, ведь каждый раз будет необходимо исследовать фичу или (не дай бог!) общаться с другими тестировщиками и (!) разработчиками, чтобы понять, что надо бы тут проверять. Урок: общая документация, позволяющая определить, что стоит тестировать в той или иной задаче — хорошо. Подробные инструкции и кейсы… наверное, не очень. (разработчики самолетов — забудьте, что сейчас прочитали. ПОЖАЛУЙСТА!) В компании «ПРИНТЕЛ» очень ценят разделение труда. Каждый тестировщик привязан к тому или иному функционалу и компоненту — и он прекрасно знает, что и как имеет смысл в нем тестировать. Качество и скорость на высоте, компания идет к успеху. А потом один из QA-инженеров выигрывает в лотерею и уезжает жить на Канары. Оставшиеся переглянулись и попробовали разобраться в том, что он за собой оставил. Никто ничего не понял, и тестировали кое-как, пока не был найден новый инженер на место счастливчика. Все вздохнули от облегчения…Пока не выяснилось, что в мечтах уехавший был врачом и все его записи велись немного непонятным почерком. Разработка компонента встала почти целиком до тех пор, пока новичок не смог освоиться в нем с нуля. Урок: имеет смысл иметь практику обмена знаниями внутри QA-отдела. Можно периодически обмениваться задачами, чтобы не привыкать к одному компоненту (одно из плохих последствий такой «специализации» — «замыливающийся» глаз), можно проводить внутренние семинары и лекции, на которых специалисты расскажут о новшествах в своей сфере ответственности, интересных кейсах и технологиях: это приведет не только к взаимозаменяемости специалистов, но профессиональному росту каждого из них. QA-инженер компании «КРАБЫРАДЫ» наконец-то закончил работу над сложной системной задачей, на которую он потратил не один рабочий день. Он проследил за ее отправкой на продакшн, вздохнул свободно и отправился пить пиво с друзьями. Правильно ли он поступает? Я так не думаю. Даже если у его компании есть серьезный отдел мониторинга, круглосуточно красными глазами наблюдающий за десятками и сотнями графиков и метрик, ему может потребоваться немало времени, чтобы локализовать внезапно возникшую из ниоткуда ошибку или падение активности. Вот было бы здорово, если бы кто-то мог им помочь или даже просто не допустить того, чтоб им пришлось искать причины этого беспорядка… А ведь тот самый инженер мог выпить сегодня всего на одну пинту «Гиннеса» меньше, зато спасти немало человеко-часов (и, возможно, денег компании), если бы потратил какое-то время на изучение поведения продакшена после релиза. Изучить логи ошибок, проверить тренды тех графиков, которые описывают состояние затронутых в задаче компонентов. Да, иногда баги добираются до продакшена. Виной тому может быть человеческий фактор, различия в окружении или даже просто одна из тех миллионов user story, которые генерируют настоящие пользователи. Урок: QA-процесс не прекращается сразу же после релиза задачи на продакшен. Всегда имеет смысл последить за поведением нового функционала, и крайне важно иметь инструменты, которые это позволяют. Тестировщик компании «ЯБЛОЧКО» впервые в жизни пропустил на продакшен досадный баг. Наверное, он мог его обнаружить, если бы потратил на это еще пару часов, но это уже случилось. Баг починили, но он успел затронуть пользователей. Компания очень недовольна тестировщиком. Разработчик фичи недоволен тестировщиком. Он получает взыскание и лишается премии, чтобы неповадно было и в дальнейшем не щадил себя при тестировании. Правильно ли поступила компания? Я думаю, что нет. QA-процессы не отменяют возможность появления дефектов — они направлены на понижение вероятности их возникновения. И в этих процессах участвуют все затронутые в проекте люди. И ответственность за дефекты в равной степени ложится на всех: на руководителя, который недостаточно замотивировал и обучил своих сотрудников; на разработчика, который допустил ошибку; на тестировщика, который эту ошибку пропустил. Даже на тех инженеров, которые покрывали этот функционал автотестами — ведь их тесты могли поймать этот баг, но не смогли! Стоит ли их наказывать? Возможно, но только при системных проколах. Гораздо полезнее будет провести глубокое изучение причин произошедшего, организовать образовательные семинары и все возможные мероприятия, для того чтобы понизить вероятность возникновения подобных дефектов в будущем. Урок: в возникновении дефектов виноваты все участвующие в проекте стороны, не стоит обвинять в его возникновении только тестировщика. Автоматизация В компании «СЦОННИ» приняли решение начать разработку автоматизированных тестов. Один из тестировщиков имеет навыки программирования, и эту задачу отдали ему. Он писал тесты, был доволен своей работой и в какой-то момент покрыл тестами почти весь продукт. Все были рады, пока не заметили, что ушедшему в другой проект тестировщику не стали искать замену. Событие превратилось в тенденцию, и QA-отдел начал таять. Когда перепуганные инженеры прибежали к руководству, то с улыбкой ответило: «У нас теперь такие замечательные автотесты, зачем нам скучные несовременные ручные тестировщики?» Объяснить им ничего не получилось, и все осталось на своих местах. Дела шли хорошо до тех пор, пока на продакшене не стало появляться все больше и больше ошибок, и все они — в самом новом, еще не покрытом тестами функционалом. Руководство осознало свою ошибку, но было уже слишком поздно… *громкая драматическая музыка* Урок: автотесты являются исключительно вспомогательным средством контроля качества и никоим образом не заменяют собой ручное тестирование. А вот в компании «ШАНТСУНГ» такой проблемы не испытывали. Их отдел автоматизации тестирования был полностью отделен от отдела ручного тестирования. «Автоматизаторы» даже чувствовали себя представителями какой-то более высокой касты и снисходительно наблюдали за теми, кого они называли «ручниками». И было такое разделение, казалось, удобно всем, пока не стали возникать проблемы. «Автоматизаторы» стали так глубоко погружены в поддержку сотен своих тестов, что потеряли всякую возможность разрабатывать что-то новое (и соблюдать поставленные KPI, конечно), а «ручники» совершенно не представляли, что там происходит у их коллег, и перестали полагаться на тесты, проверяя вручную все то, что было тестами вполне покрыто (но про это никто не знал!), и это существенно уменьшило пользу от всего мероприятия. Урок: гораздо лучше, когда с автотестами работают все представители QA-отдела. Пусть не все из них будут в состоянии написать тест с нуля, но сделать так, чтобы каждый инженер мог оценить состояние тестов в данный момент, понять причину их провалов, поправить простенькую ошибку или покрыть тестом новый несложный кейс, стоит. Вместо послесловия Надеюсь, что-то из того, о чем я многословно писал, окажется для вас полезным. Кому-то поможет найти шероховатости в процессах, другим подскажет выход из уже изучаемой проблемы. Даже если и не так, может, вы хотя бы посмеялись над тем, что я вам рассказал. Или хотя бы над моей наивностью. Главное — сделать мир лучше хоть в чем-то, хоть немножко. Правда?

Метки:  

[Перевод] Readme Driven Development

Четверг, 23 Июня 2016 г. 19:36 + в цитатник
RDD — это крайне простая практика. И здесь «DD» может означать «минута на освоение и вся жизнь для мастерства». Но, к счастью, не в этом случае. Пишите Readme в первую очередь. Вот в принципе и все. Но почему? Всякий раз, когда вы начинаете программный проект, будь то ваш личный проект или принадлежащий компании на которую вы работаете. Вы должны (по возможности) стремиться писать понятный, поддерживаемый код, который можно использовать многократно. У каждого есть своя точка зрения о том какие инструменты, практики и процессы способствуют улучшению программного обеспечения. В конце дня ваша программа по-прежнему должна работать. Это легко забыть, если слишком сильно сосредоточиться на том, чтобы закончить её или использовать все красивые решения. Работа программы это не только о её код. Если никто не может использовать программу, потому что не знает как, то не важно содержит ли она кучу ошибок или не содержит ни одной. Скромняга Readme Readme — это самый важный файл во всем проекте. Он должен содержать краткий обзор задач проекта (его назначение, зачем он создан), инструкции по установке, известные проблемы и достаточно подробное описание того, что нужно сделать чтобы быстро начать пользоваться программой, для тех людей, которые никогда до этого не пользовались вашим программным обеспечением. Не поймите меня неправильно, Readme это не вся документация которая только может вам понадобится. Однако, вы можете удивиться, узнав, что небольшой Readme охватывает подавляющее большинство проблем и вопросов, тех людей, которые его читают. Если вы напишете свой Readme, до того как приступить к написанию кода, вы получите несколько крутых преимуществ: Вы получите полный обзор того, какую функциональность вы должны реализовать, и как вы можете её обеспечить с помощью публичного API. В этот момент, до того как вы начали писать код, вы можете легко менять архитектуру проекта. Когда вы начнёте писать код, вы будете иметь чёткое представление, что и как именно должно быть реализовано. Readme также может выступать в качестве индикатора для вас самих и других людей о прогрессе в разработке проекта. Если вы работаете в команде с другими разработчиками, у вас будет почти идеальная спецификация. И другие разработчики смогут подключаться к проекту с меньшим страхом того, что спецификация может измениться в процессе разработки. Обсуждения очень важны. И гораздо легче обсуждать, то что записано. Легче изменить Readme чем бесконечно спорить о том, как что-то должно работать, когда и если вы до него доберётесь. Как правило, наиболее активная и захватывающая часть проекта в начале. Это лучшее время, чтобы написать небольшой объем документации, который впоследствии будет служить Вам и другим людям. Позже написание документации всегда затягивается и я очень удивлюсь, если в итоге, вы будете помнить все детали реализации и известные проблемы. Изменяются даже самые продуманные проекты, надеюсь, что эти изменения будут происходить не из-за каких-либо проблем. а для добавления новой функциональности. Но они все равно неизбежны и как правило происходят путем развития. Единственный документ (надеюсь, в системе контроля версий) может выступать идеальной средой для связи между изменениями по мере того, как они происходят. Также стоит отметить, что записывать изменения по мере того как они происходят гораздо проще, чем пытаться вспомнить их все потом. Добавление RDD в существующий проект требует отдельной статьи. Но на данный момент, надеюсь, у вас появилась пища для размышлений.

Telegram бот для службы поддержки (часть 1)

Вторник, 21 Июня 2016 г. 20:08 + в цитатник
В этом цикле статей мы реализуем службу поддержки для онлайн-чатов. Система должна уведомлять команду операторов о новом сообщении, делить нагрузку на команду любого размера, делегировать сообщения в зависимости от приоритета. Звучит жутко. Но без паники, я поделюсь нашим опытом построения такой системы, которая уместилась всего в пару сотен строк кода. Да, мы будем использовать Telegram-бота. Но не потому, что это модно, а потому что супер удобно. Всё началось с того, как мы захотели делать мобильное приложение, где люди могут писать любой вопрос в чаты заведений вокруг и получить быстрый ответ. Сделать чат — не проблема. Но что если мы хотим получать уведомления о новых сообщениях в real-time, для мгновенного ответа пользователю? В первой части статьи я покажу на тестовом примере, как можно управлять системой службы поддержки через чат-бота, почему это очень простой и удобный способ. А во второй части статьи мы реализуем этот пример на Python. Проблема и решение Любая команда операторов службы поддержки должна отвечать на запросы оперативно, для этого её нужно оперативно уведомлять. Нет нужды придумывать что-то своё — любой современный мессенджер справится с этой задачей на ура. Я выбрал Telegram. Он удобен, работает на всех основных платформах, а функционал ботов опережает даже титанов рынка мессенджеров как минимум на год. К чему это я про ботов? В нашем случае, бот представляет собой информационный канал, к которому легко можно подключать людей, с которым можно взаимодествовать текстовыми командами. После того, как мы создали бота, подключить к нему людей легко, достаточно кинуть им ссылку. Однако, наш бот исключительно для внутреннего использования. Нельзя допустить, чтобы кто угодно мог получить доступ по этой ссылке. Ссылку мы прятать надёжно не можем, а вот включать функционал специальной командой с подтверждением пароля — запросто. Telegram бот позволяет задавать для бота свои текстовые команды. Делаем так: создадим команду "/on" которая «включает» функционал бота для пользователя. Но только после подтверждения паролем! Ну и на всякий случай можно предусмотреть команду "/off", которая отключает функционал. Теперь наш бот знает группу людей — операторов службы поддержки. Пока что представим, что группа операторов у нас всего одна, каждый вопрос от клиента очень важен, поэтому будем рассылать уведомления всей группе. В этом нет никакой магии, конечно Telegram имеет апи для рассылки сообщений людям, подключившимся к нашему боту. Теперь каждый член команды операторов получит уведомление. В текст сообщения можно вставить ссылку, по которой можно ответить клиенту. Например, это может быть ссылка на веб-версию чата, через который вы осуществляете поддержку. Система, которую мы разработали, работает корректно, когда оператор службы поддержки один. Безусловно, мы можем рассылать уведомления любому количеству людей. Но как понять, что кто-то уже отвечает на запрос клиента? Как распределять нагрузку, чтобы не возникло путаницы? Это мы будем делать в следующей статье с помощью… кнопок в чате. Не так давно Telegram опубликовал Bot Api 2.0. Теперь стало возможным добавлять кнопки к сообщениям и отслеживать нажатия на них пользователей. Чем мы и займёмся в следующей статье. Ну и скриншот для превью того, что мы будем делать. Реализация Всё необходимое для создания бота можно почитать в документации. После того, как мы создали бота, приступаем к коду. Будем использовать Python библиотеку — обёртку Telegram API. Она позволяет писать обработку сообщений в обычных функциях с декораторами, что довольно удобно. Полный код нашего тестового примера доступен тут, по мере выхода следующих статей я буду его обновлять. @bot.message_handler(commands=['start', 'help']) def send_welcome(message): bot.reply_to(message, "Welcome to Support_Bot!") Так выглядит код, который реагирует на команды "/start", "/help", а так же приветствует новых пользователей бота (при первом открытии бота автоматически посылается команда "/start"). @bot.message_handler(commands=['on']) def subscribe_chat(message): if message.chat.id in team_users: bot.reply_to(message, "You are already an operator") else: user_step[message.chat.id] = TEAM_USER_LOGGING bot.reply_to(message, "Enter team secret phrase:") Это уже обработка не стандартных команд ("/start" и "/help" есть по умолчанию у всех ботов). Мы создали обработчик команды "/on". После обработки мы просим ввести пароль. @bot.message_handler(func=lambda message: user_step.get(message.chat.id) == 'password1': team_users.add(TeamUser(message.chat.id)) user_step[message.chat.id] = TEAM_USER_ACCEPTED bot.reply_to(message, "You`ve started receiving messages") else: bot.reply_to(message, "Wrong secrete phrase, try again") Эта функция проверяет пароль на валидность. Но как понять, что последнее сообщение было паролем? В обработчике "/on" мы сохраняем статус диалога в глобальной переменной. Декораторы обработчиков сообщений могут принимать lambda-функции, в которые попадют входящие сообщения и если lambda-функция вернула True — идём в обработчик. На самом деле, в нашем случае текст сообщения не так важен, но мы проверяем статус глобальной переменной. Если пользователь до этого вызывал команду "/on" — значит нужно интерпретировать его сообщение, как пароль. Если пароль проходит проверку — сохраним так называемый chat id куда-нибудь, например в файл. С помощью этого id мы позже будем отправлять сообщения в чат оператору. @bot.message_handler(commands=['off']) def team_user_logout(message): if message.chat.id not in team_users: bot.reply_to(message, "You are not an operator anyway") else: team_users.remove_by_chat_id(message.chat.id) bot.reply_to(message, "You`ve stopped receiving messages") Аналогично реализуем команду отключения оператора, который больше не хочет получать уведомления. def process(message): text = '%s\n%s writes to %s\nReply: %s' %\ (message, 'Vasya', 'Super Support Team', '*reply_url*') for user in team_users: bot.send_message(user.chat_id, text, > Ну и рассылка сообщений делается ещё проще. Так как в сообщениях мы можем передавать разную необходимую информацию, включая ссылки, не будем заставлять приложение Telegram пытаться распарсить их, это будет только мешать. С помощью флага disable_web_page_preview = True Telegram не будет пытаться проходить по нашим ссылкам и выдавать картинку превью в чате. threading.Thread(target=bot.polling).start() Запускаем бота одной строчкой (метод polling, ещё доступны webhook-и, но для начала этого хватит с головой). В этой статье мы сделали бота, научили его добавлять операторов только после ввода пароля, так же научили его рассылать всем в группе операторов уведомления. Я буду продолжать цикл и расскажу, как убрать возможную путаницу «кто на какой запрос отвечает», как на основе бота сделать разбиение операторов на группы, делегирование сообщений определённой группе, а так же как отвечать на вопросы клиентов не выходя из Telegram чата. Подобную систему мы используем в работе нашего приложения (Android и iOS). Ну и, конечно, будем изучать новые классные фишки Telegram Bot API 2.0. Надеюсь, наш опыт будет полезен.

Метки:  

[Из песочницы] Maven vs Gradle? Это неправильная постановка вопроса

Понедельник, 20 Июня 2016 г. 20:39 + в цитатник
Написать, наконец, этот пост меня заставила уже давняя дискуссия вот к этому посту на тему, которая время от времени всплывает то там, то тут. Я много раз имел возможность убедиться, что далеко не все одинаково понимают, в чем же состоит декларативность vs процедурность той или иной системы сборки. Основным достоинством инструмента сборки зачастую считается возможность писать алгоритмы сборки на удобном языке. Нужен DSL, никуда без него. В gradle этот DSL базируется на groovy. sbt использует скалу, leiningen — Clojure, Ant использует xml (совершенно не по делу, кстати). Несложно припомнить системы сборки на базе javascript. Каждый собирает на том языке, который ему ближе. И новые инструменты пишут, например, на котлине. Увы, но наличие DSL совсем не означает декларативности. Скорее наоборот. В итоге, gradle проект вообще не может полноценно жить без pom.xml. Это шутка, но с большой долей правды. Посмотрите вот сюда: это репозиторий. Что у нас тут лежит? Да-да, именно pom.xml, он самый. А где же у нас build.gradle? А нет его. Понимаете? Его тут нет. То есть все метаданные, которые предоставлены о собранном проекте, который заметим, собирается при помощи gradle, состоят только и исключительно из метаданных maven. Вас это не удивляет? Меня — нисколько. На мой взгляд, gradle, sbt, leiningen и многие другие инструменты почти (или вовсе) не предоставляют метаданных в доступном другим продуктам виде. Они реально видны только самим себе, и только изнутри процесса сборки. Просто потому, что скрипт сборки — это груви код (Clojure, скала, javascript). Именно поэтому же их так плохо поддерживают IDE (в сравнении с maven или ant, где скрипт это xml). Чтобы понять, что там происходит, нужно выполнить. Нужно иметь gradle внутри, и нужно чтобы gradle отдавал в IDE необходимую информацию. Как я вижу себе декларативность, и зачем она бывает нужна? В качестве иллюстрации приведу два своих проекта, и один от apache: Начнем пожалуй с Apache Karaf. В ssh-консоли вам доступна команда установки модуля (OSGI-bundle). Эта команда использует не что иное, как координаты модуля в maven repository: bundle:install mvn:groupId/artifactId/version. При этом самого maven karaf не содержит — под капотом ничто иное, как Aether, плюс обертка над ним (Pax URL). Аналогичную конструкцию я реализовал когда-то давно на Jython, и работала она внутри Weblogic. Использовался тот же Aether, плюс WLST API. И позволяло все это автоматически обновлять установленные в контейнере JavaEE модули, разыскивая их новые версии в репозитории. Опять же — maven в конструкцию не входил. Использовались репозиторий, Aether, и pom.xml, которые maven упаковывает в META-INF модуля. И последний пример. В моей практике был один maven plugin, который в качестве исходных данных для своей работы использовал SVN, сканируя папки и файлы на предмет изменений в проектах, сравнивая их с bug tracker, и принимая решения, какие именно собранные артифакты нужно включать в релиз, и деплоить. Какие выводы можно из этого сделать? Во-первых, мы видим, что с описанием проекта (в моем случае это всегда был pom.xml) иногда бывает нужно и можно работать из любого достаточно развитого языка. Это не обязан быть инструмент сборки, на который изначально расчитан проект. Во-вторых, если репозиторий спроектирован правильно, в соответствии с принципами REST, то нам не нужен никакой специальный софт для работы с ним, кроме http-сервера. Нужны только данные метауровня чуть выше проекта (список доступных версий, например). В-третьих, очень удобно то, что важная часть инфраструктуры, в нашем случае plugins, сами просто обычные артефакты, лежат в том же репозитории, и никак не связаны вообще с конкретным проектом. Вот это я называю декларативным подходом. У нас есть проекты, их много. Они бывают в репозитории, в виде собранных артефактов, в VCS, и еще где-либо, и могут обрабатываться разными инструментами — а не только одним единственным. Дескриптор проекта — это просто файл, любого стандартного и удобного для обработки формата. Репозиторий артефактов — это тоже стандартизованный формат + простой REST API. А логика сборки, на любом удобном вам DSL, лежит отдельно. Хотите — в самом дескрипторе, хотите — в репозитории. Как бы я вообще это все сделал? В сущности, если брать за основу maven, то сейчас тут не хватает гибкости в части plugins, их настроек, и т.п., потому что существующий xml — это сериализованное представление java-модели данных plugins и ядра, и оно не гибко. Если разработчики решили, что какие-то данные о проекте вам не нужны — у вас остается только вариант key-value в виде properties. А следовало бы сделать нечто произвольной, но регулярной структуры, ну скажем типа RDF (не обязательно именно его). Описание проекта в виде RDF сразу позволяет делать полезные вещи вроде поиска в нем, как в базе данных (т.е. репозиторий, в части метаданных, становится просто SPARQL endpoint, и умеет отвечать на поисковые запросы). И такие же запросы можно строить применительно к проекту. Вот это и был бы истинный poliglot maven. Причем это, кстати, выглядит вполне реализуемо, даже в рамках существующей инфраструктуры.

Метки:  

Device Lab от Google: маячки с технологией Eddystone

Воскресенье, 19 Июня 2016 г. 23:04 + в цитатник
Долгое время мобильные приложения и физический мир никак не пересекались. Но технология Bluetooth маячков позволила разработчикам "общаться" с объектами реального мира, а  пользователям получать самые релевантные данные от их текущей локации с точностью до сантиметра. Первые устройства уже отправились разработчикам, а сегодня в Лаборатории Google мы представляем разработчикам маячки Eddystone - iBKS и BKON, реализующие, в том числе, и функцию так называемого Physical Web ("физического веба"). Подайте заявку, возьмите устройства для разработки, поделитесь с сообществом результатами, а с миром новым приложением, способным изменить его!
Читать далее

Метки:  

Поиск сообщений в comdersrek
Страницы: [2] 1 Календарь