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

Поиск сообщений в 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 ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

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

Открытый протокол для децентрализованной коммуникации [matrix] ищет спонсоров для продолжения разработки

Среда, 26 Июля 2017 г. 23:47 + в цитатник

Метки:  

Нематериальная мотивация — что туда включено

Среда, 26 Июля 2017 г. 22:28 + в цитатник
Очень, очень люблю читать про пирамиду Маслоу, нематериальную мотивацию, рост в коллективе, и вообще решпект и уважуху, которые ну никак нельзя посчитать в деньгах.

tl/dr: список всяких нематериальных бонусов, и что спросить на собеседовании.

Больше этого люблю только рассказы от HR на собеседованиях, вида — у нас, вы не поверите, белая !1одинодин зарплата .
Вот только часто список этим и исчерпывается, увы. Конечно, возможность получить 2-НДФЛ с большой суммой для ипотеки кому-то и сгодится как бонус, но я слышал о несознательных бухгалтериях (один мой друг, граф ДлФ даже работал в таковой), которые в 2-НДФЛ напишут сколько надо, даже если у тебя официально 30к (в Москве), а остальное премия, бонус, и иногда конвертик.
Для удобства опроса HR-ов на собеседованиях и был составлен список ниже. Список, конечно, местами очень нематериальный — но легко пересчитывается в рубли.

Начну с все же материального:
Зарплата: белая, серая или как. И в каком соотношении. Сколько оклад, сколько премия, есть ли она.
Премии. Связаны ли они с KPI и вообще есть ли он.
Обратное премии – штрафы. Есть ли, за что и откуда вычитаются.
Индексация ЗП по инфляции
Переработки, работа в выходные, их частота, оплата.
Работа вне плана – например, устранение аварий. Оплата, сроки оплаты.
Есть ли система переаттестации по и не итогам, «грейдов» и прочего, и как это все работает.
Пенсионные планы. Конечно, 401(к) в РФ нет, но можно и уточнить.
ВНЕЗАПНО актуально для РФ. Даже для некоторых крупных (действительно крупных) организаций – что у вас с задержками ЗП за последний год.
Также в некоторых финансовых учреждениях и нефтегазовых компаниях дают льготную ипотеку или программу улучшения жилищных условий
Правда, автор и критики/коллеги, за годы работы не встречали коллег, успешно участвующих в настоящей программе. При этом кредиты (порой невозвратные, или под 0%) для топ-менеджмента – явление более чем постоянное.

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

Теперь не материальное, но все еще не бонусы.
График работы – 8-17, 9-18, сменный, прочие варианты. Возможность сдвига графика на +- час.
Строгость контроля графика. Надо ли приходить строго за 2 минуты до, или как.
Сам график – обед, перерывы на покурить / чай / прочее. Строго 5 минут/час, или свободно.

Дресс-код. Есть ли, строгий/не строгий.

Отпуска, и особенно вызов из отпуска
Есть такая штука, как передача дел во время отпуска (замещение). Как это оформлено, устроено, практикуется ли и вообще.
Проезд в отпуск (актуально для около-РЖД, около-авиа и в некоторых регионах).
Уходы с половины дня – например, к зубному или по другим задачам.

Нематериальное: ДМС и прочий ЗОЖ
ДМС. Включена ли в ДМС стоматология и в каком объеме
Фитнесс (свой или бонусы / скидки)
1-2 дня болезни без оформления.
Доплата за время болезни по полной ставке, а не по стандарту ОМС.
Страховка (дмс) на детей.
Страхование жизни также кое-где присутствует и страховка для выезжающих за границу (мелочь но приятно, особенно когда нужно на визу такую страховку делать).
Врач в офисе, который может выписать какое лекарство или первичный осмотр провести.
Да хотя бы просто аптечка в офисе.
Примечание – автор с времен работы сборщиком компов из говнокорпусов привык держать на работе свою аптечку — бинт, пластырь, йод, перекись, и универсальную таблетку – от головы и вторая половинка. Поскольку автор еще и немного жирный и чуть-чуть дебиловат (не так как некоторые дизайнеры, конечно) – то в аптечке есть еще и жгут, и хлоргексидин, и термометр (электронный), и еще что-то. И, внезапно, ацикловир, после наблюдения коллег с распухшей физиономией.

ЗОЖ
Наличие велопарковки (открытой/закрытой) и, например, душа. Опять же, актуально при устранении серьезных аварий, когда иногда приходится сутки-двое проводить на работе.

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

Транспорт
Стоянка (актуально для МСК). Есть ли, открытая/закрытая, что и как с оплатой.
Корпоративный транспорт, служебный проездной (в 1с вроде было).

Специфика транспорта в РФ.
Иногда могут предложить служебный автомобиль (или Рено Логан вместо автомобиля) или предложить компенсацию использования собственного автомобиля (Но готовы ли вы использовать собственный автомобиль за 1000 (одну) тысячу рублей в месяц – видел такое объявление).
Но в целом для работы в около-ИТ (например, обслуживание кассовой и сопутствующей техники в магазинах) служебная машина – это часто встречающееся явление. Могут быть фокусы с оплатой бензина (лимиты, по чекам, итд).

Доступность.
Сотовый телефон (служебный, актуально для тех кто всегда на связи, даже в отпуске).
Состояние «на телефоне» — и в выходные, и в отпуске тоже или как? Оплата пребывания «на телефоне в зоне 3 часовой физической доступности / с доступом к интернету и доступности в любой точке мира даже в отпуске».
Работа из дома. Можно ли, как часто.
Оплата интернета (бывает кое-где).

Учеба.
Учеба по специальности. Есть ли, каковы условия. Есть ли отработка и прочие условия. Сколько лет срок рабства при оплате за тебя конторой. В том числе поездки скажем на VMworld.
Отпустят ли в учебный отпуск (если учеба в институте)
Как будет проходить отсутствие на рабочем месте, если учебу сам оплатил – как отпуск за свой счет, как вычитание из отпуска или как учебный отпуск? Или просто закроют глаза по какой-то договоренности?

Примечание: Вообще говоря, стоит избегать неявных договоренностей с рядом руководителей. Гораздо проще, чтобы это все проводилось через отдел кадров, и потом не возникало недоговорок «кто что подумал».
Скидки или какие-то учебные курсы в офисе (иностранный язык) или по партнерским программам
Наличие у организации подписок на всякие MSDN
Наличие партнерских курсов за бонусы (у интеграторов и крупных продавцов)
Наличие связей у организации для отправки на всякие вроде бесплатные курсы на 1-3 дня, иногда даже и в рабочее время.

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

Рабочее место.
Просто показать рабочее место.
Что хотя бы просто с ПК – потому что для ИТ порой удобно держать два монитора. Иногда три, на третий выводится мониторинг.
Что с освещением, вентиляцией, оборудованием. Тепло/холодно, особенно в случае холодных балок и закрытых наглухо окнах(принципиально не открываемых). Шумность, удобство. Степень опен-спейсности. Возможность поставить свой увлажнитель.
Наличие контроля CO/CO2. Видел в одном офисе (одной кампании с хабра, хочу заметить) такое вживую.
Всякие офисные бонусные зоны – мини-переговорки, настольный теннис итд.

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

Пополнение приветствуется.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334212/


Метки:  

Универсальная рекламная кампания для всех видов бизнеса

Среда, 26 Июля 2017 г. 21:50 + в цитатник
Привет хабр. Меня зовут Олег Пацай. Последние четыре года я живу в рекламных кабинетах соц. сетей. Я провёл более 300 рекламных кампаний в 108 разных направлениях. Через таргет я доносил до людей разную информацию. То, что я наблюдаю в реакции людей на рекламные сообщения натолкнуто меня на мысль о создании универсальной рекламной кампании. Я задумался о создании такого креатива, который бы работал идеально в любых проектах.

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

image



Персональное обращение



Самая эффективная реклама была тогда, когда у потенциального покупателя создавалось впечатление диалога. Когда бренд обращается к потребителю напрямую. Один на один. Без всяких заумных слоганов, без лишнего. А с простым вопросом в подтексте: «А тебе вообще это надо?». На что у потребителя возникал ответ да или нет.

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

image

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

И в итоге найден тот самый



image

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


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

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

https://habrahabr.ru/post/334208/


Метки:  

[Перевод] Почему я ненавижу Spring

Среда, 26 Июля 2017 г. 18:33 + в цитатник
В начале своей карьеры я реально влюбился в Spring. Я так долго ждал его. Я использовал его во всех своих проектах. Вдобавок мне даже удалось впихнуть туда кучу всякой всячины из Spring Integration. Я был кем-то вроде короля XML. Я делал RPC-слой на основе JMS, protobufs и Kaazing для всего нашего отдела и банка в целом. Я думал: «Это так конфигурируемо. Всего-то пара XML-файлов — это действительно гибко». Я был очень доволен собой.

Но некоторые мои коллеги были склонны не согласиться. У них возникали проблемы, когда они пытались связать всё так, как им хочется; они не знали, где какие XML-файлы им нужны. Были проблемы с версиями Spring, с тем, как подружить их (я, к тому же, далеко зашел с модульностью: у нас было 5 или 6 разных модулей с разными номерами версий, и нельзя было просто так взять и понять, какой из них использовать, не спросив меня). Это были тревожные звоночки, но я их не замечал; я думал, что нужно больше документации или что те ребята просто тупые. Такая ситуация типична сама по себе: мольбы пользователей одного из самых нелюбимых и трудных в использовании фреймворков о помощи часто разбиваются о «да там один файл и немного параметров, это не так уж и тяжело», в то время как все остальные целыми днями пытаются найти магическую комбинацию файлов и параметров, чтобы хоть что-нибудь как-нибудь заработало.

Я всё ещё работаю в той же организации, но теперь я пользователь своего старого фреймворка. В результате этого питания кормом своей собаки я стал ненавидеть Сэма (автор имеет в виду себя — прим. пер.) 2009-2010 годов по нескольким причинам, но в основном — за Spring. Spring — это зло в хорошую погоду, но когда его включают в состав библиотеки или API, которым пользуются другие программисты, — это уже другой уровень зла: как плод любви Гитлера и дьявола. Не позволяйте Spring торчать из вашего API наружу.



Spring — отстой по ряду причин, и я почувствовал, что их нужно перечислить, т.к. в google нет четких контраргументов.

  • Конфигурация в XML. Хотел бы я думать, что мы как профессия оставили XML в прошлом. Он невероятно многословен, но это ещё цветочки. Намного важнее то,
    что я не хочу программировать на XML. Связывание всех классов воедино — чрезвычайно важная часть вашего приложения. Вы Java-разработчик, а не XML-разработчик. Одна из прелестей Java как языка — compile time safety. Я могу скомпилировать свои приложения, в которых нет Spring, и быть на 100% уверенным, что всё собрано, подключено и готово к работе. Но если в приложении есть Spring, ты запускаешь его, ждешь 30-60 секунд, пока оно инициализирует бины, прежде чем упасть. В современном мире это безумие, особенно если это еще и умножается на кучу интеграционных тестов, в которых вам нужно вертеть контейнер так и этак. Отдельного места в расстрельном списке заслуживает «это значит, что я могу менять реализацию без перекомпиляции!». Так никто не делает. Никогда.
  • Магия. Тут обычно следует реплика: «Теперь вы можете делать всё с помощью аннотаций! Больше никакого XML!». Здорово, когда не нужно программировать на XML, но аннотации — это всё ещё магия. Пока вы не запустите приложение, вы понятия не имеете, свяжется ли оно правильно. И даже потом вы не знаете, правильно ли оно связалось; вы всего лишь знаете, что оно связалось. Не люблю магию.
  • Импортирование других Spring-файлов. В данный момент это бесит меня больше всего. Я обнаружил, что существует тенденция разбивать Spring-файлы на более мелкие и раскидывать их по модулям. Я только что убил 2 недели, продираясь сквозь JAR'ы и пытаясь найти правильную комбинацию/порядок/версию Spring-файлов, чтобы кое-что заработало. Spring-файлы в JAR'ах — это плохая, плохая идея. Ужасная. Каждый раз, когда вы размазываете зависимые Spring-файлы по JAR'ам, где-то умирает ребенок.
  • Сложность. Когда на собеседовании спрашиваешь кандидата: «Какие подводные камни есть в Spring?» — чаще всего слышишь в ответ, что у него крутая кривая обучения. Правда это или нет — отдельная тема, но я хотел бы подчеркнуть тот факт, что Spring сейчас настолько сложен, что у него есть собственный фреймворк — Spring Boot. Фреймворк для фреймворка. Мы во «Framework Inception» — фильме о Леонардо Ди Каприо, который пытается найти свой давно потерянный Java-код, всё глубже и глубже погружаясь в слои XML и аннотаций, прежде чем в конце концов покончить с собой.


Штука в том, что я уверен: удачно использовать Spring в приложении теоретически возможно. Я еще никогда такого не видел, и это проблема. Как по мне, все «плюшки», которые он предлагает, вполне возможны и без него. Когда мы спрашиваем о Spring на собеседовании, кандидат обычно отвечает: «Со Spring у вас есть чистый код, разделение ответственности, к тому же он действительно хорош для тестирования». В общем, все те вещи, большим поклонником которых я являюсь (особенно тестирование), но на самом деле это результаты не использования Spring, а хорошего программирования. Возможно, для новичков Spring — это хороший костыль для освоения таких идей, как внедрение зависимостей, mocking и тестирование, но на самом деле они ортогональны Spring. Если вы применяете TDD, у вас в коде не будет геттеров и сеттеров — только внедрение зависимостей через конструкторы, которые вы можете «замокать» для тестирования, а затем, когда вы связываете своё приложение воедино, просто используете часто забываемый способ создания объектов — ключевое слово «new». Зачастую мы создаем класс «ApplicationContext», который отвечает за связывание всего воедино. Он чистый, всё тестируемо, у меня есть compile time safety, и мои тесты выполняются чертовски быстро.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334118/


