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

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

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

 

 -Статистика

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

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Боремся с вирусами и инфраструктурой, или отключение SMB v1

Четверг, 29 Июня 2017 г. 12:07 + в цитатник


В связи с недавной эпидемией шифровальщика WannaCry, эксплуатирующим уязвимость SMB v1, в сети снова появились советы по отключению этого протокола. Более того, Microsoft настоятельно рекомендовала отключить первую версию SMB еще в сентябре 2016 года. Но такое отключение может привести к неожиданным последствиям, вплоть до курьезов: лично сталкивался с компанией, где после борьбы с SMB перестали играть беспроводные колонки Sonos.


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


SMB (Server Message Block) – сетевой протокол для удаленного доступа к файлам и принтерам. Именно он используется при подключении ресурсов через \servername\sharename. Протокол изначально работал поверх NetBIOS, используя порты UDP 137, 138 и TCP 137, 139. С выходом Windows 2000 стал работать напрямую, используя порт TCP 445. SMB используется также для входа в домен Active Directory и работы в нем.


Помимо удаленного доступа к ресурсам протокол используется еще и для межпроцессорного взаимодействия через «именованные потоки» – named pipes. Обращение к процессу производится по пути \.\pipe\name.

Первая версия протокола, также известная как CIFS (Common Internet File System), была создана еще в 1980-х годах, а вот вторая версия появилась только с Windows Vista, в 2006. Третья версия протокола вышла с Windows 8. Параллельно с Microsoft протокол создавался и обновлялся в его открытой имплементации Samba.


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


Под спойлером вы найдете сводную таблицу изменений в версиях SMB.
Версия Операционная система Добавлено, по сравнению с предыдущей версией
SMB 2.0 Windows Vista/2008 Изменилось количество команд протокола со 100+ до 19
Возможность «конвейерной» работы – отправки дополнительных запросов до получения ответа на предыдущий
Поддержка символьных ссылок
Подпись сообщений HMAC SHA256 вместо MD5
Увеличение кэша и блоков записи\чтения
SMB 2.1 Windows 7/2008R2 Улучшение производительности
Поддержка большего значения MTU
Поддержка службы BranchCache – механизм, кэширующий запросы в глобальную сеть в локальной сети
SMB 3.0 Windows 8/2012 Возможность построения прозрачного отказоустойчивого кластера с распределением нагрузки
Поддержка прямого доступа к памяти (RDMA)
Управление посредством командлетов Powershell
Поддержка VSS
Подпись AES–CMAC
Шифрование AES–CCM
Возможность использовать сетевые папки для хранения виртуальных машин HyperV
Возможность использовать сетевые папки для хранения баз Microsoft SQL
SMB 3.02 Windows 8.1/2012R2 Улучшения безопасности и быстродействия
Автоматическая балансировка в кластере
SMB 3.1.1 Windows 10/2016 Поддержка шифрования AES–GCM
Проверка целостности до аутентификации с использованием хеша SHA512
Обязательные безопасные «переговоры» при работе с клиентами SMB 2.x и выше

Считаем условно пострадавших


Посмотреть используемую в текущий момент версию протокола довольно просто, используем для этого командлет Get–SmbConnection:



Вывод командлета при открытых сетевых ресурсах на серверах с разной версией Windows.


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


Get–SmbServerConfiguration | Select EnableSMB1Protocol, EnableSMB2Protocol


Выключаем SMBv1 на сервере с Windows 2012 R2.



Результат при подключении с Windows 2003.


Таким образом, при отключении старого, уязвимого протокола можно лишиться работоспособности сети со старыми клиентами. При этом помимо Windows XP и 2003 SMB v1 используется и в ряде программных и аппаратных решений (например NAS на GNU\Linux, использующий старую версию samba).


Под спойлером приведу список производителей и продуктов, которые полностью или частично перестанут работать при отключении SMB v1.
Производитель Продукт Комментарий
Barracuda SSL VPN
Web Security Gateway backups
Canon Сканирование на сетевой ресурс
Cisco WSA/WSAv
WAAS Версии 5.0 и старше
F5 RDP client gateway
Microsoft Exchange Proxy
Forcepoint (Raytheon) «Некоторые продукты»
HPE ArcSight Legacy Unified Connector Старые версии
IBM NetServer Версия V7R2 и старше
QRadar Vulnerability Manager Версии 7.2.x и старше
Lexmark МФУ, сканирование на сетевой ресурс Прошивки Firmware eSF 2.x и eSF 3.x
Linux Kernel Клиент CIFS С 2.5.42 до 3.5.x
McAfee Web Gateway
Microsoft Windows XP/2003 и старше
MYOB Accountants
NetApp ONTAP Версии до 9.1
NetGear ReadyNAS
Oracle Solaris 11.3 и старше
Pulse Secure PCS 8.1R9/8.2R4 и старше
PPS 5.1R9/5.3R4 и старше
QNAP Все устройства хранения Прошивка старше 4.1
RedHat RHEL Версии до 7.2
Ricoh МФУ, сканирование на сетевой ресурс Кроме ряда моделей
RSA Authentication Manager Server
Samba Samba Старше 3.5
Sonos Беспроводные колонки
Sophos Sophos UTM
Sophos XG firewall
Sophos Web Appliance
SUSE SLES 11 и старше
Synology Diskstation Manager Только управление
Thomson Reuters CS Professional Suite
Tintri Tintri OS, Tintri Global Center
VMware Vcenter
ESXi Старше 6.0
Worldox GX3 DMS
Xerox МФУ, сканирование на сетевой ресурс Прошивки без ConnectKey Firmware

Список взят с сайта Microsoft, где он регулярно пополняется.


Перечень продуктов, использующих старую версию протокола, достаточно велик – перед отключением SMB v1 обязательно нужно подумать о последствиях.


Все-таки отключаем


Если программ и устройств, использующих SMB v1 в сети нет, то, конечно, старый протокол лучше отключить. При этом если выключение на SMB сервере Windows 8/2012 производится при помощи командлета Powershell, то для Windows 7/2008 понадобится правка реестра. Это можно сделать тоже при помощи Powershell:



Set–ItemProperty –Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB1 –Type DWORD –Value 0 –Force

Или любым другим удобным способом. При этом для применения изменений понадобится перезагрузка.


Для отключения поддержки SMB v1 на клиенте достаточно остановить отвечающую за его работу службу и поправить зависимости службы lanmanworkstation. Это можно сделать следующими командами:


sc.exe config lanmanworkstation depend=bowser/mrxsmb20/nsi 

sc.exe config mrxsmb10 start=disabled

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



Создание элемента реестра через групповые политики.


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


  • путь: HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters;


  • новый параметр: REG_DWORD c именем SMB1;


  • значение: 0.


Создание параметра реестра для отключения SMB v1 на сервере через групповые политики.


Для отключения поддержки SMB v1 на клиентах понадобится изменить значение двух параметров.


Сначала отключим службу протокола SMB v1:


  • путь: HKLM:\SYSTEM\CurrentControlSet\services\mrxsmb10;


  • параметр: REG_DWORD c именем Start;


  • значение: 4.


Обновляем один из параметров.


Потом поправим зависимость службы LanmanWorkstation, чтоб она не зависела от SMB v1:


  • путь: HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation;


  • параметр: REG_MULTI_SZ с именем DependOnService;


  • значение: три строки – Bowser, MRxSmb20 и NSI.


И заменяем другой.


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


Работает – не трогай


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


Расскажите, а вы уже отключили у себя SMB первой версии? Много было жертв?

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331906/


Метки:  

Размеры растровых изображений: пиксели, DPI, PPI, сантиметры — вы ничего не путаете?

Четверг, 29 Июня 2017 г. 12:03 + в цитатник
Приветствую уважаемое сообщество Хабра!

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




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

DPI, PPI и изменение размеров



Самое частое заблуждение — использование единиц DPI (dots per inch — точек на дюйм) и PPI (pixels per inch — пикселей на дюйм). На самом деле эти единицы относятся к принтерам и сканерам соответственно. Также их можно применять в характеристиках экранов. По сути это коэффициенты для перевода между физическими размерами в аналоге (в сантиметрах или дюймах) и размерами в пикселях для цифрового изображения.
Например, изображение в 100 пикселей, распечатанное с разрешением 100 DPI будет иметь размер 1 дюйм. Всё просто и понятно.
Однако, при изменении размеров в графических редакторах нам предлагают указать размеры в удобных нам измерениях, в том числе в DPI. Здесь и начинается путаница.
На самом деле физические размеры изображения (в сантиметрах, дюймах и т.д.) и значение DPI это всего лишь мета-информация в свойствах файла. Но редактор может использовать эти значения как средство указания требуемых размеров в пикселях.



Допустим, у нас изображение размером 3000 пикселей (квадратное), у которого стоит значение 300 DPI. Получаем: 3000 пикселей / 300 DPI = 10 дюймов. А теперь заходим в редактор (Photoshop) и изменяем значение DPI на 600. Что мы получим? А это зависит от галки «Resample». Если она стоит, мы получим upsampling (увеличение) изображения до 6000 пикселей. Если не стоит, то размер в дюймах станет 5 вместо 10.
Таким образом, для веб-разработки все значения физических размеров (DPI, сантиметры, дюймы и т.д.) можно смело игнорировать и смотреть исключительно на размеры в пикселях.

DPI/PPI экранов



Здесь мы подошли к вопросу разрешения и плотности пикселей экранов. Корректно эта плотность обозначается как PPI (pixels per inch) и показывает, сколько пикселей может быть отображено на одном дюйме экрана.
Здесь часто возникают мифические 72 и 96 PPI, которые должны показывать «стандартную» плотность пикселей для экранов. Для задач отображения графики в вебе они бесполезны. При этом реальная плотность пикселей экрана может быть совсем другой: типично что-то около 120 PPI (можете измерить и посчитать для своего экрана).
Но мы помним, что растровые картинки измеряются только в пикселях и никак иначе. Зачем мы вообще говорим о PPI экранов? Потому что есть «Retina» или «HiDPI» экраны.

Retina и HiDPI экраны


Такие дисплеи широко распространены в мобильных устройствах и дорогих ноутбуках. По сути это количественное увеличение пикселей при сохранении физических размеров экрана (например, 5 дюймов по диагонали и 330 PPI).

Для нас, как веб-разработчиков это значит появление разных пикселей в браузере: CSS-пикселей (которые мы обычно указываем в размерах элементов) и физических пикселей (реальных пикселей на экране). Формула такая: Физические пиксели = CSS-пиксели * DPR.
DPR это device pixel ratio — коэффициент перевода CSS-пикселей в физические.
При размещении картинки мы можем написать тег img с размерами 20px, а картинка будет 40 пикселей. При этом на экране с DPR=2,0 мы увидим все пиксели картинки. Но в этой ситуации нас абсолютно не волнуют реальные значения PPI экрана.
При этом мы можем использовать картинки с высокой плотностью пикселей и для обычных экранов, браузер сам отмасштабирует изображение. И опять, DPI и PPI здесь ни при чем, а картинки измеряются в пикселях. Как их показать будет решать браузер, у которого уже есть два вида пикселей.

Вот и вся история, хотя я конечно ничего не говорил об адаптивных картинках, способах оптимизации их отдачи и client hints. Но это другая история.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331864/


Метки:  

Усатый стрелок с полигональным пузом. Часть вторая

Четверг, 29 Июня 2017 г. 11:16 + в цитатник


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


А теперь, когда опубликована вторая часть, материала достаточно и для третьей части! :)

Сегодня в программе: смесь визуала и архитектуры проекта. Но сначала, ещё парочка деталей про тени.
Итак, поехали!


Статьи



Оглавление



Level 3.4. Менеджер теней.


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


  1. У каждого объекта, отбрасывающего тень, два потомка, которые рендерят тени с разными шейдерами (один только back — грани, другой — front);
  2. На сцене лежит огромный спрайт, который отрисовывается самым последним, и подкрашивается в нужный цвет, если в стенсиле ненулевое значение.

Догадываетесь, какие проблемы это вызывает?
  1. Самое простое — дублирование объектов (по два одинаковых потомка у каждого элемента). Избавиться от них, сделав двухпроходный шейдер — не вариант, т.к. объекты с многопроходными шейдерами не умеют батчиться;
  2. Далее, возможность сделать только один источник света с тенями;
  3. Очень скупые возможности по работе со светом (т.к. по сути, света и нет, только тень). Так что сделать цветную тень можно, а цветное освещение — нет;
  4. Стенсил буфер занят целиком и его не получится использовать для других эффектов.

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


  • LightSource, фонарик с бесконечной дальностью, настройкой цветов тени и освещения;
  • IShadowSource, интерфейс с функцией пересчёта тени void RebuildShadow(Vector3 lightPosition);
  • ShadowRenderer, который регистрирует все источники света и теней и умеет рендерить тени.

Код написан, шейдеры проверены, можно двигаться дальше. И тут начались проблемы.
Косяки с тенями
Забагованные тени.
На изображении выше целых две проблемы.
Во-первых, тени слишком длинные и иногда неправильно перекрывают объекты. Такое может быть, если тени рендерятся поверх пустого z-buffer'а (другие объекты могут перекрывать тень, но сами тени в z-buffer ничего не пишут).
Во-вторых, тени в каком-то странном шуме. Такое бывает, если работать с неочищенным буфером.


Итак, проблема в том, что z-buffer, с которым я работаю, судя по всему, не использовался камерой. Рендеринг кадра сейчас работает так:


  1. Рендеринг сцены в RenderTexture;
  2. Рендеринг тени, depth-buffer берётся из п.1, а color-buffer свой (об этом ниже);
  3. Композинг теней и отрендереной сцены;
  4. Постэффекты.

Про раздельное использование буферов.

Когда работаешь с постэффектами зачастую нужно с помощью какого-то шейдера преобразовать текстуру. В Unity3D для этого есть метод Graphics.Blit. Мы передаём в него исходную текстуру, указываем target — куда отрисовывать, материал и даже проход шейдера.
По сути, мы работаем минимум с тремя различными буферами:


  1. Исходный color buffer, откуда мы читаем цвета пикселей;
  2. Целевой color buffer, куда мы пишем цвета;
  3. Depth+stencil buffer, в который мы пишем (и из которого читаем глубину и данные стенсила).

И в методе Graphics.Blit целевой color buffer и depth buffer неразделимы. Т.е., если нам нужно, например, читать глубину геометрии сцены из исходной текстуры, а записывать пиксели в целевую — облом.
Или если мы сделали рендеринг сцены в текстуру, при этом часть шейдеров записала данные в стенсил, а теперь хотим получить новую текстуру, воспользовавшись этими данными (и сохранив исходную текстуру!) — тоже облом.


Выход есть и в документации Unity3D об этом прямо сказано:


Note that if you want to use depth or stencil buffer that is part of the source (Render)texture, you'll have to do equivalent of Blit functionality manually — i.e. Graphics.SetRenderTarget with destination color buffer and source depth buffer, setup orthographic projection (GL.LoadOrtho), setup material pass (Material.SetPass) and draw a quad (GL.Begin).

В общем, модифицированная версия Blit, позволяющая разделить передачу буферов:


static void Blit(RenderBuffer colorBuffer, RenderBuffer depthBuffer, Material material) {
    Graphics.SetRenderTarget(colorBuffer, depthBuffer);

    GL.PushMatrix();
    GL.LoadOrtho();

    for (int i = 0, passCount = material.passCount; i < passCount; ++i) {
        material.SetPass(i);

        GL.Begin(GL.QUADS);
        GL.TexCoord(new Vector3(0, 0, 0));
        GL.Vertex3(0, 0, 0);
        GL.TexCoord(new Vector3(0, 1, 0));
        GL.Vertex3(0, 1, 0);
        GL.TexCoord(new Vector3(1, 1, 0));
        GL.Vertex3(1, 1, 0);
        GL.TexCoord(new Vector3(1, 0, 0));
        GL.Vertex3(1, 0, 0);
        GL.End();
    }

    GL.PopMatrix();

    Graphics.SetRenderTarget(null);
}

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


void RenderShadowEffect(RenderTexture source, RenderTexture target, LightSource light) {
    shadowEffect.SetColor("_ShadowColor", light.ShadowColor);
    shadowEffect.SetColor("_LightColor", light.LightColor);
    shadowEffect.SetTexture("_WorldTexture", source);
    shadowEffect.SetTexture("_ShadowedTexture", target);

    Blit(target.colorBuffer, source.depthBuffer, shadowEffect);
}

Итак, в чем же дело? Почему моя RenderTexture, в которую я рендерю камеру на выходе совершенно пуста (и даже не очищена от мусора)?
Выключаю тени и смотрю, что показывает frame debug:


Странные рендер-текстуры.
Любопытно. Судя по всему, постэффект антиалиасинга принудительно переводит камеру на рендеринг в свою текстуру. При этом доступа до этой текстуры у меня нет: при дебаге в Camera.аctiveTexture пустая.
Ах, так, антиалиасинг! Лезешь в мою последовательность отрисовки? Тогда я залезу в твой код!
Постэффекты работают через метод MonoBehaviour.OnRenderImage, а я через MonoBehaviour.OnRenderImage и
MonoBehaviour.OnPostRender. Делаю грязный хак: переименовываю OnRenderImage в Apply и вызываю его руками, после рендеринга теней, с моими renderTexture. Теперь антиалиасинг не мешает теням.


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

Сотня обычных бледных теней с небольшим смещением.

Три цветных тени.


Пока тени притормаживают на мобилках (съедают примерно 10 — 15 лишних fps). Если все будет грустно, переведу под конец все в однопроходную отрисовку, а пока не буду налегать на источники света.


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

Дебажная визуализация через шейдеры и гизмо.

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


Level 4.1. Рефакторинг архитектуры.


