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

Enterprise

Cordova. Опыт Enterprise-проекта

11.04.2021 22:06:33 | Автор: admin

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

Немного истории

Четыре года назад для нужд нашей организации было принято решение написать мобильное приложение для двух платформ (iOS и Android). Программист был один, а опыта работы с нативными языками на тот момент не было. Для этих целей мы решили попробовать кроссплатформенную схему разработки от Cordova.

Выбор фреймворка

Оказалось, что реализовать проект в основе которого лежит один подход, можно по-разному. Выбрав Phonegap можно было получить платформу Cordova, плюс несколько полезных инструментов для отладки и демонстрации приложения, а главное, облачную сборку для разных платформ (не бесплатно). Для тех кто не в курсе, приложения для iOS собираются только на macOS, а для Android, можно собирать как на macOS, так и на Windows. Судя по всему идея заработать на облачной сборке у Phonegap провалилась, так как Adobe прекратила инвестиции в проект. Другой путь это Ionic, команда этой группы предлагает набор инструментов охватывающий все этапы разработки гибридного приложения от А до Я. Здесь к платформе Cordova вы получите возможность интеграции с популярными фреймворками (Angular, React, Vue), инструменты для бесплатной и платной разработки, подробную документацию и многое другое. Мы пошли по пути наименьшей зависимости от кого бы то ни было. Взяли Cordova, а в качестве фреймворка для single page application выбрали менее хайповый, но довольно симпатичный Framework 7 (так же были доступны Angular, React, Vue и другие). В реальном проекте трудности обычно возникают либо с плагинами, либо с особенностями самих платформ. Так как команда Ionic предлагает готовые решения известных проблем, многим, будет легче поддерживать проект присоединившись к ним.

Плюсы и минусы

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

Плюсы:

  • не нужен программист для каждой платформы на начальном этапе

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

  • разнообразие фреймворков для разработки одностраничных приложений

  • возможность обновлять код без выпуска новых сборок

  • возможность использования большого количества бесплатных веб компонентов

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

Минусы

  • поддержка существующих плагинов

  • особенности браузерных компонентов webview

  • неудобная работа с файловой системой

  • многозвенная схема отладки приложения

  • вечно-зеленый компонент webview у Android

Программисты и плагины

На начальном этапе можно действительно обойтись без навыков нативной разработки, но по мере увеличения количества плагинов в вашем проекте, это будет неизбежно. Дело в том, что код плагинов быстро устаревает и часть функционала либо перестает работать, либо будет работать неправильно в определенных версиях ОС той или иной платформы. Бывают ситуации и хуже. Так обновленный Xcode поддерживающий последнюю версию платформы iOS, может отказаться собирать ваш проект, обнаружив в нем плагин написанный на предыдущей версии swift. Пример конечно экзотичен, потому как 99% плагинов под iOS написаны на Objective C, тем не менее, с этим приходилось сталкиваться. Немалое количество плагинов сообщество энтузиастов-разработчиков забросило, а те что поддерживаются, порой ждут обновлений довольно долго. Так же, нужного плагина может и не быть вовсе. В итоге, чтобы иметь актуальный и работающий проект, вам необходимо будет вносить изменения в нативный код плагинов, писать их с нуля или просто редактировать главные модули приложения (на Objective C и Java соответственно).

Интеграции

Интегрировать в проект отдельные элементы веб приложений или полноценные приложения довольно удобно. Ваш проект работает в браузере, а это значит, что вы сможете загружать в него веб страницы, делать запросы к веб сервисам, использовать возможности WebDAV и многое другое. При HTTP запросах из вашего приложения к другим веб ресурсам, вы наверняка столкнётесь с проблемами аутентификации, CORS ограничениями, нюансами работы с сертификатами итд. Полноценные веб приложения лучше загружать в отдельный браузерный компонент с помощью плагина. Если потребуется, вы даже сможете настроить обмен данными между вашим основным браузерным компонентом (webview) и внешним. При этом, пользователь не будет покидать окна мобильного приложения. Как показала практика, многие десктопные приложения уже имеют веб интерфейсы, а некоторые из них, даже адаптированы к мобильным телефонам и планшетам. Так, например, мне удалось интегрировать веб версии клиентов MS Outlook, 1С, Redmine. Конечно, там не все гладко, неоднородность интерфейсов, отсутствие поддержки touch экранов, ограничения при работе с файловой системой и другие нюансы. Но спектр возможностей от таких интеграции, по-моему, перевешивает все недостатки.

WebView

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

iOS

Android

Поддержка стандартов

хорошо

отлично

Поддержка touch

отлично

удовлетворительно

Рендеринг анимаций

отлично

хорошо

Поддержка WebRTC

нет

есть

Встроенный вьювер файлов

основные форматы Microsoft Office, OpenOffice, PDF, изображения

изображения

Отладка приложения

хорошо

отлично

VPN

При работе с корпоративными удаленными ресурсами (веб приложения, сервисы, базы данных), которые не являются публичными, возможно, придётся использовать VPN. Такой подход является довольно логичным, но затея не является безобидной. В реальности это накладные расходы на разработку и обслуживание, плюс негативный опыт ваших пользователей. Идеальным решением будет интеграция VPN клиента в приложение, что тоже не просто. Так, например, библиотеку с открытым кодом Open VPN можно интегрировать в проект с помощью нативного кода и предварительно скомпилированных библиотек. Плагина для Cordova нет, возможно, появится позже. Здесь так же придется немного помучиться с приложениями и сервисами работающими по протоколу HTTPS. Дело в том, что последние в корпоративной среде используют либо самоподписанные сертификаты, либо сертификаты выданные локальным центром сертификации, что для ваших webview не являются доверенными. Этот вопрос решается для двух платформ, но универсального и однозначного подхода здесь нет. Кто-то считает, что доступ к ресурсам внутри сети может быть осуществлен по-обычному HTTP. В этом есть логика, но не надо забывать, что весь трафик в данном случае будет передан без шифрования. Можно научить приложения для iOS и Android работать по HTTPS с ресурсами внутри сети и такой вариант считаю предпочтительным.

Провайдер сервер за прокси

Реализация такого сервера задача необходимая, если конечно, ваше приложение собирается получать push-уведомления. Для работы с APNS (служба Push-уведомлений Apple), потребуется установка соединения только по протоколу HTTP v.2 + TLS. Библиотеки и API популярных серверов научились работать с HTTP2, но не все они умеют работать с прокси серверами и здесь, возможно, будут сложности. Я какое-то время для этих целей использовал Apache, позже перешёл на собственный сервер, который был написан на Nodejs. Это оказалось невероятно просто и удобно. FCM для Android в этом смысле не такой требовательный (работает на HTTP v.1), при работе с ним проблем не наблюдалось.

Распространение приложений

Для iOS приложений придется оплачивать ежегодную enterprise лицензию, для Android это бесплатно. Плюсом enterprise лицензии для iOS является отсутствие модерации кода и возможность свободного распространения приложения без App Store. Достаточно иметь публичный сервер на котором у вас будут файл приложения и файл манифеста. Ссылку на манифест в специальном формате вы и будете распространять среди новых пользователей вашей организации. У Android приложений ограничений в распространении нет изначально. Последние рекомендую распространять через стандартные магазины приложений, так как APK загруженные не из магазина, по умолчанию, не являются доверенными для ОС Android.

Заключение

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

Подробнее..

5 самых популярных вопросов при внедрении service mesh в корпорации на примере Istio

19.06.2020 14:16:52 | Автор: admin
Не только на мировом, но и на российском рынке можно заметить волну интереса к технологиям сервисных сеток, или service mesh. Ниже под катом мы разберемся, какие задачи эта технология решает, как она развивалась, а также с какими вопросами сталкиваются корпорации при адаптации Istio у себя в ИТ-инфраструктуре.

image


Мое знакомство с service mesh было во многом случайным, когда в 2017 году мне на глаза попался анонс о сотрудничестве Google и IBM по созданию нового open source проекта. Не сказать, что партнерства крупнейших технологических компаний редки, но именно этот случай вызвал у меня большой интерес. Во-первых, примеров взаимодействия именно компаний Google и IBM все же не так много: пожалуй, наиболее известными фактами будут работа вокруг открытой аппаратной архитектуры OpenPOWER, а также наличие сервисов IBM в Google Cloud. Во-вторых, несмотря на наличие примеров, когда и Google, и IBM развивают один и тот же open source проект (Kubernetes или TensorFlow), случаев, чтобы обе эти компании стали именно основателями проекта, очень мало, и они достаточно уникальны. И, в-третьих, наличие среди основателей проекта IBM и Google компании Lyft конкурента Uber как сервиса вызова такси, вызывало вопросы и неподдельный интерес. Тот анонс в 2017 году рассказывал о выпуске технологии Istio, предназначенной для управления взаимодействием различных сервисов. Поначалу не совсем очевидно, в чем заключается проблема и зачем создавать такой проект, так как подходов по управлению взаимодействием между сервисами было известно довольно много. Чтобы понять проблематику, стоит взглянуть на ситуацию шире и посмотреть на изменения в ИТ-архитектуре на тот момент времени.

Что такое service mesh


Причины появления и столь стремительно нарастающей популярности service mesh неразрывно связаны с изменениями в ИТ архитектуре. Представить появление service mesh без микросервисной архитектуры достаточно сложно давайте посмотрим почему. Можно долго спорить, что такое микросервисная архитектура, так как единого и устоявшегося определения нет (и вообще эта тема заслуживает отдельной статьи), но для упрощения остановимся на следующих ключевых характеристиках: это небольшие автономные части бизнес-логики, реализованные как сервисы, каждый из которых имеет свой цикл сборки и поддержки. В таком случае логично задуматься о том, как эти небольшие сервисы будут взаимодействовать друг с другом и как контролировать этот процесс. Здесь и появляется service mesh. В реальной жизни эту технологию можно сравнить с дорожным навигатором. На дорогах могут случаться различные ситуации: аварии, заторы, выход из строя светофоров, а система позволяет вам добраться из пункта А в пункт Б наиболее оптимальным способом, зная обо всех произошедших событиях.

Ключевыми задачами, которые берет на себя service mesh, являются:
  • управление трафиком
  • балансировка нагрузки
  • обеспечение безопасности при взаимодействии сервисов
  • сбор метрик и мониторинг

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

Эволюция развития service mesh


В настоящее время service mesh стал отдельным слоем и во многом стандартом де-факто современной ИТ-архитектуры на уровне инфраструктуры. Можно ли строить современные решения без service mesh и реализовывать этот функционал как-то по-другому? Конечно, да, только вопрос в удобстве, гибкости, времени реализации и дальнейшей поддержке решения. Безусловно, задачи, связанные с управлением трафика или балансировкой, можно решить самому на уровне кода для каждого из сервисов. Но так как микросервисная архитектура подразумевает существование десятков, сотен или даже тысяч различных сервисов, то реализовывать один и тот же функционал при разработке каждого из них совсем не удобно. Зачем разрабатывать один и тот же функционал десятки или сотни раз, если можно вынести его отдельно?
Первые реализации service mesh были сделаны на прикладном уровне. Самый известный пример фреймворк (или набор библиотек) Netflix OSS, доступный для использования с 2012 года. В него вошли компоненты, реализующие функционал, присущий service mesh: с помощью Eureka производится обнаружение сервисов (service discovery), с помощью Hystrix ряд паттернов обнаружений ошибок (circuit breaker), Zuul решает задачи динамической маршрутизации (dynamic routing).

На необходимость изменения этого подхода оказали сильное влияние следующие факторы:
  • поддержка нескольких языков программирования и отсутствие зависимости от них
  • удобство разделения прикладных и инфраструктурных задач для DevOps: возможность вносить изменения в прикладной код без влияния на инфраструктуру
  • развитие контейнерных технологий

Как ни крути, Netflix OSS куда больше был интегрирован в прикладную логику сервиса, требовал использование стека технологий Netflix, имел зависимость библиотек от языка разработки и не был заточен для использования в контейнерах.
Istio как пример следующей волны эволюции технологии использует sidecar (Envoy от Lyft), то есть прокси, который располагается рядом с каждым сервисом и берет на себя функционал по управлению политиками безопасности, трафиком, сбор телеметрии и пр. Это позволяет быть нейтральным к выбору языка программирования, иметь хорошую интеграцию с Kubernetes как стандарта де-факто по оркестрации контейнерных сред и не иметь никаких зависимостей от прикладной логики сервисов. По факту именно на этом шаге эволюции технологии service mesh произошло ее окончательное выделение в отдельный инфраструктурный слой как самостоятельный уровень современной ИТ-архитектуры.

Адаптация технологии в корпоративном мире


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

image

Вопрос 1: Достигла ли технология Istio достаточной зрелости для внедрения в корпорациях?


Так как мы говорим о крупных организациях, то для них вопрос зрелости той или иной технологии является одним из самых первых. Что подразумевается под зрелостью? Параметрами зрелости могут быть функциональность, стабильность работы, количество промышленных внедрений, максимальная нагрузка, а также соответствие ряду нефункциональных требований, например, по отказоустойчивости или масштабированию. Важно понимать, что для каждой компании количественные значения каждого из параметров будут своими в зависимости от ее масштабов и сценариев использования.
Что можно сказать про Istio? С точки зрения стабильности работы в мире open source немаловажным является выпуск версии 1.0, которая сообществом контрибьюторов Istio была представлена еще летом 2018 года. Примерами по использованию технологии являются уже десятки компаний, наиболее известными среди которых являются Ebay, Yahoo и банк ING. Интересными примером является история использования Istio при эксплуатации истребителя F16. Отдельно стоит выделить факт, что ведущие облачные провайдеры IBM и Google предоставляют сервисы на базе Istio для своих клиентов. Более того, Istio используется даже как часть новых open source фреймворков. Пример: Kabanero, направленный на более быструю разработку приложений поверх контейнерной инфраструктуры.

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

Вопрос 2: Service mesh для новых сред с контейнерами, а что делать с традиционным ландшафтом на виртуальных машинах?


Service mesh принадлежит типу технологий, относящихся к cloud native, которые создавались в эру развития контейнеров. Но, вспоминая реальность ИТ ландшафта корпораций, можно заметить, что промышленных систем, работающих поверх контейнеров не так много, и корпорации стоят лишь в начале пути по их массовому использованию. Многие бизнес-критичные задачи по-прежнему работают на виртуальных машинах и здесь возникает вопрос: неужели для них нельзя использовать Istio?
Краткий ответ конечно, можно. Istio позволяет создавать разные конфигурации с использованием как контейнерной инфраструктуры, так и виртуальных машин или даже bare metal. Для связи виртуальных машин и service mesh необходимо выполнить ряд действий, например обеспечить видимость IP-адресов кластера с Istio и пр. Более подробное описание и примеры можно найти здесь.

Вопрос 3: Какую модель развертывания выбрать?


Этот вопрос, между прочим, весьма непростой и затрагивающий много областей, включая как технические вещи (нефункциональные требования по отказоустойчивости, безопасности и производительности), так и организационные (структуру команд). Какие опции развертывания возможны?
  • один или несколько кластеров (мультикластер)
  • один или несколько сетевых сегментов
  • одна или несколько контрольных точек управления (control panel)
  • одна или несколько сеток (mesh)

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

Вопрос 4: А какую нагрузку выдержит?


Так как речь идет о корпорациях, то, как правило, они обслуживают большое число клиентов и, соответственно, имеют на своих системах большие нагрузки. Поэтому вопрос абсолютно не праздный и на практике не редки случаи, когда та или иная новая технология не давала нужную производительность и не могла обеспечить предоставление сервисов компании по запросу клиентов.
Конечно, самый грамотный ответ на этот вопрос: зависит от множества факторов. То, как развернута система, какие требования по отказоустойчивости или изоляции, какая версия технологии используется все эти факторы оказывают прямое воздействие на производительность. Но вряд ли этот ответ способен дать хоть какие-то оценки, поэтому посмотрим на уже имеющийся опыт других компаний. К сожалению, в открытых источниках сложно найти детальную информацию от компаний по их опыту использования Istio, но на различных встречах, митапах или конференциях уже в начале 2019 года одной из компаний в области информационной безопасности были представлены цифры в десятки тысяч транзакций в секунду (TPS) системы, использующей Istio. Многие корпорации провели пилотные проекты и получили результаты в несколько сотен транзакций в секунду. Много это или мало? Для примера, только несколько крупных банков России имеют нагрузки в несколько тысяч TPS на своих ИТ системах, поэтому оценка даже в несколько сотен TPS с лихвой покроет подавляющее большинство задач любой корпорации.

Вопрос 5: Когда будут нужные нам фичи?


Во время внедрения Istio технические специалисты организаций часто обращаются в IBM как к компании-основателю проекта с вопросами о сроках реализации конкретных новых фич технологии.

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

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

Вместо заключения



Что можно сказать в итоге? Несмотря на то, что Istio достаточно молодая технология, ее текущий уровень зрелости и существующий функционал полностью отвечают требованиям корпораций. Видно, что среди крупных российских компаний интерес к Istio за последний год существенно вырос и все больше и больше ИТ команд начинают свои первые проекты, а ряд из них уже использует технологию в промышленной среде.
Для тех, кто хочет видеть Istio не только в своих ИТ системах, но и на полке или столе, мой коллега создал модель парусника как копию логотипа Istio для распечатки на 3D-принтере, которую можно скачать здесь.
Подробнее..

Управление корпоративным сервисом на разных уровнях SSM, ESM и xOps

25.12.2020 00:16:02 | Автор: admin
Управление сервисом в современной корпорации требует эффективного сочетания лучших практик сервис-менеджмента из различных отраслей и инструментов автоматизации для выбранных подходов, подходящих для использования в корпоративной информационной среде.

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


Три уровня организации предоставления корпоративного сервиса

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

1. Внешний провайдер услуг. Область менеджмента: Shared Service Management (SSM)


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

  • если у компании имеется некоторое количество распределённых географически офисов / отделений;
  • если компания представляет из себя несколько автономных бизнес-единиц (группа компаний);
  • если у компании есть ряд аффилированных или дочерних предприятий.

Как правило, проблемы возникающие при сервисном обслуживании подобных массивных бизнес-структур, решаются физическим и, в некоторой степени, юридическим отделением непрофильных департаментов компании (HR, IT, ИБ, бухгалтерия, АХО и т. п.) в общий центр обслуживания (ОЦО). Такие автономные центры служат единой точкой входа для сотрудников компании, пользующихся централизованными сервисами (например, получение справок, оплата счетов, организация рабочих мест).

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

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

Общим центрам обслуживания тоже необходима цифровая трансформация. Подчас даже им она необходима в первую очередь. Вопросы оптимизации работы ОЦО лежат в области управления общим сервисом (shared service management), которая помогает найти оптимальные пути автоматизации работы ОЦО и расширения их функциональности.

2. Провайдер услуг на уровне сервисных подразделений компании. Область менеджмента: Enterprise Service Management (ESM)


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

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

3. Провайдер услуг внутри подразделения. Область менеджмента: xOps


Самый неявный уровень провайдера услуг в организации тот, который находится внутри подразделения, а именно xOps.

Термин xOps это калька с термина DevOps: тот же подход, но только уже не области разработки ПО, а в любой другой области маркетинге (MarketigOps), продажах (SalesOps), кадрах (HROps), юридической службе (LegalOps) и т.п.


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

Такой сотрудник необходим для того, чтобы обеспечить команде возможность решать возникающие задачи здесь и сейчас, не дожидаясь, пока раскрутится тяжелый маховик корпоративной автоматизации сверху. Очевидно что такой подход сопряжен и с определенными рисками, например с риском возникновения теневых ИТ. Для предотвращения связанных с этим проблем в организации должна быть внедрена одна или несколько интегрированных между собой платформ автоматизации, которые позволяли бы продвинутым пользователям без навыков программирования с помощью инструментов no и low code настраивать для своей команды цифровое пространство коллективной работы. Второе требование к таким платформам продвинутый инструментарий для интеграции со специализированными инструментами и сторонним ПО.

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

Общий инструментарий


Современные ESM-платформы могут автоматизировать работу провайдеров услуг сразу на всех трёх уровнях SSM, ESM и xOps. Для этого они должны удовлетворять следующим требованиям:

  1. Реализовывать лучшие практики процессно-сервисного подхода.
  2. Поддерживать возможность работы с внешними клиентами-потребителями и их контактными лицами.
  3. Поддерживать мультидепартаментный режим работы в части каталога услуг и других процессов из области сервис-менеджмента.
  4. Иметь развитый инструментарий интеграции системы со сторонним программным обеспечением.
  5. Обеспечивать возможность доработки системы с помощью визуальных инструментов и несложных скриптов, доступных для продвинутых пользователей.
Подробнее..

Архитектура архитектуры архитектора

28.02.2021 04:04:14 | Автор: admin

Архитектор это звучит Звучит как-то не понятно. Наверное, поэтому всегда добавляют что-то. Ну типа системный архитектор или там программный архитектор. Не то чтоб так стало понятно, что он делает, но точно кто-то важный. Я вообще пишу архитектор информационных систем и программного обеспечения. Это ж как назовёшься -так и поплывешь! С архитекторами тут вообще такое дело это как бы и не профессия. Ведь архитектором как стать? Либо тебя назовут таковым, либо сам назовёшься. Другого пути нет. Ни школы, ни спец. образования, никаких то там универсальных сертификатов нету. Только название и есть.

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

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

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

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

От теории к практике. Линия на картинке плевое дело. А как насчет реальной архитектуры то? Вот тут бы хотелось немного поподробней. Тем более, что картинка глупая. Если фича нужна, то её запилят. Как и положено, зеленой пересекающей параллельной линией прозрачного цвета. Поэтому и архитектуру нужно гибкую и разноцветную. Но сначала прямые линии на голубом листе и ярылчки с брендами. Blueprint и tech. stack. И это вообще не архитектура, а дизайн. Набросок.

Как это в Agile устроено при построении задания, так и здесь: цель, средства, что дано. Для этого шага есть много сапог. Померяв несколько, я решил быть в тренде. На одной ноге IDesign, на другой DDD. Вот только не надо мне тут про микросервисы, клиент-сервер и всякие распределенки. Мы не на этом этапе. Нас интересует то, что нужно клиенту, а не как. В старом добром UML мы бы сейчас построили use-case и block диаграммы. Нам нужно определить основных игроков и функции - расставить точки на карте. Я обычно не углубляюсь пытаюсь рисовать человечков пользователи разные, но система одна. Так что я просто отрезаю интерфейс от сценариев. Грубый план обычно - такой синий пирог с разноцветными цукатами.

набросок для внутреннего обсуждениянабросок для внутреннего обсуждения

Опытный инженер сразу заметит, что как-то попахивает заданием для продуктового отдела нашего супермаркета. Все вот эти Product Owner и Business Analyst должны дать те самые юзкейсы и фитчи. Хотя нет, опытный инженер вообще это читать не будет. И уж тем более кто как не он, должен знать, что архитектуру сначала надо продать своим. Начальству, инженерам, поддержке и тд. Поэтому и диаграмма должна говорить на их языке. Что же важно мне на данном этапе определить блоки, которые будут служить основой. Те, что ближе к константам, чем к переменным. Несущие конструкции. Количество стен, не углубляясь из чего они сделаны.

Продали колонны? Что теперь интересно вашим клиентам? Цвет труб! То что они увидят, только в случае серьёзного чп. Логично же. Большой и неповоротливый энтерпрайз любит, чтоб о нём говорили как о динамичном и энергичном. Так чтоб в тренде, вон с тем стратапом. Но только, чтоб надёжно. Вам нужны жужалки и стразики - buzz words. Вот тут уже надо начать набрасывать распределенные микросервисы на облако. После первого этапа все должны в курсе будет ли эта закрытая ли система, с доступом в сеть или нет, количество пользователей и срок жизни, дискретность окружения и всё такое. Это, однако, не помешает клиентам требовать cloud для системы в offline. Нет, я не преувеличиваю. И вот чтоб были автономные микромодули, но только монолитом. Актуальные и верные данные в любое время в постоянно доступной, разрозненной системе. Привет кэп! Можно обнаружить (в копилке личного опыта), что клиент в северной Африке на диалапе, лучший пинг в ближайшее облако больше 300, а хотят они реалтайм для управления дронами по видео с бортовой камеры. Инженеры, работающие с клиентами напрямую, в цирке не смеются.

Значит теперь задача набросать много звучных и цветных иконок трендовых технологий. Универсального рецепта нет, так как готовить всё равно придётся из того, что есть в холодильнике. Вряд ли вам дадут нанять новую команду специалистов. Энтерпрайз проекты живут десяток лет и года 2-3 в разработке. Так что в одну клавиатуру такое не поднимешь. Необходимы готовые команды, а у них уже есть какой-то опыт и знания. Если у вас 5 команд бэкенда пишет на Java, то переводить их Python нет не времени не смысла. Играете с теми кубиками что есть, и будьте любезны собрать слово счастье. Однако стоит всё-таки делать выбор и не пускать на самотёк. Если у вас есть клиент (UI/UX), и он не слишком мудрёный и жирный, то тут можно вставить свежачок. Лицо системы долго без изменений не живёт, да и фронтэнд технологии тоже. Так что, если актуален сейчас React бери его и найдите одного специалиста. Бэкхэнд на 10 лет вперёд требует и технологию, которая не исчезнет. Поэтому то и популярны .NET и Java. Если есть место микросервисам, то каждая команда может взять свою технологию. Но они же в том же холодильнике, так что сюрпризов не будет. Только помните, что микросервисы не всегда уместны. А иногда и совсем не уместны. Нет у вас центра и не нужно динамическое масштабирование, то может и не надо городить огород? Люди десятки лет, работавшие на поддержке монолита, не обрадуются тому, что им придётся содержать зоопарк. Они даже не понимают, что это надо выкатывать и содержать вручную в случае частного закрытого решения (on-premises project). Нельзя поехать и поменять или подключиться по RDP и залезть ручками в базу данных. А потом они всё равно это сделают через какой-нибудь джампер бастион и поменяют что-то, как-то не догадавшись, что это лишь одна из 12 баз и теперь данные всей системы не стыкуются - прощай выходные!