Метки:  

Процесс создания синематика вживую. Стрим завтра, 27 июля в 15.00

Среда, 26 Июля 2017 г. 18:06 + в цитатник
Для того, чтобы каждый смог понаблюдать за процессом создания синематика в игровой компании, мы начинаем серию живых включений прямо из Video Production Department в Plarium Kharkiv.





Наблюдайте вживую за отрисовкой скетчей, митингами, созданием анимаций и процессом озвучки нового синематика для игры Vikings: War of Clans.

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

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



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

https://habrahabr.ru/post/334198/


Высокотехнологичный шопинг: инновации, меняющие облик ритейла и торговых центров

Среда, 26 Июля 2017 г. 17:48 + в цитатник
По мере того, как высокие технологии активно приходят в ритейл, совершать покупки становится не только проще, но и… интереснее. Шопинг все больше напоминает увлекательную игру, в которой товары фактически общаются с покупателем, а роботы помогают сделать выбор и расплатиться.


Фото foodandnutrition.org

Покупателям не понадобятся деньги…


До коммунизма, при котором «все будет бесплатно», мы, похоже, не доживем. Зато шопинг в современном торговом центре без наличных денег и даже банковских карт – это уже наша действительность. Внедряющийся повсеместно процесс оплаты при помощи смартфона предельно прост. Клиент использует либо мобильное приложение своего банка, либо софт, поставляемый ритейлером. Удобно со всех сторон – даже с точки зрения хранения чеков и квитанций, которые приходят покупателю по электронной почте. Похоже, что в скором времени большей неприятностью при поездке в торговый центр станет не забытый дома кошелек, а разрядившийся смартфон. Хотя МЕГА, например, уже решила эту проблему: гости торговых центров могут зарядить свои телефоны в защищенных замками ячейках.

Сегодня смартфон – важнейший союзник ритейла в деле сбора информации о потенциальных клиентах. Эти данные, именуемые Big Data, содержат сведения о «средних чеках», предпочтениях и интересах покупателей.

Большие данные – волшебный ключик к лояльности клиента, который позволяет максимально персонализировать взаимоотношения. Многие ритейлеры разрабатывают для этих целей собственное ПО. С одной стороны, такой софт помогает продавцу собрать еще больше данных. С другой – улучшает сервис для постоянных клиентов. В тех же торговых центрах МЕГА при помощи мобильного приложения покупатель может получить множество приятных привилегий. Например, быстро найти нужный магазин, синхронизировать данные с другими устройствами или поделиться списком покупок с другими членами семьи. Приложение МЕГА также помогает найти самый удобный способ добраться до торгового центра (в зависимости от местоположения пользователя, времени суток и загруженности дорог) и оперативно получать информацию о новых интересных акциях во всех (или определенных) магазинах.  Хит программы лояльности МЕГА — дебетовая или кредитная карта MEGACARD, которая работает как полноценная банковская карта и при этом позволяет накапливать баллы за МЕГА-шоппинг и практически полностью оплачивать ими товары в магазинах торгового центра.

… а магазинам – продавцы


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

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

Внешне эта система напоминает тестовый проект Amazon Go. Впрочем, этот знаменитый оффлайновый супермаркет, открывшийся в Сиэтле в конце прошлого года, не использует чипы. Контроль ведут системы искусственного интеллекта, однако им пока далеко до совершенства. К примеру, если в магазине находится больше 20 человек – система дает сбои. Проблемы возникают и в случае, когда товар меняет свое положение на полке. Например, клиент посмотрел на продукт, покрутил его в руках – и положил на другую полку. А система его уже «потеряла». Так что массовый запуск сети «роботизированных магазинов», планировавшийся изначально на весну 2017 года, не состоялся.


Amazon Go – магазин, в котором не нужны продавцы. Фото engadget.com

В любом случае роботы выполняют в Amazon все больше задач. И довольно эффективно: например, робо-кладовщики Kiva позволили компании снизить складские расходы аж на 20%.

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

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

Тележки с планшетами и планшеты без тележек



Кстати о тележках. Оригинальную противоугонную систему CartControl запатентовала канадская компания Gatekeeper Systems. «Умные» колеса автоматически блокируются при попытке пересечь заданный периметр. Администрация может установить необходимые границы – например, в пределах парковки. Теперь и супермаркет не несет потери от «угонщиков», и клиенту не нужно оставлять залог за тележку в виде жетонов или монет.

Такое антиугонное устройство не помешало бы smart-тележке, созданной белорусскими стартаперами. Суть инновации – планшет в антивандальном корпусе, который вмонтирован в тележку. Гаджет Shop Carts помогает выбирать товары и даже оплачивать покупки, избавляя клиентов от необходимости терять время в очередях. Удобная навигация включает голосовой поиск. Поднесите к планшету штрих-код – на тачскрине отобразится цена продукта и другая информация. Гаджет подсчитывает стоимость всех товаров в корзине и без проблем принимает оплату при помощи мобильных телефонов и банковских карт. Shop Carts может хранить информацию о каждом клиенте: в следующий раз «умная» тележка быстро сориентирует вас по сохраненному в «Личном кабинете» списку покупок.


Интерфейс «умной» тележки: исчерпывающая информация о товарах плюс возможность прорекламировать акции магазина.
Фото tech.onliner.by


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

«Умное» зеркало и непогода в примерочной


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


Зеркала в примерочных Ralph Lauren дают дельные советы по обновлению гардероба.
Фото starfl.com


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

Бывает и так, что примерять одежду по каким-либо причинам не хочется.  Здесь как раз пригодится разработка Texel. Компания — разработчик программного обеспечения и производитель профессиональных 3D-сканеров для получения 3D-моделей людей и крупногабаритных объектов, победитель российского этапа конкурса для стартапов Seedstars World 2015 и финалист прошлогоднего МЕГА Accelerator (подробно о продукте и о том, что ему дал акселератор, мы рассказывали в прошлой публикации).

По словам разработчиков, созданная ими 3D-кабина способна сканировать по 40 объектов в час, при этом полученные с ее помощью модели могут легко использоваться пользователями для 3D-печати, поскольку точность передачи текстуры составляет 1 миллиметр. В ходе пилотного проекта в МЕГА Белая Дача были отсканированы более 20 тыс. человек.

Покупки, которые добираются «своим ходом»


Современный ритейл упрощает не только процесс приобретения товара, но и его доставку. Не исключено, что вскоре торговые центры последуют примеру онлайн-ритейлеров, успешно наладивших оперативную транспортировку посылок беспилотниками. Например, китайский интернет-магазин JD.com к концу года намерен наладить доставку заказов дронами по ста регулярным маршрутам. Кстати, по «дронизации» ритейла Китай уже обогнал Соединенные Штаты. Хотя родоначальник такого типа доставки, упомянутый выше Amazon, продолжает внедрять инновации в «воздушное направление». Компания намерена запускать «складские дирижабли» над районами, в которых наблюдается повышенный спрос. Время доставки таким образом можно будет свести к минимуму.


Беспилотники могут быстро доставить заказ покупателю. Фото gagadget.com

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

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

Подробную информацию можно получить на нашем сайте. Последний день приема заявок — 27 июля.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334184/


Метки:  

Что нового в nginx?

Среда, 26 Июля 2017 г. 17:15 + в цитатник


Максим Дунин (Nginx, Inc.)


Ведущий: Я представляю вашему вниманию следующего докладчика. Встречайте – Максим Дунин. И он расскажет о том, что же нового появилось в технологии под названием nginx.

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

Максим Дунин: Добрый день! Я Максим Дунин. Как вы, наверное, знаете, я разработчик nginx. Сегодня буду вам читать changelog вслух и с выражением. Для начала давайте определимся, с какого именно места мы будем читать changelog. Посмотрим на статистику.



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




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



Смотрим подробнее на то, что происходит в первой версии. И видим, что фактически 50% пользователей уже на текущем стейбле 1.10, еще 5% достаточно смелые, чтобы использовать то, что мы используем и разрабатываем mainline 1.11. Остальные, так или иначе, выучили, что четные версии у нас стабильные, и как-то не спешат обновляться, наверное, просто потому что используют то, что предоставляют собственные дистрибутивы операционных систем и nginx не особо пользуются или не знают, чего нового появилось и зачем им нужно обновляться.

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

Для начала – то, что появилось в ветке 1.9 и доступно в версии 1.10.



Мы научились, наконец-то, использовать порт клиента в различных местах, отошли от моделей, что IP’шников хватит всем, и, если вы много работаете с клиентами за NAT’ом (что сейчас, наверное, у всех), то Real_IP-модуль в том числе поддерживает порт, и можно вытаскивать его из proxy-протокола, можно передавать на бэкенд руками через X-Real-IP.



Следующий вопрос – идемпотентность. Кто знает, что такое идемпотентность? 3 человека в зале. Круто… Приблизительно это мне и говорил Игорь, когда я произносил слово «идемпотентность».



Идемпотентность – это такое свойство объекта или операции при повторе давать тот же самый результат. С точки зрения http, GET-запрос идемпотентен, потому что каждый раз вам возвращают один и тот же ресурс, если вы сделаете запрос не один раз, а два раза, то ничего не изменится. Если вы сознательно не пытались нарушить протокол http и не повесили на GET-запрос какую-нибудь операцию, как большинство счетчиков делают. Например, любая статистика у вас в результате не идемпотентна, потому что повторенный дважды GET-запрос засчитывает два хита. Но с точки зрения стандарта GET идемпотентен. Практически все методы http идемпотентны, кроме POST из основного стандарта и двух дополнительных методов LOCK И PATCH.

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

Если nignx начал уже отправлять запрос на бэкенд, случилась ошибка, повторно он этот запрос не отправляет для POST-запросов. GET-запросы замечательно отправляет, потому что имеет право. POST-запросы не отправляет. Если вам хочется вернуть прежнее поведение, это можно сделать легко с помощью конфигурации. Пишете: «proxy_next_upstream» и добавляете параметр «non_idempotent».



Следующий вопрос – запись в кэш. Мы в nginx записью особо долгие годы не занимались, потому что с записью все обычно просто. Вы сказали ОС: «Запиши мне в файлик данные», ОС сказала: «OK, я записала», а на самом деле сохранила в буфера и когда-то потом запишет.

Это не всегда так. Если у вас очень много записи, вы можете наступить на то, что буфера ОС закончились, и ваша запись заблокируется. Чтобы этого не происходило, теперь nginx умеет писать через thread’ы, если у вас очень много записи в кэш, вы можете с помощью директивы aio_write включить запись через thread’ы. Пока работает только через thread’ы. Вероятно, когда-нибудь в будущем сделаем и через posix aio.

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



Теперь вы ошибок аллокации видеть не должны, если вдруг у вас зона маленькая, просто nginx будет хранить столько, сколько в зоне помещается. Он и раньше это пытался делать, но пытался он это делать по факту, т.е. когда он не мог аллоцировать очередную запись в разделяемой памяти, он говорил: «А давайте мы попробуем удалить самую старую запись», удалял ее и пытался аллоцировать снова. Обычно это получалось. Если у вас высокая нагрузка, много рабочих процессов, это могло не получиться просто потому, что какой-то другой рабочий процесс успевал освобожденную память занять. Плюс к тому, это требует некоторого времени, потому что предполагает удаление файла, соответственно, syscall, уход в диск. Не хочется этого делать в рамках обработки запроса, не хочется, чтобы пользователь ждал, теперь этим умеет заниматься cache manager.

Напрограммировали динамические модули, наконец-то.



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

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

Вторая цель, которая ставилась – это упростить отладку, потому что писать хорошие модули для nginx мало кто умеет и зачастую, когда к нам приходят с проблемами, проблема оказывается в сторонних модулях. Поэтому уже долгие годы первое, что мы просим, когда к нам приходят со словами: «А у меня nginx падает, все разваливается!», мы говорим: «Покажите нам “nginx –V”» и рекомендуем пересобраться без сторонних модулей и посмотреть, воспроизведется ли проблема. Скорее всего, она не воспроизведется.



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



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

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

Конфиг переделывается как-то так.



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

Следующий вопрос – CPU affinity.



Nginx давно умеет CPU affinity, биндить рабочие процессы конкретным процессорам. Это конфигурилось как-то так. Т.е. бинарную маску задаете для каждого рабочего процесса, соответствующий рабочий процесс начинает работать на тех процессорах, которые ему разрешены. Это хорошо работало, когда были 2х-процессорные машины, 4х-процессорные машины. Сейчас, когда машины бывают 64х-процессорные, это уже немного неудобно конфигурить, потому что если вы хотите занять всю машину, у вас там 64 рабочих процесса по 64 бита в каждой маске, руками это уже писать невозможно. Я видел людей, которые пишут PERL-скрипты для того, чтобы делать это. Мы приняли их боль, сделали простую ручку auto, которая раскладывает рабочие процессы по процессорам один за одним. Если полной автоматики мало, можно указать маску, из которой nginx будет выбирать процессоры. Это позволяет ограничить эту раскладку каким-то сапсетом процессоров. Если в маске меньше бит, чем имеется рабочих процессов nginx, он просто пойдет по кругу.