Как вы помните, я развиваю проект с прототипа. Но тянуть все прототипную архитектуру (знаете, какая архитектура в прототипах, написанных за 2 часа?) не хочется, значит, нужен рефакторинг.
Итак:
Для начала выношу как можно больше данных из MonoBehaviour в ScriptableObject. Это всяческие стили, настройки, библиотека префабов;

Настройки проекта.


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


Эти классы обладают очень простым интерфейсом.
public class BulletCaster : MonoBehaviour {
    public void CastBullet(Vector2 direction);
}

public class MovingBody : MonoBehaviour {
    public Vector2 Direction {get; set;}
    public bool IsStopped {get; set;}
}


Из микроклассов можно собрать сложную логику.


Убираю прямые зависимости от синглтонов (Clock, ShadowManager и т.д.) и реализую паттерн service locator (несколько спорная вещь, но куда аккуратнее, чем россыпь синглтонов).


Реализую обработку столкновений через слои, оптимизирую их, явно убирая невозможные столкновения (например, статика <-> статика).


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


А однажды с пулом вышел забавный казус.

У моих пуль есть ограничение по времени жизни (примерно 10 секунд "незамороженного" времени). Как то раз появился странный баг: часть пуль исчезала прямо в воздухе, словно кулдаун наступал раньше срока и пуля исчезала по таймеру.
Отловить было сложно: не все пули исчезали, а дебажить каждую, надеясь, что хоть одна исчезнет — очень утомительно.
Впрочем, удалось выяснить два странных факта:


  1. Пули начинали исчезать только после перезапуска уровня;
  2. Код, ответственный за удаление пуль вообще не вызывался.

Самое важное правило в очередной раз не подвело:


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

Итак, наслаждайтесь:


  1. Уровни пересоздаются на одной сцене, без перезагрузки;
  2. При создании уровня я забыл удалять старые стены (т.к. уровень одинаковый, это не было заметно нигде, кроме иерархии;
  3. Когда пуля касалась такой двойной стены, обработчик коллизии вызывался дважды;
  4. В обработчике коллизии пуля удаляется (добавляется в пул). Таким образом, в данных пула оказывалось две ссылки на одну и ту же пулю;
  5. Через какое-то время игрок стрелял этой пулей;
  6. При попытке выстрелить ещё раз из пула забиралась ссылка на уже активную, летящую пулю. Она переинициализировалась, меняла свои координаты и "предыдущая" пуля исчезала прямо в воздухе.

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


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


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


Todo: подумать над геймплейными элементами, понятностью и простотой геймплея для игрока.


Level 4.2. Рефакторинг игровых объектов.


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


  1. Отражает ли пули или поглощает их?
  2. Уничтожим ли объект пулей?
  3. Подвижен ли или статичен?
  4. Каков тип объекта (игрок/враг/гражданский)?

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


  1. Обычные стены. Поглощают пули;
  2. Зеркальные стены. Отражают пули;
  3. Многоэтажные стены. Каждый этаж — обычный или зеркальный. При попадании пули нижний этаж уничтожается, верхние падают вниз. Так можно делать счётчики и т.д.;
  4. Ящики. Динамические, но неуничтожимые, поглощают пули;
  5. Зеркальные ящики. Динамические, но неуничтожимые, отражают пули.;
  6. Цыплята. Динамические, уничтожимые, игрок теряет очки при их гибели;
  7. Враги. Динамические, уничтожимые, нужно победить всех для прохождения уровня;
  8. Зеркальные враги. Обычные враги, но пуля, уничтожая врага, отражается;
  9. Кристаллы. Динамические, уничтожаются пулей, если игрок коснётся их, он получает бонус;
  10. Игрок.


Все доступные объекты.


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


  1. Цвет кромки определяет тип объекта;
  2. Белый цвет потолка обозначает статический объект (стену), тонированный в цвет кромки потолок — динамический.

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


  1. Многоэтажные стены. Когда остаётся только один этаж — он не будет отличаться от обычной стены. Но он будет уничтожим. Или нет? Очень нелогичная фича;
  2. Зеркальные ящики. Пуля всегда движется с одной скоростью. Переотражаясь от ящиков, она будет их бесконечно и непредсказуемо ускорять;
  3. Зеркальные враги. Придётся использовать другой цвет, не похожий ни на "вражеский", ни на "зеркальный". Эта сущность только путает все карты.

Итого, остаётся:


  1. Два типа стен, обычные и зеркальные;
  2. Игрок;
  3. Цыплята;
  4. Враги;
  5. Кристаллы;
  6. Ящики.

    Объекты, оставшиеся после чистки.

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


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


Todo: начать разработку релизных эффектов.


Level 5.1. Эффект гибели.


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

Да, хочется какого-то фана при попадании пули. Чтобы игра визуально говорила:


  • "Да, чел, ты это сделал! Ты расфигачил его в чёртовой бабушке!"
    Или наоборот:
  • "Аккуратнее, аккуратнее… Нееееет! Ты был так близко, а теперь придётся проходить все снова!"

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


Ладно, что требуется от эффекта гибели?


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

Осколки! Пусть пуля разбивает противников на кусочки! Хм, а это не сложно? Неа, все объекты выпуклые, а резать выпуклые многоугольники — одно удовольствие.


На самом деле, просто разрезать противника пополам я не могу. Он состоит из нескольких мешей:


  1. Внутренняя часть, выпуклый многоугольник, тут все просто;
  2. Цветное кольцо. Оно мало того, что не выпуклое, да ещё и с дыркой. Но состоит из N (где N — количество сторон) выпуклых четырёхугольников. Так что просто сохраню их в массиве и разрежу каждый из них;
  3. Внешняя сторона. По сути, это внешняя сторона четырёхугольников из предыдущего пункта. Но я буду работать с ней как с большим выпуклым многоугольником — для рендеринга боковых граней и физики через PolygonCollider2D.


Части объекта, которые нужно разрезать отдельно.


В результате алгоритм получается такой:


  1. Преобразую объект (игрока, врага и т.д.) во внутреннюю часть, массив кусков кольца, внешнюю часть. В дальнейшем буду именовать эту структуру "Piece";
  2. Нахожу геометрический центр для Piece;
  3. Выбираю случайное направление и "провожу" прямую в этом направлении через геометрический центр;
  4. Разрезаю Piece этой прямой. Для этого беру каждый многоугольник из Piece (кольцо, внутренняя и внешняя части или их кусочки):
    4.1. Создаю левый и правый массив точек;
    4.2. Указываю текущий массив — левый;
    4.3. Добавляю первую точку многоугольника в текущий массив;
    4.4. Прохожу по всем оставшимся точкам;
    4.5. Если текущая и предыдущая точки находятся с одной стороны прямой, добавляю текущую точку в текущий массив;
    4.5. Если текущая и предыдущая точки находятся с разных сторон прямой, нахожу точку пересечения, добавляю её и в левый и в правый массивы. Переключаю текущий массив на противоположный. Добавляю в новый текущий массив текущую точку.
  5. Добавляю все левые осколки в новый левый Piece, а правые — в правый;
  6. Снов разрезаю получившиеся осколки рекурсивно, до указанной глубины.

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





Получаю примерно такие осколки.


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

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

Итак, теперь при попадании пули в объект я подменяю последний на осколки. Объект убирается в пул, а осколки загружаются из пула и обновляют свои меши/коллайдеры согласно своей новой форме. Скорости для rigidBody рассчитываются исходя из скорости разрушенного элемента и направления пули. У осколков выключен флаг isBullet, они взаимодействуют только со стенами и друг с другом. У каждого осколка есть специальный класс FloorHider, он опускает объект по координате z сквозь пол, а после его полного исчезновения — удаляет (перемещает в пул.)


Небольшая ретроспектива:


  1. Осколки — очень "физически" понятный образ. Поэтому он помогает понять концепцию остановки времени. Осколки начинают разлетаться, тут время останавливается и всё замирает. Игра перестала выглядеть детерминированно пошаговой;
  2. Все осколки батчатся друг с другом и не тормозят;
  3. Кристалл сейчас удаляется при прикосновении без эффектов. Может, тоже разбивать на кусочки?
  4. Не хватает какого-то следа после уничтожений, хочется, чтобы на уровне оставались последствия атак;
  5. Фаново смотрится, хочется стрелять!




Осколки!


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


Todo: реализовать эффект следов от осколков.


Level 5.2.1. Эффект пятен.


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

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


Разные варианты пятен.


Думаю над полноценной заливкой, среди вариантов прототипирую такой:





Просто создание кучи треугольников.
Да, этот вариант мне понравился больше. Но создавать множество треугольников с диким overdraw'ом — плохая идея. Впрочем, результат похож на мозаику, так что думаю в сторону диаграммы Вороного.
Вот только генерировать её на лету, особенно с последующей релаксацией Ллойда (релаксация делает ячейки схожими по размеру) на мобильных устройствах будет слишком больно. Нужен предрассчет. И отсюда очередная проблема: пятна могут быть на любом расстоянии друг от друга, и я, очевидно, не могу предрассчитать бесконечно большую диаграмму. Знаете, что такое тайлинг? :)


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


  1. Создаю N точек в квадрате с координатами {-0.5, -0.5, 0.5, 0.5};
  2. Для каждого Y в интервале [-tiles, tiles] и X в интервале [-tiles, tiles], кроме X = 0, Y = 0:
    2.1. Копирую точки со смещением X, Y (при tiles = 1 получается 9 тайлов с моим начальным в центре);
  3. Строю по всем точкам (включая смещённые клоны) диаграмму Вороного;
  4. Применяю при необходимости релаксацию Ллойда;
  5. Прохожу по всем получившимся полигонам и оставляю только те, у которых центр находится в исходном квадрате {-0.5, -0.5, 0.5, 0.5}.

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

Найдёте повторения?


Подсказка


Итак, получается примерно такой кусочек мозаики:

Мозаика отрендерена на текстуре средствами библиотеки.


Делаю небольшой ScriptableObject, хранящий массив рассчитанных тайлов и редактор с большой кнопкой "recalculate tiles".


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

Теперь бы выводить эти тайлы на экран!


Todo: генерировать треугольники тайлов мозаики.


Level 5.2.2. Рендеринг тайлов.


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


Для проверки алгоритма создал вот такую "мозаику", с ней проще будет найти проблемы:

Поддельная мозаика


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

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


Итак, логика поиска такая:
Дана окружность с координатами center и радиусом radius. Нужно найти все полигоны, попадающие в окружность.


  1. Считаем из AABB окружности координаты первого и последнего блоков, попадающих в AABB (Значения координат могут быть меньше 0 или больше rows — 1 из-за тайлинга).
    var rectSize = size / (float)rows;
    int minX = Mathf.FloorToInt((center.x - radius) / rectSize);
    int minY = Mathf.FloorToInt((center.y - radius) / rectSize);
    int maxX = Mathf.CeilToInt((center.x + radius) / rectSize);
    int maxY = Mathf.CeilToInt((center.y + radius) / rectSize);
  2. Проходим по каждому блоку от min до max;
  3. Отбрасываем блоки, не пересекающиеся с окружностью;
  4. Получаем реальные координаты блока внутри тайла:
    int innerX = ((x + rows) % rows + rows) % rows;
    int innerY = ((y + rows) % rows + rows) % rows;
  5. Проходим по всем полигонам в блоке;
  6. Добавляем в список те полигоны, центры которых принадлежат окружности (с учётом смещения).

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

Запрос полигонов. Тестовая мозаика изменена на более наглядную


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





Выглядит, мягко говоря, скучно. Более того, если два пятна создаются с примерно на расстоянии одного тайла, например, {0, 0} и {1, 1}, бывают заметны повторения.


Спасибо любимой, она предложила хорошую модификацию этого алгоритма:


  1. Убрать релаксацию Ллойда, сделав полигоны более резкими;
  2. Заменить многоугольники на треугольники;
  3. Добавить больше случайности в расположение треугольников.

А теперь в картинках:
Пусть у нас есть вот такая мозаика:

Points = 500, Relax = 5


В ней бывают видны повторы, а ещё она очень однообразна.
Убираем релаксацию Ллойда:

Points = 500, Relax = 0


А теперь смешиваем все карты: считаем полигоном не многоугольник, сгенерированные в диаграмме Вороного, а треугольники, получаемые триангуляцией для рендеринга:

Triangles, Points = 500, Relax = 0


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

Выделены нулевые треугольники в каждом полигоне диаграммы.


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

Паттерны перестали быть заметны.


Резюмирую: теперь у меня есть бесконечная мозаика, в которой не видно повторов. Я могу делать запрос на получение треугольников этой мозаики в определённом радиусе. Судя по всему, основа для пятен "крови" готова.


Todo: придумать конкретную геометрию пятен и замостить её мозаикой.


Заключение.


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


Итак, ещё несколько выводов:


  1. Процедурные эффекты рулят. Иногда классические алгоритмы (вроде диаграммы Вороного) не очень подходят, но после напильника и лобзика приобретают нужные качества;
  2. Закон Хофштадтера: Любое дело всегда длится дольше, чем ожидается, даже если учесть закон Хофштадтера. В общем, разработка проекта затягивается. :)
  3. Unity3D очень полезна, но иногда ставит палки в колёса. Если ваши кастомные постэффекты перестали работать — посмотрите во frame debug, может, после обновления Unity3D решила дополнить отрисовку своими эффектами (и включила на камере msaa).

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


Спасибо за внимание, жду ваших комментариев и feedback'a!

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/326840/


[Перевод] Как создаются визуальные эффекты для игр

Четверг, 29 Июня 2017 г. 11:11 + в цитатник

Метки:  

[Перевод] Разработка нового сервиса в Android 7 | Кастомизация строки навигации

Четверг, 29 Июня 2017 г. 11:08 + в цитатник
image

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

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


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

В этой статье я хочу описать процесс расширения Android API на примере создания нового сервиса для кастомизации строки навигации.

Формулировка задачи


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

Давайте возьмем Nexus 9:
image

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

Для того чтоб сделать API максимально гибким, возьмем Android Remote View как основный параметр нашего API. Это позволит пользователю (т.е. другому разработчику) использовать многие стандартные компоненты для кастомизации. Также это предоставит механизм обратной связи от элементов в приложение.

Как точку расширения, возьмем непосредственно Android SDK: мы внесем изменения в AOSP (Android Open Source Project) и соберем собственное Android SDK. Такое SDK подойдет только для устройств работающих под управлением нашей модифицированной прошивки, но нам такое ограничение подходит априори. Как результат наши службы будет очень просто использовать и они будут доступны сразу из Android SDK.

Релизация



Скачайте и настройте среду разработки AOSP



Вся необходимая информация для настройки среды разработки AOSP предоставлена здесь. Выберите соответствующую ветвь AOSP (это влияет на версию Android) совместимую с выбранным устройством. В моем случае это Nexus 9 и ветвь android-7.1.1_r33.

Разработайте новую службу



Забегая вперед следующая схема показывает все задействованные в реализации компоненты:
image

Идея состоит в том, чтоб предоставить расширенные функции по управлению строкой навигации клиентским приложениям через службу Android. Строка навигации определена в файлах NavigationBarInflaterView.java и {aosp}/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml. Но мы не можем получить доступ к ним напрямую из клиентского приложения, так как они находятся в системном приложении SystemUI в то время, как основные службы Android располагаются в процессе system_process.

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

1. Создать прокси сервиса (менеджер) который будет видим из клиентского приложения. Это стандартный Java класс, который делегирует все функции сервису:
код
package android.os;
 
/**
 * /framework/base/core/java/android/os/NavBarExServiceMgr.java
 * It will be available in framework through import android.os.NavBarExServiceMgr;
 */
 
import android.content.Context;
import android.widget.RemoteViews;
 
public class NavBarExServiceMgr
{
    private static final String TAG = "NavBarExServiceMgr";
 
    private final Context context;
    private final INavBarExService navBarExService;
 
    public static NavBarExServiceMgr getInstance(Context context)
 {
   	 return (NavBarExServiceMgr) context.getSystemService(Context.NAVBAREX_SERVICE);
    }
 
    /**
     * Creates a new instance.
     *
     * @param context The current context in which to operate.
     * @param service The backing system service.
     * @hide
     */
    public NavBarExServiceMgr(Context context, INavBarExService service)
    {
   	 this.context = context;
   	 if (service == null) throw new IllegalArgumentException("service is null");
   	 this.navBarExService = service;
    }
 
    /**
     * Sets the UI component
     *
     * @param ui - ui component
     * @throws RemoteException
     * @hide
     */
    public void setUI(INavBarExServiceUI ui) throws RemoteException
    {
   	 navBarExService.setUI(ui);
    }
 
    public String addView(int priority, RemoteViews remoteViews)
    {
   	 try { return navBarExService.addView(priority, remoteViews); }
   	 catch (RemoteException ignored) {}
   	 return null;
    }
 
    public boolean removeView(String id)
    {
   	 try { return navBarExService.removeView(id); }
   	 catch (RemoteException ignored) {}
   	 return false;
    }
 
    public boolean replaceView(String id, RemoteViews remoteViews)
    {
   	 try { return navBarExService.replaceView(id, remoteViews); }
   	 catch (RemoteException e) {}
   	 return false;
 }
 
    public boolean viewExist(String id)
    {
   	 try { return navBarExService.viewExist(id); }
   	 catch (RemoteException e) {}
   	 return false;
    }
}



Этот класс должен быть зарегистрирован в статической секции класса SystemServiceRegistry:
код
registerService(Context.NAVBAREX_SERVICE, NavBarExServiceMgr.class,
	new CachedServiceFetcher() {
		@Override
		public NavBarExServiceMgr createService(ContextImpl ctx) {
     			IBinder b = ServiceManager.getService(Context.NAVBAREX_SERVICE);
			INavBarExService service = INavBarExService.Stub.asInterface(b);
			if (service == null) {
				Log.wtf(TAG, "Failed to get INavBarExService service.");
				return null;
			}
			return new NavBarExServiceMgr(ctx, service);
}});