Немного оффтопа. Клиент как кит в океане, только старый, не грациозный, с тремя головами и вяло текущей деменцией. Но и корпорации, которые его обслуживают не лучше. У них старые связи с клиентом. Они когда-то поставляли/производили железо и пытаются видеть в софте всё те же станки. Сделали рабочий прототип фигачим еще миллион и поставляем. Долгая проектирование, потом немного допилим, в производство и на моментально на полки/клиентам. Они же всегда так делали. Как это roll-out это долгий процесс? Ведь copy-paste и в продакшн! В общем, как много нам открытий чудных Поэтому решение надо не только продать и утвердить внутри своей компании, нужно еще удостовериться, что сама компания будет соответствовать решению.

И так наша следующая диаграмма будет всё еще аморфной, но уже на технологиях. Точность компонентов и связей здесь не столь важна, а вот обоснование выбора картинок необходима. Именно здесь впервые затронут бюджет. Лицензии, специалисты, обучение, поддержка, система. Много иконок клиент радуется, большие траты клиент дуется. Есть, конечно, горячие пирожки. Не важно куда и как, но нужен Kubernetes. Даже если и нет масштабирования засуньте в автоматическое тестирование как часть CI-CD. Но иконка должна быть. Бесплатные пирожки ещё вкусней. Вам понятно, что Kubernetes будет с контейнерами Docker, но заказчик будет брызгать деньгами, если вы добавите и этот образок. И безопасность туда же прилепите https.

технологиитехнологии

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

монотонное множество архитектурымонотонное множество архитектуры

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

Подробнее..

О заказчиках и приказчиках

07.03.2021 06:17:32 | Автор: admin

Продолжаем.

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

белый дик архитектурыбелый дик архитектуры

Часть шума создают потенциальные клиенты. Они шуршат RFP, трясут золотыми яйцами государственных куриц, тыкают в календарики и всегда улыбаются. А чего им не улыбаться то? За ними под запах курятины вьются роем адвокаты, консультанты, маркетологи, аналитики и анаболики. Что сразу бросается в глаза это возраст. Его просто нет. Вот в стартапах все такие на 20, начальство под 40 и сразу всё ясно без цветовой дифференциации штанов. Тут же вас может встретить Багира, только что закончившая институт и возглавляющая отдел предпенсионных бандерлогов. Суровый Балу вяло шуршит пылесосом. Каменные статуи с галстуками смотрят не мигающим глазом сразу в 3 монитора. Блестящий Ка застывший между 40 и бесконечностью с бесом в голове и сединой в бровях встретит вас в большом овальном кабинете с видео камерой и конференц-связью. Кто он и что у него за должность вы будете гадать до конца встречи.

И так, где же мёд и о чём жужжат дикие пчёлы? Особенностью Энтерпрайза всегда является размер. Он таки имеет значение. Наращивается он по-разному и это сильно влияет на структуру. Где-то это слияния, где-то поглощение, а где-то кооперация. То есть иногда голова одна, а иногда десяток и по всему миру. Но всегда есть общая черта многослойность. Матрица или иерархия не столь важно. Главное понимать, что любой контакт с внешним миром запускает процесс внутренних коммуникаций вверх. И вверх это как бы против течения. Сверху вниз все стекает очень быстро. Вот, кстати, и ответ почему так скользко. А вот вверх только под усиленным давлением.

Свежий пример

Тут недавно закинули на gap analysis требование потенциальной системы для будущего тендера. Это оказался экселик с чеклистом на 600 пунктов с названием СистемаБудущего20150512. В мете документа тоже 2015. Да, компания поняла, что их система устарела и начала готовиться к тендеру 5+ лет назад, но пока еще не созрела. Случай, конечно, исключительный, но показательный.

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

Значит первоочередной задачей становится поиск ключевых фигур. Среди всего роя нужно найти людей опытных и технических. Они не обязательно будут присутствовать непосредственно на встречах. Но с каждым вашим вопросом, вы будете замечать, что улыбающиеся люди лезут в телефон или имейл и выуживают информацию оттуда. Вам нужны те люди, которые эту информацию туда кладут. Нужен святой грааль, за которым потянуться рыцари этого королевства, а не пажи и придворные. Обычно грааль стоит искать в DR. Пара-тройка вопросов о поведении в не предвиденных обстоятельствах и пошлют за спецами. Из них нужно вытянуть как можно больше инфы и еще контакт наладить. Если вошедший протянул тебе визитку, то скорее всего это бесполезная улыбашка. Потому что у спеца на лице будет транспарант, что его оторвали от IDE ради какого-то клоуна, который явно случайно собрал услышанные где-то слова в призывающее заклинание. Хороший инженер не любит context switch. Поэтому не курит и пьёт чай из огромной кружки.

Чем выше пирамида, тем дальше голова от мозга. В огромных компаниях у каждого свой узкий коридор без дверей и окон. Тот, кто принимает заявку на тендер и тот, кто эту заявку рассматривает могут оказаться в конкурирующих отделах. Тот, кто составляет требования, скорее всего никогда к системе не прикоснётся. А зачастую даже никогда и опыта подобного не имел. Точнее сказать имел он всех тех, кто будет этим пользоваться. Например, директор ITnотдела будет вести тендер на мобильные устройства для подсчёта товара на складе помидорок. Почему именно он? Ну потому, что над ним сидит вицепрезидент отдела продаж, которому доложили, что неустойка возникла из-за не правильной оценки количества доступного товара. И вот VP решил поискать сейлфарс-копросоциальной сети: инновация и облако (нам, специалистам, без облака никак низя) и попал на IT. И пофиг, что IT просто хранит в облаке фотки с корпоративов или отвечает за офис 256. Поэтому, тому IT директору нужно от вас только, чтоб он ни за что не отвечал и хоть что-то понимал. И так как эта частая история, то мой вам совет самые важные стрелочки в диаграммах на первых этапах коммуникации. Какой порт открыть и какой будет модель деплоя на железки вот то, что он знает и хочет видеть. За безопасность отвечает тоже он. И, как вы уже угадали, ему пофиг на ассиметричное шифрование. Главное, чтоб порт 443, пару сертификатов и базу данных с бэкапами побольше. Поэтому и подаем обычно что-то типа наскальной живописи. Примитивно, но сюжет понятен.

обрезанный кусок из реального проекта обрезанный кусок из реального проекта

Страх и ненависть в Enterprise без которых рамки архитектуры будут не полными:

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

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

Размер имеет значение. Если ваша система требует установки на клиентские машины, то учтите, что их может оказаться тысячи и всё старье. Да, даже Windows XP/CE в наладонниках какой-нибудь гос. структуры. В таком варианте заявленный TLS 1.3 выльется в рукописное шифрование и всякие termination proxy.

Всё что вы скажите может быть использовано против вас. Протоколы бесед и совещаний и разговоры с адвокатами. Вы как бы для мажора сказали, что тут realtime, а потом посмотрят в конечном продукте, что есть фиксированная задержка и приедут обсуждать штраф. Из личного опыта было: обсуждение падения кластера в присутствии адвокатов с обеих сторон. А в соседнем проекте сначала уведомительное письмо о большой адвокатской конторы, что не соответствие SLA в производительности станет причиной разрыва контракта. Не подтянули что-то по производительности и волна увольнений. А дело там совсем не критичное было. Просто клиент хотел спрыгнуть и нашёл повод. Так что no commitment и никакого fine tunning. Не знаете точно потянет ли один сервер или нужно 2 укажите в заявке, что необходимо 2, но может меняться в зависимости от

Vendor lock ненависть во все поля. Энтерпрайз такое не терпит. Как можно больше стандартов и открытых протоколов.

Vendor lock очень не любят. Поэтому раздельные тендер на поставку, обслуживание, поддержку и тд. То есть вы можете выиграть в нескольких или в одном. Зачастую вы поставляете софтину, кто-то другой железо, кто-то третий будет это ставить и обслуживать. Лучший вариант, когда для on-prem у вас чёрный ящик ваша компания не продаёт софт отдельно. Но всё равно поддержка будет не у вас. Не рассчитывайте на определённую версию софта и что не будет конкуренции за ресурсы. Будьте stateless где только можно.

Vendor lock одно из самых важных. Даже открытые технологии бывают связанны с вендором. Допустим с Google. И такие вещи не примут в каком-нибудь Китае.


Мой компас опыта указывает строго на запад, а потому насаживать ли его на ваши реали дело личное. Сценарий обычно прост и неизбежен. Маркетинг и продажи находят потенциального клиента, собирают документы и совещания, чтоб определиться кидать ли гарпун. Это было в пошлом выпуске. Теперь надо заявить о себе! Нет, если вы крутой специалист то, наверное, вы еще подождёте. Пусть вон менеджеры по продажным сами разбираются. И они всегда разбираются. Их ведь работа пройти все уровни до подписания, а там и босс, бонус и финальные титры. Прикинь, а им ничего разрабатывать не надо! Они даже не всегда понимают, о чем тендер. Поэтому обещать и торговаться они будут по стратегии наибольшей личной выгоды. То есть как можно больше, в минимальные сроки и дорого (именно от дорого, а не от что и когда, зависит их премия). Поэтому сначала в вашей корпорации ставят план отделу продаж, а потом, когда его выполняют и перевыполняют, и выясняется, что 9 программистов не смогут родить за месяц, потому что они все одного пола. Тогда на presale и начинают отправлять в нагрузку бизнес-аналитика и архитектора.

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

Сложность бытия проводника обычно в том, что ожидание это проводник электричества и сигналы непрерывно текут в оба конца, пусть и звучит это иногда для наблюдателя как подключение модема. На самом деле вы проводник в поезде и разносите чай от головы к хвосту, проходя через вагон ресторан и полностью теряя связь с предыдущем вагоном, как только вошли в тамбур. Все понимают, что без чая хуже и самим его делать не всегда быстро и вкусно, но особой любви не будет. Машинист всё время думает, что он тянет слишком много. Он видит и слышит, что твориться в ближайших вагонах, но то длиннющий хвост явно баласт. Сбросить бы его и взлететь! О том, что в этом составе вагоны не тянут, а толкают, он не думает. Поэтому он любит добавлять вагоны в голову они-то точно несут полезную нагрузку. Он её видит лично. Вагон-ресторан близко к голове и чай с сахаром оттуда разносят во все стороны, а загружают лишь на коротких остановках. Так как самые жирные остановки - не по расписанию, то и забота оберегать запас. Потом вагончики менеджментов. Продажи за коммунизм всем чаю, много и быстро! Вы их не почему-то не поддерживаете. Поддержка и инфраструктуры любят подстаканники и стаканы с готовым чаем, чтоб сразу пить. А все вот эти ваши чаи в пакетиках, сотня сортов, 5 вида сахара с 3 форм факторами, да ещё эта влагочувствительность при хранении. А уж одноразовые странички, которые надо раздавать и утилизировать. Короче, раньше чай был вкусней и проводник знал свое место. В вагоне PM любят только кипяток и маленькими глотками. И заварку подмешивать в каждый глоток, потому что, вдруг захочется другой сорт или вообще кофе. А вы тут с вашими предварительными заказами и не возможности сделать холодно-горячий кофе-чай с безмолоком-сахарнетом. Dev менеджеры любят, чтоб им приносили много и всегда. Но не учили как пить и когда. И не критиковали за то, что чай проливается, если его переливать в карман, пить без стакана, напёрстками, стоя на голове. Что сливать остатки в один стакан это не новый сорт, и есть сахар это не то же самое, что пить чай. Потом синьоры-эстеты. Они обязательно должны заваривать сами и не любят прозрачные стаканы, в которых всё видно. В общем вас действительно ждут только в хвосте, где сидят джуны, но их нужно поить каждого отдельно и ложечкой. Ну и, конечно, своего вагона у вас нет.

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

Обычный клиент получает ванильку. Энтерпрайз клиенту туда добавят шоколад и орешки.
Функционал и вид могут сильно отличаться. Ваша задача не пойти лёгкой дорогой и создать бранч под клиента или утыкать всё ифками. Компания не хочет больше расходов на тесты и модификацию, хрупкий код и поддержку. Чтоб остаться с как можно меньшими частями специфичного клиента не плохо было бы использовать заменяемые модули, enrichment, event drive, плагины, no-code.

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

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

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

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

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

Помните Vendor lock? Не рассчитывайте, что ваша система будет полностью в ваших руках. Если это on-prem, то и вообще доступа не будет. Учитывайте, что дебажить надо будет по логам, а поддержка будет оперировать с огромной задержкой. Описание проблемы вы получите частичное и запоздалое. Многоуровнивые логи, чёткие сообщения об ошибках, система предупреждений (warnings) и развёрнутого healthcheck. Инструменты для сбора необходимой информации. Всё, что часто называют production readiness, должно быть частью архитектуры.


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

a.На других посмотреть

i. Возраст организации не показатель опыта и профессионализма

ii. Время всегда работает против вас

iii. Нужного спеца лови на живца!

iv. Следи за собой будь осторожен.

b.Себя показать

i. Не оставлять предпродажу на самотёк

ii. Вы часть той силы, что хотит добра, но

iii. Окружение формирует архитектуру

Подробнее..

Как программист читает Происхождение видов Дарвина

01.09.2020 08:13:07 | Автор: admin
Во время чтения Происхождения видов путем естественного отбора Чарльза Дарвина, меня не покидало стойкое дежавю. Позже я понял, что механизмы, описанные в книге сильно коррелируют с механизмами enterprise разработки в больших компаниях. Где в качестве условий окружающей среды выступают постоянно меняющиеся бизнес-требования и программисты, а в качестве организмов код.

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

Глава V. Законы вариации. Краткий обзор


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

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

Термины, которые я заменил в оригинальном параграфе



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


Еще заменил термины, которые в данном контексте будут выглядеть странно:
  • употребление -> использование (так как слово выглядит немного устаревшим)
  • организация -> структура приложения (чтобы смысл был верным)
  • образ жизни -> жизненный цикл


Так же предлагаю ознакомиться с оригинальным параграфом, его я спрятал под спойлер.

Читать оригинальный параграф из книги
Наше незнание законов вариации глубоко. Ни в одном из 100 случаев мы не можем определить причину, почему тот или другой орган изменился. Но во всех случаях, где мы обладаем средствами для сравнения, оказывается, что образование меньших различий между разновидностями одного вида вызывается действием тех же законов, что и больших различий между видами одного рода. Перемены в условиях обычно вызывают только колеблющуюся вариабельность, но иногда ведут к прямым и определенным результатам: и эти результаты с течением времени могут сделаться более сильно выраженными, хотя в пользу этого еще не имеется достаточного доказательства. Привычка в образовании конституциональных особенностей, употребление в усилении органа и неупотребление в их ослаблении и уменьшении во многих случаях кажутся мощными в своем действии. Части гомологичные склонны варьировать одинаковым образом, а равно и связываться друг с другом. Модификация твердых и наружных частей действует на части мягкие и внутренние. Когда одна какая-нибудь часть сильно развивается, она, возможно, отвлекает питательные вещества от с нею смежных частей, и всякая часть организации, которая может быть устранена без ущерба, будет устранена. Изменения в строении в раннем возрасте могут воздействовать на части, развивающиеся позднее; несомненно, встречаются многочисленные случаи коррелятивной вариации, природу которой мы не способны понять. Части, многократно повторяющиеся, изменчивы как в своем числе, так и в строении, и это, вероятно, проистекает из отсутствия строгой специализации таких частей для какой-либо особой функции, так что их модификациям не препятствовал естественный отбор. Последствием этой же причины, быть может, является факт, что органические существа, стоящие на низших ступенях органической лестницы, более изменчивы, чем вышестоящие, вся организация которых более специализирована. Органы рудиментарные, будучи бесполезными, не подпадают под действие естественного отбора и поэтому изменчивы. Признаки видовые, т. е. признаки, которыми виды одного рода стали различаться с того времени, как они ответвились от общего предка, более изменчивы, чем признаки родовые, т. е. такие, которые унаследованы издавна и у которых на протяжении указанного периода не возникали различия. В этих замечаниях мы касались специальных органов или частей, но тем не менее изменчивых, потому что они варьировали еще недавно и вследствие этого становились различными; но во II главе мы видели, что тот же принцип применим и к особи в целом. Мы убедились, что в области, заключающей много видов данного рода, т. е. где недавно происходило значительное изменение и дифференцировка или где активно шло производство новых видовых форм, в такой области и у таких видов мы и в настоящее время встречаем в среднем наибольшее число разновидностей. Вторичные половые признаки очень изменчивы; они же сильно различаются у видов одной группы. Изменчивость одних и тех же частей организации обычно была полезной как для образования вторичных половых различий между двумя полами одного вида, так и образования видовых различий между видами одного рода. Всякая часть или орган, чрезмерно или исключительным образом развитые по сравнению с той же частью или органом у родственных видов, должны были подвергнуться модификации в необычайных размерах со времени возникновения этого рода; отсюда нам понятно, почему они еще часто изменчивы в гораздо более значительной мере, чем другие части, так как вариация представляет медленный и долго длящийся процесс и естественный отбор в подобных случаях не располагал до сих пор достаточным временем, чтобы осилить тенденцию к дальнейшей изменчивости и реверсии к менее модифицированному состоянию. Но когда вид с необычайно развитым органом сделался родоначальником многочисленных модифицированных потомков, что, согласно моему взгляду, должно быть крайне медленным процессом, требующим огромного промежутка времени, то в подобном случае естественный отбор уже успел сообщить этому органу постоянные черты, несмотря на необычайность его развития. Виды, унаследовавшие от своего общего предка почти одинаковую конституцию и подвергшиеся воздействию сходных условий, естественно, имеют наклонность давать аналогичные вариации или иногда возвращаются к некоторым признакам своих далеких предков. Хотя, из-за реверсии и аналогичной вариации, новые и важные модификации не могут возникать, такие модификации будут добавляться к прекрасному и гармоничному многообразию природы.
Какова бы ни была причина, быть может, каждого слабого различия между потомством и их родителями и причина для каждого из них должна существовать, мы имеем основание полагать, что неуклонное кумулирование благоприятных различий вызвало все наиболее важные модификации строения в связи с образом жизни каждого вида.




Небольшое объяснение



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

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

Пример 1


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

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


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

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

Пример 2


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

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

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

Пример из жизни:
Если вы используете в проекте, например, кнопки из CSS Bootstrap фреймворка, то очевидно, что чаще будет меняться содержимое классов .btn или .btn-primary, чем переименовывание этих классов во что-нибудь в духе .g-button или g-button-first

Заключение


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

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

Ловушки для современного PHP

26.12.2020 16:10:02 | Автор: admin


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


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


Примечание


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


PHP для "простых" решений и малого бизнеса


Первое очевидное применение языка лежит в написании на нём всевозможных сайтов-визиток, интернет-магазинов, форумов и даже немного стартапов. PHP долгое время был крайне прост и не имел множества фич, присущих более строгим языкам.


Также язык был крайне нетребователен к инфраструктуре, так как можно было просто поправить нужный файлик на своей VPSке прямо через FTP, без сборок и релизов.
К квалификации разработчиков он, впрочем, тоже был нетребователен, так как интерпретируемый, типизация слабая, а архитектура вообще уникальна: php "обречен на смерть" и каждый запрос обрабатывается в новом процессе, можно не бояться ни утечек памяти, ни манипуляций общим состоянием программы, ни прочих способов одному запросу помешать другому.
Также из-за своей динамической структуры PHP стал отличным движком для создания CMS, позволяя очень легко расширить и отладить программу, методом подкладывания на сервер файликов с исходниками, для чего даже не нужно быть программистом.


Итого, был язык, простой, как палка, прощающий множество ошибок, легкий для изучения и в целом нетребовательный. Логично, такой привлекает множество разработчиков не самой высокой квалификации, просто за счёт того, что более высокая квалификация для работы им и не требуется. А это порождает следующее: низкая квалификация означает низкие рейты, низкие рейты означают привлекательность для малого бизнеса, а это создаёт множество рабочих место и своеобразную популярность, привлекая ещё больше новичков и тд и тп.
Где-то здесь находятся и стартапы: имея в начале мало денег и вынужденные выживать среди бесконечных MVP и перестроек, им проще взять что-то максимально простое и дешевое. Большинство стартапов, конечно, умирает, но самые удачливые "выстреливают", стремительно обрастая деньгами и более развитыми технологиями, при этом продолжая нести в себе ядро из всем знакомого PHP. Привет, Facebook, VK, Slack, Такси и тд и тп.
Область понятна, как понятно и то, что нужно сделать для того, чтобы оставаться "королём CMSок": ничего не испортить. Нужно просто быть таким же простым и, может, даже примитивным, чтобы за счёт этого выигрывать популярность среди новичков и малого бизнеса у более навороченных технологий.


PHP для энтерпрайза


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