Еще одна проблема, с которой периодически люди сталкиваются – это кэширование больших файлов. Совсем больших файлов, когда у вас 4 ГБ имидж или 40 ГБ имидж, или много-гигабайтное видео. Nginx, конечно, умеет такие файлы кэшировать, но делает это не очень эффективно, особенно, когда речь идет про range-запросы. Если вам присылают range-запрос на что-то из файлика 2 Гб, nginx пойдет скачивать файл целиком, чтобы положить его в кэш, положит его целиком в кэш и, когда до второго Гб докачает, начнет возвращать ответ клиенту. Latency для клиента получается совершенно запредельной. Как-то с этим хочется бороться, но опять же зачастую нужно только начало файла. Наоборот, если у вас какой-нибудь видеостриминг с длинным и скучным фильмом, большинство клиентов открывают, скачивают первые несколько Мб этого потока и после чего соединение закрывают. А вы пошли и скачали все несколько Гб, к себе в кэш положили и думаете, что они нужные.

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



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



Пока суд да дело, SPDY умер, вместо него появился HTTP/2. Отличия есть, но небольшие. С точки зрения общей логики идея все та же – мы в рамках одного соединения мультиплексируем много запросов, за счет этого пытаемся экономить на установлении соединений и экономить latency. Как-то это работает, что-то это дает. Не могу сказать, что это работает хорошо с той точки зрения, что очень много всяких нюансов в реализациях, протокол новый, много кто делает неправильно, в том числе сам google делает в chrome неправильно. Мы им периодически пишем тикеты про то, что они эту часть протокола обрабатывают не так, ту часть протокола обрабатывают не так, встраиваем в nginx workaround для всего этого. Как-то оно работает, я лично не большой фанат этого протокола, в основном, потому что протокол бинарный, и это боль с точки зрения отладки и разработки.

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



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



Разогнали слегка обработку новых соединений. Точнее говоря, сделали ручку, которая их позволяет обрабатывать быстрее. Смотрим на график. На графике тест количества обрабатываемых запросов в секунду в тысячах запросов от количества рабочих процессов. Видим, что совсем не скалируется. Почему так? Потому что у нас по умолчанию включен accept_mutex, и фактически у нас всегда работает один рабочий процесс. 25 тыс. соединений в секунду он как-то обрабатывает, а дальше не может, потому что все сериализованно.

Выключаем accept_mutex. Смотрим – где-то до 2-х рабочих процессов, может быть, до 3-х скалируется, 60 тыс. запросов в секунду выдает, дальше все становится только хуже с увеличением количества рабочих процессов. Почему так? Процессор у нас не кончился, но зато система начала лочиться на listen-сокете. У нас один listen-сокет, получаем contention просто на этом listen-сокете.

Как решать? Добавлять listen-сокетов. Простое решение. Можно добавить руками, разнести по IP-адресам, и все у вас будет хорошо. Если руками неудобно или невозможно, IP-адрес, например, один, теперь это можно сделать с помощью специальной ручки reuseport. Эта ручка позволяет nginx создавать для каждого рабочего процесса собственный listen-сокет, с помощью опции so_ reuseport.

Работает на Linux’е не очень хорошо, работает на DragonFly BSD хорошо, но, к сожалению, малопопулярная ОС. Если вы пытаетесь сделать это на Linux’е, стоит иметь в виду, что при изменении количества рабочих процессов у вас будут теряться соединения. Если вы уменьшили количество рабочих процессов, nginx один из listen-сокетов закроет. Если какие-то соединения в этом listen-сокете лежат, они закроются. Linux пока не умеет перераспределять эти соединения между другими сокетами.

С точки зрения производительности что получаем? Получаем вполне неплохое скалирование где-то до 8-ми рабочих процессов. Дальше опять полка. Почему полка? Потому что клиент на той же машине и ест вдвое больше, чем nginx. И когда у нас 8 процессоров заняты nginx, а остальные 16 заняты клиентом, больше машина не может – все, у нее процессор кончился. Если хочется больше, надо клиента на какие-нибудь другие машины выносить.



Еще одна большая вещь, которую добавили – это модуль Stream. Он позволяет балансировать произвольные соединения, не привязываясь к HTTP. В общем и целом, умеет почти то же, что и HTTP, но чуть попроще, чуть поменьше. Сейчас мы говорим про версии 1.9 и 1.10. Умеет балансировку произвольных соединений с теми же методами балансировки, что и у HTTP, Round-robin умеет, IP hash умеет. Умеет принимать SSL от клиентов, умеет устанавливать SSL к бэкендам. Умеет ограничивать количество соединений, умеет ограничивать скорость в этих соединениях, на бэкенд умеет через proxy-протокол отправлять адрес клиента. Даже умеет немного UDP, но так, чуть-чуть. Можно принять UDP-пакетик от клиента и отправить его на бэкенд, а потом обратно принять один или несколько пакетиков от бэкенда и отправить его обратно к клиенту. Если вам нужно, скажем, балансировать DNS, то, в принципе, можно сделать это с помощью модуля Stream. Если у вас что-то сложное на UDP, то, наверное, сейчас вам счастья не будет. Но зато произвольные TCP-соединения умеем в хвост и в гриву, как хотите.



И всякого разного по мелочи. Научили Resolver пользоваться не только UDP, но и TCP. Это позволяет работать нормально, если у вас больше 30 А-записей, и DNS-ответ не влезает в 512 байт UDP-пакета. Теперь Resolver может в этом случае увидеть, что там стоит битик truncate и пойти по TCP получить полный список. Если вы балансируете с использованием переменных имен и т.д. и используете Resolver, чтобы узнавать списки бэкендов, то вам это немного поможет. Блоки upstream теперь могут быть в разделяемой памяти. Это позволяет держать общий state между рабочими процессами. Т.о. если один рабочий процесс увидит, что ваш бэкенд умер, то все остальные об этом тоже узнают. Если у вас лист кон балансировка, и вы хотите минимизировать количество соединений к бэкендам, то, опять же, оно теперь не в рамках одного рабочего процесса работает и знает соединения только в конкретном рабочем процессе, но и знает все соединения по всему nginx.

Разделяемая память теперь работает на версиях Windows ASLR, т.е. Vista и новее. Если вы вдруг пытаетесь использовать nginx под Windows, вам это немного поможет. Но хочу заметить, что не надо использовать nginx под Windows в продакшне, пожалуйста. Это может быть очень больно. Он серьезно для этого никогда не точился.

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

Добавили переменную $upstream_connect_time, которая – сюрприз – показывает время, потраченное на установление соединения с бэкендом.

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

И научились выводить версию OpenSSL в выводе «-V». Причем, даже научились ее выводить не просто так, а смотреть, с какой версией OpenSSL nginx был собран и с какой будет сейчас работать. Если вдруг у вас nginx был собран с одной версией OpenSSL, а вы сейчас работаете с другой версией OpenSSL, он вам это покажет.

Собственно, более или менее все про ветку 1.9. Все это доступно в стабильной версии 1.10.2.



Что у нас появилось нового в 1.11. Это mainline-ветка, которую мы сейчас разрабатываем. Последняя версия 1.11.5. Что появилось?



В Stream появились переменные. Вообще, Stream усиленно развивается. Появились модули, которые умеют работать с переменными – map, geo, geoip, split_clients, real ip, access log, появилась возможность вернуть некий простой ответ из переменных или просто статическую строку return. Можно теперь делать всякие странные конструкции с помощью map’ов, limit_conn, чтобы применять ограничения избирательно. В общем, практически то же самое, что мы умеем делать в HTTP.



Опять же, в Stream мы научились заглядывать внутрь SSL-соединения, при этом, не снимая SSL. Зачем это может быть нужно? Вам может быть нужно посмотреть на server_name, который прислал клиент, и отправить клиента либо на один бэкенд, либо на другой бэкенд. Сейчас умеем вытаскивать из client_hello server_name. Есть для этого переменная, можно по этой переменной отбалансировать на один или другой бэкенд – на слайде пример, как это сделать. Это нужно включать явно, потому что по умолчанию мы, конечно, ничего не ждем. Если мы хотим дождаться client_hello, то включаем директиву ssl_preread, nginx дождется и, соответственно, будет переменная ssl_preread_server_name.



Научились ограничивать количество соединений с конкретными бэкендами, т.е. для каждого сервера вы теперь можете прописать max_conns, и nginx не будет открывать больше заданного числа соединений к данному бэкенду. Исходно это было сделано для NGINX Plus. Сейчас мы помержили open source просто для того, чтобы сделать людям приятно, с одной стороны, и таскать кастомного кода – с другой.



Научились работать в режиме transparent proxy. Обычно, если вам нужно передать адрес клиента на бэкенд, вы либо в HTTP используете заголовки с адресом клиента, либо, если речь идет про произвольные соединения, вначале соединения передаете заголовок proxy-протокола с адресом, портом. Это, к сожалению, не всегда возможно использовать, есть люди, у которых ничего из этого не работает. Есть люди, которые пытаются использовать nginx не со своими бэкендами, а просто внешний мир как-то проксировать.

Теперь можно в директиве proxy_bind сказать параметр «transparent», и она попытается сделать bind с нужной опцией для того адреса, который ей передали. Соответственно, если вы передадите туда remote_addr, т.е. адрес клиента, она сделает bind на адрес клиента. Соответственно, если вы построили сеть так, чтобы это все работало, то transparent proxy будет работать. Но для этого нужен root, для этого нужна специально построенная сеть. Вообще, если вы со своими бэкендами работаете, скорее всего вам лучше этого не пытаться делать. Может быть, это полезно со всяким legaсy-софтом, который обучить понимать X-Forwarded-For или X-Real-IP нереально.

Еще одна вещь, которой научились… Кто скажет, сколько соединений можно установить к одному бэкенду, если у нас есть один IP-адрес? Есть фронтенд с одним IP-адресом. Сколько соединений можно установить?



65 535 по количеству портов. Потому что destination-порт у нас один, а локальных портов, ну, максимум 65 535. Если у нас, соответственно, два бэкенда – 128 тысяч. Если у нас 10 бэкендов, то больше полумиллиона соединений можно установить, это не проблема.

А теперь пишем в конфиг «proxy_bind» и указываем IP-адрес. Наши полмиллиона портов при десяти бэкендах превращаются обратно в 65 тысяч. Почему так происходит? Происходит это потому что системный вызов bind делается до коннекта, то есть он не знает, куда именно мы будем коннектиться и он должен выбрать локальный порт. Поскольку куда именно мы будем коннектиться, он не знает, он должен выбрать локальный порт так, чтобы можно было потом законнектиться куда угодно, а всего локальных портов у нас 65 тыс. Соответственно, в 65 тысяч мы начинаем упираться, просто написав в конфиге «proxy_bind».

Как с этим бороться? Бороться с этим можно. На свежих версиях Linux есть специальная опция IP_BIND_ADDRESS_NO_PORT, которая говорит bind’у, что не надо ему выбирать локальный порт, мы его использовать не будем, клянемся, что не будем и, соответственно, операционная система не будет его выбирать, а сделает это как обычно в системном вызове connect, когда уже будет знать, куда именно мы хотим приконнектиться. Это опять возвращает нам наши многие тысячи соединений, даже если мы используем bind.



Следующий вопрос – accept mutex. Что, вообще, такое accept mutex? Это такая ручка для борьбы с проблемой thundering herd. Если у вас есть listen-сокет и много процессов, все процессы ждут событий на этом listen-сокете, т.е. ждут, пока придет клиент. Вот, клиент приходит, все процессы ждут, ядро все процессы разбудило. Клиент один, какой-то один процесс его забрал, а все остальные проснулись просто так, просто потратили процессор, погрели окружающий воздух, ничего полезного не сделали. Традиционный метод борьбы – это сказать только одному процессу, чтобы он слушал и ждал новых соединений, а все остальные пусть обрабатывают старые и о новых соединениях не беспокоятся.

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

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

При использовании listen reuseport accept mutex не нужен, потому что у каждого рабочего процесса свой listen-сокет. И, наконец, на свежих версиях Linux в ядре появился флаг EPOLLEXCLUSIVE, который позволяет сказать ядру, чтобы оно будило не все процессы, а только один. Это не для всех программ допустимо, потому что у вас может случиться какая-то другая активность, т.е. процесс разбудят, а он пойдет чем-то другим заниматься. В nginx это вполне работает. Так что мы accept mutex по умолчанию выключили, EPOLLEXCLUSIVE теперь поддерживаем.



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



Следующий вопрос – SSL и сертификаты. SSL – это такая штука, где большая часть времени тратится на handshake. И handshake сводится к тому, чтобы проверить подлинность сертификата. Сертификаты бывают современные – RSA и ECDSA, т.е. на эллиптических кривых. RSA – это хорошо, но дорого, а эллиптические кривые – это быстро и, в общем, тоже хорошо, но не везде работает. В частности, не работает на Windows XP. Как показывают всякие сервисы статистики, Windows XP сейчас все еще от 5 до 10%. Так что, если переключитесь на ECDSA-сертификаты, вам будет несчастье, вы 5% клиентов потеряете. Наверное, если вы большая компания, вы себе не можете этого позволить.

Что делать? Вот циферки (на слайде). Запускаем по SSL speed, видим, что двухкилобитный RSA дает 400 подписей на ядре, мы можем сделать, а ECDSA – 5000 с лишним, и это не предел на самом деле. Это циферки от достаточно старой версии ОpenSSL. Конечно, когда вы поставите перед этим еще forward secrecy, все немножко ухудшится. На реальных handshake’ах с nginx циферки немного не такие впечатляющие, но все равно 300 handshake’ов в секунду в случае RSA, 1000 handshake’ов в секунду на ядре – в случае ECDSA. Рост в три раза.