С клиентской стороны служба может быть доступна следующим образом:
код
NavBarExServiceMgr navBarExServiceMgr = (NavBarExServiceMgr) getSystemService(Context.NAVBAREX_SERVICE);
// TODO



2. Определить AIDL интерфейс службы:
код
/*
* aidl file :
* frameworks/base/core/java/android/os/INavBarExService.aidl
* This file contains definitions of functions which are
* exposed by service.
*/

package android.os;

import android.os.INavBarExServiceUI;
import android.widget.RemoteViews;

/** */
interface INavBarExService
{
/**
* @hide
*/
void setUI(INavBarExServiceUI ui);

String addView(in int priority, in RemoteViews remoteViews);
boolean removeView(in String id);
boolean replaceView(in String id, in RemoteViews remoteViews);
boolean viewExist(in String id);
}



И реализовать его:
код
public class NavBarExService extends INavBarExService.Stub
…



Как видно большинство методов прямолинейны, только setUI выглядит странно. Это внутренний метод используемый классом, который реализует интерфейс INavBarExServiceUI для регистрации себя в NavBarExService. Все сущности помеченные комментарием “@hide” будут вырезаны из финального Android SDK и таким образом не будут видимы из клиентского кода.

Несколько комментариев относительно семантики API:
  • Каждый элемент идентифицируется строковым идентификатором. Он генерируется службой при добавлении нового элемента. Таким образом каждое приложение, что добавляет новые элементы через нашу службу должны сохранять возвращаемый идентификатор для того, чтоб иметь возможность работы с элементом в дальнейшем;
  • Другие методы принимает идентификатор как параметр который идентифицирует элемент;
  • Каждый элемент также имеет параметр «приоритет» который указывает в каком месте разместить элемент. Чем выше значение приоритета, тем левее будет размещение.


Реализация метода setUI:
код
@Override
public void setUI(INavBarExServiceUI ui)
{
	Log.d(TAG, "setUI");
	this.ui = ui;
	if (ui != null)
	{
		try
		{
			for (Pair entry : remoteViewsList.getList())
			{
				ui.navBarExAddViewAtEnd(entry.first, entry.second);
			}
		}
		catch (Exception e)
		{
			Log.e(TAG, "Failed to configure UI", e);
		}
	}
}



Реализация метода addView:
код
@Override
public String addView(int priority, RemoteViews remoteViews) throws RemoteException
{
	String id = UUID.randomUUID().toString();
	int pos = remoteViewsList.add(priority, id, remoteViews);
	if (ui != null)
	{
		if (pos == 0)
			ui.navBarExAddViewAtStart(id, remoteViews);
		else if (pos == remoteViewsList.size() - 1)
			ui.navBarExAddViewAtEnd(id, remoteViews);
		else
		{
			// find previous element ID
			Pair prevElPair = remoteViewsList.getAt(pos - 1);
			ui.navBarExAddViewAfter(prevElPair.first, id, remoteViews);
		}
	}
	return id;
}



remoteViewsList используется чтоб удерживать созданные элементы пока UI не будет подключен (не будет вызван метод setUI). Если он уже подключен (поле ui не равно null) новый элемент добавляется прямо в UI.