И всё кажется прекрасным, потому что "энтерпрайзный PHP" действительно даёт возможность нормально писать сложные продукты и даже не сильно при этом страдать, но здесь есть одно большое НО и имя ему Java (либо C#).
В виртуальную машину Java вложены десятки тысяч человеко-лет, которые делают её лучшей на текущий момент виртуальной машиной в мире. Тулчейн и экосистема джавы развивались годами сразу для серьезного языка и тоже множеством людей и компаний, в итоге предоставив огромную и крайне проработанную экосистему (от IDE до стандартов и библиотек), равной которой найти сложно и равной которой экосистема PHP при всех её плюсах не является. На Java пишет намного больше квалифицированных разработчиков, а также намного больше серьёзных энтерпрайз решений, что означает большие рейты, что означает больше квалифицированных разработчиков и тд и тп.


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


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


PHP для микросервисов и современных фич


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


  • PHP быстр, но и golang/nodejs/{any modern lang} далеко не медленнее, а при этом ещё умеют в ассинхронность/многозадачность "из коробки", без внешних расширений языка, велосипедов и воркеров на супервизорах.
  • PHP много чего умеет, но и golang/nodejs/{any modern lang} могут работать через сокеты "из коробки", а вот "слоник" нет.
  • PHP как бы умеет в функиональщину, но довольно ограниченно, в отличие от современных typescript/scala/kotlin/*.
  • PHP скоро научится в дженерики и аннотации, но эти вещи существуют в той же Java и прочих "современных" языках уже давно, вместе с целым рядом других фич.
  • Ну и уж конечно, в области микросервисов, low latency, выбора и тюнинга сборщиков мусора, замеров аллокаций и прочих элементов разработки действительно высокопроизводительных приложений, php чувствует себя не очень уверенно, будучи изначально не тем (ну не контейнер с nginx, phpfpm и сотней воркеров микросервисом-то называть, в самом-то деле) и не про то.

Чтобы доминировать здесь, PHP было бы необходимо в корне измениться, от синтаксиса до архитектуры своей виртуальной машины и принципов её работы, а также основательно обрасти фичами, что в итоге сделает "слоника" совсем другим языком.
Это опять возвращает нас к вопросу: а нужен ли сообществу тот, новый PHP? И возможно ли стать новым крутым языком с гринтредами, встроенным сервером, монадами и черт знает чем ещё, сохранив свою фирменную нетребовательность?


Выводы


Кажется, что PHP пытается усидеть на нескольких стульях сразу: быть и удобным для быстрокодеров на CMS за 10$ в час, и изучаться за две недели вчерашним студентом чтобы завтра же найти работу, и чтобы уважаемые люди серьёзные проекты для других уважаемых и серьезных людей могли делать, и чтобы всё было современно и красиво. Не порвутся ли эти штаны? Не потеряет ли "слоник" старых пользователей, не снискав при этом достаточного внимания новых?
Непонятно.
Конечно, даже самый негативный вариант не означает неминуемой гибели: легаси написано уже очень много, а разработчиков, знающих и любящих именно PHP тоже порядочно. Языки программирования способны умирать очень долго и крестражей у них значительно больше семи.
Но, с другой стороны, ada, smalltalk, delphi и прочие всё же умерли, а тот же ruby, похоже, завис где-то в чистилище, при наличии и множества программистов, и кодовой базы.
С третьей стороны, пора бы уже включить похороны PHP в список спортивных дисциплин, двадцать лет хоронят уже, да всё не умирает никак вот ведь какая ирония.
Разумеется, даже при самом удачном течении событий, даже успешно совместивший и старое и новое PHP вряд ли станет языком #1.
И уж конечно, никто не заставляет писать на одном только PHP, все будут выносить нагруженные места в приложения на golang, работать с сокетами на ноде и крутить это всё в кубернетесе, но это уже совсем другая история.

Подробнее..

R, Монте-Карло и enterprise задачи, часть 2

05.04.2021 12:20:40 | Автор: admin

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


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


Рассмотрим далее на примере одной из нестандартных задач.


Является продолжением серии предыдущих публикаций.


Постановка задачи


Задача имеет корни в IoT для сельского хозяйства. А именно, расстановка датчиков на картофельном поле с круговой схемой полива. Попросим у гугла немного картинок: Разгадка тайны круглых полей: всё интересней, чем ты думаешь!. Нужно обеспечить нужные характеристики покрытия mesh сети, учитывая допустимые расстояния между соседями. При этом надо оптимизировать бюджет и выдать gps координаты на расстановку датчиков и сформировать кратчайшую схему обхода.


Решение


Подключаем пакеты


Пакеты
library(tidyverse)library(magrittr)library(scales)library(data.table)library(tictoc)library(stringi)library(arrangements)library(ggforce)

Декомпозиця


Сначала попробуем сформировать этапы.


  1. Берем N датчиков.
  2. Ищем оптимальную расстановку.
  3. Если характеристики не достигнуты, увеличиваем N на 1. Повторяем процедуру.
  4. Для найденной расстановки ищем оптимальный маршрут обхода.

План вроде простой. Но как будем решать? Напрашивается метод Монте-Карло.


Функции-хелперы


Оформим функцию для визуального отображения расположения зондов.


Визуализация поля
drawDisk <- function(df) {  # отрисуем расположение точек и действующие силы  # если силы не заданы, создадим их по умолчанию равными 0  for(col in c("force_x", "force_y")){    if (!(col %in% names(df))) df[, col] <- 0  }  ggplot(data = df, aes(x = x, y = y)) +    ggforce::geom_circle(aes(x0 = 0, y0 = 0, r = 1, colour = "red"),                          inherit.aes = FALSE) +    geom_point(size = 2, fill = "black", shape = 21) +    geom_text(aes(label = idx), hjust = 0.5, vjust = -1) +    # рисуем векторное поле    geom_segment(aes(xend = x + force_x / 10, yend = y + force_y / 10),                  colour = "red",                  arrow = arrow(length = unit(0.2,"cm")), size = 0.6) +     xlim(-1.5, 1.5) +    ylim(-1.5, 1.5) +    coord_fixed() +    labs(x = "Ось X", y = "Ось Y") +    theme_bw()}

Генерация первичной расстановки


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


Но есть выход можем вспомнить физику.


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


Генерация первичной расстановки
# Генерим точки-зонды внутри окружности единичного радиуса.# Считаем, что все частицы единичного заряда, поэтому его опускаемcharges_dt <- tibble(idx = 1:13) %>%  mutate(angle = runif(n(), min = 0, max = 2*pi),          r = runif(n(), min = 0, max = 1),         x = r * cos(angle), y = r * sin(angle)) %>%  select(idx, x, y) %>%  setDT(key = "idx")# для сходимости задачи генерируем также зафиксированные точки на внешней окружностиkeepers_dt <- max(charges_dt$idx) %>%   {tibble(idx = (. + 1):(. + 40))} %>%  mutate(angle = (idx - 1) * (2 * pi / n()),         x = 1.3 * cos(angle), y = 1.3 * sin(angle)) %>%  select(idx, x, y) %>%  setDT(key = "idx")

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


Визуализируем
full_dt <- rbindlist(list(charges_dt, keepers_dt))drawDisk(full_dt)

Поиск оптимального расположения


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


  • каждую новую итерацию как движение из статичного состояния (как-бы случайная расстановка зондов);
  • все зонды обладают единичным зарядом и единичной массой.

$s = at^2/2 = (F/m)t^2/2$


Для малых изменений получаем $\delta s = F \delta t$


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


Поиск оптимального расположения
max_force <- 10tic("Balancing charges")# Определяем точность моделирования!# Будем двигать заряды пока они не застабилизируются # Максимальная равнодействуюущая будет близка к 0 # и точки не стали разлетаться в бесконечностьwhile (max_force > 0.05 & nrow(charges_dt[x^2 + y^2 > 1.2]) == 0) {  # общий пул координат частиц на текущую итерацию  full_dt <- rbindlist(list(charges_dt, keepers_dt), fill = TRUE)  ff <- function(x0, y0){    # сила взаимодействия -- 1/r2, заряды единичные;    # проекция силы на оси, sqrt(r2) -- гипотенуза    # суперпозиция векторов даст результирующее воздействие на частицу    dx = full_dt$x - x0    dy = full_dt$y - y0    r2 = dx^2 + dy^2    # na.rm исключает NaN в т.ч.    list(sum(-dx * r2^(-1.5), na.rm = TRUE),         sum(-dy * r2^(-1.5), na.rm = TRUE))  }    # проведем расчет сил, итерируем по каждой "неприбитой гвоздями" точке  charges_dt[, c("force_x", "force_y") := ff(x0 = x, y0 = y), by = idx]  # определим максимальную силу, действующую на частицу  max_force <- charges_dt[, max(sqrt(force_x^2 + force_y^2), na.rm = TRUE)]  force_scale = if_else(max_force > 1, 1 / max_force / 1e2, 1/ max_force / 5e2)  # проводим передвижение точек  charges_dt %>%    .[, `:=`(x = x + force_x * force_scale,              y = y + force_y * force_scale)]}toc()full_dt <- rbindlist(list(charges_dt, keepers_dt), fill = TRUE)

Оптимизация маршрута обхода


Для выбора оптимального маршрута опять же используем Монте-Карло. Ряд соображений:


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

Оптимизация маршрута обхода
optimizePath <- function(dt) {  # попробуем оптимизировать маршрут обхода по предоставленным точкам  # 1. Выбираем в качестве начальной точки датчик, максимально близко расположенный к краю поля  dt[, r0 := sqrt(x^2+y^2)] %>%    setorder(-r0)  n1 <- dt[1, idx]  # теперь проводим симуляцию различных вариантов расстановки сенсоров  # получаем последовательность номеров и убираем n1, его будем принудительно ставить первым  points_in <- dt[idx != n1, idx]  # для каждой точки добавим еще ближайшую точку выхода   # (перпендикуляр к окружности, которая единичного радиуса)  augment_tbl <- dt %>%    mutate_at("idx", `*`, -1) %>%    mutate(r0 = sqrt(x^2 + y^2)) %>%    mutate_at(vars(x, y), ~(.x/r0)) %>%    bind_rows(dt) %>%    select(idx, x, y)  # однократно посчитаем матрицу расстояний между зондами  ll_tbl <- unique(augment_tbl$idx) %>%    tidyr::expand_grid(l = ., r = .) %>%    filter(l != r, (l > 0 | r > 0)) %>%    # построим уникальный идентификатор ребра    rowwise() %>%    # mutate(m = list(sort(c(l, r))))    mutate(edge_id = stri_c(sort(c(l, r)), collapse = "=")) %>%    ungroup() %>%    distinct(edge_id, .keep_all = TRUE) %>%    # подтягиваем координаты левой точки    left_join(select(augment_tbl, idx, l_x = x, l_y = y), by = c("l" = "idx")) %>%    # подтягиваем координаты левой точки    left_join(select(augment_tbl, idx, r_x = x, r_y = y), by = c("r" = "idx")) %>%    mutate(s = sqrt((l_x - r_x)^2 + (l_y - r_y)^2)) %>%    arrange(l, r)  points_seq <- arrangements::permutations(v = points_in, replace = FALSE,                                        layout = "column", nsample = 5000)  # добавляем точку входа в качестве первой и соотв. точку выхода в качестве последней  routes_lst <- points_seq %>%     rbind(-n1, n1, ., -tail(., 1)) %>%    as.data.frame() %>% as.list()  # превращаем все пути обхода в последовательности ребер  routes_dt <- data.table(route_id = seq_along(routes_lst), route = routes_lst) %>%    .[, .(from = unlist(route)), by = route_id] %>%    .[, to := shift(from, type = "lead"), by = route_id] %>%    # выкидываем все терминальные точки    na.omit() %>%    # строим нормализованный идентификатор ребра    .[, edge_id := stri_c(sort(unlist(.BY)), collapse = "="), by = .(from, to)] %>%    .[, .(route_id, edge_id)] %>%    # подтянем информацию о длине ребра из справочника    .[as.data.table(ll_tbl), s := i.s, on = "edge_id"]  # считаем длину маршрутов, оставляем кратчайший  best_routes <- routes_dt[, .(len = sum(s)), by = route_id] %>%    setorder(len) %>%    head(10) %T>%    print()  # сформируем ТП-10 лучших маршрутов  best_routes %>%    select(route_id) %>%    mutate(idx = routes_lst[route_id]) %>%    tidyr::unnest(idx) %>%    left_join(augment_tbl) %>%    tidyr::nest(data = -route_id) %>%    left_join(best_routes)}

Получаем табличку подобного рода


    route_id      len 1:     2070 8.332854 2:     2167 8.377680 3:     4067 8.384417 4:     3614 8.418678 5:     5000 8.471521 6:     4495 8.542041 7:     2233 8.598278 8:     4430 8.609391 9:     2915 8.61604810:     3380 8.695547

И посмотрим результат размещения


Визуализируем
tic("Route optimization")best_tbl <- optimizePath(charges_dt)toc()best_route_tbl <- best_tbl$data[[1]]full_dt <- rbindlist(list(best_route_tbl, keepers_dt), fill = TRUE)gp <- drawDisk(full_dt) +  # добавим маршрут обхода  geom_path(arrow = arrow(type = "closed"), data = best_route_tbl)gp

Маршрут обхода


Формирование задания


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


Полезные трюки


Как всегда, затронем вопросы производительности. Если писать не думая, то можно отправить машину на счет на часы или дни. tidyverse подход оказывается медленнее в $10^3$-$10^4$ раз. В приведенном выше коде расчеты по блокам занимают доли секунды. Этого достаточно для обычной задачи, но если нужно быстрее, то можно делать вставки на C++. В целом, скоростные характеристики достигаются результат рядом мер и методик.


  1. Для небольших циклических расчетов накладные расходы на разыменовывание переменных даже в data.table могут оказаться значительными. Base R в блоке поиска оптимального расположения дает выйгрыш на порядок.
  2. Если задачу можно распараллелить, то надо применять функциональные подходы. Проще будет сделать последующее распараллеливание.
  3. Для однородных величин работа с матрицами оказывается на несколько порядков быстрее работы с data.frame. Связано это со схемой выделения памяти и адресации к элементам. Про матрицы незаслуженно забывают при погружении в tidyverse.
  4. Все, что можно посчитать однократно и оформить в виде справочной таблицы, должно быть посчитано заранее.
  5. Монте-Карло очень хороший подход. Быстрое первичное применение может дать полезный результат, а также взглянуть на решение задачи и, возможно, найти какие-то упрощения и аналитики.
  6. Не стесняемся использовать методы аналогии. Они могут позволить построить упрощенную модель исходной задачи, которая вычислительно существенно проще исходной и легко перекладывается на Монте-Карло.

Предыдущая публикация Дети, русский язык и R.

Подробнее..

R и работа со временем. Что за кулисами?

29.04.2021 18:18:03 | Автор: admin

Даты и время являются весьма непростыми объектами:


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

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


Совсем краткое резюме для смартфоночиталей: на больших объемах данных используем только POSIXct с дробными долями секунд. Будет хорошо, понятно, быстро.


Является продолжением серии предыдущих публикаций.


Стандарты для специфицирования дат и времени


ISO 8601 Data elements and interchange formats Information interchange Representation of dates and times is an international standard covering the exchange of date- and time-related data.


Базовые методы для работы с датой


Дата


Sys.Date()print("-----")x <- as.Date("2019-01-29") # в UTCprint(x)tz(x)str(x)dput(x)print("-----")dput(as.Date("1970-01-01")) # ! origin

Вывод в консоль
## [1] "2021-04-29"## [1] "-----"## [1] "2019-01-29"## [1] "UTC"##  Date[1:1], format: "2019-01-29"## structure(17925, class = "Date")## [1] "-----"## structure(0, class = "Date")

Нестандартный формат даты при инициализации должен специфицироваться специально


as.Date("04/20/2011", format = "%m/%d/%Y")

## [1] "2011-04-20"

Время


В R применяются два базовых типа времени: POSIXct и POSIXlt.
Внешние представления POSIXct и POSIXlt выглядят похожими. А внутренние?


z <- Sys.time()glue("Внешнее представление",      "POSIXct - {z}",      "POSIXlt - {as.POSIXlt(z)}", "---", .sep = "\n")glue("Внутреннее представление",      "POSIXct - {capture.output(dput(z))}",      "POSIXlt - {paste0(capture.output(dput(as.POSIXlt(z))), collapse = '')}",     "---", .sep = "\n")# Получение отдельных элементов даты/времени базовыми средствамиglue("Год: {year(z)} \nМинуты: {minute(z)}\nСекунды: {second(z)}\n---")

Вывод в консоль
## Внешнее представление## POSIXct - 2021-04-29 15:18:04## POSIXlt - 2021-04-29 15:18:04## ---## Внутреннее представление## POSIXct - structure(1619698684.50764, class = c("POSIXct", "POSIXt"))## POSIXlt - structure(list(sec = 4.50764489173889, min = 18L, hour = 15L,     mday = 29L, mon = 3L, year = 121L, wday = 4L, yday = 118L,     isdst = 0L, zone = "MSK", gmtoff = 10800L), class = c("POSIXlt", "POSIXt"), tzone = c("", "MSK", "MSD"))## ---## Год: 2021 ## Минуты: 18## Секунды: 4## ---

Сразу делаем заключение, что для серьезной работы с данными (более 10 строк с временем), про POSIXlt забываем как про страшный сон.


POSIXct по своей сути является оберткой для unixtimestamp, количество секунд (миллисекунд) с некоей нулевой точки (обычно за 0 полагают 01.01.1970). Делаем ставку в работе именно на него.


Полезный инструмент online преобразование времени в unixtimestamp:



Sys.time()z <- 1548802400as.POSIXct(z, origin = "1970-01-01")                # localas.POSIXct(z, origin = "1970-01-01", tz = "UTC")    # in UTC

Вывод в консоль
## [1] "2021-04-29 15:18:04 MSK"## [1] "2019-01-30 01:53:20 MSK"## [1] "2019-01-29 22:53:20 UTC"

Работа с долями секунды


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


  • по рекомендациям ISO, с долями секунд в виде дробной части (ISO 8601-2019);
  • с какими-нибудь другими разделителями;
  • как отдельное поле.

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


x <- ymd_hms("2014-09-24 15:23:10")xx + 0.5x + 0.5 + 0.6options(digits.secs=5)x + 0.45756options(digits.secs=0)x

Вывод в консоль
## [1] "2014-09-24 15:23:10 UTC"## [1] "2014-09-24 15:23:10 UTC"## [1] "2014-09-24 15:23:11 UTC"## [1] "2014-09-24 15:23:10.45756 UTC"## [1] "2014-09-24 15:23:10 UTC"

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


options(digits.secs=5)# generate datadf <- data.frame(  timestamp = as_datetime(    round(runif(20, min = now() - seconds(10), max = now()), 0),     tz ="Europe/Moscow")) %>%  mutate(ms = round(runif(n(), 0, 999), 0)) %>%  mutate(value = round(runif(n(), 0, 100), 0))dput(df)# сортируем "в лоб"df %>%  arrange(timestamp, ms)options(digits.secs=0)

Вывод в консоль
## structure(list(timestamp = structure(c(1619698677, 1619698680, ## 1619698676, 1619698682, 1619698675, 1619698682, 1619698679, 1619698679, ## 1619698684, 1619698683, 1619698684, 1619698677, 1619698682, 1619698683, ## 1619698675, 1619698676, 1619698685, 1619698681, 1619698683, 1619698681## ), class = c("POSIXct", "POSIXt"), tzone = "Europe/Moscow"), ##     ms = c(418, 689, 729, 108, 226, 843, 12, 370, 5, 581, 587, ##     691, 102, 79, 640, 284, 241, 85, 329, 936), value = c(63, ##     44, 63, 45, 29, 34, 80, 85, 42, 76, 94, 89, 34, 80, 1, 66, ##     29, 81, 15, 98)), class = "data.frame", row.names = c(NA, ## -20L))


# "умное" преобразование# [magrittr aliases](http://personeltest.ru/aways/magrittr.tidyverse.org/reference/aliases.html)df2 <- df %>%  mutate(timestamp = timestamp + ms/1000) %>%  # mutate_at("timestamp", ~`+`(. + ms/1000)) %>%  select(-ms)df2 %>% arrange(timestamp)


# сравним подходыdt <- as.data.table(df2)bench::mark(  naive = dplyr::arrange(df, timestamp, ms),  smart = dplyr::arrange(df2, timestamp),  dt = dt[order(timestamp)],  check = FALSE,  relative = TRUE,  min_iterations = 1000)

## # A tibble: 3 x 6##   expression   min median `itr/sec` mem_alloc `gc/sec`##   <bch:expr> <dbl>  <dbl>     <dbl>     <dbl>    <dbl>## 1 naive       11.9   11.8      1         1.06     1   ## 2 smart       11.1   11.0      1.06      1        1.06## 3 dt           1      1       11.6     494.       1.22

Парсинг данных с миллисекундами.


data <- c("05102019210003657", "05102019210003757", "05102019210003857")dmy_hms(stri_c(stri_sub(data, to = 14L), ".", stri_sub(data, from = 15L)), tz = "Europe/Moscow")# Измерение скорости различных вариантовdata2 <- data %>%  sample(10^6, replace = TRUE)bench::mark(  stri_sub = stri_c(stri_sub(data2, to = 14L), ".", stri_sub(data2, from = 15L)),  stri_replace = stri_replace_first_regex(data2, pattern = "(^.{14})(.*)", replacement = "$1.$2"),  re2_replace = re2_replace(data2, pattern = "(^.{14})(.*)", replacement = "\\1.\\2", parallel = TRUE))

Вывод в консоль
## [1] "2019-10-05 21:00:03 MSK" "2019-10-05 21:00:03 MSK"## [3] "2019-10-05 21:00:03 MSK"## # A tibble: 3 x 6##   expression        min   median `itr/sec` mem_alloc `gc/sec`##   <bch:expr>   <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>## 1 stri_sub        214ms    222ms      4.10   22.89MB     5.47## 2 stri_replace    653ms    653ms      1.53    7.63MB     0   ## 3 re2_replace     409ms    413ms      2.42   15.29MB     1.21

Пакет lubridate


x <- ymd(20101215)print(x)class(x)

## [1] "2010-12-15"## [1] "Date"

Магия lubridate


ymd(20101215) == mdy("12/15/10")

## [1] TRUE

df <- tibble(first = c("Иван", "Петр", "Алексей"),             last = c("Иванов", "Петров", "Сидоров"),             birthday_str = c("31-10-06", "2/4/2007", "1 June, 2005")) %>%  mutate(birthday = dmy(birthday_str))df


А что делать, если время может поступать в частично обрезанном формате?


# управляем отображением форматов парсинга в lubridateoptions(lubridate.verbose = TRUE)# базовый формат даты: д.м.гdf <- tibble(time_str = c("08.05.19 12:04:56", "09.05.19 12:05", "12.05.19 23"))lubridate::dmy_hms(df$time_str, tz = "Europe/Moscow")print("---------------------")lubridate::dmy(df$time_str, tz = "Europe/Moscow")

## [1] "2019-05-08 12:04:56 MSK" NA                       ## [3] NA                       ## [1] "---------------------"## [1] NA NA NA

Разрешим вариативность определенной глубины


# управляем отображением форматов парсинга в lubridateoptions(lubridate.verbose = TRUE)lubridate::dmy_hms(df$time_str, truncated = 3, tz = "Europe/Moscow")

## [1] "2019-05-08 12:04:56 MSK" "2019-05-09 12:05:00 MSK"## [3] "2019-05-12 23:00:00 MSK"

# управляем отображением форматов парсинга в lubridateoptions(lubridate.verbose = TRUE)# базовый формат даты: д.м.гdf <- tibble(date_str = c("08.05.19", "9/5/2019", "2019-05-07"))

Пробуем провести конвертацию


# пробуем первый вариантglimpse(dmy(df$date_str))print("---------------------")# пробуем второй вариантglimpse(ymd(df$date_str))print("---------------------")

##  Date[1:3], format: "2019-05-08" "2019-05-09" NA## [1] "---------------------"##  Date[1:3], format: "2008-05-19" NA "2019-05-07"## [1] "---------------------"

Что делать? Вариант, конечно, ужасен, но что-то можно поделать.


df %>%  mutate(date = dplyr::coalesce(dmy(date_str), ymd(date_str)))

tab4


df1 <- dfdf1$date <- dmy(df1$date_str)idx <- is.na(df1$date)print("---------------------")idxdf1$date[idx] <- ymd(df1$date_str[idx])print("---------------------")df1

## [1] "---------------------"## [1] FALSE FALSE  TRUE## [1] "---------------------"

tab5


Еще пакеты


Еще пакеты на "посмотреть" и поизучать:



Арифметические операции с POSIXct


Разность


options(lubridate.verbose = FALSE)date1 <- ymd_hms("2011-09-23-03-45-23")date2 <- ymd_hms("2011-10-03-21-02-19")# какова разница между этими датами?as.numeric(date2) - as.numeric(date1) # как мы помним, разница в секундах(date2 - date1) %>% dput()difftime(date2, date1)difftime(date2, date1, unit="mins")difftime(date2, date1, unit="secs")

## [1] 926216## structure(10.7200925925926, class = "difftime", units = "days")## Time difference of 10.72009 days## Time difference of 15436.93 mins## Time difference of 926216 secs

Периоды


date1 <- ymd_hms("2019-01-30 00:00:00")date1date1 - days(1)date1 + days(1)date1 + days(2)

## [1] "2019-01-30 UTC"## [1] "2019-01-29 UTC"## [1] "2019-01-31 UTC"## [1] "2019-02-01 UTC"

А теперь более сложный пример добавляем месяцы


date1 - months(1)date1 + months(1) # УПС!!!

## [1] "2018-12-30 UTC"## [1] NA

Есть выход. Но операции не коммутативны, это надо помнить.


date1 %m-% months(1)date1 %m+% months(1)date1 %m+% months(1) %m-% months(1)

## [1] "2018-12-30 UTC"## [1] "2019-02-28 UTC"## [1] "2019-01-28 UTC"

Нюансы временных зон


date1 <- ymd_hms("2019-01-30 01:00:00")date1 %T>% print() %>% dput()with_tz(date1, tzone = "Europe/Moscow") %T>% print() %>% dput()force_tz(date1, tzone = "Europe/Moscow") %T>% print() %>% dput()

Вывод в консоль
## [1] "2019-01-30 01:00:00 UTC"## structure(1548810000, class = c("POSIXct", "POSIXt"), tzone = "UTC")## [1] "2019-01-30 04:00:00 MSK"## structure(1548810000, class = c("POSIXct", "POSIXt"), tzone = "Europe/Moscow")## [1] "2019-01-30 01:00:00 MSK"## structure(1548799200, class = c("POSIXct", "POSIXt"), tzone = "Europe/Moscow")

Работа только с временми значениями


Что делать, если у нас есть только время, а даты не указаны? Не проблема, нам поможет пакет hms. Такие данные представляются как периоды.


hms_str <- "03:22:14"as_hms(hms_str)dput(as_hms(hms_str))print("-------")x <- as_hms(hms_str) * 15xstr(x)# seconds_to_period(period_to_seconds(x))seconds_to_period(x) %T>% dput() %>% print()

Вывод в консоль
## 03:22:14## structure(12134, units = "secs", class = c("hms", "difftime"))## [1] "-------"## Time difference of 182010 secs##  'difftime' num 182010##  - attr(*, "units")= chr "secs"## new("Period", .Data = 30, year = 0, month = 0, day = 2, hour = 2, ##     minute = 33)## [1] "2d 2H 33M 30S"

БД и временне данные


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


Потенциальные сложности и засады:


  • При запросе у БД колонки времени под ее капотом может происходить масса метаморфоз. БД сериализует timestamp, при этом могут оказать свое влияние параметры временных зон из БД, ОС, поля, смежного поля, переменных окружения.
  • При получении данных на клиентской стороне вмешивается драйвер (серия драйверов и врапперов). При развертывании времени замешивается логика драйверов, параметры локали ОС, языковые и временные параметры среды, значение переменных окружения и отражение лунного света в болоте.
  • В поле unixtimestamp разработчики могут помещать отнюдь не UTC время, а московское. Или иное (сюрприз!).
  • В БД может быть агрегация и партиционирование по дате, вычисляемой на основании поля timestamp. В силу расхождения в трактовке временных зон, данные за день Х вполне могут уехать в партиции X-1 или X+1, что необходимо учитывать при построении быстрого запроса к БД.

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


Чтобы избежать этого и параллельно получить еще массу преимуществ достаточно перейти на ручное управление.
Суть заключается в переводе дат в числовой формат на стороне базы и обратное преобразование во время (там, где надо) на стороне клиента. Такое решение не сильно обременительно, зато дает дает массу преимуществ:


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

Трюк по экономии памяти и времени исполнения без потери информации


-- диалект ClickHouseSELECT DISTINCT    store, pos,    timestamp, ms,    concat(toString(store), '-', toString(pos)) AS pos_uid,    toFloat64(timestamp) + (ms / 1000)          AS timestamp

flog.info(paste("SQL query:", sql_req))tic("Загрузка из CH")raw_df <- dbGetQuery(conn, stri_encode(sql_req, to = "UTF-8")) %>%  mutate_if(is.character, `Encoding<-`, "UTF-8") %>%  as_tibble() %>%  mutate_at(vars(timestamp), anytime::anytime, tz = "Europe/Moscow") %>%  mutate_at("event", as.factor)flog.info(capture.output(toc()))DBI::dbDisconnect(conn)

Хелпер для детального анализа занимаемой data.frame памятью


# сводка по объемам данныхdf -> as_tibble(_df) %>%  map(pryr::object_size) %>%   unlist() %>%   enframe() %>%   arrange(desc(value)) %>%  mutate_at("value", fs::as_fs_bytes) %>%  mutate(ratio = formattable::percent(value / sum(value), 2)) %>%  add_row(name = "TOTAL", value = sum(.$value))

Повторно полезные ссылки по форматам и калькуляторам, необходимым при анализе путей следования дат в ИС и БД



Форматирование дат


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


Привязка к рабочим неделям


df <- seq.Date(from = as.Date("2021-01-01"),                to = as.Date("2021-05-31"),                by = "2 days") %>%  # sample(20, replace = FALSE) %>%  tibble(date = .)

# формируем композитное представление год/месяц/номер недели# способ 1df %>%  mutate(month_num = stri_c(lubridate::year(date),                             sprintf("%02d", lubridate::month(date)),                             sep = "/"),         week_num = stri_c(lubridate::isoyear(date),                            sprintf("%02d", lubridate::isoweek(date)),                            sep = "/")  )

tab6


# формируем композитное представление год/месяц/номер недели# способ 2, заодно добавим день недели# особое внимание обращаем, что текстовые поля генерятся согласно текущей локали!!!df %>%  mutate(month_num = format(date, "%Y/%m (%a) ISO week %V"))

tab7


# формируем композитное представление год/месяц/номер недели# способ 3, заодно добавим день недели# хелпер по преобразованию формата strptime (ISO 8601) в ICU# https://man7.org/linux/man-pages/man3/strptime.3.htmlstri_datetime_fstr("%Y/%m (%a) week %V")# ggthemes::tableau_color_pal("Tableau 20")(20) %>% scales::show_col()# особое внимание обращаем, что мы можем управлять локалью самостоятельно!!!df %>%  mutate(    month_num_ru = stri_datetime_format(      date, "yyyy'/'MM' ('ccc') week 'ww", locale = "ru", tz = "UTC"),    month_num_en = stri_datetime_format(      date, "yyyy'/'MM' ('ccc') week 'ww", locale = "en", tz = "UTC"))

tab8


Дни недели


Пишем дни недели в различных локалях. Не зависит от платформы исполнения.


stri_datetime_format(today(), "LLLL", locale="ru@calendar=Persian")stri_datetime_format(today(), "LLLL", locale="ru@calendar=Indian")stri_datetime_format(today(), "LLLL", locale="ru@calendar=Hebrew")stri_datetime_format(today(), "LLLL", locale="ru@calendar=Islamic")stri_datetime_format(today(), "LLLL", locale="ru@calendar=Coptic")stri_datetime_format(today(), "LLLL", locale="ru@calendar=Ethiopic")stri_datetime_format(today(), "dd MMMM yyyy", locale="ru")stri_datetime_format(today(), "LLLL d, yyyy", locale="ru")

## [1] "ордибехешт"## [1] "ваисакха"## [1] "ияр"## [1] "рамадан"## [1] "бармуда"## [1] "миазия"## [1] "29 апреля 2021"## [1] "апрель 29, 2021"

Собственное форматирование дат по осям графиков


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


# сгенерируем тестовые данныеmap_tbl <- tibble(  date = as_date(Sys.time() + rnorm(10^3, mean = 0, sd = 60 * 60 * 24 * 7))) %>%  mutate(store = stri_c(sample(c("A", "F", "Y", "Z"), n(), replace = TRUE),                        sample(101:105, n(), replace = TRUE))) %>%  mutate(store_fct = as.factor(store)) %>%  mutate(fail_ratio = abs(rnorm(n(), mean = 0.3, sd = 1)))

my_date_format <- function (format = "dd MMMM yyyy", tz = "Europe/Moscow") {  scales:::force_all(format, tz)  # stri_datetime_fstr("%d.%m%n%A")  # stri_datetime_fstr("%d.%m (%a)")  function(x) stri_datetime_format(x, format, locale = "ru", tz = tz)}# такой же график, но в развертке по горизонталиgp <- map_tbl %>%  ggplot(aes(x = date, y = store_fct, fill = fail_ratio)) +  geom_tile(color = "white", size = 0.1) +  # scale_fill_distiller(palette = "RdYlGn", name = "Fail Ratio", label = comma) +  # scale_fill_distiller(palette = "RdYlGn", name = "Fail Ratio", guide = guide_legend(keywidth = unit(4, "cm"))) +  scale_fill_distiller(palette = "RdYlGn", name = "Fail Ratio") +  scale_x_date(breaks = scales::date_breaks("1 week"), labels = my_date_format("dd'.'MM' ('ccc')'")) +  coord_equal() +  labs(x = NULL, y = NULL, title = "Средний % сбоев по дням") +  theme_minimal() +  theme(plot.title = element_text(hjust = 0)) +  theme(axis.ticks = element_blank()) +  theme(axis.text = element_text(size = 7)) +  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +  theme(legend.position = "bottom") +  theme(legend.key.width = unit(3, "cm"))gp

heatmap


Тесты производительности


Простая математика


Создадим тестовый набор записей


base_df <- tibble(  start = Sys.time() + rnorm(10^3, mean = 0, sd = 60 * 24 * 3)) %>%  mutate(finish = start + rnorm(n(), mean = 100, sd = 60)) %>%  mutate(user_id = sample(as.character(1000:1100), n(), replace = TRUE)) %>%  arrange(user_id, start)dt <- as.data.table(base_df, key = c("user_id", "start")) %>%  .[, c("start", "finish") := lapply(.SD, as.numeric),     .SDcols = c("start", "finish")]

Сам бенчмарк
df <- group_by(base_df, user_id)bench::mark(  dplyr_v1 = df %>% transmute(delta_t = as.numeric(difftime(finish, start, units = "secs"))) %>% ungroup(),  dplyr_v2 = ungroup(df) %>% transmute(delta_t = as.numeric(difftime(finish, start, units = "secs"))),  dplyr_v3 = dt %>% transmute(delta_t = finish - start),  dt_v1 = dt[, .(delta_t = finish - start), by = user_id],  dt_v2 = dt[, .(delta_t = finish - start)],  check = FALSE # all_equal работает более корректно)

## # A tibble: 5 x 6##   expression      min   median `itr/sec` mem_alloc `gc/sec`##   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>## 1 dplyr_v1      4.3ms   4.86ms      200.   103.1KB    11.4 ## 2 dplyr_v2     2.17ms   2.46ms      380.    17.9KB     6.24## 3 dplyr_v3     1.67ms   1.77ms      527.    29.8KB     8.51## 4 dt_v1       410.4us  438.7us     2139.    90.8KB     8.35## 5 dt_v2       304.4us  335.3us     2785.   264.6KB     8.38

У меня данные хранятся в формате год/месяц/число. Мне не все нужны, а только суббота, как мне отфильтровать?


# https://stackoverflow.com/questions/16347731/how-to-change-the-locale-of-r# https://jangorecki.gitlab.io/data.cube/library/stringi/html/stringi-locale.htmldf <- as.Date("2020-01-01") %>%   seq.Date(to = . + months(4), by = "1 day") %>%  tibble(date = .) %>%  mutate(wday = lubridate::wday(date, week_start = 1),         wday_abb_rus = lubridate::wday(date, label = TRUE, week_start = 1),         wday_abb_enu = lubridate::wday(date, label = TRUE, week_start = 1, locale = "English"),         wday_stri = stringi::stri_datetime_format(date, "EEEE", locale = "en"))# оставим только субботыfilter(df, wday == 6)

tab9


Предыдущая публикация R vs Python в продуктивном контуре.

Подробнее..

Будни OEMщика (Часть 1)

10.09.2020 10:11:09 | Автор: admin

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


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


Предисловие


OEMщик довольно редкая специальность т.к. она требуется в компаниях, которые производят устройства с Windows: компьютеры, ноутбуки, планшеты, банкоматы, информационные киоски, рекламные панели, серверы.


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


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


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



В Кварте можно купить любую редакцию Windows, но основная специализация компании это продажа Windows 10 IoT Enterprise, ранее известная как Embedded, которая предназначена для устройств фиксированного назначения. Специальные возможности этой системы можно увидеть на этом видео.


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


Начало начал


Берем дистрибутив Windows 10 IoT Enterprise 1809. Если Вас интересует только тиражирование, можете взять любую другую редакцию Windows 10, кроме Windows Core, процесс подготовки и тиражирования для всех редакций будет одинаковым. Иногда бывают вопросы Где взять оригинальный дистрибутив? и Как записать образ на флэшку?.


Коммерческий оригинальный дистрибутив можно скачать на сайте microsoftoem.com. Для загрузки дистрибутивов рекомендую использовать IE. Относительно недавно Майкрософт поменял оболочку сайта, это некоторым образом приводит в замешательство тех, кто им пользуется крайне редко. Убедитесь, что Вы вошли на сайт, для этого подведите курсор мыши к символу учетной записи в правом верхнем углу, после чего в выпадающем сообщении должны отобразиться учетные данные. Для перехода к загрузке образа перейдите по пунктам выпадающего меню Orders > Software Downloads > Software Order Center



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



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



Для записи образа на флэшку можно воспользоваться скриптом MakeBootMedia, который находится в наборе скриптов. Обратите внимание, что для комфортного запуска скриптов PS1 есть скрипты BAT.


И еще небольшое замечание, если Вы устанавливаете систему в UEFI режиме, то разрядность устанавливаемой системы должна соответствовать разрядности, которую поддерживает UEFI BIOS устройства, иначе Вы просто не сможете загрузиться даже для установки системы. Проще говоря, если у Вас не получается загрузиться с флэшки для установки Widows 10 x64, попробуйте установить Widows 10 x32.


Нечистая, нечистая, братцы!


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


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


Так как мы готовим образ для тиражирования, то сразу после установки можно перевести систему в режим аудита. Для перевода системы в режим аудита нужно нажать Ctrl + Shift + F3 на шаге выбора региона.



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


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


А теперь немного углубимся в запечатывание системы и снятие образа. Когда система загрузится в режиме аудита, автоматически запустится утилита Sysprep. Для запечатывания в режиме аудита в разделе System Cleanup Action выберите Enter System Audit Mode. Чтобы система без проблем загрузилась на другом оборудовании, то ее можно отвязать от текущего оборудования, для этого ставим флажок Generalize. В разделе Shutdown Options выбираем Shutdown и нажимаем OK, после чего система выключится. Система запечатана только до тех пор, пока не загружена, не пытайтесь снять образ загруженной системы.



Для снятия образа нам понадобится флэшка с WinPE


Создаем флэшку с WinPE


Используя набор Windows ADK можно собрать WinPE с различным набором компонентов, но можно поступить проще, WinPE есть на установочном диске Windows, можно использовать его, только нужно, чтобы вместо запуска установщика запускался скрипт с помощью которого можно легко снять или развернуть образ системы. Для подготовки флэшки будем использовать скрипт MakeBootMedia из набора скриптов.


Для создания флэшки с WinPE с помощью предлагаемого скрипта необходимо использовать Windows 10 с версией не ранее чем 1703.


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


После очистки выбранного диска скрипт создаст два раздела NTFS и FAT32. Т.к. версии Windows до Windows 10 1703 не видят на флэшке более одного раздела, то раздел NTFS будет первым, а FAT32 вторым. Если вдруг у Вас будет дистрибутив Windows 10 1607 и соответствующее WinPE, то WinPE загрузится со второго раздела FAT32, который будет помечен как загрузочный и сможет работать с разделом NTFS. Раздел NTFS нужен для хранения файлов большого объема, а раздел FAT32 нужен для загрузки в UEFI режиме.


После копирования файлов, необходимых для загрузки, скрипт подключит образ с последним индексом, который находится в файле boot.wim и добавит в него файл Winpeshl.ini, в котором будет прописано что нужно запускать при загрузке WinPE. В файле Winpeshl.ini прописан запуск файла Winpeshl.bat, который будет скопирован туда же, рядом с ini файлом. После этого образ будет отключен с сохранением.


В корень тома NTFS будет скопирован файл меню Menu.bat и будет создан файл Serial.txt с серийным номером флэшки, которая была подготовлена как загрузочная.


Создаем образ системы


Загрузитесь с подготовленной флэшки. После загрузки запустится файл Winpeshl.bat, который нужен только для поиска и запуска файла меню Menu.bat, в котором находится основное меню.


При выборе пункта снятия образа системы скрипт автоматически найдет раздел с системой и свернет ее в WIM образ, который будет на томе NTFS в папке Images. Обратите внимание, что будет снят образ только системного раздела. После снятия образа вытащите флэшку из ПК и перезагрузите его. Для перезагрузки достаточно просто закрыть запущенное окно.



Что такое WIM и с чем его едят


В Windows есть штатная утилита для обслуживания системы DISM. Одна из ее возможностей создание образов WIM. С ее помощью можно создать образ раздела или папки, при создании образа системного раздела DISM по умолчанию исключает ненужные файлы, такие, как файл подкачки и файл гибернации. В одном wim файле может быть множество образов, получить к ним доступ можно по индексу (номеру образа). Множество образов лучше хранить в одном wim файле т.к. у него есть дедупликация одинаковых файлов. Но при повреждении такого файла будут потеряны все образа, которые в нем хранились. В едином wim файле я храню архив образов, которые может быть когда-нибудь понадобятся.


Для упрощения работы с wim образами есть множество графических утилит, например GImageX и Dism++


Локализация


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


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


Запустите скрипт Localization.bat, выберите пункт полной локализации системы и дождитесь завершения локализации, во время локализации система перезагрузится несколько раз, просто не мешайте ей. Если у Вас есть необходимость сделать дистрибутив для установки локализованной системы, то инструкцию по его созданию можно найти здесь.


После локализации запечатайте систему в режиме аудита и снимите образ системы как в прошлый раз. Для запечатывания можно запустить утилиту sysprep или можно запечатать систему с помощью скрипта. Запустите Sysprep.bat, выберите пункт запечатывания в режиме аудита, а затем пункт запечатывания без файла ответов.



Пробуем развернуть систему


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


Маленькая хитрость. Если во время установки системы установщик сообщает, что система не сможет работать на данном оборудовании и прекращает установку, не верьте ему, просто разверните образ системы с помощью DISM'а, не исключено, что она будет работать.


Загрузитесь с ранее подготовленной флэшки c WinPE. Обратите внимание, что для развертывания системы в меню скрипта есть несколько пунктов. В любом случае Вам подойдет вариант с автоматическим определением режима загрузки, это значит, что система будет развернута в том режиме загрузки, в котором она загрузилась с флэшки. С помощью других пунктов развертывания можно развернуть систему для загрузки в режиме UEFI или Legacy. Но учтите, что система не загрузится если ее развернуть в режиме загрузки, который не поддерживает BIOS.


После выбора пункта развертывания, скрипт предложит выбрать один из wim файлов, который находится в папке Images. А если в выбранном файле будет более одного образа, то он предложит выбрать образ. Образ будет развернут на первый найденный диск, который не соответствует серийному номеру в файле Serial.txt. Это нужно, чтобы не удалить данные с загрузочной флэшки, ведь в WinPE у флэшки может быть номер диска 0 или 1. После развертывания образа скрипт инициализирует загрузочный раздел и скопирует на него файлы WindowsRE.


Развертывание по сети


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


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


На подготовленной флэшке, рядом с файлом Menu.bat создайте файл NetConfig.txt и вставьте в него следующие строки:


LanPath=User=Password=MenuFilePath=

Сразу после знака равенства без пробелов укажите для LanPath полный путь к сетевой папке, для User имя пользователя, для Password пароль для подключения к папке. Для MenuFilePath укажите путь к запускаемому файлу меню относительно сетевой папки. Пример:


LanPath=\\desktop\dUser=UserNamePassword=YourPasswordMenuFilePath=Images\WIM\Network\LanMenu.bat

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


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


А если Вы хотите, чтобы при загрузке с флэшки система автоматически запускала LanMenu.bat, то это тоже сделать очень легко. На флэшке, рядом с файлом Menu.bat создайте файл AutoRun.txt. Все команды, прописанные в этом файле, будут выполнены сразу после загрузки в контексте файла Menu.bat. Т.е. для автоматического выполнения пункта Меню сети нужно добавить в файл одну строчку


goto NetworkMenu

При необходимости временно отключить выполнение команд при загрузке WinPE можно просто изменить имя файла AutoRun.txt.


Драйверы


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



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


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


При создании утилит для определения возможности использования драйвера с устройством учтите некоторые моменты. Для сопоставления идентификаторов оборудования и идентификаторов в inf файле можно использовать самый короткий идентификатор inf файла, который совпадает с началом длинных идентификаторов. При сопоставлении идентификаторов можно отбрасывать окончания: &SUBSYS, &REV, &CC вместе со всеми символами после этих окончаний. Пример такого обрезания идентификаторов можно увидеть в скрипте DriverRestrictions, в функции Add-Devices.


Файл ответов Sysprepа


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


Какие параметры можно настроить в файле ответов, можно посмотреть здесь. Наиболее часто используемые параметры находятся в разделе Microsoft-Windows-Shell-Setup. Для добавления новых разделов или создания больших файлов ответов можно использовать WSIM Windows System Image Manager, он находится в наборе Windows ADK. Для правки небольших файлов ответов удобней использовать текстовый редактор. В наборе скриптов, в папке Unattend, есть примеры файлов ответов.


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


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


Для чего нужен скрипт для запечатывания



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


В каждом разделе файла ответов есть параметр processorArchitecture, разрядность, указанная в значении этого параметра должна соответствовать разрядности системы, в которой он используется, иначе весь раздел будет проигнорирован. Данное обстоятельство вынуждает создавать одинаковые файлы ответов для систем X32 и X64. При запечатывании системы с файлом ответов скрипт меняет в выбранном файле значения всех параметров processorArchitecture в соответствии с разрядностью запечатываемой системы, таким образом скрипт избавляет от необходимости создавать файлы ответов с одинаковыми настройками для систем разных разрядностей.


Плюс к этому, если Вы добавляли команду для автоматического закрытия окна Sysprepа, то при запечатывании в режиме OOBE она будет удалена.


В примерах файлов ответов настроен автоматический вход пользователя Admin. Использование настройки автоматического входа в систему с учетной записью, которой нет в системе приводит к тому, что система пытается войти в учетную запись, которой нет. При запечатывании с файлом ответов скрипт проверяет, есть ли в настройках файла ответа автоматический вход, если да, то есть ли в системе пользователь с таким именем.


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


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


  • Итоговый образ системы подготовлен на пробной версии
  • Забыли ввести ключ множественной активации ePKEA
  • Ключ ePKEA введен и находится в открытом виде

Исхитрись-ка мне добыть то, чаво не может быть


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


Как создать активированный образ системы?


Активированный образ создать нельзя. Можно только подготовить образ к активации введя ключ многократной активации ePKEA.


Как зашить ePKEA в BIOS?


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


Как сохранить ключ и предотвратить нецелевые активации с ключом?


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


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


Послесловие


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


Но если говорить не о Windows 10 в целом, а о Windows 10 IoT Enterprise, то тиражирование это только часть, которую нужно освоить. А вторая часть это ее настройка. Во второй части статьи мы рассмотрим специальные возможности Windows 10 IoT Enterprise показанные на этом видео.


Если у вас остались вопросы относительно настройки и лицензирования Windows 10 IoT Enterprise, обращайтесь по адресу mse@quarta.ru или на сайт quarta-embedded.ru.
Ответы на некоторые вопросы Вы можете найти в нашей вики или на нашем YouTube-канале


Автор статьи: Борисенков Владимир, технический эксперт компании Кварта Технологии.

Подробнее..

Будни OEMщика (Часть 2)

24.09.2020 10:22:34 | Автор: admin

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


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


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


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


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


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


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


Для каждого, кто тебя знает, ты разный


В первой части статьи речь шла о Windows 10 в целом, а теперь, учитывая, что в данной части будет рассмотрена настройка мультикиоска, речь пойдет именно о Windows 10 IoT Enterprise 2019 т.к. в предыдущих версиях Windows 10 с долгосрочным обслуживанием нет поддержки мультикиоска. Если у Вас нет дистрибутива этой системы, то здесь можно скачать пробную версию. У пробной версии системы есть только одно ограничение она выключается каждый час. Чтобы выключения не были неожиданными, можно добавить уведомление за 5 минут до выключения системы с помощью скрипта TrialShutdownTimeControl.


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



Почему многие компании реализуют свои решения именно на IoT Enterprise?


В первую очередь это вопрос цены, стоимость лицензии IoT зависит от процессора, с которым будет использоваться система. Для низкопроизводительных систем цена IoT может быть около 30% от стоимости Windows Pro.


Плюс к этому в редакции Enterprise максимальный набор возможностей, в отличии от Pro. Причем это не какие-то ненужные возможности, а возможности, которые помогут создать наиболее защищенное решение:


  • Различные режимы киоска
  • Блокировка запуска приложений
  • Блокировка устройств
  • Защита диска от записи
  • Блокировка клавиш и ввода символов
  • Поддержка 10 лет с момента выпуска без перехода на следующую версию

Еще одним важным фактором является дополнительный способ активации Windows, который есть только у Windows 10 IoT Enterprise. Это активация с помощью ключа ePKEA. ePKEA это ключ множественной активации, который выдается на компанию. С этим ключом будут активироваться все устройства, выпускаемые компанией. С таким ключом доступны все стандартные способы активации, по интернету или по телефону. Данный ключ нужно ввести в систему перед тиражированием и скрыть его.


Сочетание максимальных возможностей и минимальной цены делает операционную систему Windows 10 IoT Enterprise очень привлекательной, именно поэтому ее выбирают множество компаний для своих устройств.


Пользователи


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


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


Для быстрого создания пользователей можно воспользоваться скриптом Users, который находится в наборе скриптов. Просто введите имена пользователей в столбик в файл CreateUserList.txt и выберите в скрипте пункт меню создания пользователей. Скрипт создаст пользователей, отключит срок действия пароля и переведет пользователей в группу Администраторы. Для перевода пользователя между группами Пользователи и Администраторы достаточно выбрать имя пользователя в меню скрипта.



Безвыходных положений не бывает


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


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


Компания Кварта Технологии подготовила набор скриптов, в котором скрипты, отвечающие за типовые настройки могут работать в группе, т.е. за один раз можно включить или выключить множество настроек. Управлять группой скриптов можно с помощью скрипта SettingsGroup, который находится в корне каталога набора скриптов. С его помощью можно посмотреть текущие значения группы настроек и изменить их. По умолчанию в группе будут работать все скрипты, которые отвечают за типовые настройки. Но при необходимости можно изменить начальный каталог поиска скриптов, которые могут работать в группе, тем самым изменив набор изменяемых настроек. Настройки со значениями, нетипичными для устройств фиксированного назначения будут выделены красным, а настройки с типичными значениями для устройств фиксированного назначения зеленым.



Если Вы захотите добавить в какой-либо скрипт поддержку работы в группе, то это сделать несложно. Скрипт, который управляет группой скриптов, после выбора пункта меню ищет в указанной папке все скрипты PS1, в которых есть функция Lockdown и отправляет ей параметр в зависимости от выбранного пункта. Один из самых простых примеров реализации функции Lockdown в файле WindowsUpdate.ps1


Типовые настройки для устройств фиксированного назначения


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


Схема питания


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


Отображение ошибок


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


Отчеты об ошибках


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


Всплывающие уведомления


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


Сценарий службы политики диагностики


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


Отображение ошибок при загрузке


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


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


Отображение синего экрана


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


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


Отображение уведомлений об обновлениях


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


Автоматическое получение обновлений


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


Прокрутка от краев экрана


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


Отображение логотипа и анимации в виде крутящихся шариков


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


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


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


Отображение процесса входа пользователя в систему


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


Режимы киоска


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


  • Shell Launcher V1 средство для запуска приложений. Запускает одно классическое приложение вместо оболочки системы и контролирует его работу. При закрытии приложения можно настроить: перезапуск приложения, перезагрузку системы, выключение системы.
  • Shell Launcher V2 во второй версии добавлена возможность запуска универсальных приложений.
  • Ограниченный доступ запуск одного универсального приложения вместо оболочки системы.
  • Режим мультикиоска запуск системы в режима планшета и отображение плиток заранее назначенных приложений.

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


Shell Launcher V1


Для включения средства запуска оболочки нужно добавить компонент средства запуска оболочки в систему и заменить запуск стандартной оболочки explorer.exe на запуск средства запуска оболочки eShell.exe. Без настроек средство запуска оболочки будет запускать только командную строку, поэтому необходимо настроить средство запуска оболочки. В настройках по умолчанию можно указать приложение, которое будет запускаться для пользователя, которому не назначен запуск приложения. Плюс к этому, необходимо добавить настройку запуска оболочки системы для группы Администраторы т.к. при настройке запуска приложения для группы Пользователи у данной настройки будет приоритет выше, чем у настройки по умолчанию, следовательно, при отсутствии других настроек для группы Администраторы будет выполняться приложение, назначенное для группы Пользователи. Все эти настройки выполнит скрипт Shell Louncher при включении средства запуска оболочки.



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


  • 0 перезапуск приложения
  • 1 перезагрузка
  • 2 выключение
  • 3 отсутствие действий

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


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


Созданные задачи в планировщике заданий не будут работать в режиме аудита.


Ограниченный доступ


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


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



Режим мультикиоска


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


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

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



У каждого свой путь


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


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


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


Особенности настроек локальной групповой политики


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


Изменять настройки локальной групповой политики можно разными способами:



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


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


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


Устройство с множеством пользователей


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



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


Если у пользователя будет возможность перехода на экран вызываемый по Alt + Ctrl + Del, необходимо выполнить и его настройку. Все отключенные иконки на экране входа в систему будут отключены и на экране, вызываемом по Alt + Ctrl + Del. Для отключения кнопок, находящихся над кнопкой Отмена, есть группа скриптов, которые находятся в папке Действия по Alt+Ctrl+Del. Во всей группе скриптов есть возможность изменить настройки для всех учетных записей или для конкретной учетной записи. При изменении настройки для всех учетных записей настройка будет изменена с помощью утилиты LGPO, а при изменении настройки только для текущего пользователя, настройка будет изменена в реестре.


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


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


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


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


Устройство с одним пользователем


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


Но если в Shell Launcher V1 будут настройки для запуска конкретного приложения для группы Пользователи, то система не сможет загрузиться после запечатывания в режиме приветствия (OOBE). Обойти данную проблему поможет скрипт для запечатывания Sysprep, он временно отключит Shell Launcher V1 и создаст задачу на его включение после первой загрузки в режиме OOBE. Подробнее эту проблему мы рассмотрим в следующей части статьи.


На устройстве с одним пользователем можно не настраивать экран входа в систему и экран вызываемый по Alt + Ctrl + Del, достаточно просто лишить пользователя возможности перейти на эти экраны. Заблокировать Alt + Ctrl + Del и другие горячие клавиши нам поможет фильтр клавиатуры.


Фильтр клавиатуры


С включением и настройкой фильтра клавиатуры нам поможет скрипт Keyboard Filter из набора скриптов. При включении фильтра клавиатуры он добавит компонент фильтра клавиатуры и пропишет в реестр команду запуска службы фильтра клавиатуры при следующей загрузке системы.



Фильтр клавиатуры оказывает влияние на работу режима ограниченного доступа без какой-либо настройки. В режиме ограниченного доступа будут заблокированы горячие клавиши Alt + Ctrl + Del, перейти на экран входа в систему можно будет только при пятикратном нажатии клавиши разблокировки, по умолчанию это кнопка Win.


С помощью фильтра клавиатуры можно:


  • Запретить использование горячих клавиш специальных возможностей
  • Запретить использование комбинаций клавиш
  • Запретить ввод конкретных символов
  • Запретить использование конкретных клавиш
  • Назначить клавишу разблокировки системы

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


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


Настройки фильтра клавиатуры находятся в реестре, для быстрого перехода к настройкам фильтра клавиатуры выберите пункт открытия настроек в меню скрипта. В ветке реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Embedded\KeyboardFilter находится перечень клавиш и клавиатурных сочетаний, которые можно заблокировать, прописав значение Blocked.


При открытии настроек фильтра клавиатуры с помощью скрипта, в разделе KeyboardFilter скрипт создаст еще два подраздела CustomFilters и CustomScancodes.


В разделе CustomFilters можно добавить любые символы и клавиатурные сочетания, которых нет в разделе KeyboardFilter и заблокировать их. Учтите, что для блокировки горячих клавиш с использованием букв, необходимо указывать блокировку для имеющихся раскладок клавиатуры. Например, если в системе русская и английская раскладка, то для блокировки горячих клавиш Ctrl+X необходимо добавить еще и блокировку Ctrl+Ч, чтобы горячие клавиши не работали на русскоязычной раскладке.


В разделе CustomScancodes можно заблокировать конкретную клавишу, указав ее скан-код. Скан-код клавиши можно узнать с помощью программы SharpKeys. Чтобы узнать скан-код клавиши запустите программу SharpKeys, в окне программы нажмите на кнопку Add, после чего откроется новое окно программы, в нем нажмите на кнопку Type Key, а затем нажмите на клавишу, скан-код которой Вы хотите узнать. После нажатия на клавишу появится новое окно, в котором будет показан скан-код. В реестр нужно прописать те символы, которые указаны после нижнего подчеркивания.



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


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


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


Послесловие


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


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


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


Если у вас остались вопросы относительно настройки и лицензирования Windows 10 IoT Enterprise, обращайтесь по адресу mse@quarta.ru или на сайт quarta-embedded.ru. Ответы на некоторые вопросы Вы можете найти в нашей вики или на нашем YouTube-канале


Автор статьи: Борисенков Владимир, технический эксперт компании Кварта Технологии.

Подробнее..

Будни OEMщика (Часть 3)

30.09.2020 08:10:03 | Автор: admin

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


В этой части мы рассмотрим, как повысить безопасность и отказоустойчивость системы с помощью стандартных средств Windows: AppLocker, фильтр записи, блокировка устройств. Плюс к этому рассмотрим особенности запечатывания системы в режиме приветствия (OOBE) с некоторыми специфичными настройками системы.


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


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


  • С помощью скрипта настройки питания PowerSettings включена схема питания HORM
  • Система в режиме аудита
  • В системе есть две созданные учетные записи, одна только в группе Администраторы, вторая только в группе Пользователи
  • С помощью Shell Launcher V1 настроен запуск приложения для группы Пользователи

Напомню, что все настройки мы выполняем на Windows 10 IoT Enterprise версии 1809. Убедитесь, что у Вас именно эта версия системы, выполнив команду winver.



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


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


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


Блокировка запуска приложений


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


Блокировка запуска приложений не только усилит защиту от вредоносного ПО, а еще и не даст пользователю попасть куда не нужно, например, в настройки.


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


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


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


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


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


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


Для начала рассмотрим особенности настройки AppLockerа в целом теоретическая часть. А потом рассмотрим, как настроить правила запуска приложений по белому списку практическая часть.


Теоретическая часть


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


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



После создания правил по умолчанию можно включить AppLocker, для включения AppLockerа необходимо запустить службу AppIDSvc и перевести ее в автоматический режим запуска. Но AppLocker начнет работать не сразу, а после применения политики AppLockerа к системе. О том, что правила AppLockerа применены к системе, можно узнать из журнала AppLockerа Управление компьютером\Служебные программы\Просмотр событий\Журналы приложений и служб\Microsoft\Windows\AppLocker\EXE и DLL. После применения правил в журнале появится запись с кодом события 8001, в событии будет уведомление о том, что политика AppLockerа применена к системе.


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


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


Для правил AppLockerа можно настроить политику применения правил.



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


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


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


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


Практическая часть


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


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


Если Вы согласны с предложением скрипта создать правила, просто нажмите Enter.


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



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


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


Когда система загрузится, выполнит вход в учетную запись пользователя и запустит назначенное приложение вместо оболочки системы, перейдите в учетную запись администратора, запустите скрипт настройки AppLockerа, выберите пункт выбора группы для создания правил AppLockerа. В пункте выбора группы выберите группу Пользователи (Users).


После создания правил вернитесь в главное меню скрипта и выберите пункт отображения правил AppLockerа. У меня для пользователя был настроен запуск Tools\TestRunAs.bat, который находится в наборе скриптов, я получил вот такой набор правил.



Первые два правила для группы Administrators создал скрипт перед запуском AppLockerа. Остальные правила, с приставкой AuditBased, скрипт создал на основании результатов аудита. При желании Вы можете изменить приставку, которая добавляется к создаваемым правилам, для этого нужно просто поменять в скрипте AppLocker.ps1 значение параметра -RuleNamePrefix. Этот параметр легко найти с помощью поиска Ctrl + F.


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



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


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


После настройки AppLockerа отключите автоматический вход пользователя в систему.


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


Запечатываем систему в режиме приветствия OOBE


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


В обычном режиме работы системы мы посмотрим на те настройки, которые не работают в режиме аудита. А именно:


  • Блокировка устройств
  • Отключение отображения процесса загрузки системы
  • Фильтр записи

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


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


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


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

Для этого мы и настраивали все ограничения именно для группы. Но всякое решение плодит новые проблемы


Мюллер шел по улице. Вдруг ему на голову упал кирпич.
"Вот тебе раз," подумал Мюллер.
"Вот тебе два," подумал Штирлиц, бросая второй кирпич.


При тиражировании системы ее обязательно нужно запечатать для сброса уникальных SIDов системы и обязательно в режиме приветствия, не использовать же систему в режиме аудита. Но если настроен режим киоска Shell Launcher V1 с указанием запуска приложения именно для группы Пользователи, то система не сможет загрузиться в режиме приветствия.


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


Перед запечатыванием системы в режиме OOBE скрипт проверяет настройки Shell Launcherа и AppLockerа. Если настройки будут препятствовать загрузке системы в режиме приветствия, то скрипт предложит временное отключение этих настроек. Настройки AppLockerа и Shell Launcherа будут проверены отдельно друг от друга, и для каждой настройки отдельно будет предложено временное отключение. При подтверждении отключения настроек скрипт отключит их и создаст задачу на их включение, задача будет выполнена после входа в учетную запись при первой загрузке после запечатывания, после включения настроек система будет перезагружена еще раз.


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


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


Ограничение установки драйверов


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


Данная возможность не работает в режиме аудита.


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


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


Настройка в локальной групповой политике


Настройка ограничения установки устройств находится в локальной групповой политике. Конфигурация компьютера\Административные шаблоны\Система\Установка устройства\Ограничение на установку устройств



Можно запретить установку устройства по ID устройства или по GUIDу класса оборудования. После запрета установки устройств нельзя будет установить драйвер, который соответствует указанному GUIDу класса или указанному ID оборудования. При этом ранее установленный драйвер будет работать.



ID устройства можно указывать не полностью, сопоставление ID в правилах с ID в системе будет производиться по частичному совпадению с начала строки. Правило запрещения устройства с ID PCI\VEN_8086&DEV_9D23 будет запрещать все устройства по маске PCI\VEN_8086&DEV_9D23*, т.е. устройство с ID PCI\VEN_8086&DEV_9D23&SUBSYS_8079103C&REV_21\3&11583659&0&FC будет запрещено.


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


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


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


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


Настройка с помощью скрипта



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


При выборе пунктов разрешения или запрета установки драйверов по ID или по GUIDу класса, скрипт покажет таблицу с перечнем текущих устройств, которые еще не добавлены в правила выбранного параметра. При составлении таблицы с перечнем ID, после получения перечня всех устройств скрипт исключает ID, которые начинаются с: PRINTENUM, ROOT, SW, ACPIAPIC, MONITOR. При необходимости, перечень исключаемых ID можно изменить в функции Add-Devices. У оставшихся ID будут отброшены окончания: &SUBSYS, &REV, &CC вместе со всеми символами после этих окончаний.



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


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



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


Запретить работу уже установленных драйверов можно с помощью пунктов включения / отключения запрета к установленным драйверам.


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


Фильтр записи


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


Важно!!!


  1. Включать фильтр записи необходимо непосредственно на конечном устройстве после активации системы.
  2. При включении фильтра записи изменяются некоторые настройки системы, но при выключении фильтра записи измененные настройки не возвращаются в исходное состояние.
  3. Нельзя запечатывать систему с включенным фильтром записи.

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


А вот непридуманная ситуация. Некоторые работники каждое утро тратят 30 40 минут на то, чтобы открыть все необходимые окна в специализированном ПО, сделать их определенного размера и расставить их в определенном порядке. Эту проблему можно решить с помощью функции HORM, которая есть в фильтре записи.


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


Теоретическая часть


Фильтр записи необходим для сохранения данных в исходном состоянии. Можно выделить две основные функции:


  1. Защита данных от изменений на несъемных носителях
  2. Загрузка системы в определенное состояние из файла гибернации режим HORM
    Сначала рассмотрим работу фильтра записи с настройками по умолчанию, а затем рассмотрим, какие еще есть варианты настройки и для чего они нужны.

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



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


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


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


У фильтра записи есть уведомления об уровнях заполненности оверлея, это порог предупреждения по умолчанию 512 MB и критический порог по умолчанию 1024 MB. При достижении определенного порога в журнал системы будут внесены определенные записи. Журналы Windows > Система.


Overlay usage Source Level Event ID
Warning threshold uwfvol Warning 1
Critical threshold uwfvol Error 2
Back to normal uwfvol Information 3

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


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


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



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


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


Появляется вопрос, если вся система защищена, то как установить обновления, если они нужны? У фильтра записи для этого есть сервисный режим. Для перевода в сервисный режим необходимо выполнить команду uwfmgr servicing enable и перезагрузить систему. В сервисном режиме система сама загрузит и установит обновления, а затем перезагрузится в нормальном режиме работы.


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


HORM


HORM Hibernate Once/Resume Many (HORM). Принцип работы HORMа понять очень просто. Все наверно знают, как работает режим гибернации. При переводе системы в режим гибернации все данные из оперативной памяти записываются на жесткий диск в файл hiberfil.sys, а при включении ПК все данные из файла hiberfil.sys записываются в оперативную память. HORM работает точно так же, только есть одно маленькое но, Вы вводите систему в режим гибернации один раз, а в дальнейшем при каждой загрузке система всегда записывает данные из hiberfil.sys в оперативную память. При этом не важно, как была завершена работа системы выключением или перезагрузкой. Только учтите, что фильтр записи не защищает файл гибернации, поэтому нужно отключить все способы перевода системы в режим гибернации кроме консольного.


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


Для работы режима HORM есть ряд требований:


  1. Все тома несъемных носителей должны быть защищены
  2. Не должно быть никаких исключений из защиты в реестре и файловой системе
  3. Оверлей должен быть в оперативной памяти.

Настраиваем фильтр записи


Перед настройкой фильтра записи необходимо добавить компонент фильтра записи. Вся настройка фильтра записи производится в командной строке с помощью утилиты uwfmgr.exe. Базовые возможности фильтра записи можно настроить с помощью скрипта UnifiedWriteFilter, который находится в наборе скриптов.



Для отображения текущего состояния фильтра записи добавьте компонент фильтра записи и перезагрузите систему. Если Вам недостаточно параметров настроек, которые отображает скрипт, можно отобразить текущие настройки, выбрав соответствующий пункт меню скрипта, тогда будут показаны настройки, которые отображаются при выполнении команды uwfmgr get-config.


С помощью пункта установки размера оверлея можно переключать размер оверлея между размером по умолчанию и максимально возможным размером. Это возможность скрипта, такой возможности нет в стандартных настройках. Максимально возможный размер вычисляется следующим образом. Скрипт получает объем оперативной памяти и вычитает минимально необходимый объем для данной системы. 1 ГБ для x32 и 2ГБ для x64. При изменении объема оверлея будут автоматически изменены пороги предупреждения.


С помощью пункта изменения уровня порогов можно изменять уровень порогов межу стандартным и рекомендуемым. Это возможность скрипта, такой возможности нет в стандартных настройках. Стандартные уровни порогов: 50% от объема оверлея порог предупреждения, 100% от объема оверлея критический порог. Рекомендуемые пороги предупреждения отличаются для реального и виртуального ПК. Для реального ПК: 80% от объема оверлея порог предупреждения, 90% от текущего объема оверлея критический порог. Для виртуального ПК: 10% от объема оверлея порог предупреждения, 20% от текущего объема оверлея критический порог. При необходимости Вы можете сами изменить в скрипте % уровня порогов от оверлея, за них отвечают переменные WarningThresholdGlobal и CriticalThresholdGlobal.


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


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


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


Периодически бывают вопросы, как посмотреть содержимое оверлея, для этого в скрипт добавлен пункт отображения оверлея системного диска. Он добавлен как пример и реализован с помощью Unified Write Filter WMI т.к. содержимое оверлея нельзя посмотреть с помощью утилиты uwfmgr.


А теперь ближе к практике


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


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



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


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


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


Послесловие


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


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


Если у вас остались вопросы относительно настройки и лицензирования Windows 10 IoT Enterprise, обращайтесь по адресу mse@quarta.ru или на сайт quarta-embedded.ru.
Ответы на некоторые вопросы Вы можете найти в нашей вики или на нашем YouTube-канале


Автор статьи: Борисенков Владимир, технический эксперт компании Кварта Технологии.

Подробнее..

Storytelling отчет против BI, прагматичный подход

08.05.2021 10:22:37 | Автор: admin

Проблематика


Когда говорят про отчеты к данным (неважно, какая тема) все хотят гибкие дашборды, МНОГО дашбордов, играют конкурсы про BI, выдумывают разные сложные требования и кейсы, отсматривают массу вендоров и решений, разбиваются на непримиримые лагеря и на 100% уверены, что это то, без чего жизнь на работе тяжела, уныла и печальна.


Так ли это? По описанию очень сомнительно (похоже на серебряную пулю), а практика дает подтверждение отнюдь не так.


Является продолжением серии предыдущих публикаций.


Что в реальности


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


Откуда такие утверждения? Дело в том, что отчетные квесты больше похожи на сеансы психотерапии. Каждый раз приходится медленно пробираться через наслоение индуцированных утверждений и убеждений, чтобы добраться до истинной потребности и после этого объяснить ее компьютеру. Последний точно не умеет и не понимает общих слов и смутных ощущений. У него только 0 и 1.


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


Выгода 1. Предоставление пользователю информации в готовом к употреблению виде


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


Выгода 2. Полная отвязка от инфраструктурных ограничений


В большинстве случаев storytelling отчет нужен по закрытому дню и генерировать его надо один раз в сутки. Оптимальный вариант ночная offline генерация всех необходимых отчетов для текущего рабочего дня. Классическое окно для генерации 2:00-7:00. Когда предыдущий день закрыт и переходные процессы закрытия во всех внутренних ИС завершились. Отсюда четыре существенных плюса:


  • offline генерация на серверной стороне позволяет не заморачиваться на скорость исполнения. В случае интерактивного анализа отклик должен измеряться десятками миллисекунд, иначе пользователи начинают жаловаться на торможение системы. Здесь же мы можем считать секунды. Снижение к требованиям по железу колоссальное.
  • можно использовать любой сложности алгоритмы, в т.ч. весь спектр ML инструментов.
  • нет понятие лицензий на доступ, нет непредсказуемой конкурентности. планируете задания последовательно-параллельно, опираясь на доступные вам аппаратные средства.

Выгода 3. Полная отвязка отчета от источников данных


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


  • готовый отчет можно как рассылать пользователям по почте, так и предоставлять доступ через корпоративные порталы. пользователь сможет работать с ним везде и за пределом корп.сети, и даже в бункере в режиме полного оффлайна.
  • отчет это html файл. тривальными средствами можно обеспечить историческое хранение на любую требуемую глубину со стоимостью, близкой к 0.
  • в исторической части хорошо известная проблема, когда отлаженный неизменный отчет нельзя собрать на исторических данных так, как он собирался бы тогда, когда эта дата была. Связано это с изменчивостью данных, изменчивостью ландшафта, эволюцией ИС и систем, динамичностью справочников. В тривиальном случае оргструктура любой компании динамична и она сегодня не такова, какой была 3 года назад. Обычному отчету никогда не вернуться в прошлое. А storytelling отчет это след папоротника в известняке.

Выгода 4. Динамическая генерация, основанная на предоставленных данных


Классический отчет жестко зафиксированный состав элементов и их форма. В случае со storytelling отчетом можно использовать подходы динамической генерации, когда сама ткань отчета генерируется на основе структуры полученных данных. Тем самым возможна почти любая вариативность, при этом текст отчета остается связным и без пустых мест. Чуть детальнее с кодом можно посмотреть в публикации R Markdown. Как сделать отчет в условиях неопределенности?.


Также можно параметризировать RMarkdown отчет и получать различные представления на различных данных, используя один и тот же код.


Выгода 5. Динамический контент


Представление html позволяет добавить такой объем динамичности, что пользователь может забыть, что это offline. Включение js виджетов позволяет обеспечить динамичные таблицы, графики. Средствами html и js можно располагать части отчета на закладках, обеспечивать кросснавигацию и оглавление, управлять видимостью объектов. Использование механизмов кросскоммуникации js виджетов позволяет делать связанные обновления элементов. Более конкретно:



Выгода 6. Безопасный доступ к данным


Очень часто возникают требования по управлению доступом к данным. Та или иная группа пользователей должна иметь возможность строить отчет только по своему подмножеству. Но весь парадок в том, что все равно остается ряд показателей, которые считаются по всей компании. И если это делать через self-service bi, то потребуется продумывать как это предоставить. Витрины, кубы, выгрузки или еще что-либо.


В случае с Rmarkdown отчетами пользователи вообще не имеют доступа к данным. Все собирается на сервере с контролируемым полным доступом. А в html фиксируются посчитанные агрегаты в соответствии с ролевой моделью.


Выгода 7. Один источник масса представлений


RMarkdown позволяет из единого источника делать совершенно различные финальные представления. html, pdf, doc, pptx.


Также, технология RMarkdown позволяет делать статические сайты (blogdown) и книги (bookdown).


Выгода 8. Вся мощь devops для гарантий корректности


Поскольку Rmarkdown является набором R инструкций, то управление жизненным циклом отчетов получается идентичным управлениею жизненным циклом ПО. Репозиторий, пакетирование, документирование, автотесты, continious integration, code coverage, профилировка узких мест.


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


Выгода 9, 10, X. ......


Выберите из списка...


Заключение


Еще один важный комментарий. Для того, чтобы корректно использовать дашборды или self-analytics bi нужно очень-очень хорошо знать структуру данных, которые используются в процессе рассчета и визуализации и иметь к ним полный доступ. Данные должны быть чистые, консистентые и рафинированные. Аналитик должен обладать навыками проведения расчетов и проверки результатов. Только так можно получить показатели и картинки, которым как-то можно доверять. В противном случае имеем сплошные жареные факты и желтую прессу. Затраты на такого аналитика никак не середнячковые.


P.S.


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


Алармисты уже не дремлют. Gartner вовсю начал предрекать закат BI в том виде как он есть сейчас. Нет поводов не задуматься:



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

Подробнее..

Архитектура экосистем

15.12.2020 10:11:51 | Автор: admin

Термин Экосистема появился в бизнес-лексиконе в 1993 году. Американский ученый Джеймс Мур в статье Хищники и жертва: новая экология конкуренции так обозначил модель объединения компаний вокруг решения единой стратегической задачи. Последнее время термин особенно популярен. Упоминаемость экосистемной бизнес-модели на пике в деловых новостях, бизнес-публикациях, финансовых отчетах и программах развития корпораций. Бизнес-экосистемам посвящаются деловые форумы и конференции.

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

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

В ретроспективе 25-30 лет экосистемная бизнес-модель эволюционировала. На этапе зарождения этого понятия под экосистемой понималось в большей степени объединение вокруг одного продукта конкурирующих между собой поставщиков и производителей. Пример - разработчики клиентского ПО для компьютеров Apple или производители аппаратных компонентов для ПК IBM. Превалировала классическая платформенная модель, которая решала задачу расширения и максимизации ассортиментного состава клиентских продуктов или составных компонентов одного продукта. Сегодня экосистемы приобрели сложный сетевой характер.Бизнес-экосистема выполняет роль источника ресурсов и знаний для развития компаний-участников. Синергетический эффект от участия в экосистеме стал проявляться в намного большем объеме. Продукты и сервисы этой бизнес-модели обогащают друг друга технологиями, функциями и операционными данными.Технологии - главный драйвер эволюции и становления экосистемной бизнес-модели. Тридцать лет назад в розничном бизнесе преобладал Product-centric подход. Главной задачей было грамотно сегментировать клиентскую аудиторию, правильно позиционировать товар, сформировать стратегию продвижения и дистрибуции. С ростом популярности персональных компьютеров, развитием телекоммуникаций, Интернет-технологий и появлением смартфонов возникла ориентация на каналы продаж - WEB-first, Mobile-first, Voice-first. Появилась электронная торговля и продвижение. Золотая полка, статичная и ограниченная в размерах в офлайн-ритейле по причине расположения на уровне глаз покупателя, в электронных каналах продаж стала безграничной и кастомизируемой под каждого клиента. Бизнес представил взору клиента весь товарный ассортимент. Взрывной рост и отрыв от конкурентов получили компании, которые быстро освоили новые каналы продаж и переориентировались на платформенную электронную бизнес-модель. Netflix и Zappos вырвались вперед в конкурентной борьбе, когда предложили клиентам больший ассортимент через онлайн-каналы. Крупнейшим розничным банкам взаимодействие через личные кабинеты клиентов помогло расширить набор финансовых продуктов.

Дальнейший рост вычислительных возможностей, доступности хранилищ данных и их логистики привели к появлению клиенто-центричного подхода в розничном бизнесе. Каждый клиент компании стал отдельным самостоятельным сегментом. Благодаря технологиям регистрации, обработки и анализа неструктурированных операционных данных, бизнес научился предугадывать клиентское поведение и предвосхищать ожидание клиента. Дополнительным катализатором послужило появление CEP (Complex Event Processing) и RTDM (Real-Time Decision Manager) -решений, которые обеспечили анализ информации на лету. Большие данные перестали анализировать по ночам. Интернет-компании за мгновения узнают пользователя и отображают таргетированную рекламу или цену товара уже после обращения к WEB-странице. Благодаря предиктивной аналитике физическое формирование посылки с товарами начинается одновременно с наполнением корзины на сайте - до момента оплаты товара клиентом. А предложение международной страховки направляется клиенту финансовой компании сразу после оплаты покупки в аэропорту.

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

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

Эти профильные бизнес-модели и объединяет понятие Экосистема.

К текущему моменту сложилось две модели появления экосистем Европейская и Американо-Китайская. Первая модель предполагает децентрализованное объединение компаний - чаще стартапов - на основе единых правил, утверждаемых глобальным государственным или межгосударственным регулятором Центральным банком. Вторая модель предполагает объединение вокруг одного глобального финтех или бигтех игрока десятков меньших по объему бизнеса продуктов и сервисов. Примеры таких экосистем - Facebook, Amazon, Microsoft, Google, Apple (FAMGA) и Baidu, Alibaba, Tencent (BAT).

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

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

Для экосистем характерен ряд свойств, которые отличают их от стратегических альянсов, а также вертикально- и горизонтально-интегрированных компаний:

  • Наличие больших ресурсов для регулярных исследований, опытов и развития решений

  • Использование новых технологий, архитектуры и подходов к разработке ПО

  • Регулярная работа с большими данными

  • Цифровые бизнес-процессы

  • Отсутствие бюрократии в производственном процессе, сокращенный Time-to-market

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

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

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

  • Возможность не вводить многократно свои данные в профилях разных сервисов

  • Доступность нужных сервисов в разных интерфейсах (каналах, продуктах) экосистемы

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

  • Просмотр релевантного контента и предложений

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

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

Среди таких глобальных технологических сервисов и подходов можно выделить:

  • Сервисы обеспечения омниканальности.

  • Единую учетную запись.

  • Единый ID клиента и клиентский профиль.

  • Доступность основных сервисов и функций через API.

  • Централизованный клиентский биллинг экосистемы.

  • Ориентацию на событийную модель интеграции (Event-Driven Architecture).

  • Единый контакт центр и службу поддержки.

  • Единый аналитический и операционный CRM.

Рассмотрим некоторые из них подробней.

Омниканальность

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

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

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

Единая учетная запись

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

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

Единый ID клиента и клиентский профиль

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

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

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

Единый платежный инструмент и централизованный клиентский биллинг экосистемы

Использование одного продукта экосистемы упрощает клиенту пользование другими продуктами. Это справедливо и для способа финансовых расчетов. Участник экосистемы должен иметь возможность оплатить разные сервисы с помощью одного инструмента и получать финансовую выгоду от одновременного пользования продуктами экосистемы. Легкий способ решения задачи - привязка (токенизация) банковской карты к разным сервисам. В этом случае клиент действительно будет использовать единый платежный инструмент. Но становится практически нереализуемой задача создания механик финансовой мотивации к пользованию разными продуктами экосистемы. Пользователю сложно будет начислить повышенные бонусные баллы за приобретение ряда услуг, оформить единую подписку, показывать в разных сервисах актуальный баланс и единую историю операций, отслеживать пользование услугами, проводить тарификацию в режиме реального времени. Клиент потеряет в бесшовности финансовых выгод, а продукты экосистемы в синергетическом эффекте. Поэтому такие задачи решаются с помощью единого клиентского счета или кошелька, которые обслуживаются в централизованной биллинговой системе. AliPay наиболее яркий пример такого финансового экосистемного сервиса.

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

Событийная интеграция систем (Event-Driven Architecture)

Используя перекрестное обогащение знаниями о клиенте компании создают сложные механики анализа клиентского поведения. Они помогают предвосхищать желания и потребности клиентов и предлагать релевантную продукцию товары, контент, услуги. На таком подходе построены концепции Next Best Offer (NBO) и Next Best Action (NBA). В рамках этих решений определяется, какой товар клиент с высокой вероятностью приобретет в конкретный момент (или период) времени. И, соответственно, какое действие клиент будет готов совершить в следующий момент. Для принятия таких решений компании анализируют в режиме real-time до тысячи триггеров клиентского поведения состав покупок, суммы, тип ТСП, запрашиваемый контент, проставленные в соцсетях лайки, среднее время просмотра роликов, контакты и многое другое. Но главное, решение на основе такого анализа необходимо принимать на лету, так как спустя время готовность клиента к приобретению товара или действию может сильно снизиться и предложение станет не актуальным. Поэтому для такого рода задач важна событийно-ориентированная интеграционная архитектура. Каждый домен экосистемы (как совокупность информационных систем) должен уведомлять другие домены о событиях в жизни клиента. Поэтому необходима организация супермаркета операционных данных - решения, которое позволяет информационной системе в онлайн-режиме получать важные для себя данные (например, на базе брокера сообщений Apache Kafka). Прямая интеграция систем для получения данных по запросу или рассылки сообщений о событиях создаст спагетти-архитектуру и, как следствие: существенный прирост нагрузки на системы, более сложное сопровождение, а также предпосылки для большего количества доработок в случае расширения атрибутного состава клиентских данных.


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

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

Поэтому включение нового клиента в экосистему происходит по заранее и детально спроектированному клиентскому пути (Customer Journey). А работа с одним сервисом упрощает клиенту работу с другими сервисами.

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

Подробнее..

Перевод Почему стоит обратить внимание на подход low-codeno-code

16.02.2021 16:13:42 | Автор: admin

Все мы в последнее время довольно много слышим о платформах low-code/no-code. Платформы без кода обещают сделать разработку программного обеспечения столь же простой, как использование Wordа или PowerPointа, чтобы обычный бизнес-пользователь смог продвигать проекты без дополнительных затрат (денег и времени) на команду инженеров. В отличие от платформ без кода, low-code по-прежнему требует определенных навыков программирования, однако обещает ускорить разработку программного обеспечения, позволяя разработчикам работать с предварительно написанными компонентами кода.

Согласно Gartner, к 2024 году 65% разработанных приложений будут относиться low-code.

Еще в 2017 году я участвовал в раннем сравнительном тестировании производительности традиционной разработки (с использованием Java) и проектом low-code/no-code, основанном на моделях. Результаты были впечатляющими: при использовании метода low-code/no-code производительность увеличивалась в 5-7 раз. Опрос, проведенный компанией No-Code Census в 2020 году, показал прирост производительности в 4,6 раза по сравнению с традиционным программированием.

Low-code/no-code: Фрагментация платформы

Область low-code/no-code довольна сложна и включает в себя многочисленные решения, платформы и субрынки. Например, существуют субрынки, ориентированные на крупные, средние и малые предприятия. Корпоративные платформы low-code/no-code обеспечивают высокую масштабируемость, производительность, безопасность и интеграцию с приложениями предприятия. Они, как правило, дороже остальных. Ниже представлен Магический Квадрант Gartner для корпоративных low-code платформ:

Gartner дает платформе low-code (LCAP) следующее определение: Это платформа, которая поддерживает быструю разработку приложений, одноэтапную раскатку, выполнение и управление с использованием декларативных абстракций программирования высокого уровня, таких как языки программирования на основе моделей и метаданных.

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

Неудивительно, что многие платформы low-code являются платформами управления бизнес-процессами. BPM уже давно поддерживает разработку на основе моделей (Model-driven Development), где нужно нарисовать диаграммы, объясняющие, как должно работать программное обеспечение, прежде чем его создавать. Эта схема похожа на процессный подход BPM, при котором для задания бизнес-процесса необходимо в правильном порядке расположить блоки, представляющие собой подпроцессы. (Самым популярным стандартом отображения процессов, поддерживаемым большинством BPM-платформ, является BPMN). Поэтому процессно-ориентированные решения достаточно популярны. Примерами low-code/no-code платформ для BPM являются Appian, Pega, Outsystems.

Но существуют и другие примеры под эгидой low-code/no-code:

Веб-платформы для использования предприятиями любого размера. Ведущими конкурентами являются WordPress, Wix, Squarespace и WebFlow.

Платформы управления базами данных, начиная от таких, как Mendix, и заканчивая такими, как Airtable. Существуют также low-code/no-code платформы баз данных NoSQL, например, KgBase, предназначенная для построения графов знаний.

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

Разработка мобильных приложений. Большинство платформ low-code/no-code, таких как Bubble, предоставляют возможности адаптивного пользовательского интерфейса, другие предлагают встроенную поддержку ведущих мобильных OC (iOS и Android). Thunkable пожалуй, лучший пример low-code/no-code платформы для разработки мобильных приложений.

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

Другие категории платформ нацелены на определенные области или ниши приложений:

  • E-commerce и онлайн-магазины: лидирующим примером здесь является Shopify.

  • Управление рабочим процессом: отличный пример Monday.com.

  • Приложения ERP (планирование ресурсов предприятия): в качестве интересного примера (также указанного в MQ Gartner) можно привести Zoho. Еще одна важная и впечатляющая платформа для ERP и CRM это Salesforce.

  • Блокчейн и Интернет вещей: Atra.

  • Искусственный интеллект: сейчас мы начинаем наблюдать появление таких инструментов, как C3 AI Ex Machina.

Челленджи low-code/no-code

Платформы low-code/no-code имеют множество преимуществ, но в то же времясоздают определенные трудности и требуют обучения для работы с ними. Многие передовые практики только появляются и относительно незрелы, и следовательно, растет ответственность при их использовании. Что касается традиционного программирования, здесь накоплен огромный опыт, существуют сильные сообщества, а передовые практики задокументированы. Во многих отношениях low code/no-code находится в зачаточном состоянии даже несмотря на то, что разработка на основе моделей существует уже давно (особенно платформы BPM).

Вот некоторые из наиболее серьезных проблем:

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

2. Время и усилия на изучение платформ: low-code/no-code увеличивает скорость и производительность, но инструменты и платформы нетривиальны, и для развития необходимого уровня владения ими требуется время. Это один из наиболее неправильно понимаемых аспектов low-code/no-code. Сложные программные конструкции, такие как вложенные циклы, не так уж и просты на любой платформе.

3. Необходимость использования нескольких платформ: одни платформы имеют более полную функциональность, другие нет. Unqork и Bubble, например, предназначены для любого сценария использования и поэтому предлагают множество вариантов интеграции с корпоративными системами. Кроме того, они могут взять много полезного из других компонентов, специализирующихся в определенных областях; например, Bubble вместе, скажем, с Parabola или плагином Zapier можно использовать для автоматической интеграции. С возможностями управления данными и интеграциями в Parabola или Zapier работать легче, чем с нативными от Bubble. Существуют и другие плагины или технологические компоненты, дополняющие платформы low-code/no-code: посмотрите, например, список технологических партнеров Unqork или полный список плагинов для Bubble.

4. Недостаточность ресурсов и поддержки сообщества: в мире существуют миллионы, или даже десятки миллионов разработчиков обычных языков программирования, множество онлайн-курсов, а также книги и материалы, доступные для таких языков, как Java или C#, есть множество сообществ и ресурсов для аутсорсинга. Совсем иначе дела обстоят для low-code/no-code, особенно для более новых платформ.

5. Сбивающее с толку ценообразование: корпоративные low-code/no-code платформы, как правило, неоправданно дороги. Платформы для среднего и малого рынка менее затратны, но, как правило, менее масштабируемы. А использование нескольких платформ для создания комплексного решения еще больше усложняет вопросы ценообразования.

Это лишь некоторые из основных проблем. Они ясно дают понять, что low-code/no-code не панацея. Тем не менее, такой подход остается серьезной тенденцией для разработки инновационных решений как для действующих предприятий, так и для стартапов.

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

Готовы ли вы к переходу на low-code/no-code?

Примечание переводчика: наша компания предоставляет как low-code/no-code омниканальный облачный контакт-центр Voximplant Kit с широкими возможностями автоматизации обслуживания клиентов, так и serverless-платформу Voximplant для традиционной разработки с набором API для создания голосовых, видео- и текстовых коммуникаций.

Подробнее..

Неотправленное письмо боссу в кровавом Enterprise

30.03.2021 16:11:46 | Автор: admin

Хоть я и интроверт, но с soft skills у меня неплохо. Поэтому я стараюсь придерживаться принципа:

True wisdom:

  1. Having a lot to say.

  2. Not saying it.

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

Небольшая предыстория

Пару лет назад я помогал одной команде, ниша которой ближе всего к классической DBA team, с автоматизацией их деятельности. Было очень интересно, но использовать предложенное они не стали - разве что раз в год и на 1/10. Потом судьба нас разнесла не только по разным подразделениям фирмы, но и даже по разным фирмам.

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

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

О прогрессорстве в кровавом Enterprise

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

Такого рода системы не живут сами по себе в вакууме. Это не WinZip и не Total Commander. У них есть привязка к Active directory, пермиссии пользователей, каталог серверов и многое другое, за чем кто-то должен следить.

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

Завод по производству роботов? Да уже через пару дней он остановится. Разве что из силовых балок строения сделают мечи. Технология должна быть адекватна умениям туземцев. иначе она не приживется. Ну или приживется только как карго культ.

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

Автоматизация никому не нужна

Одна из частей автоматизации, которую я делал, делала бэкапы и восстанавливала базы по цепочке PROD -> UAT -> QA -> DEV. Я с радостью имплементировал ваши хотелки - на каждом этапе примнять к базам скрипты, которые меняют config в некоторых таблицах под конкретный environment и прячут/удаляют sensitive data. Базы можно было переименовывать (чтобы, например, на QA иметь несколько копий), а некоторые шаги (например, UAT) можно было пропускать - но все равно по пути применяя все скрипты. Эти пожелания были логичны их было приятно делать.

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

потому что отлаживать это сложно

Кто делал такие вещи то знает, что их довольно неудобно отлаживать - ведь вы не можете сделать 'DEV environment' набора реальных DEV, QA, UAT и PROD со всех их спецификой. Достаточно быстро отладка переходит на реальные серверах в режиме 'dry run', а потом и реальные прогоны на тестовых базах

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

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

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

Вот ко мне пришел один менеджер и предложил на всех серверах и всех базах прогнать скрипт, который ищет данные, похожие на персональные. Одна минута - и процесс пошел. Через пол часа отчет готов. А как бы было без меня? Да замечательно. Берут одного или двух линейных DBA из страны песен и плясок, и они "какой такой механизм, все вручную" (c) дня за два обходят все сервера и базы. Все сделано, и люди при деле. Win-win.

Теория гандикапа

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

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

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

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

Свойство

Суть гандикапа

Message

Длинные волосы

Требуют времени для ухода

Цепляются за ветки в первобытном лесу

Надо мыть а то будут животные

Индикатор здоровья

Живет в безопасности, по лесу бегать не надо

Чистый дом - важно для детей

Высокие каблуки

Не может быстро бегать

"я живу в безопасных условиях"

Узкая юбка/платье

Не может быстро бегать

"я живу в безопасных условиях"

Длинные ногти

Не могу работать и защищать себя

Есть ресурсы

Безопасные условия жизни

Заметная одежда с рюшечками

Видима для хищников

Требует ухода/стирки

Безопасные условия жизни

Чистый дом (для детей)

Самка вида homo sapiens с гандикапомСамка вида homo sapiens с гандикапом

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

У меня есть коллега, который в пятницу почти не работает. Ну только если что-то супер срочное. А так он по пятницам саморазвивается, скачивает программы, читает статьи, проводит эксперименты. А это возможно, если у людей есть свободное время - то есть если они не загнаны, как лошади. А у тебя, американец, линейный DBA это робот, который работает только по инцидентам, они примитивны, зато их поток нескончаем - убить spid (процесс в SQL server), применить скрипт, восстановить бэкап. И все это с учетом on-call в выходные. И потом у них всех потухшие глаза и ненависть к профессии.

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

Подробнее..

Нюансы эксплуатации R решений в enterprise окружении

21.02.2021 16:09:36 | Автор: admin

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

Решения на R хорошо закрывают нишу средних данных, когда данных чуть больше чем влезает в excel или в ненастроенную реляционку и нужны сложные алгоритмы и процессинг, но когда разворачивать пусковой комплекс бигдаты еще более чем рано. Речь идет о десятках-сотнях террабайт в полном объеме, которые легко умещаются в бэкенд на Cliсkhouse. Важный момент: все находится во внутреннем контуре, в подавляющем большинстве случаев ПОЛНОСТЬЮ отрезанном от интернета.

Является продолжением серии предыдущих публикаций, уточняет публикацию Конструктивные элементы надежного enterprise R приложения.

Проблематика

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

  • инфраструктурная воспроизводимость. Многие вопросы закрываются комбинацией технологий docker + renv + git.

  • программная воспроизводимость. Многие вопросы закрываются технологией пакетов и автотестов.

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

В чем заключается сложность?

Алгоритмы, выкатываемые в продуктив

  • могут быть многофазными с совокупным временем расчета несколько часов;

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

  • опираются на данные, которые поступают от постоянно изменяемых объектов наблюдения и эволюционируют во времени;

  • могут активно использовать случайные выборки из данных бэкенда;

  • могут в рамках своего жизненного цикла постоянно уточняться и модифицироваться.

  • могут иметь на выходе не один показатель, а семейства таблиц в которых каждая метрика характеризуются своим распределением;

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

В таких случаях крайне затруднительно сделать тестовый набор данных (рефересный снапшот), а для ИТ служб задача бэкапа всего инстанса БД зачастую становится либо крайне дорогой либо непосильной. Приходится дополнять аналитические решения дополнительным модулем статистической самодиагностики, исполняемым как в продуктивном процессе так и по требованию. А также приходится применять широкий спектр средств отладки для быстрой диагностики возникших отклонений, как в prod контуре (постфактум), так и в dev среде.

Контроль в продуктивном контуре

Исходные постулаты

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

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

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

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

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

Логирование

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

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

С точки зрения формирования дампов, штатный подход с использованием .Rds файлов для данных среднего размера (1-1000 Гб Ram) никуда не годится.
Существует 3 хорошие многопоточные альтернативы:

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

Валидация

Комбинируйте в зависимости от задачи и вкуса:

Есть и другие пакеты, если этого будет недостаточно. Любители альтернативных решений могут почитать репозиторий Win-Vector.

Трекинг пайплайнов

Очень часто вычисления проводятся через pipe (%>%). Все промежуточные результаты скрыты. Если что-то идет не так (а особенно часто рвет на слиянии со справочниками по уникальному ключу, который ни разу не уникальный), то по выходу очень тяжело понять проблемный шаг. В таких случаях помогают пакеты, фиксирующие характеристики объектов, передаваемых посредством . с шага шаг.

Вот примеры полезных пакетов для трекинга:

  • tidylog. Тут важно, что tidylog перехватывает глаголы tidyverse, поэтому конструкции dpylr::mutate останутся без трекинга.

  • lumberjack. Сохраняем изменения

Отладка

Есть масса хороших публикаций насчет отладки, например:

Какие сценарии на практике оказываются крайне востребованными (shiny здесь не затрагиваем)?

  • browser(). Никаких точек останова в IDE. Хардкорное прерывание в любом месте и в любом сценарии исполнения. Бонусом -- доп. трюк ниже.

  • debug()/undebug()/debugonce(). Для отладки функций, в т.ч., прилинкованных из пакетов.

  • traceback(). Докапываемся до причины в цепочке ассертов.

  • options(datatable.verbose = TRUE). Что творится у основной рабочей лошадки data.table под капотом (план запроса, перформанс, ошибки).

  • utils::getFromNamespace и пр. Хирургический скальпель для модификации функций из пакетов.

  • Пакеты waldo и diffobj. Прецизионное сравнение небольших объектов.

  • pryr::object_size(). Честное взвешивание объектов.

  • Пакет reprex. Запрашиваем помощь друга.

  • Пакет gginnards. Отладка графиков ggplot.

Трюк по использованию browser(), отлаживаем внутренние циклы data.table.

library(data.table)library(magrittr)dt <- as.data.table(mtcars) %>%  .[, {m <- head(.SD, 2); print(ls()); browser(); m}, by = gear]#>  [1] "-.POSIXt"  "am"        "carb"      "Cfastmean" "cyl"       "disp"     #>  [7] "drat"      "gear"      "hp"        "m"         "mpg"       "print"    #> [13] "qsec"      "strptime"  "vs"        "wt"       #> Called from: `[.data.table`(., , {#>     m <- head(.SD, 2)#>     print(ls())#>     browser()#>     m#> }, by = gear)

Профилировка

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

Заключение

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

  2. Для отдельного класса задач может оказаться целесообразно использовать makeинструменты. drake/targets

Предыдущая публикация -- Как в enterprise приручить при помощи R технологии process mining?.

Подробнее..

Windows 10 IoT Enterprise 2019 и 1809 основные отличия

23.07.2020 12:09:17 | Автор: admin

Введение


Windows 10 IoT Enterprise 2019 маркетинговое наименование очередного выпуска Windows 10. Выход данной версии был объявлен в сентябре прошлого года, соответственно имеет версию 1809, 18 год, 09 месяц. По новому выпуску Windows 10 1809 написано много статей, но большинство из них посвящено различным бантикам, красивостям и различному функционалу, который востребован в домашних условиях. В данной статье пойдет речь только о функционале, который востребован в коммерческом сегменте. А именно о новых возможностях режима киоска. Также будет затронута тема изменения наименований схем обслуживания редакций Windows корпоративного сегмента.


Старая схема обслуживания с новым названием


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


LTSC означает Long Term Servicing Channel (с долгосрочным обслуживанием). Ранее такой канал назывался LTSB Long Term Servicing Branch, Майкрософт просто изменил название канала обслуживания, само обслуживание осталось прежним.


Также Майкрософт поменял название ветки обслуживания CBB Current Branch for Business, теперь эта ветка обслуживания называется SAC Semi-Annual Channel. Опять же поменялось только название.


Но следует упомянуть, что для веток обслуживания LTSC и SAC используются разные дистрибутивы Windows.


Немного о новом режиме киоска в SAC


Как я уже говорил, у LTSC и SAC разные дистрибутивы. В LTSC нет стандартных универсальных приложений и магазина приложений, а в SAC есть. Соответственно, в LTSC нет браузера Edge, а в он SAC есть. Если при настройке киоска выбрать браузер Edge, то теперь доступы два режима:


  1. Как цифровой знак или интерактивный дисплей
  2. Как общедоступный браузер

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


Киоск с множеством приложений


Некоторые думают, что лицензионное использование Windows 10 IoT Enterprise подразумевает работу только одного приложения на устройстве, на самом деле это не так. Устройство должно быть предназначено для выполнения одной бизнес-задачи и у пользователя не должно быть доступа к рабочему столу. Теперь Майкрософт сам дал инструмент для использования множества приложений. Данный режим называется multi-app kiosk, далее для краткости я буду называть его мультикиоск. В данной статье мы рассмотрим настройку данного режима с помощью пакета обеспечения и некоторые особенности данного режима.


Немного о режиме Мультикиоск


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


Перечень основных настроек и возможностей режима:


  1. Настройка для множества пользователей или групп
  2. Каждому пользователю или группе можно назначить индивидуальные настройки
  3. Возможность использования универсальных и классических приложений
  4. Возможность автоматического запуска одного из приложений при входе пользователя в систему
  5. Работа приложений по белому списку
  6. Доступ к папкам по белому списку

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


В пункте 6 обозначена хорошая возможность, но на данный момент возможно дать разрешение на запись только для папки Downloads. Режим позволяет использовать универсальные и классические приложения. Все настройки режима указываются в XML-файле, в котором также можно указать настройки для киоска с одним приложением.


А теперь попробуем все это настроить


Что нам понадобится


  1. В первую очередь нам понадобится сама система, которая поддерживает режим мультикиоска. Здесь можно скачать демонстрационную версию
  2. Инструкция по настройке мультикиоска
  3. Любой XML редактор
  4. Для применения настроек мульткиоска:
    1. Для способа 1 ICD, который входит в состав ADK. ADK можно скачать здесь
    2. Для способа 2 утилита PsExec. Утилиту можно скачать здесь

Он сказал Поехали!


Все опыты я буду проводить на Windows 10 IoT Enterprise 1809 LTSC x32 коммерческая версия, а не демонстрационная. Система будет без активации т.к. отсутствие активации не сказывается на функционале системы. Я взял 32 бита только потому, что она занимает меньше места и работать с образами системы будет быстрее.


Шаг 1 установка


Установка Win 10 IoT Enterprise ничем не отличается от установки Win 10 Enterprise, поэтому весь процесс установки описывать не буду, скажу лишь о некоторых нюансах.


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


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


Т.к. мы будем создавать резервные образа системы и для этого будем ее запечатывать в режиме аудита, то можно сэкономить немного времени загрузив систему в режиме аудита сразу после установки. Для этого, когда система у Вас попросит выбрать регион Lets start with region. Is this right просто нажмите Ctrl+Shift+F3.


Шаг 2 создаем образ системы


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


Sysprep.bat для запечатывания системы.
@echo offchcp 1251>nulnet session>nul 2>nulif %errorLevel% neq 0 (powershell -command "Start-Process "%~s0" -Verb RunAs"&exit)tasklist /fi "ImageName eq sysprep.exe" | find /i "sysprep.exe"if %errorlevel% lss 1 (taskkill /im sysprep.exe)set AdminName=Adminnet user %AdminName%>nul 2>nulif %errorLevel% neq 0 (call :AddAdmin "%AdminName%")if %errorLevel% neq 0 (call :ShowMessage "Ошибка создания новой учетной записи администратора "%AdminName%"Нажмите любую клавишу для завершения работы скрипта"&pause>nul&exit)pushd "%~dp0"clscall :ShowMessage echo  1 - Запечатать систему в режиме аудитаecho  2 - Запечатать систему в режиме приветствия:Selectset /p Choice="Введите номер пункта меню: "if "%Choice%"=="1" (goto Audit)if "%Choice%"=="2" (goto OOBE)echo.&echo Выбрано недопустимое значение.&goto Selectexit:Audit    call :ShowMessage "Запечатывание системы в режиме аудита"    reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v KillSysprep /t REG_SZ /d "taskkill /im sysprep.exe" /f    %SYSTEMROOT%\System32\Sysprep\sysprep.exe /audit /generalize /shutdown /quietgoto :eof:OOBE    call :ShowMessage "Запечатывание системы в режиме приветствия"    reg delete HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v KillSysprep /f    powershell -command "(Get-Content -path 'Unattend.xml' -Raw).Trim() -replace 'Architecture=""".+?"""','Architecture="""%PROCESSOR_ARCHITECTURE%"""' | Set-Content -path 'Unattend.xml'"    %SYSTEMROOT%\System32\Sysprep\sysprep.exe /oobe /generalize /shutdown /quiet /unattend:Unattend.xmlgoto :eof:AddAdmin    setlocal    set UserName=%~1    if not defined UserName (echo Не указано имя пользователя&endlocal&exit /b 1)    call :GetGroupName "S-1-5-32-544" AdminGroup    if not defined AdminGroup (endlocal&exit /b 2)    call :GetGroupName "S-1-5-32-545" UserGroup    if not defined UserGroup (endlocal&exit /b 3)    net user %UserName% /add    wmic useraccount where "Name='%UserName%'" set PasswordExpires=False>nul    net localgroup %AdminGroup% %UserName% /add    net localgroup %UserGroup% %UserName% /delete    endlocal&exit /b 0goto :eof:GetGroupName    if "%~1"=="" (echo Не указан SID группы&goto :eof)    set %2=    for /f "tokens=2 delims=\ " %%i in ('whoami /groups /fo table^|find "%~1"') do set %2=%%i    if not defined %2 (echo Ошибка определения имени группы по SID'у "%~1")goto :eof:ShowMessage    setlocal enabledelayedexpansion    set String=%~1    if not defined String (echo.&setlocal disabledelayedexpansion&goto :eof)    set /a ConCols=120 & set /a Num=1    set "String[!Num!].str=%String:=" & set /a Num+=1 & set "String[!Num!].str=%"    for /l %%a in (1,1,%Num%) do (        for /l %%b in (0,1,%ConCols%) do if "!String[%%a].str:~%%b!" == "" (set "String[%%a].str= !String[%%a].str! "&set /a String[%%a].len-=1) else (set /a String[%%a].len+=0||set /a String[%%a].len=0)        if not defined String[%%a].str (set String[%%a].str= )        if not !String[%%a].len! equ 0 (call set String[%%a].str=%%String[%%a].str:~,!String[%%a].len!%%)        if "!String[%%a].str: =!"=="" (echo.) else (echo !String[%%a].str!))    setlocal disabledelayedexpansiongoto :eof

При запуске скрипт будет проверять наличие учетной записи Admin и создавать ее при ее отсутствии. Учетная запись будет добавлена в группу Администраторы.


Unattend.xml файл ответов для sysprepа.
<?xml version="1.0" encoding="utf-8"?><unattend xmlns="urn:schemas-microsoft-com:unattend">    <settings pass="specialize">        <component name="Microsoft-Windows-Deployment" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <RunSynchronous>                <RunSynchronousCommand wcm:action="add">                    <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v SetupDisplayedProductKey /t REG_DWORD /d 1 /f</Path>                    <Order>1</Order>                    <Description>Dont show key page</Description>                </RunSynchronousCommand>                <RunSynchronousCommand wcm:action="add">                    <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v UnattendCreatedUser /t REG_DWORD /d 1 /f</Path>                    <Order>2</Order>                    <Description>Dont make account</Description>                </RunSynchronousCommand>                <RunSynchronousCommand wcm:action="add">                    <Path>cmd.exe /c rd %systemdrive%\Sysprep /s /q</Path>                    <Order>3</Order>                    <Description>Del Folder</Description>                </RunSynchronousCommand>            </RunSynchronous>        </component>        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <AutoLogon>                <Enabled>true</Enabled>                <Username>Admin</Username>            </AutoLogon>        </component>    </settings>    <settings pass="oobeSystem">        <component name="Microsoft-Windows-International-Core" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <InputLocale>en-US; ru-RU</InputLocale>            <SystemLocale>ru-RU</SystemLocale>            <UILanguage>ru-RU</UILanguage>            <UILanguageFallback></UILanguageFallback>            <UserLocale>ru-RU</UserLocale>        </component>        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <OOBE>                <HideEULAPage>true</HideEULAPage>                <HideLocalAccountScreen>true</HideLocalAccountScreen>                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>                <ProtectYourPC>1</ProtectYourPC>            </OOBE>        </component>    </settings></unattend>

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


Теперь я запечатаю систему в режиме аудита с помощью Sysprep.bat и сниму образ системы. Снимать образ системы я буду с помощью DISMа и буду снимать образ только системного тома. Если Вы будете снимать образ только системного тома, а не всего диска, то не забывайте копировать содержимое каталога Windows\System32\Recovery на первый том в папку Recovery\WindowsRE после разворачивания системы. Это нужно будет сделать до загрузки ОС т.к. после загрузки ОС каталог Windows\System32\Recovery уже будет пустым.


Шаг 3 русификация системы


Языковой пакет можно установить без подключения к интернету, если этот пакет у Вас есть. Если нет, то система сама его загрузит из интернета, когда Вы добавите язык в настройках. Только не нужно брать языковой пакет от предыдущих версий ОС. Для Windows 10 1809 должен быть языковой пакет именно для Windows 10 1809.


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


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


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


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


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


После полной локализации системы обязательно создайте образ системы.


Шаг 4 установка необходимых приложений


Т.к. в системах LTSB и LTSC нет магазина приложений, то установка приложений из Microsoft Store вызывает некоторые трудности, а именно загрузка приложения. Для загрузки приложений компания Adguard сделала очень удобный сервис Adguard Store, с помощью которого можно получить временные ссылки на загрузку приложений и их компонентов.


Для установки приложения Вам понадобятся файлы с расширениями Appx и AppxBundle. Перед установкой самого приложения необходимо установить его компоненты. Как правило компоненты от приложения можно интуитивно отличить по названию файла.


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


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


Шаг 5 создание файла настройки для мультикиоска


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


Начнем с настройки расположения плиток. Самый простой способ создания XML-конфигурации настройки плиток экспорт их текущего состояния.


Первым делом добавим в меню Пуск плитки тех приложений, которые нам нужны. Вызываем поиск Win+s, находим нужное приложение, нажимаем на нем правой кнопкой мыши и выбираем пункт Закрепить на начальном экране.


Я закрепил следующие приложения:


  • Блокнот
  • Калькулятор
  • Internet Explorer
  • Paint
  • WordPad
  • Параметры
  • Безопасность Windows

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


Т.к. на плитке Безопасность Windows не умещается название полностью, я изменю ее размер на Широкий. Для изменения размера плитки нужно нажать на плитке правой кнопкой мыши и выбрать пункт Изменить размер.


После настройки экспортируем текущее состояние, выполняем команду в среде PowerShell Export-StartLayout path C:\Sysprep\StartLayout.xml.


Дальше проще всего не создавать файл настроек самостоятельно, а отсюда взять пример файла настроек нажимаем на кнопку Copy, вставляем содержимое в блокнот и сохраняем как MultiAppKiosk.xml. Теперь меняем настройки на свои. Для изменения настроек прикрепленных плиток копируем весь блок StartLayoutCollection из StartLayout.xml в MultiAppKiosk.xml. Чтобы добавить приложения в разрешенные необходимо вставить идентификаторы универсальных приложений в раздел AllowedApps и в этот же блок добавить полный путь к исполняемым файлам классических приложений, который прописан в свойствах ярлыках, на которые ссылаются плитки. Для быстрого перехода к ярлыку, нажмите правой кнопкой мыши на закрепленной плитке и пройдите по меню Дополнительно > Перейти к расположению файла. Обратите внимание, для указания ID универсального приложения используется параметр AppUserModelId, а для указания полного пути к классическому приложению используется параметр DesktopAppPath. И еще один маленький нюанс, если Вы планируете использовать IE в системе x64, то в перечне разрешенных приложений необходимо указать два пути для исполняемого файла Program Files\Internet Explorer\iexplore.exe и Program Files (x86)\Internet Explorer\iexplore.exe.


Доступ к папкам я давать не буду, поэтому удаляю секцию FileExplorerNamespaceRestrictions.


Отображение панели задач мне не помешает, поэтому в секции Taskbar оставляю все как есть.


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


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


У меня получился вот такой файл с параметрами


MultiAppKiosk.xml
<?xml version="1.0" encoding="utf-8" ?><AssignedAccessConfiguration   xmlns="http://personeltest.ru/away/schemas.microsoft.com/AssignedAccess/2017/config"  xmlns:rs5="http://personeltest.ru/away/schemas.microsoft.com/AssignedAccess/201810/config"  >  <Profiles>      <Profile Id="{9A2A490F-10F6-4764-974A-43B19E722C23}">          <AllAppsList>              <AllowedApps>                  <App AppUserModelId="WINDOWS.IMMERSIVECONTROLPANEL_CW5N1H2TXYEWY!MICROSOFT.WINDOWS.IMMERSIVECONTROLPANEL" />                  <App AppUserModelId="Microsoft.Windows.SecHealthUI_cw5n1h2txyewy!SecHealthUI" />                  <App DesktopAppPath="%windir%\system32\notepad.exe" />                  <App DesktopAppPath="C:\Program Files\Internet Explorer\iexplore.exe" />                  <App DesktopAppPath="%windir%\system32\win32calc.exe" />                  <App DesktopAppPath="%windir%\system32\mspaint.exe" />                  <App DesktopAppPath="%ProgramFiles%\Windows NT\Accessories\wordpad.exe" />              </AllowedApps>          </AllAppsList>          <StartLayout>              <![CDATA[<LayoutModificationTemplate xmlns:defaultlayout="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/FullDefaultLayout" xmlns:start="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/StartLayout" Version="1" xmlns="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/LayoutModification">                    <LayoutOptions StartTileGroupCellWidth="6" />                    <DefaultLayoutOverride>                      <StartLayoutCollection>                        <defaultlayout:StartLayout GroupCellWidth="6">                          <start:Group Name="Настройки">                            <start:Tile Size="2x2" Column="0" Row="0" AppUserModelID="WINDOWS.IMMERSIVECONTROLPANEL_CW5N1H2TXYEWY!MICROSOFT.WINDOWS.IMMERSIVECONTROLPANEL" />                            <start:Tile Size="4x2" Column="2" Row="0" AppUserModelID="Microsoft.Windows.SecHealthUI_cw5n1h2txyewy!SecHealthUI" />                          </start:Group>                          <start:Group Name="Офисные приложения">                            <start:DesktopApplicationTile Size="2x2" Column="2" Row="2" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Wordpad.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="0" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Notepad.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="2" Row="0" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Calculator.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="0" Row="2" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Paint.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="4" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk" />                          </start:Group>                        </defaultlayout:StartLayout>                      </StartLayoutCollection>                    </DefaultLayoutOverride>                  </LayoutModificationTemplate>              ]]>          </StartLayout>          <Taskbar ShowTaskbar="true"/>      </Profile>  </Profiles>  <Configs>      <Config>          <Account>User</Account>          <DefaultProfile Id="{9A2A490F-10F6-4764-974A-43B19E722C23}"/>      </Config>  </Configs></AssignedAccessConfiguration>

Когда будете делать свои XML-файлы настройки не забывайте, что у каждого профиля должен быть уникальный ID, причем не только в пределах одного XML-файла, а в одной ОС. Т.е. в идеале чтобы не запутаться можно каждый раз создавать новый идентификатор, это можно сделать в среде PowerShell с помощью команды [guid]::NewGuid(). И обязательно сохраняйте файл в кодировке UTF-8, если файл будет сохранен в кодировке ANSI, то при сборке пакета подготовки получите ошибку если в XML-файле будет кириллица.


Шаг 6 применение настроек мультикиоска


Рассмотрим два способа применения настроек, описанных в конфигурационном файле. Первый с помощью пакета подготовки, который нужно создавать в ICD. Для кого-то, возможно, такой способ будет более привычным. Второй с использованием MDM Bridge WMI Provider, этот способ мне показался более удобным.


Способ 1


У кого нет ICD, скачиваем ADK и устанавливаем. Установка ADK очень простая, набор компонентов можно оставить по умолчанию.


Запускаем ICD, нажимаем на плитку Дополнительная подготовка, указываем имя и папку проекта и нажимаем Далее. В следующем окне выбираем Все выпуски Windows для настольных компьютеров и нажимаем Далее. Импорт пакета подготовки можно пропустить, нажимаем Готово.


Раскрываем выпадающее меню Параметры среды выполнения, далее раскрываем подменю AssignedAccess и выбираем пункт MultiAppAssignedAccessSettings. В верхней части средней секции окна ICD нажимаем кнопку Обзор и указываем расположение XML-файла с настройками. На всякий случай можно сохранить проект нажав Ctrl+s. В левой верхней части ICD выбираем Экспорт в выпадающем меню выбираем пункт Пакет подготовки. В качестве владельца выбираем ИТ-администратор все остальные вопросы можно пропустить, нажимая Далее и в конце нажимаем Сборка и Готово.


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


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


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


Способ 2


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


MiltiKiosk.bat скрипт для запуска
@echo offchcp 1251>nulif not exist "%~dp0psexec.exe" call :ShowMessage "Для работы скрипта необходим файл psexec.exeДля завершения работы скрипта нажмите любую клавишу"&pause>nul&exitnet session>nul 2>nulif %errorLevel% neq 0 (powershell -command "Start-Process "%~s0" -Verb RunAs"&exit)for /f "tokens=2 delims==" %%i in ('wmic useraccount where "Name='%UserName%'" get SID /value^|find "SID"') do set SID=%%ireg add HKU\%SID%\Software\Sysinternals\PsExec /v EulaAccepted /t REG_DWORD /d 1 /ffor /f %%i in ('dir "%~dp0%~n0*.ps1" /b /o:n') do set PSFilePath=%~dp0%%iif not defined PSFilePath (echo Не найдено PS файлов с началом названия - "%~n0"&pause&exit)set PSFilePath=%PSFilePath: =` %"%~dp0psexec.exe" -i -s powershell -command "Start-Process powershell.exe -ArgumentList '-ExecutionPolicy Unrestricted -Command %PSFilePath%'"exit:ShowMessage    setlocal enabledelayedexpansion    set String=%~1    if not defined String (echo.&setlocal disabledelayedexpansion&goto :eof)    set /a ConCols=120 & set /a Num=1    set "String[!Num!].str=%String:=" & set /a Num+=1 & set "String[!Num!].str=%"    for /l %%a in (1,1,%Num%) do (        for /l %%b in (0,1,%ConCols%) do if "!String[%%a].str:~%%b!" == "" (set "String[%%a].str= !String[%%a].str! "&set /a String[%%a].len-=1) else (set /a String[%%a].len+=0||set /a String[%%a].len=0)        if not defined String[%%a].str (set String[%%a].str= )        if not !String[%%a].len! equ 0 (call set String[%%a].str=%%String[%%a].str:~,!String[%%a].len!%%)        if "!String[%%a].str: =!"=="" (echo.) else (echo !String[%%a].str!))    setlocal disabledelayedexpansiongoto :eof

MiltiKiosk_Ver.12.ps1 основной скрипт
Function ConvertEncoding ([string]$From, [string]$To) {    Begin{$encFrom = [System.Text.Encoding]::GetEncoding($From);$encTo = [System.Text.Encoding]::GetEncoding($To)}    Process{$bytes = $encTo.GetBytes($_);$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes);$encTo.GetString($bytes) -replace [char]0, ''}}Function ShowMessage ($Message='', $Align=0) {    Try {$Align = [decimal]$Align} Catch {Return 'Для параметра Align может быть указано только число' | ConvertEncoding 'windows-1251' -To 'UTF-16'}    if ($Message -is [int]) {for ($i=1; $i -le $Message; $i++) {Write-Host}; Return}    if ([System.Text.Encoding]::Default.WindowsCodePage -eq 1252) {$Message = $Message | ConvertEncoding 'windows-1251' -To 'UTF-16'}    if ($Message -is [string]) {[array] $Message = $Message}    foreach ($String in $Message) {        Try {$String = [int]$String} Catch {}        if ($String -is [int]) {for ($i=1; $i -le $String; $i++) {Write-Host}; continue}        if ($Host.UI.RawUI.BufferSize.Width -gt $String.Length) {            if ($Align -eq 0) {Write-Host $String            } else {Write-Host ("{0}{1}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / $Align) - [Math]::Floor($String.Length / $Align)))), $String)}        } else {Write-Host $String}    } }$script:NameSpace="root\cimv2\mdm\dmmap"$script:ClassName="MDM_AssignedAccess"$script:MultiAppKiosk = Get-CimInstance -Namespace $NameSpace -ClassName $ClassNameif (-not $MultiAppKiosk) {ShowMessage -Message (3, 'Ошибка получения объекта настроек', 2, 'Нажмите "Enter" для завершения рабты скрипта') -Align 2; Read-Host; Exit}Function MainMenu() {    ShowMessage (13, ' 0 - Выход', ' 1 - Выбрать XML-файл для установки', ' 2 - Показать текущую конфигурацию мультикиоска', ' 3 - Удалить настройки мультикиоска', 1)    $local:PromptText = 'Выберите действие'    if ([System.Text.Encoding]::Default.WindowsCodePage -eq 1252) {$PromptText = $PromptText | ConvertEncoding 'windows-1251' -To 'UTF-16'}    $local:Selections = 1..2    While ($true) {        $Select = Read-Host -Prompt $PromptText        Switch ($Select) {            0 {exit}            1 {XMLSelection}            2 {ShowMessage -Message (1, 'Начало конфигурации') -Align 2; Write-Host $MultiAppKiosk.Configuration; ShowMessage -Message ('Конец конфигурации', 1, 'Для возврата в меню нажмите "Enter"', 1) -Align 2; Read-Host}            3 {$MultiAppKiosk.Configuration = $Null; Set-CimInstance -CimInstance $MultiAppKiosk; ShowMessage -Message (1, 'Выполнена команда удаления настроек', 1) -Align 2}            DEFAULT {ShowMessage 'Выбрано недопустимое значение'}        }        if ($Selections -contains $Select) {Clear-Host; ShowMessage (15, ' 0 - Выход', ' 1 - Выбрать XML-файл для установки', ' 2 - Показать текущую конфигурацию мультикиоска', ' 3 - Удалить настройки мультикиоска', 1)}    }}Function XMLSelection() {    Clear-Host    if (!(Test-Path -Path $PSScriptRoot'\XML')) {ShowMessage -Message (13, 'Не найден каталог', $('"'+$PSScriptRoot+'\XML"'), 1, 'Нажмите "Enter" для возврвта в предыдущее меню') -Align 2; Read-Host; Return}    $local:XMLList = @()    $XMLList += Get-ChildItem -Path $PSScriptRoot'\XML' -name -filter '*.xml'    if ($XMLList.Count -eq  0) {ShowMessage -Message (13, 'Не найдено XML-файлов в каталоге', $('"'+$PSScriptRoot+'\XML"'), 1, 'Нажмите "Enter" для возврвта в предыдущее меню') -Align 2; Read-Host; Return}    [int]$local:Indent = 13 - $XMLList.Count / 2; if ($Indent -lt 1) {$Indent = 1}    ShowMessage ($Indent, ' 0 - Вернуться в предыдущее меню')    for ($i=0; $i -le $XMLList.GetUpperBound(0); $i++) {Write-Host $(' '+($i+1)+' - '+$XMLList[$i])}    Write-Host    $local:PromptText = 'Выберите файл для установки'    if ([System.Text.Encoding]::Default.WindowsCodePage -eq 1252) {$PromptText = $PromptText | ConvertEncoding 'windows-1251' -To 'UTF-16'}    $local:Selections = 1..$XMLList.Count    $local:BackToPrevMenu = 0    While ($BackToPrevMenu -eq 0) {        $Select = Read-Host -Prompt $PromptText        Switch ($Select) {            0 {$BackToPrevMenu = 1}            {$Selections -contains $Select} {ShowMessage $('Дана команда на применение настроек из файла '+$XMLList[$Select-1]);                $local:Config = (Get-Content -encoding UTF8 -path $($PSScriptRoot+'\XML\'+$XMLList[$Select-1]) -Raw).Trim()                $local:GUIDs = [regex]::matches($Config, '{.+?}') | select -ExpandProperty Value | Get-Unique                foreach ($GUID in $GUIDs) {$Config = $Config -replace $('\'+$GUID),$('{'+[guid]::NewGuid()+'}')}                $Config = $Config -replace '&','&' -replace '<','<' -replace '>','>' -replace "'",''' -replace '"','"'                $MultiAppKiosk.Configuration = $Config                Set-CimInstance -CimInstance $MultiAppKiosk            }            DEFAULT {ShowMessage ('Выбрано недопустимое значение')}         }    }}MainMenu

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


MultiAppKiosk.xml
<?xml version="1.0" encoding="utf-8" ?><AssignedAccessConfiguration   xmlns="http://personeltest.ru/away/schemas.microsoft.com/AssignedAccess/2017/config"  xmlns:rs5="http://personeltest.ru/away/schemas.microsoft.com/AssignedAccess/201810/config"  >  <Profiles>      <Profile Id="{9A2A490F-10F6-4764-974A-43B19E722C23}">          <AllAppsList>              <AllowedApps>                  <App AppUserModelId="WINDOWS.IMMERSIVECONTROLPANEL_CW5N1H2TXYEWY!MICROSOFT.WINDOWS.IMMERSIVECONTROLPANEL" />                  <App AppUserModelId="Microsoft.Windows.SecHealthUI_cw5n1h2txyewy!SecHealthUI" />                  <App DesktopAppPath="%windir%\system32\notepad.exe" />                  <App DesktopAppPath="C:\Program Files\Internet Explorer\iexplore.exe" />                  <App DesktopAppPath="%windir%\system32\win32calc.exe" />                  <App DesktopAppPath="%windir%\system32\mspaint.exe" />                  <App DesktopAppPath="%ProgramFiles%\Windows NT\Accessories\wordpad.exe" />              </AllowedApps>          </AllAppsList>          <StartLayout>              <![CDATA[<LayoutModificationTemplate xmlns:defaultlayout="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/FullDefaultLayout" xmlns:start="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/StartLayout" Version="1" xmlns="http://personeltest.ru/away/schemas.microsoft.com/Start/2014/LayoutModification">                    <LayoutOptions StartTileGroupCellWidth="6" />                    <DefaultLayoutOverride>                      <StartLayoutCollection>                        <defaultlayout:StartLayout GroupCellWidth="6">                          <start:Group Name="Настройки">                            <start:Tile Size="2x2" Column="0" Row="0" AppUserModelID="WINDOWS.IMMERSIVECONTROLPANEL_CW5N1H2TXYEWY!MICROSOFT.WINDOWS.IMMERSIVECONTROLPANEL" />                            <start:Tile Size="4x2" Column="2" Row="0" AppUserModelID="Microsoft.Windows.SecHealthUI_cw5n1h2txyewy!SecHealthUI" />                          </start:Group>                          <start:Group Name="Офисные приложения">                            <start:DesktopApplicationTile Size="2x2" Column="2" Row="2" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Wordpad.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="0" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Notepad.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="2" Row="0" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Calculator.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="0" Row="2" DesktopApplicationLinkPath="%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Paint.lnk" />                            <start:DesktopApplicationTile Size="2x2" Column="4" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk" />                          </start:Group>                        </defaultlayout:StartLayout>                      </StartLayoutCollection>                    </DefaultLayoutOverride>                  </LayoutModificationTemplate>              ]]>          </StartLayout>          <Taskbar ShowTaskbar="true"/>      </Profile>  </Profiles>  <Configs>      <Config>          <Account>User</Account>          <DefaultProfile Id="{9A2A490F-10F6-4764-974A-43B19E722C23}"/>      </Config>  </Configs></AssignedAccessConfiguration>

Немного об особенностях скрипта. Скрипт рассчитан на использование XML-файлов с кодировкой UTF8, если вы хотите использовать кодировку ANSI, то из параметра чтения файла уберите параметр encoding UTF8. В папку XML необходимо размещать XML-файлы без замены символов, скрипт сам заменит спецсимволы на соответствующие обозначения. Чтобы не запутаться в GUIDах привязки пользователей к профилям вы можете просто указывать номер или имя пользователя в фигурных скобках, все содержимое в фигурных скобках будет заменено на GUIDы.


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


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


Шаг 7 запечатывание системы


Мультикиоск работает, ну вот и все, казалось бы


Если все идет по плану, значит вы чего-то не замечаете.


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


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


Эксперименты


Что же у нас получилось. В системе две учетные записи:


Admin в группе Администраторы
User в группе Пользователи
В режиме аудита мультикиоск работал, запечатали не работает.


Эксперимент 1


Удаляем установленный пакет подготовки, в оснастке Управление компьютером удаляем пользователя User и создаем нового пользователя с именем User, применяем пакет подготовки, заходим в учетную запись User не работает. Заходим под именем Admin, удаляем пользователя User из группы Пользователи, добавляем в группу Администраторы, заходим под именем User не работает. Заходим под именем Admin, удаляем пакет подготовки с мультикиоском, заходим под именем User получилось войти, но естественно режим мультикиоска не работает т.к. был удален пакет подготовки.


Эксперимент 2


Заливаем образ системы русифицированный в режиме аудита.


ОС загрузилась, нажимаем Win+r, т.к. окно sysprepа у нас закрылось автоматически выполняем команду sysprep, в открывшемся окне запускаем sysprep. Настройки sysprepa в окне: Переход в окно приветствия системы (OOBE), Подготовка к использованию, Перезагрузка. Жмем ОК и ждем приветствия ОС. Отвечаем на вопросы при первой загрузке системы: Continue in selected language? русский; регион Россия; раскладка клавиатуры Русская; добавить вторую раскладку клавиатуры пропустить; Давайте подключим вас к сети Пока пропустить; подключитесь к интернету нет; лицензионное соглашение принять; Кто будет использовать этот компьютер Test; создание пароля оставляю поле пустым; удобная работа на разных устройствах нет; параметры конфиденциальности принять. ОС загрузилась, в оснастке Управление компьютером создаем пользователя с именем User, добавляем пакет подготовки. Результат не работает.


Эксперимент 3


Заливаем образ системы русифицированный в режиме аудита.


ОС загрузилась, подключаем систему к инету, выполняем команду gpedit.msc и в разделе Центр обновлений Windows включаем параметр Включить рекомендуемые обновления через автоматическое обновление, на всякий случай перезагружаемся. В центре обновлений жмем Проверить наличие обновлений и перезагружаемся до тех пор, пока не будут установлены все обновления. Отключаем систему от интернета. Запускаем sysprep в графическом режиме и повторяем все действия, которые описаны в предыдущем шаге с запуска утилиты sysprep до добавления пакета подготовки. Результат не работает.


Эксперимент 4


Заливаем образ системы англоязычный в режиме аудита.


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


Эксперимент 5


Заливаем образ системы русифицированный в режиме аудита.


В оснастке Управление компьютером создаем пользователя User, добавляем пакет подготовки, заходим в учетную запись User, мультикиоск работает.


Выходим из учетной записи, заходим под учетной записью Admin. Запускаем PowerShell с правами администратора, выполняем команду Dism /online /Get-Intl и видим Язык пользовательского интерфейса по умолчанию: en-US.


Загружаемся с флэшки в WinPE, развернутая ОС у меня на диске E. Выполняем команду Dism /image:E:\ /Set-UILang:ru-ru. Смотрим на результат, выполняем Dism /image:E:\ /Get-Intl и видим Default system UI language: ru-RU.


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


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


Загружаемся с флэшки в WinPE, развернутая ОС у меня на диске E. Выполняем команду Dism /image:E:\ /Set-UILang:en-us. Смотрим на результат, выполняем Dism /image:E:\ /Get-Intl и видим Default system UI language: en-US.


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


Загружаемся с флэшки в WinPE, развернутая ОС у меня на диске E. Выполняем команду Dism /image:E:\ /Set-UILang:ru-ru. Смотрим на результат, выполняем Dism /image:E:\ /Get-Intl и видим Default system UI language: ru-RU.


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


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


Эксперимент 6


Для чистоты эксперимента перезаливаем систему. Заливаем образ системы русифицированный в режиме аудита.


Запускаем sysprep в графическом режиме, запечатываем ОС с теми же параметрами что и во время эксперимента 2. Ждем приветствия ОС и отвечаем на вопросы: Continue in selected language? English (United States); регион Россия; раскладка клавиатуры Русская. Далее все параметры выбраны как и в эксперименте 2.


Смотрим параметры значения языка пользовательского интерфейса по умолчанию. Выполняем команду Dism /online /Get-Intl и видим Default system UI language: en-US. В оснастке Управление компьютером создаем пользователя User, добавляем пакет подготовки, заходим в учетную запись User, мультикиоск работает.


Пробуем сломать киоск путем изменения языка пользовательского интерфейса по умолчанию. Заходим в пользователя Test, который был создан при первой загрузке системы и включаем для него автоматический вход чтобы система не загружалась в учетную запись User, сразу. Выполняем netplwiz, выбираем пользователя Test, снимаем флажок Требовать ввод имени пользователя и пароля и применяем параметры.


Загружаемся с флэшки в WinPE. Выполняем команду Dism /image:E:\ /Set-UILang:ru-ru. Смотрим на результат, выполняем Dism /image:E:\ /Get-Intl и видим Default system UI language: ru-RU.


Загружаемся в систему, пытаемся войти в учетную запись User, мультикиоск работает. Т.е. его не получается сломать. А можно ли его таким образом заставить работать?


Эксперимент 7


Заливаем образ системы русифицированный в режиме аудита.


Запускаем Sysprep.bat, выбираем пункт 2. Загружаемся в систему, в оснастке Управление компьютером создаем пользователя User, добавляем пакет подготовки, заходим в учетную запись User, мультикиоск не работает.


Загружаемся с флэшки в WinPE. Выполняем команду Dism /image:E:\ /Set-UILang:en-us. Смотрим на результат, выполняем Dism /image:E:\ /Get-Intl и видим Default system UI language: en-US.


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


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


Эксперимент 8


Заливаем образ системы англоязычный в режиме аудита.


Подключаемся к интернету, в параметрах системы заходим в раздел Language выбираем Add language, выбираем язык Русский, нажимаем Next, параметры установки оставляем по умолчанию, нажимаем Install, после установки языкового пакета перезагружаем систему, теперь на русифицирована. Отключаем систему от интернета, запускаем Sysprep.bat, выбираем пункт 2.


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


Эксперимент 9


Попробуем русифицировать систему до установки, в оффлайн режиме. Заодно будет краткий ликбез по локализации дистрибутива.


Беру флэшку с чистым оригинальным дистрибутивом X21-96381. Она будет диском E. Для монтирования образов создаю папки: c:\Mount\Install, c:\Mount\Winre, c:\Mount\Boot. Беру набор пакетов локализации X21-87814. И в папку c:\Mount копирую из него пакеты: Microsoft-Windows-Client-Language-Pack_x86_ru-ru.cab, lp.cab, WinPE-Setup_ru-ru.cab. Запускаю консоль с правами администратора. Думаю, что дальнейшие команды будут понятны без комментариев.


Команды локализации
cd c:\mountdism /Mount-Wim /WimFile:e:\sources\install.wim /index:1 /MountDir:Installcodedism /Image:Install /Add-Package /PackagePath:Microsoft-Windows-Client-Language-Pack_x86_ru-ru.cabcodedism /Image:Installcode /Set-AllIntl:ru-rudism /Image:Install /Set-TimeZone:"Russian Standard Time"codedism /Mount-Wim /WimFile:Install\Windows\System32\Recovery\Winre.wim /index:1 /MountDir:Winrecodedism /Image:Winre /Add-Package /PackagePath:lp.cabcodedism /Image:Winrecode /Set-AllIntl:ru-rudism /Image:Winre /Set-TimeZone:"Russian Standard Time"codedism /Unmount-Image /MountDir:Winre /Commitcodedism /Image:Install /Gen-LangINI /distribution:E:\ /Set-AllIntl:ru-RUcodedism /image:Install /Set-SetupUILang:RU-ru /distribution:E:\codedism /Unmount-Image /MountDir:Install /Commitcodedism /mount-wim /wimfile:e:\sources\boot.wim /index:1 /mountdir:Bootcodedism /Image:Boot /Add-Package /PackagePath:lp.cabcodedism /Image:Bootcode /Set-AllIntl:ru-rucopy e:\sources\lang.ini Boot\sources\lang.inicodedism /Unmount-Image /MountDir:Boot /Commitcodedism /mount-wim /wimfile:e:\sources\boot.wim /index:2 /mountdir:Bootcodedism /Image:Boot /Add-Package /PackagePath:lp.cabcodedism /Image:Boot /Add-Package /PackagePath:WinPE-Setup_ru-ru.cabcodedism /Image:Bootcode /Set-AllIntl:ru-rucopy e:\sources\lang.ini Boot\sources\lang.ini /ycodedism /Unmount-Image /MountDir:Boot /Commit

Загружаемся с флэшки, выбираем русский язык и ставим систему на чистый диск. Когда система просит выбрать регион нажимаем Ctrl+Shift+F3. В оснастке Управление компьютером создаем пользователя User, добавляем пакет подготовки, заходим в учетную запись User, мультикиоск не работает.


Загружаемся с флэшки в WinPE. Выполняем команду Dism /image:E:\ /Set-UILang:en-us.


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


Видимо дело не в методах добавления пакета, попробуем добавить дополнительные пакеты.


Эксперимент 10


Берем флэшку, которую мы подготовили на предыдущем шаге.


Берем пакет Feat on Demand X21-87815. В папку c:\Mount копирую из него пакеты: Microsoft-Windows-LanguageFeatures-Basic-ru-ru-Package~31bf3856ad364e35~x86~~.cab, Microsoft-Windows-LanguageFeatures-OCR-ru-ru-Package~31bf3856ad364e35~x86~~.cab, Microsoft-Windows-LanguageFeatures-Handwriting-ru-ru-Package~31bf3856ad364e35~x86~ ~.cab, Microsoft-Windows-LanguageFeatures-TextToSpeech-ru-ru-Package~31bf3856ad364e35~x86~~.cab.


Берем пакет Feat on Demand RDX Updt X21-99781. В папку c:\Mount копирую из него пакеты: Microsoft-Windows-RetailDemo-OfflineContent-Content-Package~31bf3856ad364e35~x86~~.cab, Microsoft-Windows-RetailDemo-OfflineContent-Content-ru-ru-Package~31bf3856ad364e35~x86~~.cab.


Запускаем консоль с правами администратора и выполняем команды:


Команды
cd c:\mountdism /Mount-Wim /WimFile:e:\sources\install.wim /index:1 /MountDir:Installdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-LanguageFeatures-Basic-ru-ru-Package~31bf3856ad364e35~x86~~.cabdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-LanguageFeatures-OCR-ru-ru-Package~31bf3856ad364e35~x86~~.cabdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-LanguageFeatures-Handwriting-ru-ru-Package~31bf3856ad364e35~x86~~.cabdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-LanguageFeatures-TextToSpeech-ru-ru-Package~31bf3856ad364e35~x86~~.cabdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-RetailDemo-OfflineContent-Content-Package~31bf3856ad364e35~x86~~.cabdism /Add-Package /Image:Install /PackagePath:Microsoft-Windows-RetailDemo-OfflineContent-Content-ru-ru-Package~31bf3856ad364e35~x86~~.cabdism /Unmount-Image /MountDir:Install /Commit

Загружаемся с флэшки, выбираем русский язык и ставим систему на чистый диск. Когда система просит выбрать регион нажимаем Ctrl+Shift+F3. В оснастке Управление компьютером создаем пользователя User, добавляем пакет подготовки, заходим в учетную запись User. Я получил черный экран, который долго висел, поэтому я выполнил горячую перезагрузку системы.


Удаляем пакет подготовки, заходим под пользователем User, перезагружаем систему, добавиляем пакет подготовки, мультикиоск не работает.


Загружаемся с флэшки в WinPE. Выполняем команду Dism /image:E:\ /Set-UILang:en-us.


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


Обход проблемы


Нормальные герои. Всегда идут в обход!


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


Заливаем образ системы русифицированный в режиме аудита.


В файле Unattend.xml в параметре вписываем en-US, запускаем Sysprep.bat, выбираем пункт 2 и смотрим, что у нас получилось. Экран приветствия на английском языке, мультикиоск работает. Значит нужно добавить в Unattend.xml команду на изменение языка приветствия. А для этого необходимо выполнить команду control intl.cpl,,/f: с указанием конфигурационного файла, в котором будет прописано копирование текущих параметров в экран приветствия. Содержимое конфигурационного файла будет выглядеть вот так.


<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend">      <gs:UserList>        <gs:User UserID="Current" CopySettingsToSystemAcct="true"/>     </gs:UserList></gs:GlobalizationServices>

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


echo ^<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend"^>^<gs:UserList^>^<gs:User UserID="Current" CopySettingsToSystemAcct="true"/^>^</gs:UserList^>^</gs:GlobalizationServices^>>Config.xml

Но нам эту команду нужно поместить в XML, у которого свои требования к использованию спецсимволов:


Спецсимвол Замещающее значение
> &gt;
< &lt;
& &amp;
&apos;
&quot;

В итоге для создания конфигурационного файла получилась вот такая команда для FirstLogonCommands.


cmd.exe /c echo ^&lt;gs:GlobalizationServices xmlns:gs=&quot;urn:longhornGlobalizationUnattend&quot;^&gt;^&lt;gs:UserList^&gt;^&lt;gs:User UserID=&quot;Current&quot; CopySettingsToSystemAcct=&quot;true&quot;/^&gt;^&lt;/gs:UserList^&gt;^&lt;/gs:GlobalizationServices^&gt;&gt;&quot;%TMP%\Config.xml&quot;

Далее выполняем команду с использованием конфигурационного файла.


control intl.cpl,,/f:&quot;%TMP%\Config.xml&quot;

Далее удаляем ранее созданный файл и перезагружаем систему т.к. изменения вступят в силу после перезагрузки.


cmd.exe /c del &quot;%TMP%\Config.xml&quot; /q&amp;shutdown /r /f /t 00

В итоге у меня получился вот такой файл ответов для sysprepа.


Unattend.xml
<?xml version="1.0" encoding="utf-8"?><unattend xmlns="urn:schemas-microsoft-com:unattend">    <settings pass="specialize">        <component name="Microsoft-Windows-Deployment" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <RunSynchronous>                <RunSynchronousCommand wcm:action="add">                    <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v SetupDisplayedProductKey /t REG_DWORD /d 1 /f</Path>                    <Order>1</Order>                    <Description>Dont show key page</Description>                </RunSynchronousCommand>                <RunSynchronousCommand wcm:action="add">                    <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v UnattendCreatedUser /t REG_DWORD /d 1 /f</Path>                    <Order>2</Order>                    <Description>Dont make account</Description>                </RunSynchronousCommand>                <RunSynchronousCommand wcm:action="add">                    <Path>cmd.exe /c rd %systemdrive%\Sysprep /s /q</Path>                    <Order>3</Order>                    <Description>Del Folder</Description>                </RunSynchronousCommand>            </RunSynchronous>        </component>        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <AutoLogon>                <Enabled>true</Enabled>                <Username>Admin</Username>            </AutoLogon>        </component>    </settings>    <settings pass="oobeSystem">        <component name="Microsoft-Windows-International-Core" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <InputLocale>en-US; ru-RU</InputLocale>            <SystemLocale>ru-RU</SystemLocale>            <UILanguage>en-US</UILanguage>            <UILanguageFallback></UILanguageFallback>            <UserLocale>ru-RU</UserLocale>        </component>        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://personeltest.ru/away/schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://personeltest.ru/away/www.w3.org/2001/XMLSchema-instance">            <OOBE>                <HideEULAPage>true</HideEULAPage>                <HideLocalAccountScreen>true</HideLocalAccountScreen>                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>                <ProtectYourPC>1</ProtectYourPC>            </OOBE>            <FirstLogonCommands>                <SynchronousCommand wcm:action="add">                    <CommandLine>cmd.exe /c echo ^&lt;gs:GlobalizationServices xmlns:gs=&quot;urn:longhornGlobalizationUnattend&quot;^&gt;^&lt;gs:UserList^&gt;^&lt;gs:User UserID=&quot;Current&quot; CopySettingsToSystemAcct=&quot;true&quot;/^&gt;^&lt;/gs:UserList^&gt;^&lt;/gs:GlobalizationServices^&gt;&gt;&quot;%TMP%\Config.xml&quot;</CommandLine>                    <Description>CreateConfig</Description>                    <Order>1</Order>                </SynchronousCommand>                <SynchronousCommand wcm:action="add">                    <CommandLine>control intl.cpl,,/f:&quot;%TMP%\Config.xml&quot;</CommandLine>                    <Description>UseConfig</Description>                    <Order>2</Order>                </SynchronousCommand>                <SynchronousCommand wcm:action="add">                    <CommandLine>cmd.exe /c del &quot;%TMP%\Config.xml&quot; /q&amp;shutdown /r /f /t 00</CommandLine>                    <Description>DelConfig</Description>                    <Order>3</Order>                </SynchronousCommand>            </FirstLogonCommands>        </component>    </settings>

Проверяем


Заливаем образ системы русифицированный в режиме аудита.


Меняем файл Unattend.xml на новый, запускаем Sysprep.bat, выбираем пункт 2 и смотрим, что у нас получилось. При первой загрузке экран приветствия на английском языке, система перезагружается. Экран приветствия на русском языке, мультикиоск работает.


Если у вас остались вопросы относительно настройки и лицензирования Windows 10 IoT Enterprise, обращайтесь по адресу mse@quarta.ru или на сайт quarta-embedded.ru.
Ответы на некоторые вопросы Вы можете найти в нашей вики или на нашем YouTube-канале


Автор статьи: Борисенков Владимир, технический эксперт компании Кварта Технологии.

Подробнее..

Из песочницы Работа с enterprise как мы не сделали систему аналитики для SaaS сервиса

08.08.2020 16:12:48 | Автор: admin
Мы сильно обрадовались новому контракту и уже представляли, как логотип клиента приукрасит наше портфолио. Но все оказалось не так радужно. Расскажем, как мы работали с дочкой крупной российской IT-компании, и почему у нас не получилось сделать крутой проект.



О проекте


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

Структура процессов


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

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

Далее сделали карту со структурой взаимодействия всех систем. В ней показано, по какой логике должны идти события, и на каких этапах собирается аналитика. Основные данные берем из CRM и соотносим их с данными по рекламе и конверсиям. Собираем в myBI, визуализируем в Power BI.

Воронки продаж


Продажи у клиента велись в Enybox CRM, их мы перенесли в amoCRM для удобства интеграции. Логику продаж получилось собрать в три воронки.


Три последовательные воронки

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

Как должна была работать аналитика


Изначальные события Итоговые события
Форма обратной связи Форма обратной связи
Регистрация в сервисе Регистрация в сервисе
Первое пополнение
Тестирование (опционально при небольшом пополнении)
Повторные пополнения
Отказ от использования (прогрев через ОП)

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

Отображение данных


Пример дашборда

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

В момент конверсии на сайте генерировался отдельный ID для синхронизации рекламных систем и CRM. По этому ID мы связывали данные расходов и доходов. Так мы соотносили данные и могли строить по ним отчеты.

Юнит экономика. Retention



График rolling-retention'а сервиса с 1 по 12 месяц

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

Конверсия в первое пополнение



Конверсия сильно зависела от количества новых клиентов и начала их оплат. Первые 9 месяцев мы получали примерно по 430 новых регистраций и по 90 оплат от новых пользователей ежемесячно. Конверсия в покупку в месяц регистрации составила 20%, по данным за 12 месяцев.

Помимо стандартных показателей


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

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

Что пошло не так


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



Медленная разработка


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

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

Плохая коммуникация и отсутствие экспертизы


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

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

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

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


Факапы с нашей стороны


Мы не учли пропускную способность системы. На одно событие платформы в пике мы передавали до 10 запросов к amoCRM, чтобы выполнить логику бизнес-процессов.

100 000 ивентов в сутки * 10 запросов к amoCRM = 1 000 000 запросов в сутки

1 000 000 запросов в сутки / 10 запросов в секунду (ограничение амо) = 100 000 секунд = 27 часов

Итог: синхронизация никогда не закончится

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

Опять все сломали


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

Нам не хватило экспертности в техническом плане. Клиенту устойчивости в управлении и желания довести проект до конца.

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

Как можно было избежать неудачи


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

  1. Держать контакт с менеджером проекта: понимать его мотивацию; помогать ему защищать презентации перед руководителями. Делать все, чтобы стейкхолдер не потерял интерес к проекту.
  2. Соблюдать структуру коммуникации. Все важные чекпоинты проекта фиксировать по почте. Все обсуждения на встречах собирать в краткое резюме. Так специалистам со стороны клиента будет проще находиться в контексте действий. Не нужно будет каждый раз восстанавливать цепочку событий.
  3. Определять мотивацию специалистов со стороны клиента при старте работ. Если проект не стоит в их KPI и он изначально в низком приоритете завершить его будет практически невозможно.
  4. Думать наперед. Даже при разработке MVP нужно смотреть, на узкие места, которые могут возникнуть в будущем. Проект всегда расширяется и важно предусмотреть структуру, чтобы не переписывать весь код с нуля.



Автор статьи Фёдор Анисимов, маркетолог LAND PRO.
Подробнее..

До 40 релизов в день в Enterprise наша сool story

17.06.2021 12:20:28 | Автор: admin

Пару слов о нас: мы команда банка Открытие, которая отвечает за разработку всех розничных фронтов от рабочего места сотрудника в отделении до мобильных приложений физических лиц. В последние пару лет мы переживаем взрывной рост в несколько раз у нас более 400 сотрудников ИТ и мы продолжаем расти и расти. Как оказалось, многие решения, которые были приняты на старте нашей работы, оказались верными. И о некоторых из них мы вам расскажем. Готовы? Поехали!

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

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

  • Монорепоэто решение, которое невзлетает из коробки, так как у нас банально много кода (на сегодня его около 100 GB), который просто будет долго выкачиваться к себе на локальную машину изрепозитория;

  • Когда мы попытаемся открыть такой огромный проект вIDE, она скорее всего приляжет;

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

  • Оставался открытым вопрос разграничения доступа внутрирепозитория(большие компании, которыепиарилиподход смонорепонесколько лет назад,решали этокастомнымсамописом, который разграничивал доступ, например, на уровне папок);

  • Очевидным плюсом было удобстворазруливаниязависимостей (в одномрепозиторииэто можноконтролировать на уровне кода). Так чтоесли отказываться отмонорепозитория, то надо было придумать как решить эту проблему.

Кирпичики, из которых складывается наше решение

Учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:

  1. МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения в работе сервиса;

  2. МИНОРНУЮ версию, когда вы добавляете новую функциональность, ненарушая обратной совместимости;

  3. ПАТЧ-версию, когда вы делаете какие-то внутренние исправления в работе сервиса, которые никак не меняют внешние контракты.

Дополнительные обозначения дляпредрелизныхибилд-метаданных возможны как дополнения к МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ формату.

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

  • Публикация контрактов

В конвейер сборки сервисов внедрен процесс генерации и публикации контрактов, в которых однозначно описан интерфейс взаимодействия с ними. Доменные сервисы общаются с внешними потребителями наружу черезGraphQL(на самом деле у нас500+ сервисов, которые поделены на доменные группы, наподобие модной нынче и активно продвигаемойdomainorientedmicroservicearchitecture(DOMA). У каждой доменной группы есть только один внешнийGraphQLфасад, а внутри сервисы общаются поRabbitMQ, но для простоты понимания рассмотрим только пример с доменными сервисами). Сам контракт представляет из себя SDL схему, котораягенеритсяпри помощи стандартного функционала из коробкибиблиотекиqraphql-dotnetпри помощи утилитыgraphql-sdl-exporter. На самом деле утилиту мы написали сами, но решили ей поделиться и выложили еев паблик.

Что происходит после коммита:

Весь процесс контроля автоматизирован и встроен в конвейер сборки.

Шаги:

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

  2. После из этого контракта (SDL схемы) при помощи утилит специфичных для каждого языка генерируются клиенты для различных потребителей на их языках, которые представляют собой пакеты, хранящиеся в репозитории пакетного менеджера. В нашем случае это NuGet, NPM, Graddle для .Net, JS и Java соответственно. В качестве инструмента для хранения и управления пакетов используется Arfifactory. Версия контракта (сервиса-поставщика) соответствует версии пакета. Например, сервис Payments версии 2.1.3 имеет контракт версии 2.1.0 (не 2.1.3, т.к. перегенерация для версий от 2.1.1 и выше не требуется, а потребуется только для 2.2.0).

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

    Очень важный момент: Для feature веток и ветки master существуют различные хранилища пакетов: Release для master, Snapshot - для feature-веток. Причем из ветки master нет доступа к пакетам из Snapshot.

Рассмотрим пару примеров, которые продемонстрируют работу такого подхода.

Пусть сервис Accounts версии 4.7.2 потребляет сервис Payments версии 2.1.3 (обращается к нему, используя контракт в виде nuget пакета версии 2.1.0). Появилась необходимость добавить новую фичу в сервис Payments.

Вариант 1:

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

Когда разработчиксервиса Payments Вася сделает коммит в свою feature ветку, увеличив версию сервиса, в хранилище Snapshot появятся новые клиенты для сервиса Payments. Разработчик сервиса Accounts Петя сможет обновить свой пакет для работы с сервисом Payments до версии 2.2.0 с новой функциональностью, сможет ей воспользоваться и реализовать свою логику работы с Payments в своей feature ветке своего репозитория.

Пока Вася доводит свой функционал до идеала, Петя допиливает свою функциональность, которая теперь зависит от версии Payments 2.2.0 и подливает свои изменения в ветку master, что в нашем случае приводит к инициации процесса релиза сервиса Accounts на прод. В процессе сборки сервис Accounts пытается разрешить свои зависимости и, в частности, получить новую версию пакета для работы с Payments 2.2.0 из хранилища Release (напомню, что master смотрит только туда), где его нет. Сборка падает с ошибкой. Автоматический контроль сработал. Петя идет к Васе, просит его побыстрее раскатать на прод новую версию сервиса Payments, после чего катит свою новую версию Accounts.

Вариант 2:

В сервисе Payments необходимо сделать обратно несовместимые изменения. Вообще мы такое категорически не приветствуем, но иногда такая необходимость возникает. Вася знает о своих потребителях (откуда скажем позже), он пишет письма ответственным и предупреждает всех о том, что собирается ломать обратную совместимость и увеличить версию своего сервиса до 3.0.0. В день Икс Вася опубликует версию Payments на тестовый контур и ждет результатов интеграционных тестов. У тех, кто не готов к обновлению сервиса Payments, попадают Beta тесты и тестовый контур станет неработоспособным в той части, которая потребляет сервис Payments. Новые контракты Payments при этом будут лежать в Snapshot. Вася не обновляет master-ветку, пока все потребители Payments не обновят свои версии пакетов для работы с Payments и не будут готовы синхроннос ним (сразу после него) раскататься на бой.

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

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

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

Подробнее..

Категории

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

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