То, что хочется получить, теперь мы умеем делать так. Вы можете сказать nginx’у: «Вот тебе два сертификата, работай с ними», и nginx их по мере необходимости будет предъявлять клиенту. Если клиент новый и умеет ECDSA, будет использоваться ECDSA, все будет быстро. Если клиент старый, то для него будем использовать RSA.



Кроме того, в SSL теперь можно задавать несколько кривых одновременно, если у вас достаточно свежая OpenSSL. По умолчанию, если раньше был prime256v1, теперь загадочное слово «auto». «Auto» зависит от того, какая именно версия OpenSSL у вас используется. В совсем свежем сначала будет кривая бернштейновская 25519, потом тот же самый prime256v1, который был раньше по умолчанию. Настоятельно рекомендую не трогать, просто имеет смысл знать, что такая ручка есть. Но трогать не надо.

dhparam – параметры для Диффи-Хеллмана обычного классического. По умолчанию мы теперь не предоставляем. Если раньше внутри nginx были защиты килобитные параметры, то теперь их нет, и по умолчанию у вас DHE-шифры, т.е. forward secrecy с использованием Диффи-Хеллмана выключены. Это на самом деле хорошо, потому что они медленные по сравнению с эллиптическими кривыми и есть все основания полагать, что существуют атаки даже на достаточно большую битность, потому что они поддаются предпросчету.



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

В ситуации сборки пакетов это работает нормально. Когда вы собираете основной nginx и к нему множество пакетиков с разными модулями, вы можете контролировать опции сборки и собрать все одинаково. Это не всегда удобно, когда вы хотите свой модуль для каких-то произвольных пакетов подсобрать. Можно, но не всегда удобно. И, опять же, под каждую сборку nginx вам приходится делать свою сборку модуля. Теперь у нас есть специальная опция configure --with-compat, которая включает режим совместимости при динамической загрузке модулей, и все соответствующие поля, вне зависимости от опций сборки, в структурах nginx присутствуют. Соответственно, модули и nginx становятся бинарно совместимыми, даже если вы какие-то опции сборки поменяли, главное, чтобы среди опций был with-compat, тогда вы можете собрать свой модуль и загрузить в любой другой nginx, собранный тоже с опцией with-compat.

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



И всякое разное по мелочи:

  • EPOLLRDHUP на Linux. Теперь мы умеем на него полагаться, если видим, что ядро свежее, это экономит syscall’ы при детектировании, а не закрыл ли клиент соединение.
  • HTTP/2 улучшаем, дополняем.
  • Map научился работать с произвольными комбинациями переменных и строк.
  • Для злопамятных людей появилась переменная $request_id, которая может использоваться для идентификации конкретного запроса.

Все это есть в 1.11.5. И разработка продолжается.



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

Спасибо за внимание!

Контакты


» mdounin@mdounin.ru
» Блог компании Nginx

Этот доклад — расшифровка одного из лучших выступлений на профессиональной конференции разработчиков высоконагруженных систем HighLoad++.

Сейчас мы уже вовсю готовим конференцию 2017-года — самый большой HighLoad++
в истории. Если вам интересно и важна стоимость билетов — покупайте сейчас, пока цена ещё не высока!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334194/


Метки:  

«Data mining сейчас — это преимущество на рынке»: о конференции SmartData и больших данных

Среда, 26 Июля 2017 г. 17:01 + в цитатник


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

В ожидании конференции SmartData, которая впервые состоится в Санкт-Петербурге 21 октября, мы решили внести ясность и расспросили двух членов её программного комитета: Виталия Худобахшова (Одноклассники) и Романа p0b0rchy Поборчего. Они развеяли многие опасения, а разговор получился не только о конференции, но и о состоянии индустрии: что сейчас происходит вокруг machine learning, зачем маленьким компаниям лезть в data mining и почему менеджеры тоже покупают билеты на техническую конференцию обо всём этом.



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

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

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

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

Мы в Одноклассниках полтора года назад впервые пробовали использовать deep learning, а теперь, когда к нам приходят студенты, они говорят: «Ой, а у вас видяшечки есть, чтобы мы сеточку сделали» — и мы достаём из кармашка Tesla P40. И если несколько лет назад статья о том, что сеточку научили играть в классические игры Atari 2600, оказалась опубликована в очень серьёзном журнале Nature, то сейчас студент какого-нибудь МФТИ в состоянии написать модель, которая будет играть в те же игры лучше. Ничего такого уж сложного, по сути, в этом нет, один кто-то сделал — теперь повторить может любой. И даже сделать лучше могут уже многие.

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

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




JUG.ru: Ну, наверняка не все следят за статьями. Есть множество небольших компаний, которые не претендуют на мировое господство и революционные инновации, а занимаются довольно стандартными вещами и не особо следят за «передним краем». Вот такие на SmartData обнаружат для себя пользу или нет?

Виталий: Они-то и обнаружат, на самом деле.

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

Потому что сейчас data mining — это не что иное, как преимущество на рынке. Он позволяет вам быть лучше. А для маленькой компании быть лучше задёшево — очень ценно. Посмотрим так: можно нанять какого-нибудь умного человека, который будет принимать решения, кому что продавать. А можно скачать и обучить модель на random forest, которая будет делать лучше.

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

И у меня есть целая серия докладов, где я для студентов и начинающих специалистов по датамайнингу (да и не только начинающих) показывал, как на MapReduce сделать item-to-item коллаборативную фильтрацию, в один слайд. Я показываю, что это может сделать любой. И это то, что мы хотим донести: не обязательно быть Яндексом, Mail.Ru Group или Google. Это, конечно, очень круто, когда вы Google. Но очень классно, что мы можем взять опенсорс каких-то больших крупных компаний и воспользоваться этим. Использовать этот алгоритм в повседневной жизни и показать, что можно получить преимущество на рынке, даже если в вашей компании пять человек. Это вполне наша аудитория.

JUG.ru: Поскольку в темах заявлен data science, хочется уточнить: сколько на конференции будет «академического», а сколько «индустриального»?

Виталий: Тут есть два разных сюжета. Один — это большие данные и умные данные in production. Это то, к чему привыкли люди, которые ходят на конференцию Joker, например. И из data science, когда работаешь с продакшеном каждый день, применяется не так уж много вещей: линейная регрессия, логистическая регрессия, deep learning.

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

Между тем, что нужно делать каждый день автоматически, и тем, что можно сделать однократно, существует гигантский разрыв. Нужно понимать, что это две абсолютно разных ситуации, две разные публики, и то, что сейчас постоянно делается в продакшене — это то, что было нарисёрчено 30, 40 или 50 лет назад, а может быть, и 100-200 лет назад. Но при этом то, что будет в продакшене завтра — это то, что рисёрчится сейчас.

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

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

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

JUG.ru: А какой вы видите аудиторию конференции?

Виталий: Мы её видим как реальных профессионалов, которые приходят от практики, от программирования, хотят впитать в себя культуру data science, data mining, и может быть, внедрить это у себя в компании.

Кроме того, во многих крупных компаниях есть R&D department — те люди, которые обладают куда большим объёмом знаний, чем простые разработчики, и делают что-то, что в продакшен не попадает или попадает не сразу. Например, я в Одноклассниках, по сути, в R&D department. Ко мне обычно приходят с каким-то вопросом, на который никто не знает ответ. И вот такие люди — это, безусловно, тоже наши клиенты, пусть они и окажутся в меньшинстве. Таким, может, про продакшен и не очень интересно, зато хочется послушать доклад Алексея Потапова или других известных людей в области науки, которые смотрят вперёд в анализе данных, в искусственном интеллекте.

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

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

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

Виталий: В первую очередь на технарей, безусловно. Но нужно понимать, что это всё-таки не Joker. Тут нет Шипилёва с его «щас мы наденем перчатки, залезем в кишки JVM и посмотрим, что там есть». Мы говорим о реальных кейсах использования реальных данных. У таких задач, условно говоря, есть инженерная составляющая и предметная составляющая, и мы как раз всё делаем так, чтобы доклады были более предметными.

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

JUG.ru: Роман, вас многие знают как тренера спикеров, вы на Хабре уже подробно разбирали доклады, объясняя вещи вроде «лазерные указки — зло». Раз вы участвуете в ПК SmartData и отсматриваете доклады, то, помимо содержания, следите везде и за тем, чтобы никаких лазерных указок не было?

Роман: Да, их я искореняю везде, где встречаю, ну правда же, без них лучше? Но ладно лазерные указки, есть и другие вещи. Вот я вижу, что распространился чудесный slide deck Codeware о том, как код на слайдах оформлять. Конечно же, мы постараемся, чтобы код во всех презентациях был оформлен в соответствии с этим. Ну и будем стараться, чтобы люди не забыли рассказать, какую проблему они решают, какие рекомендации они по итогам своего рассказа хотят дать зрителям, чтобы всё, что выносят на слайды, было более-менее по делу и можно было разглядеть. Вот эти вещи — да, конечно, будем стараться делать.

JUG.ru: Что будет на конференции, стало понятнее. Напоследок такой вопрос: а чего на SmartData не будет и быть не может?

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

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

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




SmartData состоится 21 октября, билеты на конференцию уже в продаже на сайте конференции (и они дорожают со временем). Её главные темы:

  • Данные и их обработка (Spark, Kafka, Storm, Flink)
  • Storages (Базы данных, NoSQL, IMDG, Hadoop, облачные хранилища)
  • Data Science (Machine learning, нейросети, анализ данных)
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334174/


Метки:  

[Перевод] Пиратство и четыре валюты

Среда, 26 Июля 2017 г. 16:52 + в цитатник

Метки:  

Откуда появился День Сисадмина и почему важно его отмечать

Среда, 26 Июля 2017 г. 16:27 + в цитатник
image

Традиционно День сисадмина празднуется в последнюю пятницу июля. Эта традиция популярна во всем мире, а в последние годы набирает обороты и в России.

Немного истории. «Отцом» данного праздника является американский системный администратор с 20-летним стажем Тед Кекатос, увидевший журнальную рекламу Hewlett-Packard, в которой установившего новые принтеры системного администратора благодарные пользователи одаривают цветами и корзинками фруктов. Кекатос, недавно установивший несколько принтеров той же модели, решил создать специальный день, посвященный профессии системного администратора. Первый такой день, устроенный Кекатосом, пришелся на пятницу 28 июля 2000 года. Это был просто пикник на природе на окраине Чикаго, в котором приняли участие члены небольшой софтверной компании. С тех пор праздник принято отмечать в последнюю пятницу июля.

2006 года начал отмечаться «Всемирный день информационного общества» (с 2007 года Всемирный день электросвязи и информационного общества), который закреплён за 17 мая. Провозглашённый Генеральной Ассамблеей ООН, этот памятный день имеет официальный статус, и, видимо, может заменить собой день системного администратора.

Тем не менее, последняя пятница июля не собирается сдавать позиции. Например, с 2006 года под Калугой ежегодно проходит Всероссийский слёт системных администраторов, с каждым годом собирающий все больше и больше участников. Так, если первый Слет посетило около 350 человек, то в 2009 году на него приехало более 4000 человек из 174 городов России, Украины, Белоруссии и Казахстана. Также проходит сбор системных администраторов в Новосибирске, который проходит на берегу Обского моря.

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

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


Ну, и по случаю вот содержимое нашего «репозитория»:
• 0,1 л — demo;
• 0,25 л — trial version;
• 0,5 л — personal edition;
• 0,7 л — professional edition;
• 1 л — network edition;
• 1,75 л — enterprise;
• 3 л — for small business;
• 5 л — corporate edition;
• Бутыль самогона — home edition;
• На посошок — service pack;
• Рассол с утра — recovery tool;
• Закуска — plugins;
• Пиво — patch;
• Coca-cola, Fanta, 7-UP — trojan viruses.

Записаться на празднование можно заполнив анкету на TimePad (DriverPack угощает!) alt=«image»/>https://driverpack.timepad.ru/event/539899/
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334188/


Метки:  

Есть ли альтернатива MS Windows, IE и CSP при доступе в личные кабинеты порталов Госзакупок, ФНС России и Госуслуг

Среда, 26 Июля 2017 г. 16:17 + в цитатник
image

И сразу дадим ответ – да, можно и нужно, только не отказаться, а дать гражданам и организациям возможность использовать и другие операционные системы, браузеры и средства криптографической защиты информации (СКЗИ). Ответим на вопрос и как – соблюдать стандарты и технологии. Почему бы для доступа в личные кабинеты не использовать авторизованный доступ по протоколу https? И тогда нет необходимости в использования только CSP а ля Микрософт с поддержкой российской криптографии. Тогда автоматом станут востребованы и токены PKCS#11 и как международный стандарт, так и стандарт, поддерживаемый ТК-26, стандарты PKCS#12 (тем же ТК-26), может что-то другое, но стандартное. В этом случае речь уже будет идти не об MS Windows, Interner Explorer и CSP, а о браузерах или других программ с поддержкой https с российскими шифрсьютами. Это может быть и Internet Explorer, и модификации того же Mozilla Firefox, наконец Google Chrome или прокси типа stunnel.

А как обстоят дела сегодня? В принципе, задел есть. Уже сегодня мы можем попасть в личный кабинет по авторизованному https с российскими шифрсьютами и на портале ФНС России и на портале Госзакупок. И для этого нам не потребуется ни MS Windows, ни Interner Explorer и даже CSP не потребуется, как это пишется в документации на этих сайтах.