3. SystemServer должен зарегистрировать нашу службу в системе:
код
try {
	traceBeginAndSlog("StartNavBarExService");
	ServiceManager.addService(Context.NAVBAREX_SERVICE, new NavBarExService(context));
	Slog.i(TAG, "NavBarExService Started");
} catch (Throwable e) {
	reportWtf("Failure starting NavBarExService Service", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);



Добавление новой службы требует правки политик Android SEPolicy.

Добавьте новую запись в файл {aosp}/system/selinux/service.te:
type navbarex_service, app_api_service, system_server_service, service_manager_type;

Добавьте новую запись в файл {aosp}/system/selinux/service_contexts:
navbarex u:object_r:navbarex_service:s0


Имейте ввиду что формат файлов SELinux для Android 7.0 отличается от прежних версий Android.

4. Добавьте константы имени службы в класс Context чтоб клиенты могли его использовать вместо строкового значения:
код
/**
 * Use with {@link #getSystemService} to retrieve a
 * {@link android.os.NavBarExServiceMgr} for using NavBarExService
 *
 * @see #getSystemService
 */
public static final String NAVBAREX_SERVICE = "navbarex";



5. Определите интерфейс INavBarExServiceUI:
код
/*
* aidl file :
* frameworks/base/core/java/android/os/INavBarExServiceUI.aidl
* This file contains definitions of functions which are provided by UI.
*/

package android.os;

import android.widget.RemoteViews;

/** @hide */
oneway interface INavBarExServiceUI
{
void navBarExAddViewAtStart(in String id, in RemoteViews remoteViews);
void navBarExAddViewAtEnd(in String id, in RemoteViews remoteViews);
void navBarExAddViewBefore(in String targetId, in String id, in RemoteViews remoteViews);
void navBarExAddViewAfter(in String targetId, in String id, in RemoteViews remoteViews);
void navBarExRemoveView(in String id);
void navBarExReplaceView(in String id, in RemoteViews remoteViews);
}



Обратите внимание, что он помечен атрибутом “hide”, что делает его невидимым для клиентов. Также обратите внимание на ключевое слово oneway. Оно делает межпроцессное взаимодействие от system_process к SystemUI быстрее, так как все вызовы будут неблокирующими (это также требует пустого возвращаемого значения в методах).

6. VendorServices это стандартный SystemUI компонент (он наследуется от класса SystemUI), который реализует интерфейс INavBarExServiceUI:
код
public class VendorServices extends SystemUI
{
	private final Handler handler = new Handler();
 
	private NavBarExServiceMgr navBarExServiceMgr;
	private volatile PhoneStatusBar statusBar;
 
	private INavBarExServiceUI.Stub navBarExServiceUI = new INavBarExServiceUI.Stub()
	{
		@Override
		public void navBarExAddViewAtStart(final String id, final RemoteViews remoteViews)
		{
			if (!initStatusBar()) return;
 
			handler.post(new Runnable()
			{
				@Override
				public void run()
				{
					statusBar.navBarExAddViewAtStart(id, remoteViews);
				}
			});
		}
		//…
	}
 
	@Override
	protected void onBootCompleted()
	{
		super.onBootCompleted();
 
		navBarExServiceMgr = (NavBarExServiceMgr) mContext.getSystemService(Context.NAVBAREX_SERVICE);
		if (navBarExServiceMgr == null)
		{
			Log.e(TAG, "navBarExServiceMgr=null");
			return;
		}
 
		try
		{
			navBarExServiceMgr.setUI(navBarExServiceUI);
		}
		catch (Exception e)
		{
			Log.e(TAG, "setUI exception: " + e);
		}
	}
}



Интересен метод onBootCompleted. Он производит само-регистрацию (вызывает метод setUI) в NavBarExService через NavBarExServiceMgr. Также обратите внимание что процесс SystemUI может быть перезапущен (например из-за падения) в результате чего будут сделаны несколько вызовов setUI. Само собой только последний должен учитываться.

7. Класс PhoneStatusBar это ключевой элемент который связывает NavBarExService и NavigationBarInflaterView. Он содержит ссылку на NavigationBarView, который в свою очередь содержит ссылку на NavigationBarInflaterView. С другой стороны VendorServices получает ссылку на PhoneStatusBar через метод SystemUI.getComponent:

код
private boolean initStatusBar()
{
	if (statusBar == null)
	{
		synchronized (initLock)
		{
			if (statusBar == null)
			{
				statusBar = getComponent(PhoneStatusBar.class);
				if (statusBar == null)
				{
					Log.e(TAG, "statusBar = null");
					return false;
				}
 
				Log.d(TAG, "statusBar initialized");
			}
		}
	}
	return true;
}



Вы заметили странную конструкцию “if (statusBar == null)”? Она называется “Double Checking Locking Pattern” и преследует следующую цель: произвести потоко-безопасную инициализацию объекта, но избежать вхождение в секцию синхронизации когда объект уже проинициализирован. Изменения в PhoneStatusBar и NavigationBarView достаточно простые: они просто делегируют все вызовы в класс NavigationBarInflaterView.

8. Класс NavigationBarInflaterView — это конечный класс который производит непосредственно изменения в UI. Вот его метод navBarExAddViewAtStart:
код
public void navBarExAddViewAtStart(String id, RemoteViews remoteViews) {
    if ((mRot0 == null) || (mRot90 == null)) return;
    ViewGroup ends0 = (ViewGroup) mRot0.findViewById(R.id.ends_group);
    ViewGroup ends90 = (ViewGroup) mRot90.findViewById(R.id.ends_group);
    if ((ends0 == null) || (ends90 == null)) return;
 
    navBarExAddView(0, id, remoteViews, ends0);
    navBarExAddView(0, id, remoteViews, ends90);
}
 
private void navBarExAddView(int index, String id, RemoteViews remoteViews, ViewGroup parent) {
    View view = remoteViews.apply(mContext, parent);
    view.setTag(navBarExFormatTag(id));
 
    TransitionManager.beginDelayedTransition(parent);
    parent.addView(view, index);
}



Этот код полагается на существующую реализацию и использует поля mRot0, mRot90 а также R.id.ends_group как ViewGroup для кастомных элементов. mRot0 и mRot90 представляют разметку для портретного и ландшафтного режимов, так что добавляем наши элементы к обоим из них. Также мы задействовали TransitionManager для проигрывания некоторой анимации.

9. Один нюанс насчет файла Android.mk. Он должен содержать ссылки на наши AIDL файлы. Два файла в секции LOCAL_SRC_FILES:
код
LOCAL_SRC_FILES += \

core/java/android/os/INavBarExService.aidl \
core/java/android/os/INavBarExServiceUI.aidl \

...



и INavBarExService.aidl в секции “aidl_files”:
код
aidl_files := \

frameworks/base/core/java/android/os/INavBarExService.aidl \

...



Все вместе



Исходные коды доступны на GitHub. В каталоге “patches” есть два файла: frameworks_base.patch и system_sepolicy.patch. Первый патч должен быть применен к каталогу “{aosp}/frameworks/base”, второй — к “{aosp}/system/sepolicy”.

Каталог NavBarExDemo содержит демонстрационное приложение для системы сборки gradle.

Чтобы проверить реализацию на реальном устройстве нам нужно:
  1. Скачать стоковые исходные коды Android и настроить среду разработки;
  2. Применить патчи;
  3. Собрать кастомный Android SDK;
  4. Собрать кастомную прошивку и прошить устройство;
  5. Запустить демонстрационное приложение.


Для сборки Android SDK выполните следующие команды:
код
. build/envsetup.sh
lunch sdk_x86-eng
make sdk -j16



Результирующий ZIP файл расположен в каталоге {aosp}/out/host/linux-x86/sdk/sdk_x86 (если запущен в Linux). Имейте ввиду что имя файла будет содержать ваше имя пользователя Linux. Для того чтоб изменить это поведение, определите переменную окружения “BUILD_NUMBER” и ее значение будет использовано вместо имени пользователя. Параметр J указывает сколько задач запускать одновременно. Используйте количество процессорных ядер умноженное на 2.

Прошивка может быть создана используя следующие команды (для устройства Nexus 9):
код
. build/envsetup.sh
lunch aosp_flounder-userdebug
make otapackage -j16



Прошивка может быть прошита используя комманду:
код
fastboot -w flashall



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

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

image

Нажатие на кастомный элемент покажет тост даже если демо приложение не запущено (на самом деле система сама запустит процесс если нужно).
image

Недочеты



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

Резюме


Мы расширили Android SDK и внедрили новую службу предназначенную для кастомизации строки навигации Android. Также мы создали кастомную прошивку для планшета Nexus 9 содержащую нашу службу.

В прежней статье мы реализовали стабилизацию экрана для Nexus 7. Здесь эта-же реализация но для Nexus 9:




P.S. На самом деле я также являюсь и автором оригинальной англоязычной версии статьи, которая была опубликована на blog.lemberg.co.uk, так что могу ответить на технические вопросы.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331900/


Метки:  

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

Четверг, 29 Июня 2017 г. 11:06 + в цитатник


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

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

1. Практическое применение знаний


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

Скорее, речь о кругозоре. Раньше не знали, как решать, и гуглили бы 5 часов. Сейчас знаете, представляете чужой опыт, можете принять решение почти сразу. Вот разработчик из Яндекса делится:

«Был интересный доклад про дженерики. Там, типа, пазлеры с дженериками. Я после этого тоже, ну, не прямо по итогам доклада, но, типа, заинтересовался тоже темой этой более-менее и кое-что переписал в своем проекте».

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

Вот что про этот фактор говорит участник Сергей Б. (участие в JPoint и Joker с 2013 года):
«Сложно вспомнить, но совершенно точно Joker сильно расширяет кругозор. И даже если из тех докладов, которые прослушали, никаких практических выводов не делаем прямо в момент прослушивания, в любом случае это откладывается в голове. Когда мы встречаемся с какой-то проблемой, то вспоминаем, что да, что-то такое мы слышали. И во-вторых, мы расширяем кругозор в том смысле, что видим происходящее в индустрии и куда всё движется — это даже видно по темам докладов. У нас компания небольшая, нет специального отдела, следящего за тенденциями. Поэтому мы ездим сами. Вообще, мы занимаемся разработкой софта на заказ на Java уже 8 лет. Мы стараемся присутствовать и на JPoint, и на Joker — конечно, всю команду привезти не можем, но я как директор каждый раз езжу.
… Поскольку у нас много проектов на Enterprise Edition, то в каждом проекте встречаются, безусловно, задачи пакетной обработки. Мы раньше всегда их решали вручную. Сейчас это стало частью стандарта, но мы не обратили на это внимание, а после доклада стало понятно, что будем эту технологию использовать. Эффективность этой технологии в том, что она содержит в себе все вещи, которые обычно в ходе реализации пакетной обработки появляются потихоньку. То есть вам надо файл в 100 000 строк переместить — вы пишете одну строчку. Потом вы понимаете, что вам нужны чекпоинты, что нужно делать что-то с дефектными данными, нужна транзакционность, мониторинг. Всё это пишется вручную. Сейчас появился стандартизированный способ, есть поддержка контейнера для таких задач, и мы это будем использовать. Хотя это, конечно, немного не в стиле Joker, но этот доклад будет применен — не прямо завтра, но через несколько недель точно».

Гриша Б.:
«Как Шипилёв говорил в кейноуте, “нужно с умом подходить к этому делу”. Не просто так, мол, “а увидел крутую вещь — буду запиливать”. Всё пригодится на практике, просто не сразу».

2. Мировоззрение и обучение




Конференции не сделают вас сильнее-выше-быстрее просто потому, что вы там присутствуете. Точнее, для объективно хорошего стабильного эффекта пришлось бы посетить штук 40–50 конференций (почти как половина университетского семестра). Их столько просто нет. Учиться на конференциях бесполезно, учиться нужно самостоятельно.

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

«Был доклад парня из Дойче-банка, я не помню, как его звали. Он рассказывал про мониторинг производительности. Мы этим воспользовались… Ну, там он снимал дампы и проводил статистический анализ этих треддампов. И на основе их смотрел, что у него тормозит. Мы этим потом воспользовались, когда решали проблему производительности наших приложений. Также в 2015 году был доклад Андрея Паньгина. Тоже там он рассказывал про java agent, мы этим периодически пользуемся, особенно если у нас application… Ну, проблема не в нашем коде, а в application server'е. Чего-нибудь залезть там, подхачить. В прошлом году мы, например, заказали онлайн-трансляцию. И сделали у нас на corporate, и сделали типа JPoint’а, но у нас, локальный, в офисе. Это для джуниоров хорошо, такой был этот. В этом году решили сами приехать, ещё раз посмотреть. Не стали заказывать. И уже пожалели, что ребят не подтянули».

Можно не наступать на чужие грабли (отзыв разработчика UnitedTraders):
«Начали внимательно следить за версиями драйвера Postgres’а, потому что товарищ рассказывал, как он там достаточно стрёмные вещи чинил в этом самом драйвере, локи довольно жёсткие. И посмотрели на Кассандру, ну, чуть более пристально, она не пошла. Но посмотрели».

Ещё от спикеров можно услышать, чему и как учиться. Самое главное — видно, кто и как решает разные сложные задачи. Путь Senior-developer — это много импровизации, море практики и умение видеть модели за практическими задачами. Часто одна только возможность «поднять голову» над рутиной помогает научиться мыслить чуть иначе.

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

Вот рассказ команды с хорошим опытом:
«Мы уже давно ходим на конференции. У части докладов всегда был прикладной интерес. Сейчас я успел побывать на трёх (докладах), и все так или иначе для меня релевантные, даже Шипилёвский кейноут. Каждый раз открываешь для себя что-то либо изучаешь более подробно. Не знаю, что конкретно выделить. Каждый раз получаешь то, что ожидаешь получить. И нельзя рассматривать это напрямую, мол, вот я научился чему-то и сейчас пойду это запиливать. Это, скорее, толчок для дальнейшего подробного изучения и просмотра. Потому что мы уже матёрые ребята, нас сложно чем-то удивить. Конференция — это место пообщаться и некоторый способ нарушить изоляцию своего коллектива. Посмотреть, что в тренде, что народ делает. Посмотреть, насколько твоя команда актуальна сейчас. Ещё момент с точки зрения практической пользы — общение с докладчиками. В прошлый раз я с ними болтал просто так. Был спикер Venkat Subramaniam — я его книжки читаю, часто на YouTube смотрю. Было интересно с ним поговорить вживую, задать конкретные вопросы. А что касается дискуссионных зон… Вот видишь Шипилёва и думаешь, что бы у него такого спросить, и ничего в голову не приходит».

А вот так рождается желание ковырять что-то новое (Николай):
«И эти хардкорные вещи… Их обычно просто так не ищешь ради развлечения вечером. И потом, когда узнаешь о них, задумываешься: а может, так попробовать, а может, сяк? Второе — это разнообразие. Ты сидишь на работе, каждый день плюс-минус одно и то же. А конференция — это такая возможность заново окунуться в новый мир. Это сильно мотивирует. Смотришь, что народ делает, и думаешь: “А я вроде тоже не хуже! Вечером приду и тоже что-нибудь посмотрю”. И конференция действует как перезарядка. Вот, долго работаешь, всё бесит, а потом приходишь, узнаёшь кучу всего, общаешься, и уже как новый глоток воздуха».

Вот разработчик из КРОКа делится:
«Виктор Лаврентьев, брейнсторменное clean pragmatic architecture, это был очень практический доклад, который опять-таки очень помогает при создании фреймворков. Я бы отметил еще Калеолу, первый самый доклад. Просто открывает глаза на то, когда, в какие моменты жизни проекта какие оптимизации стоит применять, а когда надо опустить. Просто такой подход к ведению всего проекта».

3. Фан и драйв




С одной стороны, конференции — не развлечение и не отдых, а с другой — это он и есть. Мы это поняли, когда по просьбам участников все Joker/JPoint и DotNext с 2013 года стали проходить по будням, потому что на выходных у мидлов и сеньоров семьи (сейчас мы делаем сочетание пятница-суббота, чтобы не отжирать два рабочих дня и не забирать все выходные).

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

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

Виктор А.:
«В прошлом Джокере был Барух, который рассказывал про Мавен и Грейдл. Интересный был доклад. После него потянуло поковыряться в Грейдле, посмотреть, как с ним можно взаимодействовать. Сегодня тоже доклад про Мавен и Грейдл, который послушал, — буду разбираться дальше. Доклады про Stream API и Java 8 тоже слушаю, тоже применимы в работе. Плюс на конференции до фига знакомых».

Иван Е.:
«Потому что понравились в прошлом году — как доклады, так обстановка. Мне удалось случайно встретиться со многими людьми, которых не видел десяток лет, и это очень круто. Из полезного — в том году был доклад, который получилось принять на практике, про мутационное тестирование (спикер — Николас Франкель).
Сегодня меня интересуют две темы: микробенчмарки и проблемы микросервисов и распределённого логирования. Общаюсь с людьми, узнаю, как можно это сделать, получаю для себя полезную инфу и решения».

Евгений:
«На первом Joker было много полезного. Практическое применение — я знаю, куда рыть, чтобы интересные вещи для себя изучить более подробно. Сложно назвать что-то конкретное, потому что это по крупицам собирается из разных мест и потом применяется в работе. Ну, и плюс общение со знакомыми старыми. Так ни с кем не знакомлюсь».


4. Уровень требований и зарплат


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

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

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

Как получить максимум?


Правильный сценарий, на мой взгляд, такой:
  1. Заранее составить план захвата конференции, то есть прочитать про каждый доклад и посмотреть, насколько интересен спикер. Скорее всего, у вас есть 2–3 доклада, на которые вы пойдёте точно, и надо ещё обозначить те, которые вы будете посещать «в промежутках». Лучший способ понять, надо оно вам или нет — посмотреть 3–4 минуты видео этого докладчика с предыдущей конференции, если он был. Если не был — просто почитать его публикации.
  2. После докладов спикеры идут «на поговорить» в специальную зону, где можно обсуждать с ними животрепещущие вопросы. Тут лучше заложить время на это обсуждение (полчаса после доклада, например) и ещё собрать сами вопросы. Часть ваша, часть наверняка захотят задать ваши коллеги, которые не идут (спросите их, есть ли что-то важное, что надо уточнить).
  3. Если вы пришли на доклад, а он вас не вставляет — к чёрту вежливость, вставайте и уходите, даже если вы сидите в середине ряда. В соседних залах ещё доклады.
  4. Стоит заранее узнать, кто из ваших знакомых приедет. Особенно важно это для тех, кто на конференцию едет из другого города. Запланируйте с ними обеды-ужины-посиделки среди дня.
  5. В «резервации», то есть за пределами зоны докладов, стоят специальные будки. Чаще всего в них либо стоит эйчар и ПМ, либо разработчик инструмента. Правильные вопросы разработчикам: «Мы пользуемся вашей шнягой, есть что ещё интересное?», «А вот мы пользуемся вашим конкурентом, чем вы лучше?» и «Ты кто такой?» Можно узнать много нового и получить либо скидки на продукты (они пригодятся компании), либо ключи на триальные версии с ограничениями — это чтобы потестить в своей команде, и если пригодится — купить.
  6. С любым вопросом до конференции (вообще любым!) не стесняйтесь писать оргам. Все контакты у вас в билете, как правило. Ещё конкретно в нашем случае полезно отметиться, какие доклады вам наиболее интересны. По этому голосованию мы выбираем размер зала. Самые популярные идут в главный зал, а остальные — в залы меньше. Иногда бывает так, что в маленьком зале становится тесно: если не хотите тесниться — стоит голосовать.
  7. Кейтеринг дорогой, поэтому билеты без еды часто сильно дешевле. Да, можно взять бутерброды из дома (кофе и чай и так будут бесплатно), но если вам оплачивает компания, то надо пользоваться обедом на все сто. Для начала не используйте «писсуарную» рассадку, то есть старайтесь занимать не наиболее далёкое свободное место, а подсаживаться к кому-нибудь, кто не похож на эйчара. И дальше просто спрашивайте, кто и над чем работает, за столом. Получится хорошая дискуссия, которая рано или поздно дойдёт или до мордобоя, или обсуждения нюансов и всяких лайфхаков разработки, или рассказа о багах инструментов.


В общем, вот примерно так, шаг за шагом выстраивая хардкор (чтобы было больше нетривиальных знаний и экспертов) и убирая всё малополезное (рекламные доклады и банальные будки на выставке), мы дошли в какой-то момент до того, что задачи с Джокера и .NET стали использовать на технических собеседованиях, а в некоторых вакансиях посещение Joker/JPoint стало «плюшкой» для продвинутых инженеров. Ну и к нам возвращаются участники JUG, поэтому с каждым годом конференция всё больше и больше.

Ну и напоследок — рассказ от одного из наших постоянных гостей конференций:
«Ну, такой наиболее яркий пример — это, например, доклад Романа Елизарова «Ожидай своего счастья без блокировок». То есть после его доклада я начал экспериментировать с его информацией, которую он дал. Через полгода у меня было решение, которое внезапно пригодилось на работе. То есть очень сильно продакшн удалось разгрузить. Много чего у Алексея Шипилёва: всякие нюансы, которые помогают более тонко осознавать, что я вижу при профайлинге. На всяких метриках с продакшна. Вот сегодня я уже три полезняшки успел снять, которые я, как приеду, буду смотреть, как это применяется… Инструмент для поиска deadlock'ов превентивный. Это профайлер от Куксенко, который тоже не есть код, который обычно профайлер не берёт, и я не мог понять, чего с этим делать. Теперь я хотя бы знаю, куда я смогу копать… Я просто фотографирую, записываю по ходу дела. Ну, и плюс «Разбор Полетов» узнал оттуда же. В результате я сейчас постоянно вишу в их чате, и там опять-таки со специалистами можно обсудить, с тем же Алексеем (не далее как во вторник он мне подсказал вещь, которую мне срочно надо было, чтобы понять, что у меня на продакшне творится). И в принципе просто кругозор расширяется. То есть сначала я сам съездил, потом стал каждый раз кого-то из сотрудников притаскивать. В этот раз уже организация поняла, что польза есть, польза большая. Выделили большую квоту, и даже этой квоты не хватило, и кое-кто из наших приехал уже даже за свой счёт. То есть у нас тут сейчас целая шайка. И это, наверно, самый ценный источник информации, которую больше достать негде».

В общем, вот как-то так. Joker 2017 уже в продаже, кстати.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331898/


Метки:  

Знакомство с методологией ITIL в ITSM

Четверг, 29 Июня 2017 г. 10:10 + в цитатник
Менеджмент в IT знает несколько подходов. Главное различие между ними — приоритеты. Один метод сконцентрирован на технологиях (IT Systems Management), другой — на услугах (IT Service Management). Последний обозначается аббревиатурой ITSM и часто встречается в сопровождении другого понятия: библиотека инфраструктуры информационных технологий, или ITIL. В этой части серии статей об ITIL мы рассмотрим роль лучших практик в ITSM, а также совершим экскурс в историю зарождения ITIL и проведем краткий обзор методологии.
 
/ фото rawpixel CC
 

Что было раньше: ITSM или ITIL?


В отношении двух ключевых понятий сервисного подхода применима известная дилемма яйца и курицы — что первично? Чтобы объяснить взаимосвязь ITSM и ITIL, Стюарт Рейнс (Stuart Rance) из IT-компании BMC написал статью «ITSM vs. ITIL: What’s the Difference?». Она начинается с четкого разграничения области применений и формулировки ключевого утверждения: между ITSM и ITIL невозможно поставить союз «или». И вот почему.

Если перенести эти понятия в бытовую плоскость, ITSM можно сравнить с подходом к работе бара, все процессы которого в первую очередь сосредоточены на вкусах, предпочтениях и удобстве клиента. Тогда книга о клиентском подходе в барном деле Джона Таффера (Jon Taffer), американского консультанта и писателя, — это ITIL.

Иначе говоря, ITSM — это способ ведения IT-бизнеса, а ITIL — лучшие практики. Однако — и это важно — ITIL является не признанным стандартом, но основой, которая содержит передовые практики, а не пошаговую инструкцию обязательную к выполнению. По словам Стивена Вейла (Steven Weil), старшего консультанта по безопасности в консалтинговой компании Seitel Leeds & Associates, «ITIL не содержит конкретных, подробных описаний того, как процессы должны быть реализованы, так как они будут отличаться в каждой организации. Другими словами, ITIL сообщает предприятию, что делать, но не как это делать».

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

Суть ITSM


Роль ITSM — служить мостом между разработкой и пользователем, который может быть как нетехническим сотрудником организации, так и клиентом.
 
Л.Ф. Попова в своей работе «Влияние информационных технологий на формирование устойчивого развития предприятия» указывает на «сокращение объема персонала, связанного со сбором и обработкой информации, повышение качества и скорости коммуникации» под влиянием информационных технологий на организационную деятельность. Однако иногда автоматизация приводит к возникновению дисбаланса в отношениях между отделами и другими департаментами (или клиентами).

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

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

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

ITIL как основа ITSM


Как уже было отмечено выше, ITIL содержит руководящие принципы по реализации ITSM. Библиотека инфраструктуры IT имеет довольно интересное происхождение: её история тесно связана с британской короной. ITIL был разработан в конце 1980-х Центральным компьютерным и телекоммуникационным агентством (CCTA) Великобритании. Причиной заказа полноценного комплекса лучших практик IT стало низкое качество IT-услуг, оказываемых британскому правительству.

Таким образом, ITIL был призван улучшить сервис и одновременно с этим снизить затраты на обслуживание. Сейчас ITIL является торговой маркой AXELOS, совместного предприятия правительственной канцелярии Великобритании и лондонской компании Capita.
 
/ фото Witizia CC

Как рассказывает пользователям Quora Аманда Фэйрбразер (Amanda Fairbrother), эксперт по ITIL, власти заказали исследование, чтобы определить используемые передовые методы в 2,5 тыс. различных организаций — крупных и малых, государственных и частных, занятых во всех отраслях промышленности. Итогом работы стал свод руководящих принципов Government Information Technology Infrastructure Management, который и лег в основу первой версии ITIL. Она была опубликована в 1989 году и имела сорок томов. Годом позже библиотека начала распространяться по миру за пределы Великобритании.

В 2001 году мир увидел ITIL v2, где фокус сместился на процессную составляющую (с технических аспектов), а количество томов сократилось до семи. Этому предшествовало использование основ ITIL компанией Microsoft в 2000 году для создания собственной методологической модели Microsoft Operational Framework (MOF).

В 2007 году была выпущена ITIL v3. Количество томов опять сократилось (до пяти), а акцент был сделан на жизненном цикле IT-услуги: стратегия, проектирование, преобразование, эксплуатация, непрерывное улучшение услуг. Основной посыл ITIL v3 в актуальной редакции заключался в ложности подхода «процесс ради процесса».

Коммерческий потенциал ITIL получил массовую оценку в начале 90-х вместе с тем, как ряд частных организаций и британский Колледж Государственной Службы получили статус обучающих платформ методологии ITIL. Тогда же аттестационная комиссия ISEB, входящая в состав Британского компьютерного общества (BCS), приобщилась к первым тестам на сертификат ITIL.

Постепенно организации из всех отраслей промышленности как частных, так и государственных, начали осознавать преимущества ITIL. Этому поспособствовал запуск Великобританией и Нидерландами в первой половине 1990-х ассоциации IT Service Management Forum с целью распространения методологии в Европе. По состоянию на 2016 год она насчитывает 6 тыс. участников по всему миру.

На этом этапе ряд компаний, таких как HP, IBM, Procter & Gamble и DHL, начали вкладывать значительные средства в ITIL. Что касается США, то туда ITIL «добрался» сравнительно поздно. Однако в своем исследовании доктор экономических наук Маурицио Марроне (Mauricio Marrone) утверждает, что по состоянию на 2009 год 45% респондентов из 364 американских компаний использовали ITIL, а 15% планировали это делать.

ITIL сегодня


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

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

Проектирование услуг является этапом жизненного цикла нового или модифицированного сервиса, который разработан и подготовлен к фазе преобразования. Основной задачей здесь выступает разработка окончательного решения для удовлетворения потребностей бизнеса. Как говорит Элисон Картлидж (Alison Cartlidge) из IT Service Management Forum, проектирование услуг должно быть целостным процессом и учитывать четыре фактора: людей (навыки и компетенции, участвующие в предоставлении услуг), продукты (технологии и управление), процессы (роли и виды деятельности), партнеров (производители, разработчики). На выходе этот этап предполагает формирование пакета документов, именуемого Service Design Package (SDP), содержащего подробную проектную спецификацию. SDP будет руководящим документом при выборе решения на стадии преобразования.

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

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

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

Таким образом, ITIL приводит к налаживанию связей между IT и клиентскими потребностями, что выражается в улучшении предоставляемых услуг и повышении удовлетворенности клиентов. Это ведет к снижению затрат за счет увеличения эффективности использования ресурсов. Например, согласно исследованию Gartner, ряд японский компаний, использовавших процесс ITIL, сумели снизить влияние человеческого фактора в управлении релизами на 20% в год и сократить расходы на производство на 30% за три года. Кроме того, методы ITIL позволяют сформировать прозрачность при работе с IT-активами и более стабильные условия для поддержки постоянных изменений бизнеса.

Дополнительные материалы по теме:


 
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331376/


Метки:  

Умный замок на Android Things и Raspberry Pi3

Четверг, 29 Июня 2017 г. 10:02 + в цитатник

В декабре 2016 года Google анонсировал выход первой Developer Preview версии Android Things. С тех пор проект сильно изменился. Все еще доступна только preview-версия, но с каждым шагом у платформы появляются новые возможности и растет число поддерживаемых устройств.


С каждым днем появляются новые примеры использования IoT устройств в реальном мире, а сама платформа становится все более привлекательной. Мы в Live Typing решили тоже погрузиться в интереснейший мир Интернет Вещей и рассказать о своем опыте. Эта статья для тех, кто слышал об Android Things, но боялся попробовать. А также о том, как мы реализовали свой «умный замок» и пользуемся им в собственном офисе.


Описание идеи


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


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


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


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


Дальше идея обрастала сопутствующими нюансами и вопросами. Когда начинать и заканчивать фотографировать? Как часто и долго делать фотографии? Стоит отключать систему в нерабочие часы и темное время суток? Как визуализировать работу системы? Но обо всем этом далее и по отдельности. За основу проекта мы взяли пример Doorbell с официальной страницы Android Things. Оригинальный пример называется «звонок», однако мы хотели, чтобы пользователь системы отпирал дверь с минимальными усилиями, а посторонние люди внутрь не попали. Поэтому мы посчитали более правильным назвать его «умный замок».


Благодарности


Сначала у нас не было ничего. Ни самого Raspberry, ни комплектующих, ни опыта работы с ними — только теоретические знания, полученные из статей и документации. Первый раз попробовать поиграться c Android Things удалось на CodeLab проводимом в нашей IT-столице Сибири, городе Омск, ребятами из Mobilatorium. Мы быстро завели проект, где вместо Google Cloud Vision имплементировали свою реализацию FindFace на Tensor Flow. Если вам интересно, как устроен back-end, то можете ознакомиться с отличной статьей «Ищем знакомые лица», где автор очень подробно описал принципы и алгоритмы работы с распознаванием лиц. Если нет, то можете воспользоваться связкой Google Cloud Vision + Firebase Realtime Database, как это сделано в приведённом выше CodeLab.


Когда мы вернулись в офис, оказалось что у нашего сотрудника Миши есть все необходимые компоненты и даже сам Raspberry Pi3, которые он недавно приобрёл, желая побаловаться чем-то эдаким. Также остались компоненты от ребят, проводивших [летнюю школу] (https://vk.com/mobilatorium?w=wall-130802553_81%2Fall) с изучением Arduino. Огромное им спасибо за предоставленные железяки.


Комплектующие


Для реализации умного замка нам понадобились:


  • Raspberry Pi 3 — 1шт;
  • MicroSD 8Gb — 1шт;
  • NoIR Camera V2 — 1шт;
  • Breadboard — 1шт;
  • Infrared PIR Motion Sensor Module — 1шт;
  • SG90 Servo Motor — 1шт;
  • Photoresistor (Light Sensor) — 1шт;
  • Push Button — 1шт;
  • LED — 3 шт;
  • Resistors (1k) — 3шт;
  • Resistors (10k) — 1 шт;
  • Pin Jumper Wires — много штук;
  • Изолента — 1шт.

Все комплектующие легко найти и недорого заказать на китайских сайтах, и мы специально оставили их названия на английском для удобства поиска. Стоит лишь упомянуть, что комплект обойдётся вам примерно в 100-125$. Самыми дорогими компонентами являются камера и сам Raspberry Pi3.


Реализация


Для лучшего понимания мы разобьём описание реализации на отдельные шаги. Соединяя схему по частям, удобней восстановить картину на любом шаге. Кода мало, и если вы написали хотя бы одно приложение под Android, то проблем у вас не возникнет, на мой взгляд. Для разработки будем использовать привычную Android Studio. Вы даже сможете использовать свои любимые библиотеки и фреймворки, такие как Dagger, RxJava, Retrofit, OkHttp, Timber и т.п.


Перед началом работ стоит ознакомиться с кратким введением в Android Things, а также с пинами на Raspberry Pi3. А эта цветная картинка с распиновкой является отличным наглядным гайдом и пригодится вам ещё не один раз.


Raspberry Pi поддерживает разный набор интерфейсов оборудования. Но нас главным образом интересуют GPIO (General-purpose input/output) и PWM (Pulse Width Modulation). Они будут основными способами взаимодействия между платой и датчиками при реализации нашего проекта.


Библиотеки для различных периферийных устройств уже написаны до нас, а многие из них доступны даже сразу из коробки. Поэтому, когда начнёте интегрировать новый датчик, сначала ознакомтесь с этим и этим репозиториями. Здесь собрано множество драйверов. Скорее всего, вы найдете нужный. Если нет, то Google предоставили специальный концепт User Drivers, который расширяет возможности Android Framework Services. Он перенаправляет происходящие в железе во фреймворк и позволяет обработать их стандартными средствами Android API и таким образом создать свой драйвер. Коротко работу с любым драйвером можно разбить на следующие этапы:


  • создать объект драйвера;
  • зарегистрировать драйвер;
  • подписаться на события;
  • отписаться и отменить регистрацию;
    Можете ознакомиться с примером реализации собственного драйвера в этой статье.

Шаг 1: Установка Android Things


Устанавливаем самый свежий образ Android Things на Raspberry Pi3. Там же приведены ссылки на инструкции по установке образа для различных операционных систем.


Убедиться, что всё успешно установлено, можно, подключив к Raspberry какой-нибудь дисплей через HDMI-кабель. Если все окей, то вы увидите на экране анимацию загрузки Android Things.


img


Для более комфортного взаимодействия с устройством в документации советуют настроить подключение по WiFi. После этого внизу экрана под заставкой Android Things появится IP-адрес девайса в вашей WiFi сети.


img


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


$ adb connect Android.local

Шаг 2: Создание приложения


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


Минимальные требования:


  • Android Studio 2.2 и выше;
  • SDK Tools 25.0.3 и выше;
  • Min SDK 24 и выше;
  • Target SDK 24 и выше.

Добавим в app/build.gradle зависимость Android Things support library, которая даст нам доступ к нужному API, не являющемся частью стандартного Android SDK.


dependencies {
    ...
    provided 'com.google.android.things:androidthings:0.4-devpreview'
    ...
}

Каждое приложение связывается с используемой по умолчанию библиотекой Android, в которой имеются базовые пакеты для построения приложений (со стандартными классами, например Activity, Service, Intent, View, Button, Application, ContentProvider и так далее).
Однако некоторые пакеты находятся в собственных библиотеках. Если ваше приложение использует код из одного из таких пакетов, оно должно в явном виде потребовать, чтобы его связали с этим пакетом. Это делается через отдельный элемент .



    ...
    
    ...

Android Things позволяет одновременно устанавливать только одно приложение, а больше нам и не надо. Благодаря этому ограничению появляется возможность декларировать для Activity, как IOT_LAUCHER в AndroidManifest приложения, что позволяет запускать это Activity по-умолчанию сразу же при старте девайса. Также оставим стандартный чтобы Android Studio смогла запустить наше приложение после сборки и деплоя.



    ...
    
    
        
        
    

    
    
        
        
        
    
    ...

Шаг 3: Кнопка


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


raspberry_step#1


Кнопка подключается через макетную плату с использованием резистора на 1 кОм. Чтобы не запутаться в резисторах обратите, внимание на их цветовую кодировку. Не будем подробно расписывать процесс подключения. Просто сопоставьте представленную схему с распиновкой Raspberry, данной чуть выше.


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


dependencies {
    ...
    compile 'com.google.android.things.contrib:driver-button:0.3'
    ...
}

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


ButtonWrapper.java
import com.google.android.things.contrib.driver.button.Button;

public class ButtonWrapper {

   private @Nullable Button mButton;

   private @Nullable OnButtonClickListener mOnButtonClickListener;

   public ButtonWrapper(final String gpioPin) {
       try {
           mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH); 
           mButton.setOnButtonEventListener(new Button.OnButtonEventListener() {
               @Override
               public void onButtonEvent(Button button, boolean pressed) {
                   if (pressed && mOnButtonClickListener != null) {
                      mOnButtonClickListener.onClick();
                   }
               }
           });

       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) {
       mOnButtonClickListener = listener;
   }

   public void onDestroy() {
       if (mButton == null) {
           return;
       }
       try {
           mButton.close();
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           mButton = null;
       }
   }

   public interface OnButtonClickListener {
       public void onClick();
   }
}

Воспользуемся этой обёрткой в нашем Activity. Просто передадим в конструктор объекта кнопки название GPIO порта ("BCM4") на Raspberry Pi3, к которому она подключена на схеме.


MainActivity.java
public class MainActivity extends Activity {

    private static final String GPIO_PIN_BUTTON = "BCM4";

    private ButtonWrapper mButtonWrapper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mButtonWrapper = new ButtonWrapper(GPIO_PIN_BUTTON);
        mButtonWrapper.setOnButtonClickListener(new ButtonWrapper.OnButtonClickListener() {
            @Override
            public void onClick() {
                Timber.d("BUTTON WAS CLICKED");
                startTakingImage();
            }
        });
        ...
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ...
        mButtonWrapper.onDestroy();
        ...
    }

    private void startTakingImage() {
        // TODO take photo
        ...
    }
}

Шаг 4: Камера


Мы использовали камеру NoIR Camera V2. Примерно за 45$ вы получите характеристики, достаточные для нашего проекта:


  • максимальное разрешение: 8 Мп (3280x2464);
  • поддерживаемые видеоформаты: 1080p (30fps), 720p (60fps), 640x480p (90fps);
  • энергопотребление: 250 мА

Камера подключается к управляющей плате шлейфом через видеовход CSI (Camera Serial Interface). Такой способ снижает нагрузку на центральный процессор по сравнению с подключением аналогичных камер по USB.


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


    

    
    

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


Шаг 5: Светодиод


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


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


  • жёлтый (BCM20) — индикатор начала работы, которая продолжается указанный разработчиком интервал времени;
  • зелёный (BCM21) — программа успешно распознала лицо из базы данных;
  • красный (BCM16) — программа не распознала лицо в течении указанного интервала времени

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


raspberry_step#2


При реализации обёртки для работы со светодиодом воспользуемся PeripheralManagerService, сервисом, который дает доступ к GPIO интерфейсу. Открываем соединение и конфигурируем его для передачи сигнала. К сожалению, если заглянуть в реализацию абстрактного класса com.google.android.things.pio.Gpio, то можно увидеть, что вызов почти каждого метода способен генерировать java.io.IOException. Для простоты скроем все try-catch выражения в нашей обертке.


LedWrapper.java
public class LedWrapper {

    private @Nullable Gpio mGpio;

    public LedWrapper(String gpioPin) {
        try {
            PeripheralManagerService service = new PeripheralManagerService();
            mGpio = service.openGpio(gpioPin);
            mGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void turnOn() {
        if (mGpio == null) {
            return;
        }
        try {
            mGpio.setValue(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void turnOff() {
        if (mGpio == null) {
            return;
        }
        try {
            mGpio.setValue(false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void onDestroy() {
        try {
            mGpio.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            mGpio = null;
        }
    }
}

Имплементируем его в наше Activity для каждого светодиода по отдельности.


MainActivity.java
public class MainActivity extends Activity {

    private final static String GPIO_PIN_LED_GREEN = “BCM21”;
    private LedWrapper mLedWrapper;

    @Override   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mLedWrapper = new LedWrapper(GPIO_PIN_LED_GREEN);      
        mLedWrapper.turnOff();
        ...
    }

    private void turnOn() {
        mLedWrapper.turnOn();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ...
        mLedWrapper.onDestroy();
        ...
    }
}

Шаг 6: Датчик движения


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


Подключаем датчик движения через BCM6 пин по схеме, приведенной ниже.


img_motion


MotionWrapper.java
public class MotionWrapper {

    private @Nullable Gpio mGpio;
    private @Nullable MotionEventListener mMotionEventListener;

    public MotionWrapper(String gpioPin) {
        try {
            mGpio = new PeripheralManagerService().openGpio(gpioPin);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setMotionEventListener(@Nullable final MotionEventListener listener) {
        mMotionEventListener = listener;
    }

    public void startup() {
        try {
            mGpio.setDirection(Gpio.DIRECTION_IN);
            mGpio.setActiveType(Gpio.ACTIVE_HIGH);
            mGpio.setEdgeTriggerType(Gpio.EDGE_RISING);
            mGpio.registerGpioCallback(mCallback);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void shutdown() {
        if (mGpio == null) {
            return;
        }
        try {
            mGpio.unregisterGpioCallback(mCallback);
            mGpio.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void onDestroy() {
        try {
            mGpio.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            mGpio = null;
        }
    }

    private final GpioCallback mCallback = new GpioCallback() {
        @Override
        public boolean onGpioEdge(Gpio gpio) {
            if (mMotionEventListener != null) {
                mMotionEventListener.onMovement();
            }
            return true;
        }
    };

    public interface MotionEventListener {
        void onMovement();
    }
}

MainActivity.java

public class MainActivity extends Activity {


private static final String GPIO_PIN_MOTION_SENSOR = "BCM6";

private MotionWrapper mMotionWrapper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mMotionWrapper = new MotionWrapper(GPIO_PIN_MOTION_SENSOR);
    mMotionWrapper.setMotionEventListener(new MotionWrapper.MotionEventListener() {
        @Override
        public void onMovement() {
            startTakingPhotos();
        }
    });
    mMotionWrapper.startup();
    ...

}


@Override
protected void onDestroy() {
    super.onDestroy();
    ...
    mMotionWrapper.shutdown();
    mMotionWrapper.onDestroy();
    ...
 }

private void startTakingPhotos() {
    ...
}

}


Шаг 7: Сервопривод


Сервопривод совершает основную механическую работу в нашем девайсе. Именно он поворотом выходного вала на 180 градусов подносит карточку к считывающему устройству. Подробней про сервоприводы.


Мы снова используем уже существующий драйвер, над которым напишем свою обёртку. Добавляем в app/build.gradle зависимость.


dependencies {
    ...
    compile 'com.google.android.things.contrib:driver-pwmservo:0.2'
    ...
}

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


img_servo


ServoWrapper.java
public class ServoWrapper {

    private static final float ANGLE_CLOSE = 0f;
    private static final float ANGLE_OPEN = 180f;

    private Servo mServo;
    private Handler mHandler = new Handler();

    public ServoWrapper(final String gpioPin) {
        try {
            mServo = new Servo(gpioPin);
            mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN);
            mServo.setEnabled(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void open(final long delayMillis) {
        try {
            mServo.setAngle(ANGLE_OPEN);
        } catch (IOException e) {
            e.printStackTrace();
        }

        mHandler.removeCallbacks(mMoveServoRunnable);
        if (delayMillis > 0) {
            mHandler.postDelayed(mMoveServoRunnable, delayMillis);
        }
    }

    public void close() {
        if (mServo == null) {
            return;
        }

        try {
            mServo.setAngle(ANGLE_CLOSE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void onDestroy() {
        mHandler.removeCallbacks(mMoveServoRunnable);
        mMoveServoRunnable = null;

        if (mServo != null) {
            try {
                mServo.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mServo = null;
            }
        }
    }

    private Runnable mMoveServoRunnable = new Runnable() {
        @Override
        public void run() {
            mHandler.removeCallbacks(this);
            close();
        }
    };
}

MainActivity.java

public class MainActivity extends Activity {


private static final String GPIO_PIN_SERVO = "PWM1";

private ServoWrapper mServoWrapper;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mServoWrapper = new ServoWrapper(GPIO_PIN_SERVO);
    ...

}


private void openDoor() {
    ...
    mServoWrapper.open(DELAY_SERVO_MS);
    ...
}

@Override
protected void onDestroy() {
    super.onDestroy();
    ...
    mServoWrapper.onDestroy();
    ...
 }

}


Шаг 8: Фоторезистор


В тёмное время суток работа замка бессмысленна, потому что по полученным фотографиям сложнее распознать лица. Значит, систему можно временно отключать. Для этого в качестве датчика света используем фоторезистор — Light Dependent Resistors (LDR). Подробней о фоторезисторе.


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


dependencies {
    ...
    compile 'com.google.android.things.contrib:driver-button:0.3'
    ...
}

Схема подключения к макетной плате аналогична схеме подключения кнопки. Отличие лишь в использовании резистор в 10 кОм. Используем порт BCM25.


doorbell_full_scheme_version


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


BrightrWrapper.java
public class BrightrWrapper {

    private @Nullable Button mLightDetector;

    private @Nullable OnLightStateChangeListener mOnLightStateChangeListener;

    public BrightrWrapper(final String gpioPin) {
        try {
            mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH);
            mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() {
                @Override
                public void onButtonEvent(Button button, boolean isLighted) {
                    if (mOnLightStateChangeListener != null) {
                        mOnLightStateChangeListener.onLightStateChange(isLighted);
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) {
        mOnLightStateChangeListener = listener;
    }

    public void onDestroy() {
        if (mLightDetector == null) {
            return;
        }
        try {
            mLightDetector.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public interface OnLightStateChangeListener {
        public void onLightStateChange(boolean isLighted);
    }
}

MainActivity.java
public class MainActivity extends Activity {

    private static final String GPIO_PIN_LIGHT_DETECTOR = "BCM25";

    private BrightrWrapper mBrightrWrapper;

    private boolean mIsTakePhotoAllowed = true;

    @Override   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mBrightrWrapper = new BrightrWrapper(GPIO_PIN_LIGHT_DETECTOR);
        mBrightrWrapper.setOnLightStateListener(new BrightrWrapper.OnLightStateChangeListener() {
            @Override
            public void onLightStateChange(final boolean isLighted) {
                mIsTakePhotoAllowed = isLighted;
                handleLightState();
            }
        });
        ...
    }

    private void handleLightState() {
        if (mIsTakePhotoAllowed) {
            ...
        } else {
            ...
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ...
        mBrightrWrapper.onDestroy();
        ...
    }
}

Демонстрация реализации


Пересмотрев все выпуски телепередачи «Очумелые ручки», мы искусно упаковали нашего «монстра» в коробочку из-под старого телефона. В разобранном виде это выглядит так


img


Видео-демонстрация





Проблемы


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


Итоги


Пример кода на Github.


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


Какие варианты монетизации разработок под IoT знаете вы? Делитесь своим опытом в комментариях.


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


Полезные ссылки


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331888/


Метки:  

Четыре вопроса для выбора облачного решения аутентификации

Четверг, 29 Июня 2017 г. 10:00 + в цитатник
Нередко при выборе сервиса облачной аутентификации организации руководствуются стремлением минимизировать инвестиции в технические ресурсы и желанием снизить общую стоимость владения. Однако, для того чтобы воспользоваться в полной мере преимуществами перехода к SaaS, позволяющему компаниям избавиться от лишней нагрузки, связанной с интеграцией и обеспечением технической поддержки, следует учитывать, что сервисы облачной аутентификации могут очень сильно различаться между в отношении возможностей контроля. Сегодня на рынке средств аутентификации существуют продукты, которые способны полностью удовлетворить любые ваши потребности в части аутентификации – это могут быть как решения, целиком построенные на облачных технологиях, так и решения, предполагающие более гибридную модель. Однако перед тем как сделать выбор, следует более внимательно остановиться на тех основных элементах, от которых зависит успешное развертывание надежной аутентификации.



1. Какие приложения защищать?


Первое, на что необходимо обратить внимание при выборе облачной модели для внедрения решения строгой аутентификации, – это какие именно приложения вы хотите защитить. Здесь следует учитывать, где именно размещаются данные, и доступ к каким типам сервисов вы хотели бы защитить. Являются ли эти сервисы облачными, или они развернуты на вашем собственном оборудовании? Следующий важный фактор – это понять, какие дополнительные усилия предстоит предпринять вашей ИТ-команде с точки зрения интеграции и настройки. В этом отношении следует изучить, предполагает ли выбранный вами сервис аутентификации поддержку стандартных коммуникационных протоколов, таких как RADIUS или SAML? Предусматривает ли этот сервис использование выделенных агентов и специальных API? Вам предстоит убедиться, что вы действительно сможете защитить всю свою ИТ-экосистему, ведь сегодня она включает в себя облачные сервисы, локально развернутые приложения, VPN-сети, локальные сети, виртуальные рабочие столы, и т.д. Возможно, вы захотите выяснить, какие усилия потребуются от вашей ИТ-команды для интеграции будущих приложений с предполагаемым решением для аутентификации. Поэтому для начала было бы неплохо составить список приложений, доступ к которым вы хотели бы защитить на сегодняшний день, и при этом задаться вопросом, какие приложения могут потребоваться вашей организации в будущем.

2. Размещать ли дополнительное оборудование в локальной инфраструктуре?


Как было сказано выше, возможно, вы захотите воспользоваться облачным решением, однако полезно знать, что многие решения, доступные сегодня на рынке, будут требовать от вас размещения в своей инфраструктуре некоторых локальных компонентов, без которых сервис работать не будет. Active Directory Connector’ы, локальные серверы и прокси SAML или RADIUS, IDP-системы – вот лишь немногие примеры тех элементов, которые поставщики решений могут предложить своим клиентам установить и управлять в своей локальной инфраструктуре. Важно понимать, какие именно элементы и системы вам предстоит установить и управлять, а также – что именно от вас для этого потребуется. От того, насколько много компонентов предстоит размещать локально, зависит то время и те усилия, которые потребуются от вашей ИТ-команды для реализации всего решения.

3. Какие преимущества получат пользователи?


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

4. Как подготовиться к росту?


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

Итак, при выборе решения для аутентификации, которое бы удовлетворяло вашим текущим и (возможно) будущим потребностям, важно задать себе следующие вопросы:
  • Какие приложения вы хотите защитить?
  • Где именно они размещаются – в облаке, или в вашей локальной инфраструктуре?
  • Сколько собственных ресурсов вы готовы выделить на текущие административные задачи? Готовы ли вы инвестировать в компоненты, устанавливаемые локально, а также поддерживать их работу?
  • Каким образом можно минимизировать факторы, препятствующие успешному внедрению подобных решений, и как сделать процесс аутентификации простым и удобным для конечных пользователей?

Каковы ваши будущие потребности, и сможет ли внедряемое решение их удовлетворить?
Ответьте на эти вопросы, и переходите к выбору решения аутентификации – от размещенного в локальной инфраструктуре компании или организации до облачного решения с удаленным управлением доступом.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331824/


Метки:  

Как магазин в торговом центре узнаёт вас по Wi-Fi (точнее, по MAC-адресу) — на базе обычных хотспотов

Четверг, 29 Июня 2017 г. 09:55 + в цитатник
Телефоны ищут свои «родные» сети, поэтому время от времени отправляют в окружающее пространство пакеты с их запросами. Обычная Wi-Fi-инфраструктура (хотспот, раздающий сеть для персонала магазина) может слушать эти пакеты — не отвергать их, а записывать в лог MAC-адрес и дальность до терминала (по уровню сигнала).



В случае одной точки это используется как счётчик посетителей на уровне «за вчера 182 человека зашло в магазин, из них 34 уже у нас были», а если точек три или больше — можно уже трассировать потоки людей и видеть наиболее интересные им товары:



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


Точки доступа обычно ставятся на потолок в торговом центре, вот пример монтажа:



Сами точки, например, вот:



Архитектура решения такая:


Обратите внимание: точки Cisco и так могут отдавать свою телеметрию в Cisco. Чтобы получить к ней доступ на сервере аналитики, нужно развернуть виртуальный контроллер и зарегистрировать в нём точки. Никаких физических касаний — просто туда заносятся серийники текущей инфраструктуры и вводится пароль доступа.

Есть два режима работы: «присутствие» и «месторасположение». Присутствие — это если телефон находится в зоне действия точки и имеет некий уровень сигнала. По сути, просто счётчик пользователей, который также умеет:
— Записывать MAC-адреса для аналитики дальше: как часто клиент возвращается, сколько раз был в других магазинах сети и т. п.
— И фиксировать длительность нахождения в магазине.



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

Режим местоположения хитрее, но требует уже минимум трёх точек:



Есть определение места по триангуляции сигнала. Точки должны стоять определённым образом, и их расположение нужно будет указать с софтине сбора данных. Поскольку интерфейс «плоский», то есть 2D, имеются погрешности при разных высотных уровнях этих точек, и не обрабатываются многоэтажные магазины — на каждый этаж нужно по 3 своих точки.

Настройка новых точек довольно простая, когда всё сконфигурировано:



Есть и третий режим: если Wi-Fi планируется отдавать клиентам (а часто точки доступа ставят именно для этого), то при подключении к SSID магазина начинается уже более точный трекинг: дата-трафик позволяет получать куда больше данных о расположении с меньшими промежутками.

Заявленная точность в обычном режиме — 5–10 метров. В режиме дата-трафика — 3–5 метров. Есть возможность наблюдать в реалтайме. Ну и можно делать страницы приветствия — даже как в метро:



Итого, используя текущую инфраструктуру Циски без закупки новых устройств и без установки всяких iBeacon’ов, можно получить следующие фичи:
  • Счётчик посетителей.
  • Время визита покупателей в магазин.
  • Количество вернувшихся клиентов по всей сети магазинов.
  • Количество возвратов на клиента по всей сети.
  • Теплокарты по магазину (3–5 метров точности).
  • Оценивать эффективность BTL-мероприятий (когда точка даётся промоутеру и считаются те, кто пришёл с неё, или же когда точки работают на разного рода фестивалях).
  • Индивидуальные предложения на подключение к сети магазина. В частности, за лайк в «Фейсбуке» — скидку прямо в профиль клиента в магазине.

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

Пример монтажа


В мае у нас было 25-летие компании, решили выставить теплокарту помещения: у нас там выставка достижений, фуршетные столы с разными блюдами, улица с едой на огне, сцена и так далее. Помещение используется для других мероприятий, и в результате для того, чтобы развернуть решение, у нас был ОДИН день. Правильно — приехать на место, провести радиочастотное обследование, выявить, в какие зонах помещения какая мощность сигнала, что как отражает, поглощает и так далее, оценить уровень помех. В помещении музея Москвы нельзя было эти точки нигде вешать, дабы не испортить бетонные стены. Единственным вариантом по установке точек был шанс разместить их на фермах, на которых был свет LED (это такие головы, которые устанавливаются на концертах и крутятся во все стороны). И мы на стяжках к ним присобачивали точки доступа. Это, конечно, было не круто, потому что они металлические, а металл ухудшает сигнал. Плюс бетонные стены. Эти фермы для света поставили только в ночь до мероприятия. Более того, электричество дали только в 11:00. Нам пришлось выдёргивать сменного инженера, который нам протягивал и обжимал провода, т. к. помещение достаточно большое и у нас было три бухты кабеля сетевого. Cамо мероприятие начиналось в шесть, и в пять всё должно было быть готовым. В итоге картографировать местность с точками мы начали за час до дедлайна, чтобы правильно интерпретировать их местоположение, а также триангулировать местоположение терминалов. Мы быстро всё настроили, вывели изображение с ноутбука и за 10 минут до начала мероприятия с дергающимися глазами начали торжественно демонстрировать возможности Wi-Fi-аналитики. Не делайте так, если есть возможность. Нужно 2 дня, а в идеале с правильным RF-обследованием для высокой точности и монтажом — до недели.

Ссылки



P.S. Параноики, добро пожаловать в дивный новый мир! Отключайте Wi-Fi, выходя из дома.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331894/


Метки:  

Многоядерный DSP TMS320C6678. Операционные ядра: вычислительные ресурсы процессора

Четверг, 29 Июня 2017 г. 09:48 + в цитатник
Продолжаем рассматривать устройство многоядерного DSP TMS320C6678. Данная статья посвящена устройству операционных ядер процессора. Архитектура ядер описывается кратко с акцентом на сравнении платформы С66х с более ранними хорошо известными моделями С6000.

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

Процессоры TMS320C66x являются развитием платформы С6000 сигнальных процессоров фирмы Texas Instruments. Основы построения архитектуры являются одинаковыми, однако, их возможности и, частично, интерпретация их функционирования, претерпели некоторые модификации.

Ядро процессора TMS320C66xх строится по архитектуре с очень длинным командным словом (Very Long Instruction Word – VLIW – «Ви-Эл-Ай-Дабл-Ю»). Каждое ядро включает 8 работающих параллельно вычислительных блоков (2 умножителя и 6 АЛУ) и регистровый файл из 64 32-разрядных регистров. По сравнению с последними моделями процессоров линейки TMS320C6000 процессоры TMS320C66xх имеют следующие особенности.
  1. В 4 раза увеличено число выполняемых за такт операций умножения с накоплением как для фиксированной, так и для плавающей точки. Каждое ядро способно выполнить за один такт 32 умножения 16х16 бит с фиксированной точкой или 8 умножений 32х32 бита в формате с плавающей точкой.
  2. Повышена эффективность арифметики с плавающей точкой: реализована поддержка быстрой реализации основных операций с плавающей точкой; вычисления с плавающей точкой в SIMD-режиме (параллельные действия над частями слов данных); комплексное умножение в формате с плавающей точкой; другие расширения функционала.
  3. Расширены возможности векторной арифметики как в формате с фиксированной, так и с плавающей точкой. Под векторной арифметикой подразумевается следующая концепция. Операнды на входе арифметических блоков представляются 128-разрядными векторами, состоящими из 4-ёх 32-разрядных; 8-ми 16-разрядных или 16-ти 8-разрядных слов данных. Арифметические действия могут производиться одновременно над всеми операндами в составе векторов (SIMD-режим). Пример векторного перемножения с помощью команды QMPY32 показан на рисунке 1.

    Рисунок 1 — Пример векторного перемножения
  4. Появились дополнительные специальные наборы команд для комплексной и матричной арифметики. Данный функционал схож с векторным перемножением, однако, вместо режима SIMD используются более сложные схемы, позволяющие реализовывать, в частности, до двух комплексных перемножений вектора размерности (1х2) и матрицы размерностью (2х2) за один такт. Также поддерживаются дополнительные операции такие, как, например, взятие комплексно-сопряженного числа.

Таким образом, основной упор, с точки зрения вычислительных ресурсов процессора, в архитектуре С66х сделан на многоядерность и на расширение возможностей векторной арифметики. За счет этого вычислительная производительность повышается более, чем в 30 раз (если сравнивать процессор TMS320C6455 с тактовой частотой 1.2 ГГц и производительностью 9600 MMACS и процессор TMS320C6678 с частотой 1.25 ГГц и производительностью 320 GMACS). Основные вычислительные возможности процессоров TMS320C66x в сравнении с процессорами предыдущего семейства с плавающей точкой TMS320C674x сведены в таблицу 1.1. Заметим, что производительность, выражаемая в числе операций умножения с накоплением в секунду, не полностью отражает вычислительную мощь процессора. Векторная арифметика накладывает ряд ограничений на операнды. Один умножитель, реализующий 16 умножений за такт, это не то же самое, что 16 умножителей, выполняющих казалось бы те же 16 умножений за такт. Не все задачи могут хорошо поддерживаться векторной арифметикой. В таких случаях ресурсы процессора могут простаивать и выигрыш архитектуры не почувствуется.
C674x C66x
Число умножений с накоплением за такт в формате 16х16 бит с фиксированной точкой 8 32
Число умножений с накоплением за такт в формате 32х32 бит с фиксированной точкой 2 8
Число умножений с накоплением за такт в формате обычной точности с плавающей точкой 2 8
Число общих операций в формате с плавающей точкой за такт 6 16
Пропускная способность каналов чтения/записи между ядром и памятью 2x64 бита 2x64 бита
Размерность векторных операндов
(возможности SIMD-обработки)
32 бита
(2х16 бит, 4х8 бит)
128 бит
(4х32 бита, 4х16 бит, 4х8 бит)

Архитектура ядра процессора TMS320C66x представлена на рисунке 1.3. Как и у любого цифрового сигнального процессора, ядро ЦСП TMS320C66xх включает набор вычислительных блоков, регистровый файл, программный автомат, память программ и данных.

Процессоры TMS320C66x содержат двойной набор вычислительных блоков – один на стороне А (Data Path A); другой на стороне В (Data Path B). Набор вычислительных блоков классический и включает умножитель .M, АЛУ .L, сдвигатель .S и генератор адреса данных .D. В современных ЦСП функции каждого из этих блоков существенно расширены и могут частично перекрываться, однако, для упрощения понимания удобно использовать классическую терминологию. Все блоки работают параллельно, извлекая операнды из регистров регистрового файла (А/В Register File) и возвращая результат соответствующей операции в один из регистров.

Данные, прежде чем попасть в регистровый файл на обработку, хранятся в памяти данных внутренней или внешней (L1D, L2 Cache/SRAM, MSM SRAM, DDR3 SRAM). В память записываются также результаты обработки и промежуточные массивы данных. Подсистема памяти процессора TMS320C66x будет рассмотрена отдельно в соответствующем разделе.

Данные обрабатываются в соответствии с программой, загруженной на процессор. В ходе работы программа располагается в памяти программ (L1P, L2 Cache/SRAM, MSM SRAM, DDR3 SRAM). За чтение программы из памяти (Instruction Fetch), ее декодирование (Decode) и распределение по соответствующим исполнительным элементам (Dispatch) отвечает программный автомат.


Рисунок 2 — Архитектура ядра процессора C66x

Дополнительными аппаратными модулями в составе ядра процессора являются набор регистров контроля и управления (Control Registers), логика внутрисхемной эмуляции (In-Circuit Emulation), контроллер прерываний и исключений (Interrupt and Exception Controller), менеджер работы с памятью, включающий модуль защиты памяти (Program/Data Memory Controller), и ряд других компонентов.

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

В процессорах С66х применен принцип упакованных команд – наиболее часто используемые команды имеют 16-разрядную длину при базовой длине командного слова 32 разряда. Это позволяет экономить память программ. Программный автомат процессора способен извлекать из памяти, декодировать и распределять до 15 команд одновременно.
Регистровые файлы сторон А и В содержат по 32 32-разрядных регистра. Обеспечивается возможность работы с 8-, 16-, 32-, 64- и 128-разрядными данными (для формата с фиксированной точкой), а также с 40-разрядными данными. При этом регистры группируются по парам или четверкам.

Шины обмена между регистровым фалом и вычислительными блоками расширены до 64 бит. На блоки .L и .S одновременно может быть подано по два 64-разрядных операнда и получен 64-разряный результат. На умножитель подается два 128-разрядных операнда, формируемых как два по 64-разряда входных слов. Результат – 128-разрядный.

По каналам пересечения сторон А и В можно передавать только 64-разрядные слова.
Возможности по загрузке операндов из памяти в регистры не изменились – четыре 32-разрядных слова за один такт. Возможности записи в память расширены до четырех 32-разрядных слова за такт по сравнению с процессорами TMS320C67x.

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

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

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

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

Работа конвейера при обработке команд в целом не отличается от общего для платформы C6000 подхода к организации выполнения программ. Конвейер включает 4 стадии выборки команды, 2 стадии декодирования и от 1 до 10 стадий выполнения команды. Разные команды выполняются разное число тактов. Команды, исполняющиеся за одну стадию выполнения, называются однотактными. К однотактным командам относится большинство операций с фиксированной точкой. Команды работы с плавающей точкой, даже базовые операции умножения и сложения, являются 4-тактными командами. Команды обращения к памяти, команды переходов и многие другие не являются однотактными. Различие времени выполнения разных команд обуславливает наличие различных ограничений на совместное использование команд и ресурсов процессора. Все это делает процесс программирования процессора, особенно на низком уровне, достаточно непростой задачей. Однако данная концепция, как уже было сказано, лежит в основе всей платформы C6000.

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


Все статьи цикла:
  1. Обзор архитектуры процессора
  2. Операционные ядра: вычислительные ресурсы процессора
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331842/


Метки:  

[Из песочницы] PSEFABRIC — новый подход в менеджменте и автоматизации сетей

Четверг, 29 Июня 2017 г. 09:34 + в цитатник

О чём эта статья?


Это open source проект: PSEFABRIC

PSEFABRIC является сокращением от pseudo fabric и отражает тот факт, что с точки зрения администрирования это во многом выглядит как сетевая фабрика с возможностью управления всей сетью (или ее частью) как единым устройством, но с точки зрения control plane/data plane это все та же обычная сеть, с той архитектурой, которая была до внедрения PSEFABRIC, с сетевыми решениями, которые вы выбрали и которые на ваш взгляд вам нужны. То есть, в общем случае, это не сеть, построенная на высокоскоростных коммутаторах (хотя ваша сеть может и содержать их), что является отличительной особенностью сетевых фабрик, и именно поэтому это PSEUDO fabric.

PSEFABRIC является логической надстройкой над вашей сетевой архитектурой и не требует покупки нового оборудования или программного обеспечения.

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

Общее введение в проблему


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

  • Создание подсетей и возможности подключения к ним
  • Обеспечение связности между ними (по нужным портам)

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

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

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

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

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

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

PSEFABRIC и является этим решением.

Описание PSEFABRIC


По большому счету, нам нужно решить 4 задачи.

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

1-ая задача с появлением продукта ConfD решается довольно легко и гибко. Для этого используется YANG.

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

  • Структура (Structure)
  • Глобальная логика (Global Logic)
  • PSEFABRIC Management Data Flow Model (PMDFM)

Интерфейс


Логика заимствована из интерфейса juniper SRX. Она мне показалась самой удобной.

Чтобы отрыть доступ между подсетями мы должны:

  • Создать addresses
  • Объединить эти addresses в address-sets. В отличие от SRX в данной реализации интерфейса это является обязательным условием. Мы не открываем доступы между списками addresses – только между списками address-sets
  • Создать applications
  • Создать application-sets. Так же, как и в случае с addresses, мы всегда должны использовать application-sets
  • Создать policy

Здесь пример, как могут выглядеть эти команды:

  • Создать addresses (пока не обращаем внимание на структуру)

addresses dc1-vlan111 ipv4-prefix 10.101.1.0/24 structure dc DC1 zone none device dc1_sw1 interface e0/0 vlan 111 vrf VRF1
addresses dc1-vlan112 ipv4-prefix 10.101.2.0/24 structure dc DC1 zone none device dc1_sw1 interface e0/0 vlan 112 vrf VRF1
addresses dc2-vlan221 ipv4-prefix 10.202.1.0/24 structure dc DC2 zone none device dc2_sw1 interface e0/1 vlan 221 vrf TRUST

  • Создать address-sets

address-sets dc1-vlan111-set addresses dc1-vlan111
address-sets dc1-vlan112-set addresses dc1-vlan112
address-sets dc2-vlan221-set addresses dc2-vlan221

  • Создать applications

applications http-app prot 6 ports destination-port-range lower-port 80 upper-port 80
applications https-app prot 6 ports destination-port-range lower-port 443 upper-port 443
applications icmp-app prot 1

  • Создать application-sets

application-sets web-app-set applications [ http-app https-app ]
application-sets icmp-app-set applications  [ icmp-app ]

  • Создать доступ

policies test match source-address-sets [ dc1-vlan111-set dc1-vlan112-set ] destination-address-sets dc2-vlan221-set application-sets [ icmp-app-set web-app-set ]

ConfD дает нам полное ощущение того, что мы работаем с отдельным сетевым устройством. Например, у нас есть возможность делать «commit» и «rollback».

PSEFABRIC никак не завязана на функциях ConfD и нигде не использует код ConfD. Единственный элемент, который мы настраиваем, — это набор YANG скриптов для создания необходимого нам интерфейса. При выполнении «commit» PSEFABRIC считывает по NETCONF последнюю конфигурацию c ConfD и, сравнивая ее с предыдущей, создает конфигурационные файлы для сетевого оборудования.

Структура


Здесь мы начинаем говорить о том, что делает подход PSEFABRIC таким гибким. Речь пойдет о том, как учесть архитектуру специфичной сети.

Ясно, что мы должны иметь какой-то набор переменных, значения которых точно бы указывали что и на каком оборудовании мы должны конфигурировать. Эти переменные потом будут использоваться совместно с глобальной логикой на Demultiplexer Layer модели PMDFM.

Этот набор переменных задается в YANG файле. В данной реализации мы имеем следующий список:

  • data-centers
  • equipment
  • vrf
  • zone
  • interface
  • vlans

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

conf t
structure data-centers [ none DC1 DC2 DC3 ]
structure equipment [ none dc1_sw1 dc1_fw1 dc3_r1 dc3_sw1 dc2_fw1 dc2_sw1 ]
structure vrf [ none DMZ TRUST VRF1 VRF2 VRF3 ]
structure zone [ none ]
structure interface [ none e0/0 e0/1 e0/2 e0/3 ]
structure vlans none vlan-number 0
structure vlans  Vlan111 vlan-number 111
structure vlans Vlan112 vlan-number 112
structure vlans Vlan121 vlan-number 121
structure vlans Vlan122 vlan-number 122



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

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

Глобальная логика


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

В данной реализации PSEFABRIC для описания глобальной логики мы используем python dictionary.
Этой логикой мы должны описать все возможные действия. В нашем случае это

  • Создание/удаление addressses
  • Создание/удаление address-sets
  • Создание/удаление applications
  • Создание/удаление application-sets
  • Создание/удаление policies

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

PSEFABRIC Management Data Flow Model


Это ключевой элемент PSEFABRIC и он является, пожалуй, основным результатом исследования.
Мы можем выделить 7 уровней этой модели

  1. Configuration Management Engine
  2. Configuration Analyser
  3. Demultiplexer
  4. Configurator
  5. Configuration Encapsulator
  6. MOs Configuration Loader
  7. Control/Data Plans of MOs

Основные принципы PMDFM:

  • Существует 2 типа потока данных управления: конфигурационные данные и диагностические. Они идут в противоположных направлениях. Диагностический поток данных в данном примере PSEFABRIC на данный момент не реализован.
  • Конфигурационные данные всегда движутся в направлении сверху вниз (от уровня 1 к уровню 7).
  • Обмен конфигурационными данным всегда происходит или между соседними уровнями, или внутри одного уровня

Описание уровней и схему можно найти на wiki проекта.

Конфигурирование оборудования


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

Уровень 6 это уровень самих скриптов и др. инструментов (ansible, pappet, …).

Уровень 5 предназначен для приведения конфигурационных файлов (которые он получает с уровня 4) к нужному для инструмента, которым вы пользуетесь на уровне 6, формату.

В данном примере PSEFABRIC я использовал python и perl скрипты.

Рекомендуется следующая последовательность действий:

  • После выполнения «commit» анализируем созданные конфигурационные файлы для сетевого оборудования
  • Если не видим ошибок, то «заливаем» их на QA и проводим необходимые тесты
  • Если все хорошо, то «заливаем» их на «боевое» оборудование
  • Если процедура отлажена, и мы неоднократно убедились в корректности результатов для определенных действий, то для них можно исключить пп. 1,2 и по «commit» сразу «заливать» конфигурации на оборудование

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

Пример


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

Я не старался облегчить задачу, поэтому схема максимально приближена к возможному «боевому» сценарию. Мы имеем несколько датацентров, различные вендоры (Cisco, Juniper), различные виды фаерволов (ASA, SRX, ZBF), различные виды коммутаторов (L2, L3). Так же я постарался создать нетривиальную топологию с различными зонами и VRF.

Как все это работает можно посмотреть в видео, ссылки на которые можно найти на wiki проекта.

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

Что вы получите от внедрения PSEFABRIC?


  • Это ничего не стоит, кроме времени и усилий.
  • Если вы хотите внедрить NaaS, IaaS, PaaS, то внедрение PSEFABRIC существенно поможет в этом.
  • PSEFABRIC дает вам простой, единый интерфейс администрирования, как и в случае сетевых фабрик или sdn решений, но при этом сохраняет все сильные стороны традиционных сетей (например, полноценные фаерволы, балансировщики нагрузки).
  • Дает преимущества обычной автоматизации (perl/python/etc. scripting, ansible, puppet), но автоматизация при этом является только одним из составных элементов подхода.
  • Дает возможность легко внедрить DevOps подход к конфигурированию сети, встроить процедуру изменений для сети в общие процедуры.
  • Дает существенные преимущества для recovery процедур, т.к. хранит информацию о сети в универсальном виде. Это должно позволять легко менять оборудование, вендоров и даже архитектуру.
  • И это, конечно же, не полный список.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331892/


Метки:  

5 этапов разработки микросервиса

Четверг, 29 Июня 2017 г. 09:11 + в цитатник
Всем тем, кто много слышал про микросервисы, но так и не решился сделать ни одного — посвящается.
По причинам создания и описанием всех “за” и “против” написано уже сотни статей — здесь же я расскажу про практическую сторону создания и использования.
image
Итак, после долгих раздумий вы решились сделать сиё чудо, может, потому что у вас подвернулась на проекте задача, удачно подходящая под микросервисный подход или все вокруг уже написали по-несколько, а вы ещё ни одного.

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

1. Задача


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

2. Технологии


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

Так как в нашей компании «колеса крыша маркет» принято писать микросервисы на Go, и у меня есть опыт написания на Go, то принято решение писать на Go. В вашем случае это может быть что угодно — Nodejs, Java, PHP или любой другой, желательно, компилируемый язык. Так как стек технологий зависит и от архитектуры сервиса, то на этом этапе нужно подумать о ней, а также продумать логику работы. Здесь стоит собрать инфу со всех клиентов которые будут использовать наш микросервис, в частности с команды мобильной разработки, если таковая имеется.

3. Кодирование


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

Много о реализации на Go
Было принято решение заюзать github.com/labstack/echo — показался мне наиболее легковесным и живым проектом. Далее, так как нам придётся ходить за данными в эластик, то нужно выбрать либу для работы с эластиком github.com/olivere/elastic. Для логирования возмём github.com/sirupsen/logrus. В качестве мониторинга можно взять github.com/rcrowley/go-metrics или что-нибудь попроще github.com/cactus/go-statsd-client.
Подключаем все зависимости в main.go, и в этом же файле описываем обработку всех публичных методов.

Помимо основных методов сервиса описываем специальный метод stats, который по http будет возвращать сервисную информацию: версию микросервиса, количество и коды обработанных запросов, а так же дату запуска — будет использоваться в сервисных целях и в частности для healthcheck. Для того чтобы можно было запускать микросервис в разных окружениях (разработки, тестирования, продакшена) нужно создать конфиги под каждое окружение.

4. Документация


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

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

5. Доставка


Для этих целей мы воспользуемся CI менеджером и технологией Docker Swarm.
Про сборку буду рассказывать в терминах Bamboo (так как мы его у себя используем).

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

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

Далее нужно создать и настроить Deployment Project для деплоя микросервиса. В этом проекте описываем два окружения — Test и Production.
Деплой осуществляется через свой костыльный питон-деплоятор
В параметрах деплоя, в зависимости от окружения, указывается в какой кластер деплоить (у нас их на данный момент 4), количество реплик, лимиты процессора, памяти и т. д.

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

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

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

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

Мне удалось выделить 5 основных этапов для разработки микросервиса, надеюсь, это принесёт вам пользу и вдохнёт в вашу жизнь новую частичку творчества, которым занимаемся мы разработчики.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331674/


Метки:  

CoreDNS — DNS-сервер для мира cloud native и Service Discovery для Kubernetes

Четверг, 29 Июня 2017 г. 08:51 + в цитатник


Две недели назад Open Source-проект CoreDNS отметился своим очередным релизом — 008. Авторы называют свой продукт «DNS-сервером, состоящим из цепочки промежуточных компонентов (middleware), каждый из которых реализует какую-то возможность DNS». Что примечательно, они уже успели добиться включения CoreDNS в список официальных проектов организации CNCF (Cloud Native Computing Foundation), пополнив ряды Kubernetes, Prometheus, CNI, containerd, rkt и других разработок, активно применяемых в мире контейнеров, микросервисов и «родных облачных приложений» (cloud native).

Как появился CoreDNS, для чего он предназначен и как его можно использовать?

Знакомимся с CoreDNS


CoreDNS — DNS-сервер, появившийся в начале 2016 года (под свободной лицензией Apache License v2) как форк быстрого веб-сервера Caddy, написанного на языке Go. Сам HTTP-сервер в Caddy реализован пакетом httpserver, двумя важнейшими типами в котором являются Handler (функция обработки HTTP-запроса) и Middleware (промежуточный слой, прицепляющий один Handler к другому, — таким образом формируется цепочка из обработчиков). Этот подход с цепочкой из функций переняли и в CoreDNS, что позволило разработчикам описывать своё решение очень лаконично: «CoreDNS — DNS-сервер, сцепляющий middleware».

Второй основополагающей деталью в проекте CoreDNS является его преемственность от SkyDNS — service discovery, построенного поверх NoSQL-хранилища etcd и использующего DNS-запросы (специально сформированные SRV-записи) для обнаружения доступных сервисов. Фактически SkyDNS был лёгкой прослойкой между etcd, где на самом деле хранилась информация о сервисах, и DNS-сервером, через который эта информация становилась «публично» доступной. Судя по всему, активная разработка SkyDNS прекратилась около 7 месяцев назад (с добавлением поддержки etcd 3) в то время, как коммиты в кодовой базе CoreDNS можно наблюдать практически ежедневно.

В CoreDNS не стали ограничиваться etcd как единственным бэкендом для данных, отображаемых в DNS-записях. На данный момент поддерживается ещё Kubernetes (который, впрочем, как известно, тоже использует etcd… ), что позволяет авторам официально позиционировать CoreDNS в качестве замены kube-dns. (Подробнее о том, как эту замену попробовать в действии, читайте ниже.)

Примечание: Полная история взаимоотношений упомянутых DNS-решений: SkyDNS, CoreDNS, kube-dns — переплетена ещё теснее, чем могло показаться. Дело в том, что, во-первых, kube-dns использует библиотеки SkyDNS для обслуживания DNS-запросов, поступающих в поды и сервисы Kubernetes. А во-вторых, главным разработчиком CoreDNS является оригинальный автор SkyDNS — Miek Gieben — SRE из Google, которого также знают в сообществе Go благодаря его DNS-библиотеке. Всё это позволяет увидеть в CoreDNS не «конкурента» kube-dns, а скорее его эволюцию.

Возможности CoreDNS


Этот сервер позволяет принимать запросы по UDP/TCP, TLS (RFC 7858) и gRPC. А функционирует он как:
  • первичный DNS-сервер, отдающий данные о зоне из файла (DNS и DNSSEC) и позволяющий выполнять трансфер зоны;
  • вторичный DNS-сервер (поддерживаются только AXFR);
  • прокси (перенаправляет запросы другим серверам).

Среди других значимых возможностей CoreDNS:
  • кэширование результатов запросов;
  • rewrite для запросов (qtype, qclass, qname);
  • балансировка запросов;
  • проверка состояния (health checking) конечных узлов;
  • метрики в Prometheus;
  • журналирование запросов и ошибок;
  • профилирование.

Все перечисленные функции (включая даже режимы первичного и вторичного сервера) реализуются различными модулями, а точнее (в терминологии Caddy/CoreDNS) — middleware. Очевидно, что возможности легко расширять созданием новых middleware.


Архитектура CoreDNS, где за каждую функцию отвечает свой middleware

John Belamaric, архитектор в Infoblox и один из ведущих разработчиков CoreDNS, считает именно эту особенность главной в проекте:
Существует множество различных DNS-серверов, существуют даже другие решения для обнаружения сервисов, основанные на DNS. Но одним из главных достоинств CoreDNS является то, насколько это решение расширяемое и гибкое. Это позволяет легко адаптировать его под динамичный, часто изменяющийся мир cloud-native.

Почему CoreDNS взяли под опеку в CNCF?


Вот как объясняется это событие на сайте проекта:
Наша цель — сделать CoreDNS DNS-сервером и решением service discovery для cloud-native. CNCF как организация сосредоточена на совершенствовании архитектур для cloud-native. Таким образом, для нас это прекрасное совпадение [преследуемых целей]. Обнаружение сервисов — ключевой компонент в родном облачном пространстве CNCF, и CoreDNS первенствует в этой роли.

В заявлении от имени самой CNCF выступил Chris Aniszczyk (COO в CNCF), отметивший, что «CoreDNS предоставляет важные сервисы для именования и эффективно интегрируется со многими другими проектами проектами категории cloud-native в CNCF», а также «CoreDNS — привлекательный вариант для обнаружения сервисов в Kubernetes».

Примечание: На данный момент CoreDNS имеет начальный статус (inception) среди проектов CNCF, что означает необходимость пересмотра техническим комитетом этого статуса через год и принятия решения о его дальнейшей судьбе: убрать, продлить, повысить до incubating или graduated.

Перейдём от теории к практике.

CoreDNS как Service Discovery для Kubernetes


Как уже писалось в примечании выше, разработчики CoreDNS не просто предлагают альтернативу для kube-dns — они взаимодействуют с сообществом Kubernetes, чтобы результат их работы был полезным для всех. Хороший тому пример — их инициатива по созданию спецификации, описывающей Service Discovery на базе DNS для Kubernetes. Она появилась с тем, чтобы «гарантировать совместимость существующей реализации в Kube-DNS и новой в CoreDNS». Версия 1.0.0 этой спецификации в основном копирует поведение kube-dns — ей соответствуют релизы CoreDNS 005 и выше (предлагая, помимо этого, дополнительные возможности, если сравнивать с kube-dns).

Чтобы начать использовать CoreDNS в качестве Service Discovery в Kubernetes, разработчики подготовили конфигурацию (ConfigMap и Deployment) и даже Bash-скрипт deploy.sh для быстрого деплоя. Они позаботились и о примере, как этим пользоваться (все дальнейшие листинги взяты из него):
$ ./deploy.sh 10.3.0.0/24 cluster.local

  • 10.3.0.0/24 — CIDRs сервисов;
  • cluster.local (указывается опционально) — доменное имя кластера.

Результатом выполнения скрипта станет такой манифест:
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        log stdout
        health
        kubernetes cluster.local {
          cidrs 10.3.0.0/24
        }
        proxy . /etc/resolv.conf
        cache 30
    }
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: coredns
  template:
    metadata:
      labels:
        k8s-app: coredns
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
    spec:
      containers:
      - name: coredns
        image: coredns/coredns:latest
        imagePullPolicy: Always
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: coredns
  clusterIP: 10.3.0.10
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

Указанная здесь (в Corefile) директива cidrs 10.3.0.0/24 сообщает в Kubernetes middleware из CoreDNS, что необходимо обслуживать PTR-запросы для обратной зоны 0.3.10.in-addr.arpa.

Остаётся передать результат на исполнение в Kubernetes:
$ ./deploy.sh 10.3.0.0/24 | kubectl apply -f -
configmap "coredns" created
deployment "coredns" created
service "kube-dns" configured

… и убедиться, что новый DNS-сервер действительно заработал:
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
Waiting for pod default/dnstools to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
# host kubernetes
kubernetes.default.svc.cluster.local has address 10.3.0.1
# host kube-dns.kube-system
kube-dns.kube-system.svc.cluster.local has address 10.3.0.10
# host 10.3.0.1
1.0.3.10.in-addr.arpa domain name pointer kubernetes.default.svc.cluster.local.
# host 10.3.0.10
10.0.3.10.in-addr.arpa domain name pointer kube-dns.kube-system.svc.cluster.local.

Как это выглядит на стороне самого CoreDNS? Вот пример для случая кластера из двух реплик CoreDNS, между которыми делается балансировка DNS-запросов:
# найдем поды со службой CoreDNS
$ kubectl get --namespace kube-system pods
NAME                                    READY     STATUS    RESTARTS   AGE
coredns-3558181428-0zhnh                1/1       Running   0          2m
coredns-3558181428-xri9i                1/1       Running   0          2m
heapster-v1.2.0-4088228293-a8gkc        2/2       Running   0          126d
kube-apiserver-10.222.243.77            1/1       Running   2          126d
kube-controller-manager-10.222.243.77   1/1       Running   2          126d
kube-proxy-10.222.243.77                1/1       Running   2          126d
kube-proxy-10.222.243.78                1/1       Running   0          126d
kube-scheduler-10.222.243.77            1/1       Running   2          126d
kubernetes-dashboard-v1.4.1-gi2xr       1/1       Running   0          24d
tiller-deploy-3299276078-e8phb          1/1       Running   0          24d
# посмотрим на логи первого
$ kubectl logs --namespace kube-system coredns-3558181428-0zhnh
2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "AAAA IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 544.128µs
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "MX IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 7.576897ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.default.svc.cluster.local. udp 64 false 512" NXDOMAIN 117 471.176µs
23/Feb/2017:14:49:52 +0000 [ERROR 0 kube-dns.kube-system.default.svc.cluster.local. A] no items found
10.2.6.127 - [23/Feb/2017:14:50:00 +0000] "PTR IN 10.0.3.10.in-addr.arpa. udp 40 false 512" NOERROR 92 752.956µs
# посмотрим на логи второго
$ kubectl logs --namespace kube-system coredns-3558181428-xri9i
2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 70 1.10732ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 72 409.74µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "AAAA IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 210.817µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "MX IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 796.703µs
10.2.6.127 - [23/Feb/2017:14:49:56 +0000] "PTR IN 1.0.3.10.in-addr.arpa. udp 39 false 512" NOERROR 89 694.649µs

Для отключения логирования всех DNS-запросов (большая нагрузка на диск при реальном применени) достаточно убрать строку log stdout из Corefile.

Важно: авторы предупреждают, что в случае использования Google Container Engine (GKE) описываемый пример не сработает из-за дополнительных процессов, не позволяющих заменить стандартный kube-dns. Есть путь решения этой проблемы, однако официально он пока не был ими документирован/анонсирован.

CoreDNS для Minikube


В случае локального запуска Kubernetes с Minikube есть схожая проблема: используемый в нём addon manager периодически проверяет (и поддерживает) состояние конфигураций всех установленных дополнений, одним из которых является kube-dns. Чтобы этот менеджер не мешал работе CoreDNS, есть простое решение.

Оно заключается в том, чтобы изменить список установленных дополнений для minikube:
$ minikube addons list
- dashboard: enabled
- default-storageclass: enabled
- kube-dns: enabled
- heapster: disabled
- ingress: disabled
- registry-creds: disabled
- addon-manager: enabled
$ minikube addons disable kube-dns
kube-dns was successfully disabled
$ minikube addons list
- heapster: disabled
- ingress: disabled
- registry-creds: disabled
- addon-manager: enabled
- dashboard: enabled
- default-storageclass: enabled
- kube-dns: disabled

Эту настройку необходимо выполнить до применения конфигурации CoreDNS в Kubernetes (т.е. до запуска kubectl apply -f из примера выше). А после применения этой конфигурации потребуется ещё удалить ReplicationController из kube-dns, поскольку отключение дополнения не делает этого автоматически:
$ kubectl get -n kube-system pods
NAME                          READY     STATUS    RESTARTS   AGE
coredns-980047985-g2748       1/1       Running   1          36m
kube-addon-manager-minikube   1/1       Running   0          9d
kube-dns-v20-qzvr2            3/3       Running   0          1m
kubernetes-dashboard-ks1jp    1/1       Running   0          9d
$ kubectl delete -n kube-system rc kube-dns-v20
replicationcontroller "kube-dns-v20" deleted

Заключение


CoreDNS — интересный проект, реальные перспективы которому придают его убедительное наследие (опыт со времён SkyDNS), тесная кооперация с профильным сообществом (Kubernetes и Go), признание в CNCF и, конечно, современный подход к реализации.

Читайте также в нашем блоге по близким темам:
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331872/


Как NVIDIA и AMD зарабатывают на росте популярности криптовалют

Четверг, 29 Июня 2017 г. 08:50 + в цитатник
Представляю вниманию читателей Хабра мой вольный перевод (или даже пересказ) статьи This Is Why Nvidia and AMD Continue to Ride the Cryptocurrency Mining Wave

За последнее время акции NVIDIA и AMD показали весьма впечатляющий рост (соответственно, +232% и +183% за год), в немалой степени благодаря спросу со стороны майнеров криптовалют. Только на этот раз речь идёт не о биткоине, а об одном из его младших братьев – этериуме, чьи майнеры из Европы и Китая пачками скупают графические карты вышеназванных производителей. Так, по мнению аналитика Митча Стивса из RBC Capital Markets, только за последние 11 дней майнеры скупили карт на 100 млн. долларов. (прим. перев.: насколько точно установлена связь между продажами карт и майнингом, судить не берусь).

Среди непосвящённых распространено заблуждение, что майнеры применяют графические карты в основном для майнинга биткоинов, тогда как для этой цели они уже несколько лет как перешли на ASIC-чипы (Application-Specific Integrated Circuit), оснащённые более мощными процессорами. На сегодня сложность майнинга настолько возросла, что с графическими процессорами расход электроэнергии превышал бы выгоду от самого майнинга (прим. перев.: возможно, в странах с дешевой электроэнергией графические карты всё ещё окупаются, но при достаточно большом количестве майнеров с ASIC остальные участники просто будут проигрывать в скорости и ничего не заработают, так как вознаграждение начисляется тому, кто закончит вычисление первым).

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

В свете изложенных событий возникает естественный вопрос: стоит ли инвестировать в производителей графических карт? Большинство аналитиков не рассчитывают на стабильно высокий спрос со стороны майнеров. Курсы криптовалют подвержены резким скачкам, и в случае сильного падения тратиться на дорогие карты может стать невыгодным, что очень быстро отразится на доходах производителей.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331848/


Метки:  

Отчет об инциденте: «GoldenEye/Petya»

Четверг, 29 Июня 2017 г. 08:26 + в цитатник


27 июня 2017 года началась масштабная атака с использованием варианта семейства
шифровальщиков, известных как GoldenEye, от которой пострадали многие страны мира.
Помимо шифрования файлов, это семейство шифровальщиков характеризуется шифрованием MBR (главной загрузочной записи Windows) при наличии прав, блокируя полный доступ к компьютеру.

Общая информация

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

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



После этого на экране показывается окно с требованием выкупа.



Распространение

В это раз мы увидели различные методы проникновения и распространения угрозы в сетях:

• Атака против системы обновлений в MeDoc — популярном сервисе электронного
документооборота на Украине (эта страна сильно пострадала от атаки)

• ETERNALBLUE: Этот вариант угрозы использует код, который эксплуатирует уязвимость,
опубликованную Microsoft 14 марта 2017 года и описанную в бюллетене MS17-010.

• PSEXEC: Включает в себя удаленное выполнение в системе, используя команду PSEXEC.

• WMI: Содержит удаленное выполнение в системе, используя команду WMI

Общий анализ образцов

Образец 1: 7e37ab34ecdcc3e77e24522ddfd4852d

Мы не увидели направления входа. Но мы увидели три различных техники для распространения во внутренней сети:

• EternalBlue



• PSEXEC

v8 = wsprintfW(a2, L”%s \\\\%s -accepteula -s “, v3, a3);
v9 = wsprintfW(&a2[v8], L”-d C:\\Windows\\System32\\rundll32.exe \”C:\\Windows\\%s\”,#1 “, &v14)
+ v8;

• WMI

wbem\wmic.exe %s /node:”%ws” /user:”%ws” /password:”%ws” process call create “C:\Windows
\System32\ rundll32.exe \”C:\Windows\%s\” #1



Образец 2: 71b6a493388e7d0b40c83ce903bc6b04

Мы видели, что направление входа — это EZVIT, часть продукта MeDoc, популярной системы
электронного документооборота на Украине. Это подтверждается выполнением GoldenEye через эту программу:



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

Советы и рекомендации

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

• Обновляйте ваши операционные системы, ПО и прошивки на всех устройствах.

• В этот раз мы обнаружили использование ETERNALBLUE, а потому мы рекомендуем, чтобы вы скачали и установили следующий патч на всех компьютерах в Вашей сети:
technet.microsoft.com/en-us/library/security/ms17-010.aspx

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

• Если вы уже являетесь клиентом Adaptive Defense, и в случае новых масштабных атак установите в решении Adaptive Defense режим работы Lock: запускайте только те процессы, которые классифицированы компанией Panda Security как надежные.

• Периодически делайте резервные копии и проверяйте, что они корректно работают и не
подключены к сети.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331886/


Метки:  

GUI на Grafana для mgstat — утилиты мониторинга системы на InterSystems Cach'e, Ensemble или HealthShare

Четверг, 29 Июня 2017 г. 07:38 + в цитатник

Метки:  

Как запутать аналитика. Часть первая

Четверг, 29 Июня 2017 г. 07:28 + в цитатник
— В армии научились совмещать пространство и время.
— Как?
— Очень просто! Прапорщик дает задание: «Сегодня будем копать от забора и до обеда»

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

В прошлой статье я дал определения типу и атрибуту. Напомню их:

  • Тип – это выделение кучки (подмножества) из кучи (множества) и наделение объектов этой кучки уникальным именем — существительным.
  • Атрибут разделяет кучу (множество) на кучки (подмножества) и наделяет объекты этих кучек разными прилагательными.

Это было определение типа и определение атрибута на основе анализа – мы делили кучу на части. Фактически, это было построение типа при помощи анализа. Теперь я покажу, как можно строить типы и атрибуты на основе синтеза.

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

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

  • перечислением всех объектов учета, относящихся к этому типу
  • перечислением всех типов объектов учета, которые относятся к этому типу.

Точно так же можно поступить с атрибутом. Можно взять несколько кучек, присвоить им значения, объединить вместе и назвать это все атрибутом.

Обобщим на любые операции над множествами:

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

Вы можете сказать, что оперировать кучками – слишком примитивно. Ведь мы умеем работать с такими абстракциями как графы, логики, алгебры. Однако, введение новых абстракций без глубокого понимания того, что за этим стоит, быстро приводит к тому, что мы начинаем путаться. При этом математики, применяя свои инструменты, не совершают логических ошибок, потому что, с одной стороны, придерживаются жесткой дисциплины рассуждений, которую им прививает изучение основ математики, а с другой стороны, создавая модели для решения конкретных задач, они не обременяют себя стыковкой этих моделей между собой. Мы же, строя модели разных предметных областей, зачастую не владеем необходимым математическим аппаратом, например, не знаем, что такое мера Жордана, или что такое шкалирование, но при этом решаем сложнейшие задачи стыковок разных моделей. Например, вы легко можете столкнуться с моделями, в одной из которых цвет выражен длиной волны, в другой – частотой колебания электромагнитных волн, а в третьей – словами типа «красный». Или может случиться, что «Колли» в одном модели – это атрибут класса «собаки», в другой – это отдельный класс объектов. Конечно, вы можете построить преобразование из одной модели в другую. Но как вы это сделаете, и что за этим стоит?

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

Чтобы понять, о каких путаницах я говорю, надо задать простые вопросы:

  • Почему в результате умножения 3-х яблок и 4-х корзин, получается 12 яблок, а не 12 корзин, или 12 яблоко-корзин?
  • Почему 3 Ампера, умноженные на 4 Вольта дают 12 Ватт, а не 12 Ампер, или 12 Вольт?
  • Почему 3 метра, умноженные на 4 метра, дают 12 квадратных метров?
  • Почему Паскаль заходит в кафе и видит, что там 100000 Паскалей?
  • Почему модели линейного преобразования пространства и линейного преобразования базиса выглядят совершенно одинаково: в виде матрицы? Хотя физический смысл этих действий совершенно разный?

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

Начнем с модели объекта учета. Объект учета – это то, что выделено субъектом в качестве части реального мира, но еще не классифицировано и не названо, например, четырехмерный пространственно-временной объем. Далее этот объект учета проходит этап моделирования в сознании субъекта при помощи метамодели. Метамодель – это представление человека о том, как производить моделирование. Например, для всех нас общим является представление о том, что есть объекты, есть действия, совершаемые объектами, есть типы объектов, типы совершаемых ими действий и свойства. Эта метамодель была подмечена и хорошо описана Аристотелем. Только один вопрос у него остался без ответа: если есть атрибут «высота» у деревьев, и есть атрибут «высота» у зданий, то это один и тот же атрибут, или это разные атрибуты? Мы не знаем, что думал Аристотель на эту тему, но зато знаем, что мы думаем на этот счет: все зависит от точки зрения субъекта и решаемых задач — это может быть один атрибут, а могут быть разные атрибуты.

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

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

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

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

Так для моделирования типов в ООП используются «классы». Они моделируются набором встроенных в них атрибутов. Также можно указать имя объектов данного типа. Но ничего более для описания типа в ООП не предусмотрено.

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

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

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

Путаница типов и объектов


Программисты часто думают, что моделирование типа объектов и моделирование объекта – это одно и то же. Например, класс в ООП почему-то упорно именуют объектом, например, чашкой, а не типом объектов, а объект почему-то упорно называют «экземпляром этой чашки», а не «чашкой». Из-за этого рождаются стандарты с уже заложенными в них коллизиями.

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

Путаница типов и множеств


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

Это были примеры путаниц распространенных, но далее круга программистов не выходящих. Есть и такие, которые распространены гораздо шире. В следующих статьях попробуем поговорить о них.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331882/


Метки:  

[Питер] Встреча JUG.ru c легендой параллельного программирования Maurice Herlihy — Transactional Memory and Beyond

Четверг, 29 Июня 2017 г. 00:36 + в цитатник


У нас праздник! В начале июля в Санкт-Петербурге пройдет SPTCC 2017, летняя школа по параллельному программированию. Одним из лекторов школы станет Морис Херлихи (Maurice Herlihy), легенда параллельного программирования, один из авторов знаменитого учебника «The Art of Multiprocessor Programming».

В четверг, 6 июля, в 19:00 в Университете ИТМО Морис выступит на встрече JUG.ru. На этот раз мы будем говорить не про Java. Тема встречи — транзакционная память.

О чем же нам расскажет Морис?

Транзакционная память


Новое поколение процессорных архитектур предоставляет нам аппаратную транзакционную память (Hardware Transactional Memory — HTM), механизм синхронизации для быстрых транзакций в оперативной памяти. В данном докладе будет показано, что HTM это не просто более быстрый путь для релизации старых-добрых monitor-ов и latch-ей. На самом деле, HTM обеспечивает фундаментальные позитивные изменения в том, как мы программируем многоядерные машины (и возможно даже базы данных), позволяя нам переосмыслить базовые примитивы синхронизации, такие, как lock-и, управление памятью, и многообразие многопоточных структур данных.


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




О докладчике


Maurice Herlihy получил степень бакалавра в Гарварде, потом стал Ph.D. в M.I.T. Долгое время работал в Университете Carnegie Mellon, в DEC Cambridge Research Lab. В данный момент — профессор в Brown University.

Обладатель множества наград в области Computer Science:
  • the 2003 Dijkstra Prize in Distributed Computing
  • the 2004 G"odel Prize in theoretical computer science
  • the 2008 ISCA influential paper award
  • the 2012 Edsger W. Dijkstra Prize
  • the 2013 Wallace McDowell award


Морис — член Ассоциации Вычислительной Техники (ACM), член Национальной Академии Изобретателей, член Национальной Академии Инженерии и Американской Академии Искусств и Наук. Один из авторов знаменитого учебника по параллельному программированию «The Art of Multiprocessor Programming». Короче, у кого есть эта книга — тащите подписывать.




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

Участие бесплатное. Регистрация — ТУТ.

Онлайн-трансляции не будет, но будет записываться видео. Видео будет выложено на Youtube-канале JUG.ru в районе 15 июля.




P.S.: Я благодарю организаторов SPTCC 2017 Виталия Аксёнова, Романа Елизарова и Петра Кузнецова за помощь в приглашении Мориса к нам на встречу.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331880/


Шифровальщик, которому не нужны деньги

Четверг, 29 Июня 2017 г. 00:14 + в цитатник
Возвращение Petya-подобного шифровальщика уже во всю анализируют специалисты по ИБ. Среди первой волны экспертных оценок стоит выделит мнение о том, что основная задача (в рамках данной атаки) могла заключаться совсем не в вымогательстве денежных средств, а в повреждении ИТ-систем.

/ фото Adam Foster CC

Такую оценку дают независимые эксперты и специалисты по ИБ, представляющие научное сообщество (например, Калифорнийский университет в Беркли).

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

В качестве канала для коммуникации был предложен обыкновенный email-ящик, размещенный в Германии у местного провайдера Posteo. Как только атака набрала обороты, ящик закрыли. Таким образом, даже те, кто перевел денежные средства, не смогли получить «дешифратор».

С другой стороны, эксперты подчеркивают многовекторный характер атаки и общую сложность «шифровальщика». С технологической точки зрения NotPetya выполнен на очень высоком уровне и использует EternalBlue и EternalRomance, эксплуатирующих уязвимость в Windows-реализации протокола SMB (многие компании проигнорировали соответствующий патч).

Пока мы готовили эту заметку, появились и другие экспертные мнения, которые подтвердили предположения коллег. Petya-2017 производит необратимое воздействие, что в корне отличается от поведения Petya-2016, который позволял сделать «откат» к изначальному состоянию.

Эксперты говорят о том, что «маскировка» под «шифровальщика-вымогателя» могла быть применена для того, чтобы получить наиболее широкий охват в медиа по аналогии с WannaCry.

Материалы по теме на Хабре:


Дополнительное чтение — наши материалы:

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330582/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1028 1027 [1026] 1025 1024 ..
.. 1 Календарь