Токен PKCS#11


Для демонстрации в качестве СКЗИ мы будем использовать облачный токен PKCS#11. В принципе можно использовать любой токен с поддержкой российской криптографии соответствующий стандарту PKCS#11 v.2.30, если речь идет об электронной подписи ГОСТ Р 34.10-2001 г. (напомним, что этот стандарт действует только до 31 декабря 2018 и фактически уже с 1 января 2018 года надо получать сертификаты с ключом электронной подписи по ГОСТ Р 34.10-2012, если мы хотим сэкономить свои деньги). Если используются сертификаты ключа проверки электронной подписи по ГОСТ Р 34.10-2012, то токен должен соответствовать стандарту PKCS#11 v.2.40.

Итак, наша задача показать альтернативу MS Windows. Это может быть и OS X и Linux и Android и т.д. Остановимся на Linux. В качестве браузера рассмотрим браузер Redfox, который представляет собой доработанный с учетом поддержки российской криптографии браузер Mozilla Firefox.

Первое что надо сделать, это получить в аккредитованном Минкомсвязью Удостоверяющем Центре личный сертификат на токене PKCS#11. Если какой-то УЦ не может выпускать/выдавать сертификаты на токенах PKCS#11, то тоже не страшно. Пусть выдает на CSP, но при генерации ключевой пары необходимо будет указать, что закрытый ключ экспортируемый. После этого, с помощью утилиты P12FromGostCSP сертификат и ключевую пару экспортируем в защищенный контейнер PKCS#12. Затем мы импортируем сертификат и ключи на токен, который необходимо подключить к браузеру Redfox. Убедиться в том, что у вас в руках именно токен PKCS#11 с поддержкой российской криптографии и на нем установлен ваш личный сертификат, можно воспользовавшись утилитой p11conf. Чтобы убедиться, что токен с поддержкой российской криптографии, достаточно просмотреть его механизмы (GUI для MS Windows):

image

Чтобы проверить, что на токене есть ваш сертификат и закрытый ключ достаточно посмотреть какие объекты находятся на нем (GUI для Linux ):

image

При этом также нельзя забывать об импорте корневых сертификатов УЦ в хранилище браузера.

Портал ФНС России


Личный кабинет гражданина на портале ФНС России доступен по прямой ссылке:

image

Выбрав соответствующий сертификат, гражданин окажется в своем личном кабинете:

image

При этом канал доступа в личный кабинет защищен:

image

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

Сегодня электронная подпись ставится, как правило, с помощью плагинов. И если до недавнего времени это еще имело оправдание поскольку плагины NPAPI были доступны практически для любых браузеров, то сегодня ситуация резко поменялась. Google больше года назад отказался от поддержки NPAPI и перешел для плагинов на платформу Google Native Client. Браузер Mozilla Firefox с версии 53.0 тоже отказался от поддержки плагинов NPAPI и поддерживает стандарт WebAssembly. WebAssembly — открытый стандарт, разработанный Mozilla, Google, Microsoft и Apple. Как можно заметить, эта группа представляет разработчиков четырёх наиболее распространённых браузеров, так что в перспективе все же можно рассчитывать на становление WebAssembly как всеобщего стандарта. Но это перспектива.

Именно поэтому, было бы разумно отказаться от плагинов (особенно с учетом того, что ГОСТ Р 34.10-2001 прекращает свое действие и в силу вступает ГОСТ Р 34.10-2012) и отдать на откуп гражданам самим решать где и как подписывать электронной подписью документы. А в личный кабинет они будут «приносить» уже документы в формате PKCS#7/CMS, т.е. документы с электронной подписью. Тем более, что этот формат поддерживается ТК-26 . Это более правильно и с точки зрения безопасности, чем хранить закрытый ключ, например, в ФНС России.

Единая информационная система в сфере закупок


Но идем дальше. На портале Госзакупок фактически предоставляется доступ в два различных кабинета – в личный кабинет по 44 ФЗ и в личный кабинет по 223 ФЗ:

image

Доступ в личный кабинет по 223 ФЗ осуществляется через портал госуслуг, т.е. путем предъявления сертификата. Здесь мы только отметим, что поскольку предъявлялся сертификат физического лица, который не зарегистрирован на портале госзакупок, то ему было отказано в доступе:

image

И так, мы идем в личный кабинет 44 ФЗ:

image

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

image

После нажатия кнопки «продолжить работу с сайтом» будет предложено предъявить личный сертификат:

image

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

image

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

И так, чего мы ожидаем?

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

Что это дает? Дает самое главное – гражданин не привязан ни к конкретным ОС, ни к конкретному браузеру, ни к конкретному СКЗИ. Граждане и организации теперь используют стандарты PKI, регламентируемые ТК-26, и любые сертифицированные в системе сертификации ФСБ России средства криптографической защиты информации. Вырастет компьютерная грамотность населения России, работы у ФАС России станет меньше, никто больше не будет говорить (а точнее навязывать) об использовании конкретных средств, речь будет идти только о стандартных интерфейсах и протоколах…
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334162/


Приглашаем на Tarantool Meetup 10 августа

Среда, 26 Июля 2017 г. 16:02 + в цитатник


Всем привет! 10 августа 2017 мы приглашаем архитекторов и разработчиков в московский офис Mail.Ru Group, где состоится Tarantool Meetup, посвященный архитектуре и реализации корпоративных микросервисов с использованием Tarantool. Мы поделимся с вами своими подходами к проектированию решений и покажем на примере двух простых сервисов как можно за два часа решить две типовые задачи. И традиционно будет много интересных технических дискуссий на самые разные темы! А если вы возьмете с собой ноутбук с установленным Docker, то сможете сами пощупать все своими руками. Программу читайте под катом.


17:00-17:15. Сбор гостей, welcome-кофе.

17:15-17:30. Денис Аникин. «Обзор Tarantool in-memory Data Grid».

Архитектурный обзор Tarantool как полноценного in-memory Data Grid. Этот доклад будет особенно интересен архитекторам, в нем будет рассмотрено множество архитектурных паттернов и их реального применения. Также слушатель узнает об лучших и худших практиках.

17:30-18:00. Современная архитектура Digital-микросервисов.

18:00-18:15. Перерыв.

18:15-19:45. Делаем микросервисы вместе: авторизация, банковская выписка.

19:45-20:15 Василий Сошников. «Нагружаем, проверяем».

Современная Digital-архитектура — это пять уровней. Не много ли это? Я думаю, что много и когда-то пришел к мысли, что все эти 5 уровней могут заменить всего 2 уровня. Web proxy и database proxy можно соединить в первый уровень. Application server, система кеширования и DBMS соединяются во второй уровень. Всего два уровня! Но что это дает? Меньше уровней — меньше ресурсов, меньше зависимостей, и, как бонус, — высокая производительность.

Так о чем я расскажу и чему вы научитесь? Я поделюсь опытом создания таких микросервисов, используя NGINX и DBMS Tarantool. Мы научимся их масштабировать, используя кластеризацию (шардинг или/и репликацию). Я очень рекомендую захватить ваши лаптопы, ибо будет очень много практики!

Участие в митапе бесплатное, но нужно зарегистрироваться. Адрес: Ленинградский пр-т, 39, стр. 79.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334150/


Метки:  

Конкурс по программированию: JSDash (промежуточные результаты 2)

Среда, 26 Июля 2017 г. 15:59 + в цитатник
Объявление: срок приёма решений продлевается до 17 августа.

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

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

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

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

Ещё есть время, чтобы обойти нынешних лидеров. Присылайте свои решения!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334186/


[Из песочницы] Покойся с миром, REST. Долгих лет жизни GraphQL

Среда, 26 Июля 2017 г. 14:33 + в цитатник


Перевод. Автор оригинала Samer Buna. Оригинал статьи.

Когда я впервые узнал о GraphQL после долгого использования различных REST API, то не мог удержаться от твитов такого содержания:

Rest API превратился в REST-in-Peace API. Долгих лет жизни GraphQL


Примечание переводчика – Rest In Peace, RIP – распространенная эпитафия "Покойся с миром". Первое слово в ней пишется так же, как акроним REST.

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


Поймите правильно. Я не собираюсь обвинять GraphQL в убийстве REST или чём-то таком. REST не умрет никогда, также как XML будет жить вечно. Но кто в здравом уме станет использовать XML поверх JSON? На мой взгляд, GraphQL сделает для REST то же самое, что JSON сделал для XML.


Эта статья не стопроцентная агитация в пользу GraphQL. За его гибкость приходится платить. Этому посвящен отдельный раздел.


Я поклонник подхода Начните с вопроса ЗАЧЕМ, поэтому так и поступим.


Вкратце: Зачем GraphQL?


Вот три наиболее важные проблемы, которые решает GraphQL:


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


  • Зависимость клиента от сервера. С помощью GraphQL клиент общается на универсальном языке запросов, который: 1) отменяет необходимость для сервера жестко задавать структуру или состав возвращаемых данных и 2) не привязывает клиента к конкретному серверу.


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

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


Начнем с простого описания для тех, кто еще не знаком с GraphQL.


Чем является GraphQL?


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


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


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


Уровень GraphQL, написанный на любом языке программирования, содержит схему (schema) на подобии графа или диаграммы связей, из которой клиенты узнают о возможностях сервиса. Клиентские приложения, знакомые с GraphQL, могут делать запросы по этой схеме в соответствии со своими собственными возможностями. Такой подход отделяет клиентов от сервера и позволяет им развиваться и масштабироваться независимо.


Запросы на языке GraphQL могут быть либо запросами данных – query (операция чтения), либо мутациями – mutation (операции записи). В обоих случаях запрос это обычная строка, которую GraphQL-сервис разбирает, выполняет и сопоставляет с данными в определенном формате. Распространенный формат ответа для мобильных и веб-приложений – JSON.


Чем является GraphQL? (объяснение на пальцах)


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


image


Скриншот из моего обучающего курса на Pluralsight – Building Scalable APIs with GraphQL


Вы спросите, почему клиент не может общаться с сервером напрямую? Конечно, может.


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


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


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


image


Скриншот из моего обучающего курса на Pluralsight – Building Scalable APIs with GraphQL


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


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


Но компьютеры пока не столь умны, чтобы самостоятельно отвечать на произвольные вопросы, и где-то должны существовать алгоритмы. Вот почему на уровне GraphQL необходимо задать схему (schema), которую смогут использовать клиенты.


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


Не совсем понятно? Давайте взглянем на GraphQL, как на замену REST API, чем он в действительности является. Позвольте ответить на вопрос, который вы, наверняка, сейчас задаете.


Что не так с REST API?


Большая проблема REST API в многочисленности точек назначения (endpoints). Это вынуждает клиентов делать много запросов, чтобы получить нужные данные.


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


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


Например, точка назначения для операции READ позволяет сделать одно из двух:


  • GET /ResouceName – получить список записей;
  • GET /ResourceName/ResourceID – получить запись по ID.

Клиент не может указать, например, какие поля записи хочет взять у данного ресурса. Эта информация зашита в самом REST-сервисе, и он всегда вернет все предусмотренные поля независимо от того, какие из них нужны клиенту. В GraphQL эта проблема называется перевыгрузкой (over-fetching) информации, которая не требуется. Перевыгрузка напрасно нагружает сеть и расходует память на стороне клиента и сервера.


Еще одна значимая проблема REST API – версионирование. Необходимость поддерживать несколько версий означает новые точки назначения. Это влечет дополнительные трудности в использовании и поддержке API и может стать причиной дублирования кода на сервере.


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


Что стоит за магией GraphQL?


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


  • GraphQL-схема является строго типизированной. Чтобы создать схему, задают поля (fields) определенных типов (types). Эти типы могут быть примитивами или пользовательскими типами, но все в схеме типизировано. Развитая система типов открывает такие возможности, как интроспекция API, и позволяет создавать мощные инструменты для клиентской и серверной части.


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


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

Благодаря последнему пункту я лично верю в превосходство GraphQL.


Все это высокоуровневые концепции. Рассмотрим чуть подробнее.


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


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


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


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


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


Все еще не убедил? Что если сравнить GraphQL и REST на конкретном примере?


RESTful API против GraphQL API — Пример


Допустим, разрабатывается интерфейс на тему фильма «Звездные войны» и его персонажей.


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


Звучит легко, но мы имеем дело с тремя различными ресурсами: Person, Planet и Film. Они достаточно просто взаимосвязаны, так что любой угадает структуру данных. Объект Person принадлежит планете и сам владеет от одного до нескольких объектов Film.


Данные для первого компонента выглядят так:


{
  "data": {
    "person": {
      "name": "Darth Vader",
      "birthYear": "41.9BBY",
      "planet": {
        "name": "Tatooine"
      },
      "films": [
        { "title": "A New Hope" },
        { "title": "The Empire Strikes Back" },
        { "title": "Return of the Jedi" },
        { "title": "Revenge of the Sith" }
      ]
    }
  }
}

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


// The Container Component:


// The PersonProfile Component:
Name: {person.name}
Birth Year: {person.birthYear}
Planet: {person.planet.name}
Films: {person.films.map(film => film.title)}

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


Посмотрим, как получить эти данные через RESTful API.


Сначала получим информацию о персонаже по ID. Ожидается, что RESTful API предоставляет ее так:


GET - /people/{id}

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


Ответ JSON может выглядеть так:


{
  "name": "Darth Vader",
  "birthYear": "41.9BBY",
  "planetId": 1
  "filmIds": [1, 2, 3, 6],
  *** other information we do not need ***
}

Затем получаем название планеты:


GET - /planets/1

И затем получаем названия фильмов:


GET - /films/1
GET - /films/2
GET - /films/3
GET - /films/6

И только после шести запросов мы можем собрать ответы и обеспечить компонент необходимыми данными.


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


Вы можете сами попробовать и увидеть, что я имею в виду. У Звездных войн есть RESTful API по адресу http://swapi.co/. Сконструируйте объект данных персонажа. Ключи могут называться чуть иначе, но урлы ресурсов будут те же. Вам потребуется ровно шесть запросов. Более того, вы получите избыточную информацию, не нужную для компонента.


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


GET - /people/{id}/films

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


Теперь взглянем на подход GraphQL. Сервер GraphQL по максимуму воплощает идею настраиваемой точки назначения, доводя идею до абсолюта. На сервере есть только одна точка назначения, и способ связи с ней не важен. Если обратиться по HTTP, то метод HTTP-запроса будет проигнорирован. Предположим, имеется точка назначения GraphQL, доступная на /graphql по HTTP.


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


GET or POST - /graphql?query={...}

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


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


{
  person(ID: ...) {
    name,
    birthYear,
    planet {
      name
    },
    films {
      title
    }
  }
}

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


Если ответ выглядит так:


Ближайшая к солнцу планета – Меркурий.

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


(Какая) ближайшая к солнцу планета?

Таким же сходство обладает запрос GraphQL. Если взять результирующий JSON, убрать все «ответы» (значения), то получим запрос GraphQL, подходящий на роль вопроса о данном JSON.


Теперь сравним запрос GraphQL c декларативным кодом React UI, в котором описаны данные. Все, что указано в запросе GraphQL, используется в UI, и все используемое в UI присутствует в запросе.


Это отличный способ представлять модель данных GraphQL. Интерфейс знает, какие данные нужны, и получить их не составляет труда. Оформление запроса GraphQL – это простая задача по выявлению того, что используется в качестве переменных непосредственно в UI.


Если поменять местами части этой модели, она будет так же полезна. По запросу GraphQL легко представить, как используется ответ в UI, поскольку ответ имеет такую же «структуру», как запрос. Не нужно специально изучать ответ чтобы понять, как его использовать, и даже не нужна документация по API. Все внутри запроса.


У Звездных войн имеется GraphQL API по адресу. Попробуйте с его помощью получить данные о персонаже. Есть незначительные отличия, но в целом запрос для получения необходимых данных в этом API выглядит так (с Дартом Вейдером в качестве примера):


{
  person(personID: 4) {
    name,
    birthYear,
    homeworld {
      name
    },
    filmConnection {
      films {
        title
      }
    }
  }
}

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


Плата за гибкость GraphQL


Идеальное решение – миф. Вместе с гибкостью GraphQL приходят некоторые проблемы и заботы.


Одна из угроз, которой открыт GraphQL, это сетевые атаки на исчерпание ресурсов (типа Denial of Service). Сервер GraphQL может быть атакован избыточно сложными запросами, потребляющими все ресурсы. Легко запросить данные с глубокой вложенностью (пользователь –> друзья –> друзья друзей … ) или применить синонимы полей, чтобы принудить сервер получать одни и те же данные много раз. Хотя подобные атаки происходят не только на GraphQL, при работе с GraphQL нужно иметь их в виду.


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


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


Еще один вопрос при работе с GraphQL – идентификация и авторизация пользователей. Когда выполнять ее – перед, во время или после обработки запроса на GraphQL?


Чтобы ответить на этот вопрос, будем считать, что GraphQL это DSL (domain specific language – язык предметной области) поверх обычной логики получения данных на бекенде. Действительно, это просто дополнительный уровень между клиентом и сервисом данных (или несколькими сервисами).


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


В GraphQL сложнее кешировать данные на клиенте. С RESTful API это проще, поскольку он подобен словарю. Конкретный адрес возвращает конкретные данные. Можно непосредственно использовать адрес как ключ кеширования.


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


Однако существует блестящее решение этой проблемы. Graph Query равно Graph Cache. Если нормализовать данные, которые сформировал GraphQL: превратить иерархическую структуру в плоский список записей и присвоить каждой записи уникальный идентификатор, – то можно легко кешировать записи по отдельности, вместо целого ответа.


Это не так просто реализовать. Существуют взаимозависимые записи, и приходится работать с зацикленными графами. Чтобы записать в кеш или прочитать из него, необходимо полностью разобрать запрос. Требуется дополнительный уровень логики для работы с кешем. Но этот метод намного превосходит кеширование на основе текста запроса. Фреймворк Relay.js реализует эту стратегию кеширования «из коробки».


Возможно, самая большая проблема при использовании GraphQL – так называемые N+1 SQL-запросы. В GraphQL поля запроса реализованы как обычные функции, отправляющие запросы к базе данных. Чтобы заполнить все поля данными, может потребоваться новый SQL-запрос на каждое поле.


В обычном RESTful API легко проанализировать, выявить и решить проблему N+1, просто улучшая сконструированные SQL-запросы. Но в GraphQL, который обрабатывает поля динамически, это сложнее. К счастью, Facebook одним из первых предложил решение этой проблемы – DataLoader.


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


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


...


Спасибо за внимание. Я также разработал онлайн-курсы на Pluralsight и Lynda. Самые последние курсы – Advanced React.jsAdvanced Node.js и Learning Full-stack JavaScript.


Я провожу онлайн- и офлайн-тренинги для групп по JavaScript, Node.js, React.js и GraphQL от начального до продвинутого уровня. Напишите мне, если ищете преподавателя (англ.). Если возникли вопросы по данной статье или другим моим статьям, меня можно найти в этом аккаунте слак (принимаются приглашения самому себе) и задать вопрос в комнате #questions.


Автор оригинала Samer Buna
Оригинал статьи

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

https://habrahabr.ru/post/334182/


Метки:  

IP unnumbered в Debian или раздаем адреса экономно

Среда, 26 Июля 2017 г. 13:53 + в цитатник
Когда мы получили блок IP-адресов для новой технической площадки в Варшаве, автоматически возник вопрос о том, как им распорядиться экономнее — адресов никогда не бывает много, даже у свежеиспеченного LIR.

При проектировании сети в новом месте хотелось новых плюшек:

  • В некоторой степени изолировать серверы клиентов от чужого трафика;
  • Не дать недобросовестным клиентам повесить себе на интерфейс адреса добросовестных;
  • При необходимости иметь возможность без особой нагрузки порезать трафик;
  • Иметь возможность дать клиенту любое количество IP-адресов.

Теоретически, все эти моменты решаются с помощью обычных VLAN. Однако, возникает проблема с перерасходом адресов — все же жалко клиенту, заказавшему сервер с одним адресом, отдавать сеть /30 и терять три адреса впустую. Также жалко адреса и в обратной ситуации — клиенту надо 6 доступных адресов, а в сеть /29 он уже не поместится, приходится выдавать сеть /28 и терять 7 штук.

Тут на помощь приходит технология IP unnumbered. С ее помощью можно клиенту выдать хоть один адрес, хоть 6, хоть 99. На Хабре о ней уже писали, однако, статья уже довольно старая и в чистом виде нам не подошла — с той конфигурацией isc-dhcpd не слушает клиентские интерфейсы. Нам же хотелось сделать сетевую загрузку.

Итак, на входе у нас есть:

  • Сеть большого размера, например, 99.111.222.129/25
  • Маршрутизатор на базе Linux Debian 8/9
  • Layer-2 коммутатор, например, Cisco/Juniper
  • Три клиента, которым надо выдать 1, 2 и 3 IP-адреса
  • DHCP-сервер, который должен слушать клиентские виланы

Сначала создадим технический VLAN, на котором будет большая сеть. Добавляем в /etc/network/interfaces:

# Base interface for IP Unnumbered
auto eth1.3000
iface eth1.3000 inet static
address 99.111.222.129
netmask 255.255.255.128


И поднимаем сам интерфейс:

ifup eth1.3000

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

Дальше добавляем клиентские интерфейсы в /etc/network/interfaces:

# Клиент 1
auto eth1.3111
iface eth1.3111 inet static
address 10.31.11.1
netmask 255.255.255.0
up ip ro add 99.111.222.130 dev eth1.3111 src 99.111.222.129
down ip ro del 99.111.222.130 dev eth1.3111 src 99.111.222.129

# Клиент 2
auto eth1.3112
iface eth1.3112 inet static
address 10.31.12.1
netmask 255.255.255.0
up ip ro add 99.111.222.131 dev eth1.3112 src 99.111.222.129
up ip ro add 99.111.222.132 dev eth1.3112 src 99.111.222.129
down ip ro del 99.111.222.131 dev eth1.3112 src 99.111.222.129
down ip ro del 99.111.222.132 dev eth1.3112 src 99.111.222.129

# Клиент 3
auto eth1.3113
iface eth1.3113 inet static
address 10.31.13.1
netmask 255.255.255.0
up ip ro add 99.111.222.133 dev eth1.3113 src 99.111.222.129
up ip ro add 99.111.222.134 dev eth1.3113 src 99.111.222.129
up ip ro add 99.111.222.135 dev eth1.3113 src 99.111.222.129
down ip ro del 99.111.222.133 dev eth1.3113 src 99.111.222.129
down ip ro del 99.111.222.134 dev eth1.3113 src 99.111.222.129
down ip ro del 99.111.222.135 dev eth1.3113 src 99.111.222.129


И поднимаем их:

ifup eth1.3111
ifup eth1.3112
ifup eth1.3113


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

Чтобы на клиентских интерфейсах работал isc-dhcpd, добавляем в /etc/dhcp/dhcpd.conf:

subnet 10.31.11.0 netmask 255.255.255.0 {}
subnet 10.31.12.0 netmask 255.255.255.0 {}
subnet 10.31.13.0 netmask 255.255.255.0 {}


Также, чтобы не править его каждый раз при добавлении клиента, в /etc/default/isc-dhcp-server комментируем опцию

#INTERFACES=...

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

Если клиентские машины должны друг друга видеть — добавляем в /etc/sysctl.conf:

net.ipv4.conf.all.proxy_arp=1

И применяем это на лету:

sysctl -w net.ipv4.conf.all.proxy_arp=1

Дальше осталось сконфигурировать коммутаторы.

Пример для Juniper
set vlans vlan3111 vlan-id 3111
set vlans vlan3112 vlan-id 3112
set vlans vlan3113 vlan-id 3113
set interfaces xe-0/1/0 unit 0 family ethernet-switching port-mode trunk
set interfaces xe-0/1/0 unit 0 family ethernet-switching vlan members 3111-3113
set interfaces ge-0/0/0 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/1 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/2 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members 3111
set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members 3112
set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members 3113

Здесь порт xe-0/1/0 смотрит на наш маршрутизатор, а на портах ge-0/0/0 — ge-0/0/2 живут клиенты.

Пример для Cisco
vlan 3111
name vlan3111
vlan 3112
name vlan3112
vlan 3113
name vlan3113
interface GigabitEthernet0/48
switchport mode trunk
switchport trunk allowed vlan add 3111-3113
interface GigabitEthernet0/1
switchport mode access
switchport access vlan 3111
interface GigabitEthernet0/2
switchport mode access
switchport access vlan 3112
interface GigabitEthernet0/3
switchport mode access
switchport access vlan 3113

Здесь порт GigabitEthernet0/48 смотрит на наш маршрутизатор, а на портах GigabitEthernet0/1 — GigabitEthernet0/3 живут клиенты.

Все, теперь клиент может на своем сетевом интерфейсе прописать обычные настройки вида

auto eth0
iface eth0 inet static
address 99.111.222.130
netmask 255.255.255.128
gateway 99.111.222.129

И получит только выделенные ему адреса, остальные просто не будут работать, что бы он не вешал на свой интерфейс. А мы потратили из своей сети ровно то количество адресов, которые клиент заказал.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334124/


Метки:  

[Перевод] Синглтоны и общие экземпляры

Среда, 26 Июля 2017 г. 13:51 + в цитатник


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


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


Что такое синглтон?


Синглтон — это шаблон проектирования в разработке программного обеспечения, описанный в книге Design Patterns: Elements of Reusable Object-Oriented Software (авторы — Банда четырёх), благодаря которой о шаблонах проектирования заговорили как об инструменте разработки ПО.


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


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


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


Да.


Да, может.


Но синглтоны полезны и важны!


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


Но синглтон не является верным решением для этого.


Путаница вызвана тем, что синглтон объединяет две функции (responsibilities) в одном объекте. Допустим, есть синглтон для подключения к базе данных. Давайте назовём его (очень изобретательно) DatabaseConnection. У синглтона теперь две главных функции:


  1. Управление подключением.
  2. Управление инстансами DatabaseConnection.

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


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


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


Проблемы с синглтоном


Синглтон и SOLID


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


  • Sпринцип единственной ответственности. Очевидно, что синглтон противоречит ему, как уже говорилось раньше.
  • Oпринцип открытости/закрытости: объекты должны быть открыты для расширения, но закрыты для изменения. Синглтон нарушает данный принцип, так как контролирует точку доступа и возвращает только самого себя, а не расширение.
  • Lпринцип подстановки Барбары Лисков: объекты могут быть заменены экземплярами своих подтипов без изменения использующего их кода. Это неверно в случае с синглтоном, потому что наличие нескольких разных версий объекта означает, что это уже не синглтон.
  • Iпринцип разделения интерфейса: много специализированных интерфейсов лучше, чем один универсальный. Это единственный принцип, который синглтон нарушает не напрямую, но лишь потому, что он не позволяет использовать интерфейс.
  • Dпринцип инверсии зависимостей: вы должны зависеть только от абстракций, а не от чего-то конкретного. Синглтон нарушает его, потому что в данном случае зависеть можно только от конкретного экземпляра синглтона.

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


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


Использования шаблона синглтон


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


  • Вы не можете передавать/внедрять аргументы в конструктор. Поскольку при первом вызове синглтона реально исполняется только конструктор и вы не можете знать заранее, какой код первым обратится к синглтону, то во всём потребляющем коде нужно использовать один и тот же набор аргументов для передачи в конструктор, что во многих случаях почти невыполнимо, а вначале вообще бессмысленно. В результате синглтон делает бесполезным основной механизм инстанцирования в ООП-языках.
  • Вы не можете имитировать (mock away) синглтон при тестировании компонентов, использующих его. Это делает почти невозможным корректное модульное тестирование, потому что вы не добьётесь полной изоляции тестируемого кода. Проблема вызвана даже не самой логикой, которую вы хотите тестировать, а произвольным ограничением инстанцирования, в которое вы её оборачиваете.
  • Так как синглтон — глобально доступная конструкция, которая используется всей вашей кодовой базой, то идут прахом любые усилия по инкапсуляции, отчего появляются те же проблемы, что и в случае с глобальными переменными. То есть, как бы вы ни пытались изолировать синглтон в инкапсулированной части кода, любой другой внешний код может привести к побочным эффектам и багам в синглтоне. А без надлежащей инкапсуляции выхолащиваются сами принципы ООП.
  • Если у вас когда-либо был сайт или приложение, разросшееся настолько, что синглтону DatabaseConnection неожиданно понадобилось подключение ко второй, отличной от первой базе данных, значит, вы в беде. Придётся заново пересмотреть саму архитектуру и, возможно, полностью переписать значительную часть кода.
  • Все тесты, прямо или косвенно использующие синглтон, не могут корректно переключаться с одного на другой. Они всегда сохраняют состояние посредством синглтона, что может привести к неожиданному поведению там, где ваши тесты зависят от очерёдности запуска, или оставшееся состояние скроет от вас реальные баги.
  • Своё одиночное инстанцирование синглтоны принудительно применяют к пространству текущего процесса, что подходит для статичной области видимости. Это означает появление проблем с распараллеливанием, когда у вас несколько процессов или распределённое выполнение. Это должно намекать на вероятность того, что синглтоны — всего лишь ошибочная концепция, которая ломается сразу же, как только вы начинаете работать в распределённой системе.

Альтернативы синглтону


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


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


  1. Инстанцирование App (нужны Config, Database, Controller).
  2. Инстанцирование Config для внедрения в App.
  3. Инстанцирование Database для внедрения в App.
  4. Инстанцирование Controller для внедрения в App (нужны Router, Views).
  5. Инстанцирование Router для внедрения в Controller (нужен HTTPMiddleware).

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


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

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


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


Код синглтона


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


// Синглтон.
final class DatabaseConnection {

   private static $instance;

   private function __construct() {}

   // Вызов для получения одного настоящего экземпляра.
   public static function get_instance() {
      if ( ! isset( self::$instance ) ) {
         self::$instance = new self();
      }

      return self::$instance;
   }

   // Код логики смешан с кодом механизма инстанцирования.
   public function query( ...$args ) {
      // Исполняется запрос и возвращается результат.
   }
}

// Потребляющий код.
$database = DatabaseConnection::get_instance();
$result   = $database->query( $query );

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


Фабричный метод


В большинстве случаев лучший способ уйти от проблем, связанных с синглтоном, — использовать шаблон проектирования «фабричный метод». Фабрика — это объект, чья единственная обязанность — инстанцировать другие объекты. Вместо DatabaseConnectionManager, который делает собственный экземпляр с помощью метода get_instance(), у вас есть DatabaseConnectionFactory, создающий экземпляры объекта DatabaseConnection. В общем, фабрика всегда будет производить новые экземпляры нужного объекта. Но на основании запрошенного объекта и контекста фабрика может сама решать, создавать ли новый экземпляр или всегда расшаривать какой-то один.


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


Пример фабричного метода:


// Фабрика.
final class Database {

   public function get_connection(): DatabaseConnection {
      static $connection = null;

      if ( null === $connection ) {
         // Здесь может быть произвольная логика, решающая, какую реализацию использовать.
         $connection = new MySQLDatabaseConnection();
      }

      return $connection;
   }
}

// Здесь у нас интерфейс, так что вы можете работать с несколькими реализациями и корректно имитировать (mock) ради тестирования.
interface DatabaseConnection {

   public function query( ...$args );
}

// Используемая в данный момент реализация.
final class MySQLDatabaseConnection implements DatabaseConnection {

   public function query( ...$args ) {
      // Исполняет запрос и возвращает результат.
   }
}

// Потребляющий код.
$database = ( new Database )->get_connection();
$result   = $database->query( $query );

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


Приведённая версия фабрики избавлена почти от всех ранее описанных недостатков, за одним исключением.


  • Мы убрали тесную взаимосвязь с объектом DatabaseConnection, но вместо этого создали новую, с фабрикой. Это не проблематично, потому что фабрика — чистая абстракция, вероятность того, что в какой-то момент понадобится отойти от концепции «инстанцирования», очень мала. Если это произойдёт, то, возможно, придётся пересмотреть всю парадигму ООП.

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


Статичные заместители


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


// Статичный заместитель.
final class Database {

   public static function get_connection(): DatabaseConnection {
      static $connection = null;

      if ( null === $connection ) {
         // You can have arbitrary logic in here to decide what
         // implementation to use.
         $connection = new MySQLDatabaseConnection();
      }

      return $connection;
   }

   public static function query( ...$args ) {
      // Forward call to actual implementation.
      self::get_connection()->query( ...$args );
   }
}

// Здесь у нас интерфейс, так что мы можем работать с несколькими реализациями и корректно имитировать (mock) ради тестирования.
interface DatabaseConnection {

   public function query( ...$args );
}

// Используемая в данный момент реализация.
final class MySQLDatabaseConnection implements DatabaseConnection {

   public function query( ...$args ) {
      // Исполняется запрос и возвращается результат.
   }
}

// Потребляющий код.
$result = Database::query( $query );

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


API WordPress Plugin


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


// Здесь у нас интерфейс, так что мы можем работать с несколькими реализациями и корректно имитировать (mock) ради тестирования.
interface DatabaseConnection {

   const FILTER = 'get_database_connection';

   public function query( ...$args );
}

// Используемая в данный момент реализация.
class MySQLDatabaseConnection implements DatabaseConnection {

   public function query( ...$args ) {
      // Исполняется запрос и возвращается результат.
   }
}

// Инициализирующий код.
$database = new MySQLDatabaseConnection();
add_filter( DatabaseConnection::FILTER, function () use ( $database ) {
   return $database;
} );

// Потребляющий код.
$database = apply_filters( DatabaseConnection::FILTER );
$result   = $database->query( $query );

Один из основных компромиссов состоит в том, что ваша архитектура напрямую привязана к API WordPress Plugin. Если вы планируете когда-либо предоставлять функциональность плагина для Drupal-сайтов, то код придётся полностью переписать.


Другая возможная проблема — теперь вы зависите от тайминга WordPress-перехватчиков (hooks). Это может привести к багам, связанным с таймингом, их зачастую трудно воспроизвести и исправить.


Service Locator


Локатор служб — это одна из форм контейнера инверсии управления (Inversion of Control Container). Некоторые сайты описывают метод как антишаблон. С одной стороны, это правда, но с другой, как мы уже обсуждали выше, все предложенные здесь рекомендации можно считать лишь компромиссами.


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


// Здесь у нас интерфейс контейнера, так что мы можем менять реализации локатора служб.
interface Container {

   public function has( string $key ): bool;

   public function get( string $key );
}

// Базовая реализация локатора служб.
class ServiceLocator implements Container {

   protected $services = [];

   public function has( string $key ): bool {
      return array_key_exists( $key, $this->services );
   }

   public function get( string $key ) {
      $service = $this->services[ $key ];
      if ( is_callable( $service ) ) {
         $service = $service();
      }

      return $service;
   }

   public function add( string $key, callable $service ) {
      $this->services[ $key ] = $service;
   }
}

// Здесь у нас интерфейс, так что мы можем работать с несколькими реализациями и корректно имитировать (mock) ради тестирования.
interface DatabaseConnection {

   public function query( ...$args );
}

// Используемая в данный момент реализация.
class MySQLDatabaseConnection implements DatabaseConnection {

   public function query( ...$args ) {
      // Исполняется запрос и возвращается результат.
   }
}

// Инициализирующий код.
$services = new ServiceLocator();
$services->add( 'Database', function () {
   return new MySQLDatabaseConnection();
} );

// Потребляющий код.
$result = $services->get( 'Database' )->query( $query );

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


  • С фабрикой:
    $result = ( new ServiceLocator() )->get( 'Database' )->query( $query );
  • Со статичным заместителем:
    $result = Services::get( 'Database' )->query( $query );
  • С API WordPress Plugin:
    $services = apply_filters( 'get_service_locator' );
    $result   = $services->get( 'Database' )->query( $query );

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


Но, учитывая контекст WordPress, мы должны принять тот факт, что с самого начала нам недоступно идеальное решение. Нет технических возможностей реализовать правильное внедрение зависимостей по всей кодовой базе. Это значит, что нам в любом случае придётся искать компромисс. Локатор служб — не идеальное решение, однако этот шаблон хорошо укладывается в легаси-контекст и как минимум позволяет вам собрать все «компромиссы» в одном месте, а не раскидывать их по кодовой базе.


Внедрение зависимостей


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


// Здесь у нас интерфейс, так что мы можем работать с несколькими реализациями и корректно имитировать (mock) ради тестирования.
interface DatabaseConnection {

   public function query( ...$args );
}

// Используемая в данный момент реализация.
class MySQLDatabaseConnection implements DatabaseConnection {

   public function query( ...$args ) {
      // Исполняется запрос и возвращается результат.
   }
}

// Для демонстрации идеи мы вынуждены смоделировать весь плагин.
class Plugin {

   private $database;

   public function __construct( DatabaseConnection $database ) {
      $this->database = $database;
   }

   public function run() {
      $consumer = new Consumer( $this->database );
      return $consumer->do_query();
   }
}

// Потребляющий код.
// Для демонстрации внедрения конструктора также смоделирован как целый класс.
class Consumer {

   private $database;

   public function __construct( DatabaseConnection $database ) {
      $this->database = $database;
   }

   public function do_query() {
      // А вот настоящий потребляющий код.
      // В этом месте у нас внедрено произвольное подключение к базе данных.
      return $this->database->query( $query );
   }
}

// Внедрение зависимости из загрузочного кода по всему дереву.
$database = new MySQLDatabaseConnection();
$plugin   = new Plugin( $database );
$result   = $plugin->run();

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


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


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


Вот пример того, как можно сделать это соединение с помощью такого внедрения зависимостей (даны те же классы/интерфейсы, как и в предыдущем примере):


// Позволяет внедрению узнать, какую реализацию использовать для разрешения (resolving) интерфейса DatabaseConnection.
$injector->alias( DatabaseConnection::class, MySQLDatabaseConnection::class );

// Позволяет внедрению узнать, что на запросы DatabaseConnection оно всегда должно возвращать один и тот же общий экземпляр.
$injector->share( DatabaseConnection::class );

// Позволяет внедрению инстанцировать класс Plugin, который заставит его рекурсивно обойти все конструкторы и инстанцировать объекты, чтобы решить зависимости.
$plugin = $injector->make( Plugin::class );

Комбинации


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


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


  • Каждый плагин инстанцирован с помощью централизованного автосоединяющегося внедрения зависимостей.
  • Каждый плагин — это поставщик услуг (service provider), который может регистрировать службы с помощью централизованного локатора службы.
  • Зависимости внутри плагина —> внедрение зависимостей.
  • Зависимости между плагинами —> обнаружение служб (service location).
  • Сторонние зависимости —> виртуальные службы, в которые обёрнута сторонняя функциональность.

На странице Bright Nucleus Architecture вы можете почитать об этом подходе и посмотреть записи.


Заключение


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


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


Если вы знаете ситуации, когда синглтон — единственное подходящее решение, пишите в комментариях!

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

https://habrahabr.ru/post/334078/


Developer Preview 4 уже доступна. Официальный запуск платформы Android O совсем скоро

Среда, 26 Июля 2017 г. 13:28 + в цитатник
Дейв Бёрк, вице-президент Google по инженерии

Пока мы дорабатываем платформу Android O, вы можете познакомиться с Developer Preview 4, которая поможет вам заблаговременно обновить свои приложения.

Developer Preview 4 — последняя предварительная версия перед официальным запуском платформы Android O, который состоится уже этим летом. Сейчас у вас есть возможность протестировать и опубликовать обновления (или обновленные) приложений. Так переход на Android O пройдет комфортно для пользователей.

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

Следите за информацией об официальном запуске Android O!

Что нового?

Developer Preview 4 — это предварительная версия Android O, которая позволяет обновить и протестировать ваши приложения к официальному запуску новой платформы. Developer Preview 4 уже очень близка к финальной версии: в нее включены все последние исправления и оптимизации. Тестовая система содержит в себе API 26 версии, которые были доступны еще в Developer Preview 3.

Мы представляем образы системы Developer Preview 4 для устройств, а вместе с ней и стабильную версию Android 26.0.0 Support Library. Соответствующие обновления для SDK, инструментов и образы системы Android Emulator вы увидите в ближайшие несколько дней.

Мы также хотим поделиться с вами обновленной версией Android Testing Support Library, которая включает в себя новые инструменты Android Test Orchestrator, Multiprocess Espresso и другие. Следите за новостями!

Тестируйте приложения на Android O

Образы системы Developer Preview 4 — это отличная возможность протестировать ваши приложения на версии Android O близкой к финальной. Тестирование позволит вам убедиться в том, что ваше приложение будет правильно работать после обновления до новой версии платформы.

Зарегистрируйте поддерживаемое устройство в Программе бета-тестирования Android и получите доступ к Developer Preview 4. Затем скачайте свое приложение из Google Play и протестируйте его — именно так оно будет выглядеть для обычного пользователя. Убедитесь, что интерфейс выглядит корректно, приложение быстро запускается и правильно обрабатывает изменения в поведении системы. В частности, обратите внимание на ограничения передачи данных о местоположении в фоновом режиме, оповещения, а также на изменения, которые коснулись сетевых подключений, безопасности и идентификаторов.

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

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

В Android O ярлыки можно вынести на главный экран прямо из приложения. Эта функция поможет повысить интерес пользователей к приложению. (слева)

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

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

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

Разрабатывайте быстрее с Android Studio

Когда вы будете готовы к работе с Android O, скачайте последнюю версию Android Studio 3.0, доступную здесь. Помимо улучшенных инструментов проверки производительности приложения, поддержки языка программирования Kotlin и оптимизации инструмента Gradle, Android Studio 3.0 предлагает упрощенный процесс разработки благодаря мгновенным приложениям, XML-шрифтам, скачиваемым шрифтам и адаптивным значкам.

Мы рекомендуем обновиться до стабильной версии Android Support Library 26.0.0, которая доступна в хранилище Google's Maven, а также скачать последние версии SDK, инструменты и образы системы эмулятора, которые станут доступны в ближайшие дни.

Вы можете обновить compileSdkVersion своего проекта до API 26, чтобы компиляция проходила с использованием API официальной версии Android O. Также мы рекомендуем обновить targetSdkVersion вашего приложения до API 26, чтобы получить возможность протестировать приложение с учетом изменений поведения в системе Android O. Обратитесь к руководству по миграции, чтобы узнать подробнее о том, как настроить среду разработки для программирования под Android O.

Публикация обновлений в Google Play

Google Play открыт для приложений скомпилированных или перекомпилированных под API 26. Когда вы будете готовы, загрузите обновленную альфа-, бета- или рабочую версию своего приложения.

Убедитесь, что обновленное приложение запускается как на Android O, так и на более ранних версиях Android. Советуем вам воспользоваться функцией бета-тестирования на Google Play, чтобы получить первые отзывы о вашем приложении от небольшой группы пользователей. После этого начинайте поэтапный запуск. С нетерпением ждём ваших обновленных приложений!

Как получить Developer Preview 4

Если у вас ещё нет версии для разработчиков Developer Preview 4, получить ее очень просто! Перейдите на сайт android.com/beta и зарегистрируйте подходящий телефон или планшет. Кроме того, вы можете скачать обновление и установить его вручную. Версия Android O доступна для разработчиков на устройствах Pixel, Pixel XL, Pixel C, Nexus 5X, Nexus 6P, Nexus Player и на Android Emulator. Все зарегистрированные устройства будут обновлены автоматически после выпуска официальной версии Android O.

Спасибо вам за вклад, который вы сделали на предварительной стадии. Мы ждём от вас новых отзывов и предложений!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334180/


Метки:  

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

Среда, 26 Июля 2017 г. 13:17 + в цитатник
Вопрос локализации является краеугольным камнем для множества команд разработчиков по всему миру. Особенно остро этот вопрос стоит, когда рынок продукта однозначно не определен и команда до конца не знает своего потребителя.

image

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

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

Семь раз отмерь


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

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

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

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

Важно не только снаружи, но и внутри


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

Например, Mozilla Developer Network в своем блоге рекомендует в ходе разработки обращать внимание на мелочи и в общем быть опрятными. Так, по их мнению крайне важно выбирать адекватные имена для меток (ключей) в ходе локализации и мы, исходя из опыта наших клиентов, согласны с этим утверждением. Метки, вне зависимости от степени важности и роли, «всегда должны описывать строку и ее роль в интерфейсе». Если строка привязывается к какой-то особенной функции или всплывающему окну, то метка должна отражать и эту информацию.

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

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

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

Переводчики — наше все


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

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

Банальный пример — bus, bookmark или просто слова, которые в английском имеют несколько значений исходя из контекста (fire, right, set, date и так далее, список крайне длинный). Всегда необходимо помнить, что как минимум один из участников процесса локализации (если вы привлекаете к работе носителей), говорит и пишет на неродном для себя языке. Конечно, есть специалисты, чьи способности позволяют им общаться на уровне носителей сразу на нескольких языках, но это случается крайне редко и не по карману большинству команд. Будьте терпимее к локализаторам и помните, что от того, насколько четко и однозначно вы изъясняетесь с ними, зависит, насколько качественнее будет выполнена работа.

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

https://habrahabr.ru/post/334178/


Dotty –  будущее языка Scala

Среда, 26 Июля 2017 г. 13:15 + в цитатник

Метки:  

Кубок конфедераций: что стоит за беспроблемной связью на стадионе

Среда, 26 Июля 2017 г. 11:56 + в цитатник
Выкладывая фото со стадионов в Instagram, большинство болельщиков, присутствовавших на матчах Кубка конфедерации, и не задумывались о том, что за внешне простыми услугами стоят сложнейшие технологические процессы. Тем не менее, чтобы звонок с вопросом «ты где?», фото с футбольными звездами или даже видео опасного голевого момента отправились адресату, необходима слаженная работа аппаратно-программной системы организации мобильной связи, которой совсем не просто справляться со своей задачей в условиях массовых мероприятий.
Предлагаем заглянуть за кулисы этой «магии».




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

В феврале этого года заказчик проекта — «Национальный Центр Информатизации», дочерняя компания единственного исполнителя по проекту ГК «Ростех», назначенного Минсвязи, — объявил конкурс, по результатам которого подрядчиком для развертывания телеком-инфраструктуры стала наша компания. Стоимость проекта превысила 4 млрд рублей.

О событии


Кубок конфедераций  - своеобразная «тренировка» перед чемпионатом мира по футболу 2018 года. Участники — восемь сборных стран из разных уголков Земли. При этом некоторые из них — далеко не фавориты мирового футбола, поэтому (по статистике) стадионы были заполнены совсем не на 100%. Всего 16 матчей на 4 стадионах (максимальное расстояние между которыми — более 2 тыс. км) собрали порядка полумиллиона зрителей.

Очевидно, что чемпионат мира будет гораздо более масштабным событием, однако прошедший Кубок позволил оценить степень готовности основных спортивных и инфраструктурных объектов в четырех ключевых (задействованных в нем) городах: Москве, Казани, Санкт-Петербурге и Сочи.


Почему «МегаФон»?


Надо отметить, что «МегаФон» уже не раз участвовал в подготовке крупных спортивных событий. Наша компания обеспечивала связь во время жеребьевки Кубка конфедераций в 2013 году, на Универсиаде в Казани в 2016 году, Олимпийских играх в Сочи в 2014 году, чемпионате мира по хоккею в 2016 году, а также во время ряда других крупных спортивных и политических событий. Каждый раз мы реконструировали сегмент сети, обслуживающий задействованные объекты, и прилегающую к ним инфраструктуру (магистральные каналы связи, сети в гостиницах, на транспорте и т.п.). Причем крупные спортивные мероприятия не раз становились местом тестирования новых IT-проектов — повышенный интерес зрителей к событию в данном случае играет на руку развитию технологий. Так на Олимпийских играх в Сочи в 2014 году впервые заработала сеть 4G, а в рамках тестового матча с Бельгией, предшествовавшего Кубку, весной этого года была проверена первая в России активная распределенная антенная система для футбольного стадиона вместимостью 45 тыс. зрителей.

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


Информационный экран в центре управления сетью со сводкой по спортивным объектам Кубка конфедераций. Фото: bathet.livejournal.com

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

Сам проект


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

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

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

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


Сетевое оборудование на стадионе Санкт-Петербург

Магистральные каналы


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

Конечно, все эти преобразования понадобились не только для того, чтобы болельщики со всего мира могли размещать фотографии со стадиона в Instagram. Ключевая цель — организация бесперебойного ТВ-вещания в 4K-качестве со стадионов на огромные расстояния — в Международный вещательный центр, расположившийся в Санкт-Петербурге.

Для прямых трансляций из городов-участников мы сделали магистральные волоконно-оптические линии емкостью 100 Гбит/с. Дополнительно мы организовали выделенные L2 каналы и полносвязные VPN-сети.

Беспроводная связь




В рамках реконструкции мобильного сегмента мы установили порядка 1500 новых антенн, в томи числе современные распределенные системы. Одну из них совместно с Huawei мы смонтировали на стадионе Фишт в Сочи. Там мы (впервые в мире) опробовали распределенную антенную систему на основе оборудования Single DAS 2.0 (Huawei), которая отличается низким энергопотреблением и возможностью гибкого удаленного управления и позволла нам предоставлять качественные услуги голосовой связи и передачи данных в стандартах 2G/3G/4G на максимально доступной скорости.

Еще мы установили новое оборудование, которое улучшает покрытие, в том числе внутри помещений. Работы проводились на 82 объектах — не только на стадионах, но и на тренировочных базах, на транспортных узлах, в местах продажи билетов, гостиницах и т.п. (в 3/4 этих объектов отдельно пришлось заниматься и улучшением indoor-покрытия). В труднодоступных местах использовались микро- и пикоБС (Small Cells), которые за счет малых габаритов проще в установке.

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

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



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

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

Кстати, как раз на «Санкт-Петербург Арене» была создана самая сложная и мощная система, рассчитанная на нагрузку в 80 тыс. человек (не только в чаше стадиона, но и на прилегающих территориях). Ее работоспособность обеспечивают 800 различных устройств сложения сигналов и 450 антенн. Для подключения системы было проложено порядка 40 км кабелей и смонтирована отдельная аппаратная на 250 кв.м.

Развернутая система справилась с нагрузками, несмотря на то, что во время матча с участием России (Россия — Новая Зеландия) болельщики поставили рекорд, прокачав по нашей сети 3800 Гбайт (одновременно сеть обработала 11,5 тыс. часов голосовой связи).

Трафик во время матчей бил рекорды и в других городах. Для примера — сравнение голосового и пакетного трафика на стадионе в Казани, где 18, 22 и 24 июня прошли игры Кубка:



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


Замеры скорости работы сети во время одного из матчей Кубка конфедераций

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

Мониторинг и поддержка


Весь комплекс оборудования и программного обеспечения инфраструктуры, задействованной на мероприятии «Мегафона» (а заодно и системы жизнеобеспечения каждого из объектов связи) мониторился в реальном времени при помощи собственного решения Life Control. Во время матчей отслеживалась нагрузка и качественные показатели мобильной связи в чашах стадионов. Одновременно обеспечивалась защита от Dos/DDoS-атак.

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

Еще во всех городах-участниках появились оперативные мобильные бригады, в состав которых мы постарались включить специалистов, уже успевших «понюхать пороха» во время проведения Олимпиады, саммитов ШОС и БРИКС.

Результаты



Сетевое оборудование на стадионе в Санкт-Петербурге

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

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

За три матча на стадионе «Открытие Арена» болельщиками (а их по официальным данным было чуть меньше 110 тыс. человек — причем, каждый третий был абонентом «Мегафона») было сгенерировано порядка 7 Тб данных. Если представить эти объемы более наглядно, то 7 Тб эквивалентны 8 миллионам селфи — порядка 72 снимков на каждого зрителя — или более 4 лет непрерывного эфира в социальных сетях.

В общей сложности за время проведения Кубка конфедераций на всех объектах события болельщиками было сгенерировано порядка 20 Тб данных и около 2 млн минут мобильных разговоров. При этом лидером по объему трафика был сервис Instagram. Прямые трансляции болельщики вели через YouTube и Facebook, а общались преимущественно через WatsApp.

Реконструкция сети позволила нам дополнительно провести несколько интересных проектов. Так, совместно с оператором фискальных данных OFD.ru мы создали «умные» кассы с SIM-картами «МегаФона», позволяющие болельщикам сэкономить время при покупке товаров на стадионе за счет быстрых расчетов и возможности продавца с терминалом перемещаться по объекту (то есть по сути товар пришел к болельщику — а не болельщик тратит время в очереди за товаром). Сеть работала бесперебойно, соответственно, и «умные кассы» не создавали дополнительных проблем болельщикам и продавцам.

Еще во время Кубка конфедераций мы провели «боевое» тестирование VoLTE (эту опцию с конца апреля 2017 можно бесплатно подключить на iPhone). С LTE вообще связывают большие надежды в отношении будущего чемпионата мира. Доля смартфонов с поддержкой LTE у болельщиков скорее всего увеличится, соответственно, можно будет серьезно разгрузить сеть 3G. Это позволит сохранить работоспособность сети даже в случае превышения заполнения стадионов.

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



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

Во время чемпионата мира мы такие планируем дополнительно провести тестирование стандарта 5G.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334022/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1066 1065 [1064] 1063 1062 ..
.. 1 Календарь