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

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

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

SpaceX доставит суперкомпьютер HPE на МКС. Как это ускорит миссию на Марс?

Вторник, 15 Августа 2017 г. 10:09 + в цитатник
Многие из вас вчера смотрели запуск ракеты SpaceX CRS-12 компании Илона Маска, которая отправила на МКС космический корабль Dragon. Мы смотрели его с особенным трепетом, ведь на его борту суперкомпьютер Spaceborne, созданный HPE.

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



Чем уникален Spaceborne?


Чтобы создать высокопроизводительную систему, способную на продолжительные периоды непрерывной работы, необходимо повысить устойчивость технологий перед внешними факторами. Компьютер Spaceborne, созданный в рамках текущей миссии, основывается на системах класса HPE Apollo 40 c высокоскоростной коммутационной сетью, и работает на Linux. Хотя аппаратные компоненты системы не модифицировались, компания спроектировала уникальный контейнер с водяным охлаждением, а также разработала специальное системное ПО с учетом ограничений внешней среды и повышенных требований к надежности вычислений.

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

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

«При этом космонавты не будут сисадминами», говорит доктор Энг Лим Го, Главный технический директор HPE SGI и один из руководителей эксперимента. Spaceborne Computer размещается в контейнере, которые обеспечит ему практически автономное функционирование. Он закрепляется стандартными креплениями NASA, подключается при помощи стандартных Ethernet-кабелей и 110-вольтовых блоков питания. Система будет использовать солнечную энергию для электропитания. Поскольку контейнер по сути является одним закрытым модулем, исследователям не придется просить космонавтов настраивать серверы.

Зачем в космосе суперкомпьютер?


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

Высадка на Луну 50 лет назад была под угрозой из-за компьютерной ошибки, возникшей за 8 минут до посадки. Бортовому компьютеру просто не хватило вычислительных мощностей, чтобы обработать все входящие данные. Конечно, современные смартфоны, да и, впрочем, калькуляторы или стиральные машины, уже обладают значительно более мощными вычислительными ресурсами, чем те, которыми располагало NASA в 1960-х. Однако и потребности значительно выросли.



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

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

Что дальше?


После того, как мы увидим, как себя покажет в космосе Spaceborne Computer, на следующих фазах эксперимента на МКС отправятся другие вычислительные системы, например, Memory-Driven Computing (вычисления, ориентированные на память, подробнее в нашей статье). Польза Memory-Driven Computing для проектов в космосе и миссии на Марс – в способности обрабатывать данные быстрее, чем самые мощные современные суперкомпьютеры. «Мы создаем архитектуру, которая будет очень гибкой», говорит Кирк Брезникер, главный архитектор Hewlett Packard Labs. “Какие бы новые задачи ни поступали, на них будут вычислительные мощности и достаточно памяти, чтобы не только хранить данные с каждого сенсора, но и загружать данные с предыдущих миссий”.

Дополнительные ресурсы и новости по высокопроизводительным вычислениям:
  1. Обзор суперкомпьютерного портфеля HPE: запись с конференции HPE Digitize в Москве
  2. Новости высокопроизводительных вычислений: новые системы и наши суперкомпьютеры в Топ500 и Green500


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

https://habrahabr.ru/post/335656/


[Из песочницы] Подробное руководство по созданию и развертыванию чата на Tornado + Telegram

Вторник, 15 Августа 2017 г. 10:05 + в цитатник
Данное решение подойдет для небольших проектов, так как возможность параллельно вести диалог с несколькими пользователями реализована с помощью создания нового чат-бота, то есть чем больше ботов будет, тем больше людей смогут с вами связаться в один момент времени.

Внутреннее устройство чата
image
Рис.1 UML диаграмма последовательностей

Реализация


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

Подготовка виртуального окружения


Если у вас не стоит virtualenv, то необходимо его установить:

pip install virtualenv

Создадим виртуальное окружение:

virtualenv --no-site-packages -p python3.4 chat

Активируем его:

source chat/bin/activate

Установим все необходимые библиотеки для работы нашего чата:

pip install tornado==4.4.2 psycopg2==2.7.3 pyTelegramBotAPI==2.2.3

Для опроса сервера будем использовать библиотеку для работы с telegram.

Необходимо создать следующую файловую структуру:



Создание бота


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

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

Теперь необходимо получить свой chat_id, чтобы бот знал, кому отправлять сообщения.
Для этого в приложении telegram находим своего бота, начинаем с ним взаимодействие командой /start, пишем ему какое-то сообщение и переходим по ссылке —

https://api.telegram.org/bot<токен_вашего_бота>/getUpdates

Видим примерно следующий ответ —

{"id":555455667,"first_name":"Иван","last_name":"Иванович","username":"kamrus","language_code":"ru-RU"}
id и есть ваш chat_id


Настройка postgres


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

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

sudo su - postgres

Входим в CLI postgres:

psql

Необходимо создать новую базу данных в кодировке Unicode;

CREATE DATABASE habr_chat ENCODING 'UNICODE';

Создадим нового пользователя в БД:

CREATE USER habr_user WITH PASSWORD '12345';

И отдадим ему все привилегии на базу:

GRANT ALL PRIVILEGES ON DATABASE habr_chat TO habr_user;

Подключаемся к только что созданной базе:

\c habr_chat

Создадим таблицу для хранения информации ботах, она будет иметь следующую модель:

Физическая модель

Рис.2 Физическая модель таблицы chat

CREATE TABLE chat (
	id SERIAL NOT NULL PRIMARY KEY,
	token character varying(300) NOT NULL UNIQUE,
	ready BOOLEAN NOT NULL DEFAULT True,
	last_message TEXT,
	customer_asked BOOLEAN NOT NULL DEFAULT False,
	remote_ip character varying(100)
)

И так же дадим пользователю все привилегии на таблицу:

GRANT ALL PRIVILEGES ON TABLE chat TO habr_user; 

Теперь необходимо добавить в нее токены ботов:

INSERT INTO chat (token) VALUES ('your_bot_token');

Выходим из CLI:

\q

и меняем пользователя обратно:

exit

Написание кода


Первым делом вынесем настройки для работы чата в отдельный файл.

bot_settings.py

CHAT_ID = Вставить ваш chat_id 
db = {
	'db_name': 'habr_chat',
	'user': 'habr_user',
	'password': '12345',
	'host': '',
	'port': ''
}

Основные функции будут находиться в файле core.py

from telebot import apihelper
from bot_settings import db
import psycopg2
import datetime

def get_updates(token, conn, cur, offset=None, limit=None, timeout=20):
    ''' Возвращает сообщение из телеграма '''
    json_updates = apihelper.get_updates(token, offset, limit, timeout)
    try:
        answer = json_updates[-1]['message']['text']
    except IndexError:
        answer = ''
    # если не проверять приходило ли сообщение от пользователя, то
    # функция будет просто возвращать последнее сообщение от менеджера,
    # которое в свою очередь могло предназначаться предыдущему клиенту
    if is_customer_asked(conn, cur, token):
        # необходимо проверять предыдущее сообщение, так как запрос к серверу 
        # повторяется через константное время и клиенту будет отправляться одно и тоже сообщение
        if not is_last_message(conn, cur, token, answer):
            # если сообщение прошло обе проверки то обновить это сообщение
            # в базе данных
            update_last_message(conn, cur, token, answer)
            return answer
    else:
        # если пользователь еще ничего не спросил, то необходимо все равно обновить 
        # предыдущее сообщение менеджера, на случай если предыдущии пользовватель отключится,
        # но менеджер все равно отправит сообщение
        update_last_message(conn, cur, token, answer)

def send_message(token, chat_id, text):
    '''Отправить сообщение менеджеру в телеграм'''
    apihelper.send_message(token, chat_id, text)

def connect_postgres(**kwargs):
    try:
        conn = psycopg2.connect(dbname=db['db_name'],
                                user=db['user'],
                                password=db['password'],
                                host=db['host'],
                                port=db['port'])
    except Exception as e:
        print(e, 'Ошибка при подключении к posqgres')
        raise e
    cur = conn.cursor()
    return conn, cur
    
def update_last_message(conn, cur, token, message, **kwargs):
    ''' Обновляет последнее сообщение, присланное менеджером '''
    query = "UPDATE chat SET last_message = %s WHERE token = %s"
    data = [message, token]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке обновить последнее сообщение на %s' %message)
        raise e

def add_remote_ip(conn, cur, token, ip):
    ''' Функция добавляет ip адрес пользователя '''
    query = "UPDATE chat SET remote_ip = %s WHERE token = %s"
    data = [ip, token]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке добавить ip адрес')
        raise e

def delete_remote_ip(conn, cur, token):
    ''' Удалить ip адрес у бота по переданному токену '''
    query = "UPDATE chat SET remote_ip = %s WHERE token = %s"
    data = ['', token]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке удалить ip адрес')
        raise e

def is_last_message(conn, cur, token, message, **kwargs):
    ''' Проверить является ли переданное сообщение последним сообщением менеджера '''
    query = "SELECT last_message FROM chat WHERE token = %s"
    data = [token, ]
    try:
        cur.execute(query, data)
        last_message = cur.fetchone()
        if last_message:
            if last_message[0] == message:
                return True
        return False
    except Exception as e:
        print(e, 'Ошибка при определении последнего сообщения')
        raise e

def update_customer_asked(conn, cur, token, to_value):
    ''' Обновить статус ответа клиента '''
    query = "UPDATE chat SET customer_asked = %s WHERE token = %s"
    # to_value = True/False
    data = [to_value, token]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке обновить "customer_asked" на %s' %to_value)
        raise e

def is_customer_asked(conn, cur, token):
   ''' Если клиент уже написал сообщение, то функция вернет True '''
    query = "SELECT customer_asked FROM chat WHERE token = %s"
    data = [token, ]
    try:
        cur.execute(query, data)
        customer_asked = cur.fetchone()
        return customer_asked[0]
    except Exception as e:
        print(e, "Ошибка при попытке узнать написал ли пользователь сообщение или еще нет")
        raise e

def get_bot(conn, cur):
    '''
    Функция берет из базы свободного бота, у которого ready = True.
    Возвращает (id, token, ready, last_message, customer_asked) для свободного бота
    '''
    query = "SELECT * FROM chat WHERE ready = True"
    try:
        cur.execute(query)
        bot = cur.fetchone()
        if bot:
            return bot
        else:
            return None
    except Exception as e:
         print(e, "Ошибка при попытке найти свободного бота")
        raise e

def make_bot_busy(conn, cur, token):
    ''' Меняет значение ready на False, тем самым делая бота занятым '''
    query = "UPDATE chat SET ready = False WHERE token = %s"
    data = [token,]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке изменить значение "ready" на False')
        raise e

def make_bot_free(conn, cur, token):
     ''' Меняет значение ready на False, тем самым делая бота свободным '''
    update_customer_asked(conn, cur, token, False)
    delete_remote_ip(conn, cur, token)
    query = "UPDATE chat SET ready = True WHERE token = %s"
    data = [token,]
    try:
        cur.execute(query, data)
        conn.commit()
    except Exception as e:
        print(e, 'Ошибка при попытке изменить значение "ready" на True')
        raise e

tornadino.py

import tornado.ioloop
import tornado.web
import tornado.websocket
import core
from bot_settings import CHAT_ID
import datetime

class WSHandler(tornado.websocket.WebSocketHandler):
    def __init__(self, application, request, **kwargs):
        super(WSHandler, self).__init__(application, request, **kwargs)
        # При создании нового подключения с пользователем подключимся к postgres 
        self.conn, self.cur = core.connect_postgres()
        self.get_bot(self.conn, self.cur, request.remote_ip)

    def get_bot(self, conn, cur, ip):
        while True:
            bot = core.get_bot(conn, cur)
            if bot:
                self.bot_token = bot[1]
                self.customer_asked = bot[4]
                # занять бота
                core.make_bot_busy(self.conn, self.cur, self.bot_token)  
                # добавить боту ip адрес
                core.add_remote_ip(self.conn, self.cur, self.bot_token, ip)
                break     

    def check_origin(self, origin):
        ''' Дает возможность подключаться с различных адресов '''
        return True

    def bot_callback(self):
        ''' Функция вызывается PeriodicCallback и проверяет сервер Telegram на 
            наличие новых сообщений от менеджера
        '''
        ans_telegram = core.get_updates(self.bot_token, self.conn, self.cur)
        if ans_telegram:
            # если пришло сообщение от менеджера, то отправить его в браузер клиенту
            self.write_message(ans_telegram)

    def open(self):
        ''' Функция вызываемая при открытии сокета с клиентом '''
        # Запускает опрос сервера Telegram каждые 3сек
        self.telegram_loop = tornado.ioloop.PeriodicCallback(self.bot_callback, 3000)
        self.telegram_loop.start()
    
    def on_message(self, message):
        ''' Функция вызываемая, когда по сокету приходит сообщение '''
        if not self.customer_asked:
            self.customer_asked = True
            # обновить значение в бд, что клиент задал вопрос
            core.update_customer_asked(self.conn, self.cur, self.bot_token, True)
        core.send_message(self.bot_token, CHAT_ID, message)
        
    def on_close(self):
        ''' Функция вызываемая при закрытии соединения '''
        core.send_message(self.bot_token, CHAT_ID, "Пользователь закрыл чат")
        # остановить PeriodicCallback
        self.telegram_loop.stop()
        # освободить бота
        core.make_bot_free(self.conn, self.cur, self.bot_token)

# WebSocket будет доступен по адресу ws://127.0.0.1:8080/ws
application = tornado.web.Application([
  (r'/ws', WSHandler),
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.current().start()

Теперь создадим статические файл:
chat.html
Посмотреть код


chat.css
Посмотреть код
.chatbox {
    position: fixed;
    bottom: 0;
    right: 30px;
    height: 400px;
    background-color: #fff;
    font-family: Arial, sans-serif;

    -webkit-transition: all 600ms cubic-bezier(0.19, 1, 0.22, 1);
    transition: all 600ms cubic-bezier(0.19, 1, 0.22, 1);

    display: -webkit-flex;
    display: flex;

    -webkit-flex-direction: column;
    flex-direction: column;
}

.chatbox-down {
    bottom: -350px;
}
.chatbox--closed {
    bottom: -400px;
}
.chatbox .form-control:focus {
    border-color: #1f2836;
}
.chatbox__title,
.chatbox__body {
    border-bottom: none;
}
.chatbox__title {
    min-height: 50px;
    padding-right: 10px;
    background-color: #1f2836;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
    cursor: pointer;
    display: -webkit-flex;
    display: flex;
    -webkit-align-items: center;
    align-items: center;
}
.chatbox__title h5 {
    height: 50px;
    margin: 0 0 0 15px;
    line-height: 50px;
    position: relative;
    padding-left: 20px;

    -webkit-flex-grow: 1;
    flex-grow: 1;
}
.chatbox__title h5 a {
    color: #fff;
    max-width: 195px;
    display: inline-block;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.chatbox__title h5:before {
    content: '';
    display: block;
    position: absolute;
    top: 50%;
    left: 0;
    width: 12px;
    height: 12px;
    background: #4CAF50;
    border-radius: 6px;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
}
.chatbox__title__tray,
.chatbox__title__close {
    width: 24px;
    height: 24px;
    outline: 0;
    border: none;
    background-color: transparent;
    opacity: 0.5;
    cursor: pointer;
    -webkit-transition: opacity 200ms;
    transition: opacity 200ms;
}
.chatbox__title__tray:hover,
.chatbox__title__close:hover {
    opacity: 1;
}
.chatbox__title__tray span {
    width: 12px;
    height: 12px;
    display: inline-block;
    border-bottom: 2px solid #fff
}
.chatbox__title__close svg {
    vertical-align: middle;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 1.2px;
}
.chatbox__body,
.chatbox__credentials {
    padding: 15px;
    border-top: 0;
    background-color: #f5f5f5;
    border-left: 1px solid #ddd;
    border-right: 1px solid #ddd;

    -webkit-flex-grow: 1;
    flex-grow: 1;
}
.chatbox__credentials {
    display: none;
}
.chatbox__credentials .form-control {
    -webkit-box-shadow: none;
    box-shadow: none;
}
.chatbox__body {
    overflow-y: auto;
}
.chatbox__body__message {
    position: relative;
}
.chatbox__body__message p {
    padding: 15px;
    border-radius: 4px;
    font-size: 14px;
    background-color: #fff;
    -webkit-box-shadow: 1px 1px rgba(100, 100, 100, 0.1);
    box-shadow: 1px 1px rgba(100, 100, 100, 0.1);
}
.chatbox__body__message img {
    width: 40px;
    height: 40px;
    border-radius: 4px;
    border: 2px solid #fcfcfc;
    position: absolute;
    top: 15px;
}
.chatbox__body__message--left p {
    margin-left: 15px;
    padding-left: 30px;
    text-align: left;
}
.chatbox__body__message--left img {
    left: -5px;
}
.chatbox__body__message--right p {
    margin-right: 15px;
    padding-right: 30px;
    text-align: right;
}
.chatbox__body__message--right img {
    right: -5px;
}
.chatbox__message {
    padding: 15px;
    min-height: 50px;
    outline: 0;
    resize: none;
    border: none;
    font-size: 12px;
    border: 1px solid #ddd;
    border-bottom: none;
    background-color: #fefefe;
    width: 100%;
}
.chatbox--empty {
    height: 262px;
}
.chatbox--empty.chatbox-down {
    bottom: -212px;
}
.chatbox--empty.chatbox--closed {
    bottom: -262px;
}
.chatbox--empty .chatbox__body,
.chatbox--empty .chatbox__message {
    display: none;
}
.chatbox--empty .chatbox__credentials {
    display: block;
}
.description {
	font-family: Arial, sans-serif;
	font-size: 12px; 
}
#start-ws {
    margin-top: 30px;
}
.no-visible {
    display: none;
}


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

Html код для сообщении от клиента:

Посмотреть код



Html код для сообщении от менеджера:

Посмотреть код



chat.js
Посмотреть код
(function($) {
    $(document).ready(function() {
        var $chatbox = $('.chatbox'),
            $chatboxTitle = $('.chatbox__title'),
            $chatboxTitleClose = $('.chatbox__title__close'),
            $chatboxWs = $('#start-ws');
        // Свернуть чат при нажатии на заголовок и наоборот
        $chatboxTitle.on('click', function() {
            $chatbox.toggleClass('chatbox-down');
        });
        // Закрыть чат
        $chatboxTitleClose.on('click', function(e) {
            e.stopPropagation();
            $chatbox.addClass('chatbox--closed');
            // Если на момент закрытия был открыт сокет, то 
            // следует закрыть его
            if (window.sock) {
                window.sock.close();
            }
        });
        // Подключиться к сокету
        $chatboxWs.on('click', function(e) {
            e.preventDefault();
            // сделать диалог видимым
            $chatbox.removeClass('chatbox--empty');
            // сделать кнопку начала чата невидимой
            $chatboxWs.addClass('no-visible');
            if (!("WebSocket" in window)) {
                alert("Ваш браузер не поддерживает web sockets");
            }
            else {
                alert("Начало соединения");
                setup();
            }
        });
    });
})(jQuery);

// Функция создания соединения по WebSocket
function setup(){
    var host = "ws://62.109.2.175:8084/ws";
    var socket = new WebSocket(host); 
    window.sock = socket;  
    var $txt = $("#message");
    var $btnSend = $("#sendmessage");
    // Отслеживать изменения в textarea 
    $txt.focus();
    $btnSend.on('click',function(){
        var text = $txt.val();
        if(text == ""){return}
        // отправить сообщение по сокету
        socket.send(text);
        // отобразить в дилоге сообщение
        clientRequest(text);
        $txt.val(""); 
        // $('#send')
    });
    // отслеживать нажатие enter 
    $txt.keypress(function(evt){
        // если был нажат enter
        if(evt.which == 13){
            $btnSend.click();
        }
    });

    if(socket){
        // действие на момент открытия сокета
        socket.onopen = function(){
    }
        // действие на момент получения сообщения по сокету
        socket.onmessage = function(msg){
            // отобразить сообщение в диалоге
            managerResponse(msg.data);
        }
        // действия на момент закрытия сокета
        socket.onclose = function(){
            webSocketClose("The connection has been closed.");
            window.sock = false;
        }
    }else{
        console.log("invalid socket");
    }
}
function webSocketClose(txt){
    var p = document.createElement('p');
    p.innerHTML = txt;
    document.getElementById('messages__box').appendChild(p); 
}
//функция для ответов клиента
function clientRequest(txt) {
    $("#messages__box").append("

" + txt + "

"); } // Функция для ответов менеджера function managerResponse(txt) { $("#messages__box").append("

" + txt + "

"); }


Развертывание на centos7


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

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

Настраиваем postgres


Если у вас на сервере не установлен postgres, то установить его можно так:

sudo yum install postgresql-server postgresql-devel postgresql-contrib

Запускаем postgres:

sudo postgresql-setup initdb
sudo systemctl start postgresql

Добавляем автозапуск:

sudo systemctl enable postgresql

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

Будем запускать наше tornado приложение с помощью supervisor в фоне.

Для начала установим supervisor:

sudo yum install supervisor

Теперь откроем конфигурационный файл супервизора, который будет находится в /etc/supervisor.conf

[unix_http_server]
file=/path/to/supervisor.sock ; (the path to the socket file)

[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=error ; (log level;default info; others: debug,warn,trace)
pidfile=/path/to/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root
childlogdir=/var/log/supervisord/ ; ('AUTO' child log dir, default $TEMP)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///path/to/supervisor.sock ; use a unix:// URL for a unix socket

[program:tornado-8004]
environment=PATH="/path/to/chat/bin"
command=/path/to/chat/bin/python3.4 /path/to/tornadino.py --port=8084
stopsignal=KILL
stderr_logfile=/var/log/supervisord/tornado-stderr.log
stdout_logfile=/var/log/supervisord/tornado-stdout.log

[include]
files = supervisord.d/*.ini


Не забудьте поменять пути в конфигурационном файле!

Перед тем, как запускать supervisor, необходимо создать папку /var/log/supervisord/ в ней будут собираться логи торнадо, так что, если supervisor запустил tornado-8004, но чат не работает, то ошибку стоит искать там.

Запускаем супервизор:

sudo supervisorctl start tornado-8004

Проверяем, что все в порядке:

sudo supervisorctl status

Должны получить что-то подобное:

tornado-8004 RUNNING pid 32139, uptime 0:08:10

На локальной машине вносим изменения в chat.js:

var host = "ws://адресс_вашего_сервера:8084/ws";

и открываем в браузере chat.html.

Готово!

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

https://habrahabr.ru/post/335660/


Метки:  

Что может чат-бот

Вторник, 15 Августа 2017 г. 10:04 + в цитатник
Сначала мы выделили основные офисные процессы. Про чат-бота мы даже не говорили. Вот, например, заказ командировок. Сейчас я должна написать специалисту службы деловых поездок в почту: «Я собираюсь в командировку в Сургут 5-го числа на три дня», а он: «Такой-то самолет и такая-то гостиница — всё подходит?», а я: «Да, давай». Дальше он пойдет согласовывать с руководством, забронирует сам билеты, спустя какое-то пришлёт мне подтверждение, что все Ок. Всё то же самое может делать бот.

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



Теперь давайте покажу пример чуть посложнее.




Через 3 недели:


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

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



Ещё немного магии



Разговорная речь
Боты умеют обучаться на синтаксисе пользователей. Вот простой пример того, как выглядит обращение в Help Desk через бота:



А это скриншот заявки в ITSM:



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

За несколько лет накопилось довольно много пар из словесных запросов в свободной форме и правильно заполненных форм ITSM-системы. Дальше всё просто: немного машинного обучения по этой выборке, а затем бот вместе с тикетом пользователя отправляет уже тип и подтип заявки в систему. Естественно, он может ошибаться, поэтому процесс пока поменялся незначительно — просто сотрудник хелпдеска получает уже заполненные поля (в 80% случаев правильно заполненные), но, конечно, может поменять их значения.

Администратор тоже может использовать бота в своей работе, например, для этого:



Голос


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

Интеграция с любыми процессами для многих пользователей


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


Например, чат-бот, человек или IVR — это интерфейс данных, пользовательская задача — «закажи переговорку на 15:00». Коннектор — авторизационное звено. Шина выполняет реализацию задачи.

Ещё возможности


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

Поиск по адресной книге:



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





Тут тоже всё относительно просто. Боту можно сказать «напомни мне про обед с Ивановым», и он поставит это в задачи, чтобы вовремя напомнить. Остальные данные доступны в шине.



Как всё начиналось


Всё началось с идеи выяснить, что же такое цифровая трансформация, диджитализация и т. д., а то шума на рынке много, а конкретики никакой. Для того чтобы понять, что это, мы решили начать с себя и понять, что же у нас в компании можно «диджитализировать». В ходе «копания темы» мы проработали кучу кейсов для диджитализации, нашли решения, но при этом нам не давала покоя идея «правильного» интерфейса для офисных бизнес-процессов. Про чат-бота мы даже не говорили, в принципе даже не обсуждалось. В какой-то момент поняли, что и подход к взаимодействию c офисными бизнес-процессами тоже надо менять, всё должно быть удобным и обязательно мобильным, и так как 100 мобильных приложений не сделать, то стало понятно, что будущее за естественными интерфейсами, в частности чатами. В частности, есть невероятный китайский пример WeChat — изначально аналога ICQ, который теперь стал и соцсетью, и торговой площадкой, и доской объявлений, и электронной почтой, и вообще всем.

Ещё боты могут рассказывать базовые вещи из базы знаний корпоративного обучения, искать учебные материалы, показать ближайшие внутренние курсы и семинары, играть в список ачивок с новичками («Получил свои канцтовары», «Нашёл кухню», «Зачекинился в спортзале» и так далее), забронировать комнату отдыха или встать в очередь к игровой консоли там же, получить пароль для гостевого Wi-Fi, узнать номер ДМС, поликлиники по нему, телефон скорой, сообщить офисной медслужбе о травме, записаться к офисной медслужбе, забронировать тренажёр, сообщить о потерянной или найденной вещи (бот потом коннектит людей или скидывает лог секретарю), отправить корпоративные новости, дать разную информацию новым сотрудникам, как жить, предупредить про дни рождения ваших контактов. В дальних планах — проверить длину очереди в столовой по видеоаналитике (обычно от 1 до 15 минут, сейчас это реализовано отдельным информером у нас в офисе), узнать меню на сегодня в столовой или заказать пиццу в офис, найти попутчиков, передать документы. От технической службы в планах — заменить корпоративную SIM-карту, сменить тариф, принять багрепорты на любые вещи вроде «тут на пятом этаже лампа не горит», отправить багрепорт в хозяйственную службу или уборщицам.

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

Про авторизацию же история долгая и богатая на приключения, поэтому если интересно — расскажу отдельно. Ну, и если есть вопросы не для комментариев — пишите: digital@croc.ru.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335650/


Зачем бэкап? У нас же RAID

Вторник, 15 Августа 2017 г. 10:02 + в цитатник


В корпоративные блоги принято писать success story — это положительно влияет на образ компании. К сожалению, не всегда в работе инженера всё заканчивается happy end-ом.
Надо сказать, что коллеги уже начинают подшучивать, что я «притягиваю» проблемы. Тем или иным образом я поучаствовал почти во всех проблемных заявках за последнее время. И теперь хочу рассказать одну поучительную историю из своей практики.

История началась с того, что меня попросили проанализировать производительность дискового массива IBM Storwize v7000 gen1, «тормоза» которого парализовали работу целого филиала. Исходная ситуация такая:

  • На массиве находятся датасторы VMware-фермы.
  • Все тома располагаются на RAID5 (диски 7200 и 10000) и зеркалируются между двумя идентичными массивами.
  • Контракта с IBM на поддержку этого оборудования нет.
  • Версия прошивки массива — 7.3.0.4 (актуальная на тот момент 7.6.1.1).
  • Также СХД IBM Storwize используется для виртуализации СХД HP EVA.

Согласно логам производительности массива, «тормоза» возникали не из-за повышенной нагрузки. Я заподозрил, что причиной проблем является вышедший из строя контроллер на виртуализованной СХД HP EVA. Обычно проблемы с производительностью решаются удалённо, но в данном случае решили отправить инженера на место (тогда ещё никто не подозревал, что командировка затянется на две недели).

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

И тут начинается просто фейерверк проблем.

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



Для полного счастья, прошивки двух серверов из трёх и коммутаторов (блейд-шасси) отстают от прошивки модуля управления шасси, что тоже может приводить к самым неожиданным проблемам. Ну и вишенка на торте: на коммутаторах SAN стоят разные версии прошивок, и все позапрошлой мажорной версии (6.x.x, когда доступна 8.0.x).

Напоследок выясняется, что в MS SQL Server Express закончилось свободное место, из-за чего возник «полтергейст» с доступностью консолей VM в vSphere и неверно отображались размеры томов. Так что пока администраторы решали проблемы БД, мы пытались разобраться с СХД.

После некоторых действий основной том вдруг ушёл в оффлайн.

Мы вспоминили про баг в прошивках Storwize версий 7.3, 7.4 и 7.5, из-за которого на сжатых томах после определённого количества обращений могут появиться битые блоки (в этой ситуации не может помочь ни отказоустойвость RAID, ни зеркалирование томов на соседний массив, так как ошибка находится уровнем выше).

И вот тут проявился самый интересный нюанс: оказывается, что СРК у заказчика не работает уже 3 месяца. То есть бэкапы есть, но они не актуальные, и восстанавливаться из них — всё равно, что потерять данные.

Нам удалось перевести том в онлайн (через CLI массива), но при первой же попытке хоста что-то записать, он снова упал. Мы отключили все датасторы на серверах и следующие сутки провели в офисе, почти не дыша копируя все виртуальные машины куда получится — на серверы, USB-диски и ПК.

В результате нам удалось спасти все данные, кроме ВМ, на которой запустили консолидацию снапшотов, так как в процессе консолидации LUN ушёл в оффлайн, и вместо данных ВМ осталась «каша». По закону подлости это оказалась ВМ электронного документооборота. Кроме того, для исключения разных рисков пришлось обновить почти всю инфраструктуру — VMware, Brocade, HP Blade, IBM Storwize.

Предпосылки катастрофы


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

  1. СХД была спроектирована некорректно. Один том на ~12 Тб не будет нормально работать ни на одной классической СХД. Всегда разбивайте общую ёмкость на тома порядка 1-2 Тб. Да, будет меньше полезной ёмкости, но зато будет гораздо меньше шансов открыть заявку «у нас всё тормозит».
  2. Прошивки никогда не обновлялись. Это не единственная история, когда баг в старой прошивке приводил к простоям или потере данных. Да, в новых прошивках тоже есть баги, но вас никто не принуждает пользоваться bleeding edge. Используйте стабильные, рекомендованные версии.
  3. Бэкапы. Сколько было просьб и рекомендаций делать и проверять бэкапы — не счесть. Повторяться не хочется, но ВСЕГДА ДЕЛАЙТЕ И СВОЕВРЕМЕННО ПРОВЕРЯЙТЕ БЭКАП. В этой истории можно было сократить время простоя не менее, чем в два раза, если бы СРК поддерживалась в рабочем состоянии.



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

Спасибо за внимание, работы вам без сбоев.

Алексей Трифонов Tomatos, инженер Сервисного центра компании «Инфосистемы Джет».
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335618/


Метки:  

Визуализация данных Московской Биржи с помощью InterSystems DeepSee. Часть I

Вторник, 15 Августа 2017 г. 09:49 + в цитатник

Введение


В стеке технологий InterSystems есть технология для разработки аналитических решений DeepSee. Это встраиваемая аналитическая технология и набор инструментов для создания систем поддержки принятия эффективных решений, в том числе, и с применением прогнозных моделей. DeepSee работает со структурированными и неструктурированными данными. Она предназначена для создания OLAP-решений для баз данных Cach'e и любых реляционных СУБД. InterSystems DeepSee предоставляет разработчикам средства для внедрения в свои приложения аналитической OLAP-функциональности, которая способна работать на оперативных базах данных приложений без создания отдельной инфраструктуры для решения аналитических задач.


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


Этапы


  • Получение данных
  • ETL
  • Построение куба
  • Построение сводной таблицы
  • Построение дашборда
  • Визуализация

Получение данных


Для визуализации данных о котировках акций необходимо их сначала загрузить. У Московской Биржи есть публичное задокументированное API, которое предоставляет информацию о торговле акциями в форматах HTML, XML, JSON, CSV.
Вот, к примеру, XML данные за 27 мая 2013 года. Создадим XML-Enabled класс Ticker.Data в платформе InterSystems:


Ticker.Data
Class Ticker.Data Extends (%Persistent, %XML.Adaptor)
{

/// Дата торгов
Property Date As %Date(FORMAT = 3, XMLNAME = "TRADEDATE", XMLPROJECTION = "attribute");

/// Краткое название компании
Property Name As %String(XMLNAME = "SHORTNAME", XMLPROJECTION = "attribute");

/// Тикер
Property Ticker As %String(XMLNAME = "SECID", XMLPROJECTION = "attribute");

/// Количество сделок
Property Trades As %Integer(XMLNAME = "NUMTRADES", XMLPROJECTION = "attribute");

/// Общая сумма сделок
Property Value As %Decimal(XMLNAME = "VALUE", XMLPROJECTION = "attribute");

/// Цена открытия
Property Open As %Decimal(XMLNAME = "OPEN", XMLPROJECTION = "attribute");

/// Цена закрытия
Property Close As %Decimal(XMLNAME = "CLOSE", XMLPROJECTION = "attribute");

/// Цена закрытия официальная
Property CloseLegal As %Decimal(XMLNAME = "LEGALCLOSEPRICE", XMLPROJECTION = "attribute");

/// Минимальная цена акции
Property Low As %Decimal(XMLNAME = "LOW", XMLPROJECTION = "attribute");

/// Максимальная цена акции
Property High As %Decimal(XMLNAME = "HIGH", XMLPROJECTION = "attribute");

/// Средневзвешенная цена акции http://www.moex.com/s1194
/// Может считаться как за день так и не за период.
Property Average As %Decimal(XMLNAME = "WAPRICE", XMLPROJECTION = "attribute");

/// Количество акций участвовавших в сделках
Property Volume As %Integer(XMLNAME = "VOLUME", XMLPROJECTION = "attribute");

}

И напишем загрузчик данных в формате XML. Так как класс у нас XML-Enabled то конвертация из XML в объекты класса Ticker.Data происходит автоматически. Аналогичного поведения можно достичь для данных в форматах JSON (через динамические объекты) и CSV (используя %SQL.Util.Procedures). Так как API отдаёт данные за определённую дату (день) то нам надо итерировать по дням и сохранять поступающие данные. Кроме того данные о котировках акций приходят страницами по 100 записей. Загрузчик может выглядеть так:


Загрузчик данных
/// Загрузить информацию об акциях начиная с From и заканчивая To. Purge - удалить все записи перед началом загрузки
/// Формат From, To - YYYY-MM-DD
/// Write $System.Status.GetErrorText(##class(Ticker.Loader).Populate())
ClassMethod Populate(From As %Date(DISPLAY=3) = "2013-03-25", To As %Date(DISPLAY=3) = {$ZDate($Horolog,3)}, Purge As %Boolean = {$$$YES})
{
    #Dim Status As %Status = $$$OK
    // Переводим даты во внутренний формат для простоты итерации
    Set FromH = $ZDateH(From, 3)
    Set ToH = $ZDateH(To, 3)

    Do:Purge ..Purge()

    For DateH = FromH:1:ToH {
        Write $c(13), "Populating ", $ZDate(DateH, 3)
        Set Status = ..PopulateDay(DateH)
        Quit:$$$ISERR(Status)
    }

    Quit Status
}

/// Загрузить данные за день. Данные загружаются страницами по 100 записей. 
/// Write $System.Status.GetErrorText(##class(Ticker.Loader).PopulateDay($Horolog))
ClassMethod PopulateDay(DateH As %Date) As %Status
{
    #Dim Status As %Status = $$$OK

    Set Reader = ##class(%XML.Reader).%New()
    Set Date = $ZDate(DateH, 3) // Преобразовать дату из внутреннего формата в YYYY-MM-DD
    Set Count = 0 // Число загруженных записей

    While Count '= $G(CountOld) {
        Set CountOld = Count
        Set Status = Reader.OpenURL(..GetURL(Date, Count)) // Получаем следующую страницу данных
        Quit:$$$ISERR(Status)

        // Устанавливаем соответствие нода row == объект класса Ticker.Data 
        Do Reader.Correlate("row", "Ticker.Data")

        // Десериализуем каждую ноду row в объект класса Ticker.Data
        While Reader.Next(.Object, .Status) {
            #Dim Object As Ticker.Data

            // Сохраняем объект
            If Object.Ticker '="" {
                Set Status = Object.%Save()
                Quit:$$$ISERR(Status)
                Set Count = Count + 1
            }
        }
        Quit:(Count-CountOld)<100 // На текущей странице меньше 100 записей => эта страница - последняя
    }
    Quit Status
}

/// Получить URL с информацией о котировках акций за дату Date, пропустить первые Start записей
ClassMethod GetURL(Date, Start As %Integer = 0) [ CodeMode = expression ]
{
$$$FormatText("http://iss.moex.com/iss/history/engines/stock/markets/shares/boards/tqbr/securities.xml?date=%1&start=%2", Date, Start)
}

Теперь загрузим данные командой: Write $System.Status.GetErrorText(##class(Ticker.Loader).Populate())


Весь код доступен в репозитории.


ETL


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


Таблица фактов для куба обычно является результатом работы аналитиков и разработчиков по процессу, который называется ETL (extract, transform, load). Т.е. из данных предметной области делается “выжимка” необходимых для анализа данных, и переносится в удобную для хранилища структуру "звезда"/"снежинка": факты и справочники фактов.
В нашем случае этап ETL пропустим т.к. наш класс Ticker.Data уже находятся во вполне удобном для создания куба состоянии.


Построение куба


DeepSee Architect — это веб-приложение для создания OLAP-куба. Для перехода к DeepSee Architect откроем Портал Управления Системой -> DeepSee -> Выбор области -> Architect. Открывается рабочее окно Архитектора.


Возможно нужно будет выбрать область, которая поддерживает DeepSee. В том случае если вы не видите вашей области в списке областей DeepSee перейдите в Портал Управления Системой -> Меню -> Управление веб-приложениями -> /csp/область, и там в поле Включен поставьте галочку DeepSee и нажмите кнопку сохранить. После этого выбранная область должна появиться в списке областей DeepSee.


Создаем новый куб.


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


  • Имя куба — название куба используемое в запросах к нему
  • Отображаемое Имя — локализуемое название куба (перевод осуществляется стандартными механизмами InterSystems)
  • Источник Cube — использовать таблицу фактов или другой куб в качестве источника данных
  • Исходный класс — если на предыдущем шаге был выбран класс, то указываем в качестве таблицы фактов класс Ticker.Data.
  • Имя класса для куба — имя класса, в котором будет храниться определение куба. Создаётся автоматически
  • Описание класса — произвольное описание

Вот как выглядит наш новый куб:


Создание куба


Определяем свойства куба


После нажатия кнопки OK будет создан новый куб:


Новый куб


Слева выводятся свойства базового и связанных с ним по “снежинке” классов, которые можно использовать при построении куба.
Центральная часть экрана — это скелет куба. Его можно наполнить свойствами класса с помощью drag-n-drop из области базового класса, либо добавляя элементы вручную. Основными элементами куба являются измерения, показатели и списки.


Измерения (Dimensions)


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


Для разбиения фактов по тикерам прекрасно подойдет свойство Ticker.
Перетянем Ticker на область измерений — в результате Архитектор добавит в куб измерение Ticker с одной иерархией H1 и одним уровнем Ticker. Укажем отображаемые названия в подписях к измерению и уровню.


Измерение


Измерения помимо группировки позволяют строить иерархии вложенности фактов от общего к частному. Типичным примером является измерение по дате, которое обычно часто требуется представить в виде иерархии Год-Месяц-День.
Для свойств типа дата(например как у свойства Date тип %Date) в DeepSee есть специальный тип измерения time, в котором уже предусмотрены часто используемые функции для создания иерархий по дате. Воспользуемся этим и построим трехуровневую иерархию Год-месяц-день с помощью свойства Date.


Измерение 2


Заметим, что в измерении есть элементы: собственно измерение, иерархия и уровни этой иерархии (Level). Любое измерение куба состоит как минимум из одной иерархии в котором в простейшем случае всего один уровень.


Показатели (Measures)


Показатели или метрики это такие элементы куба, куда относят какие-либо "количественные" данные, которые необходимо посчитать для "качественных" измерений куба (Dimensions).
Например в таблице фактов такими показателями могут быть свойства Volume (количество акций) и Average (Средняя цена). Перетянем свойство Volume на область показателей и создадим показатель "Количество" с функцией SUM, которая будет считать общее количество акций в текущем срезе.
Добавим также в показатели свойство Average и укажем в качестве функции расчета MAX — расчет максимального значения. С целью использования цены для визуализации изменения максимальной цены акции во времени.


Показатели


Списки (Listings)


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


Теперь зададим поля таблицы фактов, которые надо выводить. Например выведем информацию о тикерах и колебаних их цены за день (Name, Ticker, "Open", CloseLegal, Low, Average, High):


Листинг 2


Компиляция куба


Итак мы добавили в куб два показателя, два измерения и один листинг — этого вполне достаточно и уже можно посмотреть, что получилось.
Скомпилируем класс куба (Кнопка "Компилировать"). Если ошибок компиляции нет, значит куб создан правильно и можно наполнить его данными.
Для этого нужно нажать "Построить куб" — в результате DeepSee загрузит данные из таблицы фактов в хранилище данных куба.
Для работы с данными куба нам пригодится другое веб-приложение — DeepSee Analyzer.


Построение сводной таблицы (Pivot)


DeepSee Analyzer — визуальное средство для непосредственного анализа данных кубов и подготовки источников данных для дальнейшей визуализации. Для перехода к DeepSee Analyzer откроем Портал Управления Системой -> DeepSee -> Выбор области -> Analyzer. Открывается рабочее окно Аналайзера.
Analyzer
В рабочем окне Аналайзера слева мы видим элементы созданного куба: показатели и измерения. Комбинируя их мы строим запросы к кубу на языке MDX — аналоге языка SQL для многомерных OLAP кубов.
Рассмотрим интерфейс Аналайзера. Справа — поле сводной таблицы. В поле сводной таблицы Аналайзера всегда показывается результат выполнения MDX-запроса. Посмотреть текущий MDX-запрос можно если нажать кнопку Source. При первом открытии куба в поле сводной таблицы по умолчанию показывается количество записей в таблице фактов — в нашем случае это количество записей в классе Ticker.Data. Этому соответствует MDX: SELECT FROM [TICKER].


Чтобы создать сводную таблицу перетянем в поле колонок измерение “Год”. Показателем выберем "Объём". В результате получим таблицу количества проданных акций по годам.
Pivot 1
Далее перетянем измерение “Тикер” в поле колонок и получим уже сводную таблицу количества акций по инструментам, с разбиением по годам:
Pivot 2


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


Pivot 3


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


Pivot 4


На предыдущем этапе мы создали листинг — инструмент перехода от агрегированных данных к исходным фактам. Выберем любую строку сводной таблицы и нажмём кнопку Drillthrough для перехода к листингу:
Drillthrough 2


Следующий этап — визуализация. Перед сохранением упростим сводную таблицу и сохраним её под именем TickersByYears.
Pivot 5


Построение дашборда (Dashboard)


Портал Пользователя — это веб-приложение для создания и использования дашбордов (панелей индикаторов). Дашборды содержат виждеты: таблицы, графики и карты на основе сводных таблиц, созданных аналитиками в Аналайзере.
Для перехода к Порталу Пользователя DeepSee откроем Портал Управления Системой -> DeepSee -> Выбор области -> Портал Пользователя.
Portal
Создадим новый дашборд нажав на стрелку справа -> добавить -> Добавить индикаторную панель
Portal2


Создадим виджет нажав на стрелку справа -> Виджеты -> "+" -> Линейная диаграмма с маркерами. В качестве источника данных выберем TickersByYears:
Widget


Однако читатель возразит — это же средняя температура по больнице. И будет прав. Добавим фильтрацию по инструменту. Для этого нажмём стрелку справа -> Виджеты -> Виджет 1 -> Элементы управления -> "+". Форма создания нового фильтра выглядит следующим образом:
Filter


А вот так выглядит наш виджет с фильтром. Пользователь может изменить значение фильтра на любое другое.
Widget 2


После этого сохраним дашборд.


Установка MDX2JSON и DeepSeeWeb


Для визуализации созданного дашборда можно использовать следующие OpenSource решения:


  • MDX2JSON — REST API предоставляет информацию о кубах, пивотах, дашбордах и многих других элементах DeepSee, в частности — результатах исполнения MDX запросов, что позволяет встраивать пользовательский интерфейс аналитического решения на DeepSee в любое современное Web или мобильное приложение.
  • DeepSeeWeb — AngularJS приложение, предоставляющее альтернативную реализацию портала пользователя DeepSee. Может быть легко кастомизирован. Использует MDX2JSON в качестве бэкэнда. Вот пример дашборда визуализированного в DeepSeeWeb:

DeepSeeWeb


Установка MDX2JSON


Для установки MDX2JSON надо:


  1. Загрузить Installer.xml и импортировать его в любую область с помощью Studio, Портала Управления Системой или Do $System.OBJ.Load(file).
  2. Выполнить в терминале (пользователем с ролью %ALL): Do ##class(MDX2JSON.Installer).setup()

Для проверки установки надо открыть в браузере страницу http://server:port/MDX2JSON/Test?Debug. Возможно потребуется ввести логин и пароль (в зависимости от настроек безопасности сервера). Должна открыться страница с информацией о сервере. В случае получения ошибки, можно почитать на Readme и Wiki.


Установка DeepSeeWeb


Для установки DeepSeeWeb надо:


  1. Загрузить установщик и импортировать его в любую область с помощью Studio, Портала Управления Системой или Do $System.OBJ.Load(file).
  2. Выполнить в терминале (пользователем с ролью %ALL): Do ##class(DSW.Installer).setup()

Для проверки установки надо открыть в браузере страницу http://server:port/dsw/index.html. Должна открыться станица авторизации. В области SAMPLES представлено множество уже готовых дашбордов и все они автоматически отображаются в DeepSeeWeb.


Визуализация


Откроем http://server:port/dsw/index.html и авторизируемся, также нужно указать область с кубом. Откроется список дашбордов, в нашем случае есть только один созданный дашборд "Акции". Откроем его:


DSW


Отображается наш созданный виджет. Для него поддерживается Drilldown и фильтр созданный в Портале Пользователя DeepSee:


DSW 2


Выводы


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


Ссылки


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

https://habrahabr.ru/post/335586/


Метки:  

ЦОД: этапы большой жизни

Вторник, 15 Августа 2017 г. 09:31 + в цитатник
Cегодня мы решили обратить внимание на тему «жизненного цикла» центров обработки данных, рассказать о том, что это такое и как правильное управление им позволяет компаниям сократить не только текущие, но и капитальные затраты. Учитывая современные тенденции к внедрению все новых решений (включая гиперконвергентные системы) и сервисов, значительные трудности в этом процессе могут быть связаны с изменением и адаптацией физической инфраструктуры дата-центров.

Жизненный цикл ЦОДа включает в себя поэтапный процесс развития инженерной инфраструктуры в соответствии с задачами бизнеса и ИТ-процессами и может быть разделен на несколько этапов:

1. Подготовительный: понимание целей создания, формирование концепции решения, выбор площадки;
2. Проектирование в соответствии с выбранной концепцией и характеристиками площадки;
3. Строительство;
4. Эксплуатация;
5. Оценка соответствия и анализ эффективности.




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




Проектирование и строительство


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

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

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

1. Проектирование ЦОДа как офиса, в то время как это промышленный объект;
2. Ошибки в резервировании систем, компонентов, коммуникаций;
3. Ошибки в расчете размера выделяемой площади под инженерные системы и вспомогательные помещения, с оценкой веса оборудования и его габаритов, с обеспечением автономности объекта.

Важным является понимание ключевых метрик ЦОДа, перспектив его развития, так как инженерные системы должны «пережить» 2-3 поколения ИТ-оборудования. Службу эксплуатации редко вовлекают в проект на этапе строительства. Между тем специалисты по электроснабжению и системам охлаждения должны привлекаться еще на этапе проектных работ и присутствовать в рабочих группах.


Эксплуатация

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

В ИТ-отделе могут быть и свои, внутренние проблемы. Когда разные ИТ-подразделения отвечают за разные компоненты (серверы, СХД, сетевое оборудование, системы охлаждения и пр.) и при этом не имеют четких регламентов и разделения зон ответственности, на площадке возникает хаос.



В этом случае проще «переехать» на новую площадку, чем проводить глубокую модернизацию старой, и уже потом переделывать имеющийся ЦОД, не нарушая работы функционирующих на новом месте ИТ-сервисов. Еще один вариант – на время «капремонта» арендовать площади в коммерческом ЦОДе. Оптимальное решение выбирается в каждом конкретном случае.
В современных ЦОДах за непрерывную и эффективную работу инфраструктуре, как правило, отвечает отдельная команда специалистов. Для автоматизации мониторинга, управления, ведения отчётности, управления перемещениями и контроля эффективности используют инструменты, которые принято обозначать аббревиатурой DCIM (Data Center Infrastructure Management).



Задачи мониторинга событий, состояния оборудования и среды зачастую решаются в первую очередь – для этого применяются такие средства, как контроллеры NetBotz и система мониторинга Data Center Expert. Но сейчас наиболее актуальными становятся задачи эффективного использования ресурсов — от электроэнергии до пространства в машинных залах. Своевременное внедрение эффективных регламентов и контроль использования электроэнергии позволяет не только снизить весьма значительные эксплуатационные затраты и вернуть инвестиции раньше, но и планировать новые приобретения или строительство с учётом оценки реальной, а не «бумажной» эффективности оборудования. В качестве платформы для организации такого подхода можно использовать Data Center Operation – модульное решение с набором всех необходимых функций.



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


Оценка и оптимизация

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

Различные улучшения, такие как построение систем изоляции воздушных коридоров, реорганизация плит фальшпола, устранение в стойках мест с неправильной циркуляцией воздушных потоков с последующей перенастройкой систем кондиционирования, позволяет сократить энергопотребление ЦОДа в реальных проектах на 10-20%. Окупается такая оптимизация (если брать в расчет только энергопотребление) за 3-3,5 года.

Еще один эффект оптимизации – улучшение работы систем охлаждения, когда эффективнее используется установленное ранее оборудование, к примеру, становится возможной установка в стойку большего числа серверов. «Коэффициент полезного использования ЦОДа» можно довести с 70-75% до 90-95%. Такая оптимизация окупается примерно за полгода.

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

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

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

Во многих проектах работа ведется на стыке этапов эксплуатации и оценки. Сегодня у многих заказчиков появляются новые ИТ-задачи, идет информатизация, цифровизация бизнеса, приходится решать различные эксплуатационные проблемы. Справиться с ними помогает помощь экспертов на этапе оценки и проведение аудита ЦОДа. Созданный Schneider Electric в России Региональный центр разработки приложений (Regional Application Center) занимается комплексными решениями для дата-центров. Его основная задача – создание и поддержка устойчивого и эффективного функционирования ЦОДа на всех этапах его жизненного цикла.

Специалисты Schneider Electric принимают участие в проектировании, строительстве, комплексных испытаниях и вводе объектов в эксплуатацию, в последующей поддержке и модернизации дата-центра. На каждом этапе заказчику обеспечивается отказоустойчивость и эффективность работы ЦОДа. При росте масштабов и скорости цифровых технологий предлагаемые нами решения помогут компаниям, провайдерам облачных, телекоммуникационных сервисов и коммерческих площадок смотреть в будущее с уверенностью.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335654/


Метки:  

[Перевод] Kubernetes на голом железе за 10 минут

Вторник, 15 Августа 2017 г. 09:00 + в цитатник


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


По ходу этой статьи мы установим Kubernetes 1.6 на реальную (не виртуальную) машину под управлением Ubuntu 16.04 примерно за 10 минут. В результате у вас появится возможность начать изучать взаимодействие с Kubernetes посредством его CLI kubectl.

Обзор Kubernetes:



Компоненты Kubernetes, автор Julia Evans


Что нам понадобится


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

Зайдите на Packet.net и создайте новый проект. Для целей этой статьи нам хватит хоста Type 0 (4 ядра Atom и 8GB RAM за 0,05$/час).


При настройке хоста не забудьте выбрать в качестве ОС Ubuntu 16.04. В отличие от Docker Swarm Kubernetes лучше работает с проверенными временем релизами Docker. К счастью, репозиторий Ubuntu apt содержит Docker 1.12.6.


  • Установите Docker.

$ apt-get update && apt-get install -qy docker.io

Не обновляйте Docker на этом хосте. Использовать более свежие версии для сборки образов можно в инструментарии CI или на ноутбуке.

Установка


  • Установите apt-репозиторий Kubernetes.

$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
OK

$ cat </etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main  
EOF

Теперь обновите список пакетов командой apt-get update.


  • Установите kubelet, kubeadm и kubernetes-cni.

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


CNI расшифровывается как Container Networking Interface и представляет из себя спецификацию, определяющую взаимодействие сетевых драйверов с Kubernetes.

$ apt-get update
$ apt-get install -y kubelet kubeadm kubernetes-cni

  • Инициализируйте кластер с помощью kubeadm.

Из документации:


kubeadm предназначен для создания сразу «из коробки» безопасного кластера с помощью таких механизмов, как RBAC.

В Docker Swarm по умолчанию есть драйвер оверлейной сети, но с kubeadm решение остается за нами. Команда все еще работает над обновлением инструкций, поэтому я покажу, как использовать драйвер, наиболее похожий на докеровский, — flannel от CoreOS.


Flannel


Flannel позволяет организовать программно определяемую сеть (Software Defined Network, SDN), используя для этого модули ядра Linux overlay и ipvlan.


В Packet машина подключается к двум сетям: первая — это сеть дата-центра, которая соединяет хосты, входящие в определенный регион и проект, а вторая — это выход в Интернет. Брандмауэр по умолчанию не настроен, поэтому при желании ограничить сетевую активность придется настроить iptables или ufw вручную.


Внутренний IP-адрес можно выяснить с помощью ifconfig:


root@kubeadm:~# ifconfig bond0:0  
bond0:0   Link encap:Ethernet  HWaddr 0c:c4:7a:e5:48:d4  
          inet addr:10.80.75.9  Bcast:255.255.255.255  Mask:255.255.255.254
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1

Воспользуемся этим внутренним IP-адресом для трансляции Kubernetes API.


$ kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.80.75.9 --skip-preflight-checks --kubernetes-version stable-1.6

  • --pod-network-cidr необходим драйверу flannel и определяет адресное пространство для контейнеров.
  • --apiserver-advertise-address определяет IP-адрес, который Kubernetes будет афишировать в качестве своего API-сервера.
  • --skip-preflight-checks позволяет kubeadm не проверять ядро хоста на наличие требуемых функций. Это нужно из-за отсутствия метаданных ядра на хостах Packet.
  • --kubernetes-version stable-1.6 жестко определяет версию кластера (в данном случае 1.6); при желании использовать, например, Kubernetes 1.7 пропустите этот флаг.

Вот что мы должны получить на выходе:


[init] Using Kubernetes version: v1.6.6
[init] Using Authorization mode: RBAC
[preflight] Skipping pre-flight checks
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [kubeadm kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.80.75.9]
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing key and public key.
[certificates] Generated front-proxy CA certificate and key.
[certificates] Generated front-proxy client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 36.795038 seconds
[apiclient] Waiting for at least one node to register
[apiclient] First node has registered after 3.508700 seconds
[token] Using token: 02d204.3998037a42ac8108
[apiconfig] Created RBAC rules
[addons] Created essential addon: kube-proxy
[addons] Created essential addon: kube-dns

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run (as a regular user):

  sudo cp /etc/kubernetes/admin.conf $HOME/
  sudo chown $(id -u):$(id -g) $HOME/admin.conf
  export KUBECONFIG=$HOME/admin.conf

You should now deploy a pod network to the cluster.  
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:  
  http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node  
as root:

  kubeadm join --token 02d204.3998037a42ac8108 10.80.75.9:6443

  • Создайте непривилегированного пользователя.

В установке Ubuntu от Packet нет обычного пользователя, поэтому давайте создадим его.


# useradd packet -G sudo -m -s /bin/bash
# passwd packet

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

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


Войдите под учетной записью нового пользователя: sudo su packet.


$ cd $HOME
$ sudo whoami

$ sudo cp /etc/kubernetes/admin.conf $HOME/
$ sudo chown $(id -u):$(id -g) $HOME/admin.conf
$ export KUBECONFIG=$HOME/admin.conf

$ echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc

  • Примените конфигурацию сети для подов (flannel).

Теперь с помощью kubectl и двух записей из документации flannel мы применим к кластеру конфигурацию сети:


$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel-rbac.yml
clusterrole "flannel" created  
clusterrolebinding "flannel" created

$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

serviceaccount "flannel" created  
configmap "kube-flannel-cfg" created  
daemonset "kube-flannel-ds" created 

Сеть для подов сконфигурирована.


  • Разрешите использование однохостового (single-host) кластера.

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


$ kubectl taint nodes --all node-role.kubernetes.io/master-

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

  • Проверьте работоспособность кластера.

Многие компоненты Kubernetes выполняются в виде контейнеров кластера в скрытом пространстве имен kube-system. Вывести информацию о них можно следующим образом:


$ kubectl get all --namespace=kube-system

NAME                                 READY     STATUS    RESTARTS   AGE  
po/etcd-kubeadm                      1/1       Running   0          12m  
po/kube-apiserver-kubeadm            1/1       Running   0          12m  
po/kube-controller-manager-kubeadm   1/1       Running   0          13m  
po/kube-dns-692378583-kqvdd          3/3       Running   0          13m  
po/kube-flannel-ds-w9xvp             2/2       Running   0          1m  
po/kube-proxy-4vgwp                  1/1       Running   0          13m  
po/kube-scheduler-kubeadm            1/1       Running   0          13m

NAME           CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE  
svc/kube-dns   10.96.0.10           53/UDP,53/TCP   14m

NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE  
deploy/kube-dns   1         1         1            1           14m

NAME                    DESIRED   CURRENT   READY     AGE  
rs/kube-dns-692378583   1         1         1         13m 

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


Запустите контейнер


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


Проверьте, что сейчас у вас нет запущенных подов (контейнеров):


$ kubectl get pods

Теперь с помощью kubectl run запустите контейнер. Мы развернем Node.js- и Express.js-микросервис, генерирующий идентификаторы GUID по HTTP.


Этот код был изначально написан для руководства по Docker Swarm. Соответствующие исходники можно найти по этой ссылке: Scale a real microservice with Docker 1.12 Swarm Mode

$ kubectl run guids --image=alexellis2/guid-service:latest --port 9000
deployment "guids" created  

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


$ kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE  
guids-2617315942-lzwdh   0/1       Pending   0          11s  

Используйте Name для проверки состояния пода:


$ kubectl describe pod guids-2617315942-lzwdh
...
Pulling            pulling image "alexellis2/guid-service:latest"  
...

Раз у нас есть работающей контейнер, можно взять его IP-адрес и получать сгенерированные идентификаторы с помощью curl:


$ kubectl describe pod guids-2617315942-lzwdh | grep IP:
IP:        10.244.0.3

$ curl http://10.244.0.3:9000/guid ; echo
{"guid":"4659819e-cf00-4b45-99d1a9f81bdcf6ae","container":"guids-2617315942-lzwdh"}

$ curl http://10.244.0.3:9000/guid ; echo
{"guid":"1604b4cb-88d2-49e2-bd38-73b589da0469","container":"guids-2617315942-lzwdh"}

Для просмотра логов пода можно использовать следующую команду:


$ kubectl logs guids-2617315942-lzwdh
listening on port 9000  

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


$ kubectl exec -t -i guids-2617315942-lzwdh sh
/ # head -n3 /etc/os-release
NAME="Alpine Linux"  
ID=alpine  
VERSION_ID=3.5.2  
/ # exit

  • Панель инструментов (Dashboard).

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


$ kubectl create -f https://git.io/kube-dashboard
$ kubectl proxy
Starting to serve on 127.0.0.1:8001  

Теперь создадим туннель на хост Packet и откроем в веб-браузере страницу http://localhost:8001/ui/.


$ ssh -L 8001:127.0.0.1:8001 -N



Более подробную информацию можно получить здесь: Dashboard check it out on Github.


Подведем итоги


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


  • Учитесь на примерах.

Руководство Kubernetes by Example, созданное Michael Hausenblas, показалось мне детальным и доступным.


  • Добавьте больше нод.

Состоящий из одной ноды кластер у нас теперь есть, можно начинать добавлять еще ноды Type 0, используя join token, полученный от kubeadm.


  • Сравните с Docker Swarm.

Docker Swarm — это встроенный в Docker CE и EE инструмент оркестровки. Кластер Docker Swarm может быть поднят одной командой. Более подробную информацию можно почерпнуть из моих уроков по Docker Swarm.


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


Спасибо @mhausenblas, @_errm и @kubernetesonarm за обратную связь и советы по настройке кластера Kubernetes.


Ссылки:


  1. Оригинал: Kubernetes on bare-metal in 10 minutes.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334846/


Метки:  

Возвращение в строй маршрутизатора Cisco с нерабочей CF или mini-flash картой

Вторник, 15 Августа 2017 г. 04:12 + в цитатник
Как-то электрикам потребовалось провести плановые работы с отключением оборудования организации. По плану на ночь сотрудники выключают оборудование, электрики ночью работают, а утром сотрудники всё включают и радуются. Вечером отключили сервера, сетевое оборудование и ИБП. Утром всё включили и начали спокойно работать ровно до того момента, пока не поняли, что не поднялось подключение к сети интернет, а следовательно сайт организации снаружи недоступен.
image
(Cisco 1800 series)

Почему вспомнил
Вспомнил об этом случае из-за того, что похожая ситуация произошла на днях с тестовым маршрутизатором Cisco 871-K9.
image
(в этой модели модуль памяти mini-flash cisco слева внизу)

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

Выкручивать маршрутизатор из серверного шкафа не хотелось, поэтому бросили 15-20 метров витой пары от серверной до нашего кабинета в качестве удлинителя для консольного провода.
Проверяем
Берём пару патчкордов, консольный кабель cisco и соединяем всё это добро парой переходников.
image
(длина двух патчкордов с переходником ~18.3м)
Работает.

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

Сначала попробовали залить прошивку через xmodem, но скорости нас не впечатлили настолько, что сразу перешли к загрузке прошивки через tftp. На компьютере в сети был поставлен tftpd и файл прошивки маршрутизатора (в данном примере пусть адрес этого компьютера будет 192.168.1.2). На маршрутизаторе через консоль дали следующие команды:

IP_ADDRESS=192.168.1.200
IP_SUBNET_MASK=255.255.255.0
DEFAULT_GATEWAY=192.168.1.1
TFTP_SERVER=192.168.1.2
TFTP_FILE=c870-advipservicesk9-mz.124-24.T8.bin

(в названии файла прошивки я указал прошивку нашего тестового маршрутизатора, т.к. проверял всё на нём)

И даём команду tftpdnld -r (ключ -r важен в том случае, если карта памяти не работает или её унесли какие-то несознательные типы, т.к. позволяет нам загрузить файл прошивки сразу в оперативную память маршрутизатора минуя карту памяти).

Если и файл стартовой конфигурации (startup-config) был на той же карте памяти, то следующим шагом заливаем сохранённую у нас конфигурацию через tftp. Или настраиваем маршрутизатор заново из консоли.

Router#copy tftp: running-config
(на всякий случай отмечу, что Router# — это уже приглашение IOS, т.к. система должна была загрузиться)
Нам предложат указать адрес хоста tftp, имя файла источника и подтвердить имя файла назначения.

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

https://habrahabr.ru/post/335648/


Метки:  

Система управления складом с использованием CQRS и Event Sourcing. Service Layer

Вторник, 15 Августа 2017 г. 00:03 + в цитатник

Тестируем новый механизм синхронизации настроек JetBrains IDEs

Понедельник, 14 Августа 2017 г. 21:23 + в цитатник
Привет, Хабр!

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

До сих пор эту проблему частично решал встроенный плагин Settings Repository. Для того, чтобы, плагин синхронизировал настройки, необходимо самостоятельно создать Git репозиторий (на GitHub или другом сервисе) и указать его в IDE.

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

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

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

Что такое JetBrains Account

JetBrains Account можно использовать для управления лицензиями, доступа к форумам, блогам JetBrains и репозиторию плагинов. Подробнее о том как работает JetBrains Account можно узнать здесь (на английском).

Доступ к плагину

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

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

Если у вас нет приглашения, вы можете попросить его отправив письмо на idea-cloudconfig@jetbrains.com. При этом, письмо должно быть отправлено с почтового ящика, привязанного к вашему JetBrains Account.

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

Ограничения плагина на данный момент

Плагин доступен только для платных продуктов (IntelliJ IDEA Ultimate, PhpStorm, PyCharm, CLion, RubyMine, Rider, и т.п.)
Плагин пока не работает вместе с License Server (мы работаем над этим).

Чтобы плагин заработал, необходимо

1. Получить письмо с приглашением



2. Установить плагин

3. Авторизоваться в IDE (или Toolbox App) с помощью JetBrains Account



4. Включить синхронизацию



5. Отправить приглашение хорошему другу



Обратная связь

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

Я и авторы плагина будем рады ответить на вопросы.

Программируйте с удовольствием!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335646/


Метки:  

[Из песочницы] Стоимость недвижимости на тепловых картах

Понедельник, 14 Августа 2017 г. 19:47 + в цитатник

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


Тепловая карта цен Москвы


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


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


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


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


Инструменты


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


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


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



Есть один белорусский сайт где с помощью данного способа реализована карта цен. Можно посмотреть здесь.


Карта цен resta.by


Глядя на эту карту кто может сказать, где дороже, а где дешевле? Я не могу. В общем такое… три из десяти.


Поиски продолжились, и я нагуглил в итоге на стэке вот что: человек задает именно тот вопрос который интересовал меня, а именно, как сделать тепловую карту а не карту интенсивности. И в ответах есть ссылка на JS-библиотеку которая делает то что надо. Для расчетов используется Inverse Distance Weighting. JS — это конечно не шарп, но уже ближе, так что я был очень рад. Особенно после того как “пощупал” все это на jsfiddle и убедился в годности результата. Через несколько часов у меня уже был работающий код на C# (который впоследствии был сильно доработан). Вот ссылка на Гитхаб, если кому надо.


Данные


За время работы портала у меня накопилось более 20 миллионов объектов по всей России (архивные объекты сохраняются навсегда).


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


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


Я так и не смог определиться с оптимальным шагом для компоновки объектов в исходную точку на карте. Пробовал разные варианты от 100 метров до 5 км. Решил оставить на усмотрение пользователей три наиболее интересных варианта: 250, 500 и 1000 метров.


Точки генерируются следующим образом: область рекурсивно делится на 4 прямоугольные секции до тех пор пока размер секции не будет совпадать или чуть-чуть превышать минимальный, либо до тех пор пока в области не останется объектов меньше чем минимально-допустимое количество (например 3). Для секций в которых меньше трех объектов итоговая точка не создается — они искажают общую картину и создают излишнюю “дырявость”, так как часто такие одинокие объекты отличаются по цене от окружающих.


Heat Map points


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


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


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


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


Тайлы


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


Теперь чтобы отобразить все на карте надо привязать их к соответствующим координатам. Первое что я нашел в поиске — Ground Overlays.


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


Стал гуглить дальше и нашел Tile Overlays — это оказалось в итоге то что нужно. Суть такова: для каждого из уровней приближения карты (zoom index) итоговое изображение компонуется из плиток 256 на 256 пикселей, для каждой из которых можно наложить поверх свое изображение. При навигации по карте подгружаются только те тайлы которые попадают в видимую область и соответствуют значению zoom index.


Границы регионов


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


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


Москва:


Moscow Area


Санкт-Петербург:


SPB Area


Для рисования границ и получения их координат я использовал чей-то готовый код в codepen.io с небольшими изменениями. Вот ссылка для Москвы и Питера. После изменения какой-нибудь из точек на карте в окошко снизу вставляется список географических координат в виде удобном для вставки в БД.


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


Kamenny island


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


Решение было такое: выделить некоторые секции и при компоновке объектов, попавшие в секцию объекты не должны смешиваться с объектами непопавшими, либо попавшими в другую секцию. Для Питера я выделил также острова.


SPB separated areas


Точность тут не важна. Главное — чтобы не было пересечений между областями.


Выбор цветов


Я сделал настраиваемым процесс генерации тепловой карты так чтобы можно было выбирать цвета, настраивать количество уровней, и т.д.
Например для области в 500 на 500 пикселей с установленными 6 точками со значениями от -100 до 100 можно получить такие варианты.


Тестовые точки со значениями:


TestPoints


Те же данные на карте с уровнями:


MapWithTestPoints


Без ограничения по цветам и с разбивкой по уровням:



С ограничением по цветами и без уровней:



С заданными вручную цветами:



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


Результат при шаге в 500 метров выглядит так:


500m Map


Производительность


Чтобы сгенерировать карту только для Москвы при параллельных 6 потоках (на восьмиядерном сервере 3,2 GHz) требовалось более суток. Это совсем неприемлемо, потому что в перспективе регионов будет больше и запуск должен происходить по расписанию, как минимум раз в неделю.


Узкое место в алгоритме — высчитывание цвета для каждого пикселя в тайле. Нужно отсортировать все точки по расстоянию от данного пикселя. То есть массив из 6000 точек приходилось сортировать 256х256 раз. Бессмысленная трата ресурсов. Очевидно, что все точки не нужны, и можно ограничиться ближайшими. Самое простое решение взять, например топ 100 точек отсортированных по расстоянию от центра тайла. Но тут может быть ситуация когда ближайшие 100 точек находятся в группе, например с одной только стороны. Т.е. нужны не просто 100 ближайших, а так чтобы они еще и были расположены вокруг. Вот что я сделал: из середины тайла во все стороны с шагом в 10 градусов распространяются лучи каждый длиной в треть всей карты. Каждый луч растет до тех пор пока в нем не будет как минимум 5 точек, либо он не достигнет предела по длине. Таким образом, гарантированно в итоговом списке будет примерно 150 точек со всех сторон.


Выглядит это так (зеленые точки — которые попали в выборку, красные — все остальные. Красный квадратик в середине — это непосредственно тайл):


Bicycle


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


Выглядят они так:



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


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


Скорость работы выросла в разы. На Москву уходит около 3 часов, из них около часа только на обработку данных, остальное непосредственно на рисование.


Просмотр объектов


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


Display points


Заключение


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


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


Ссылки


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


Ссылки из поста

https://habrahabr.ru/post/324596/
https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap
https://resta.by/karta-cen
https://stackoverflow.com/questions/30073977/create-custom-temperature-map-with-front-end-javascript
https://github.com/optimisme/javascript-temperatureMap
https://en.wikipedia.org/wiki/Inverse_distance_weighting
https://jsfiddle.net/mertk/y9gcuf65/
https://github.com/d-sky/HeatMap
https://developers.google.com/maps/documentation/javascript/maptypes?hl=ru#MapCoordinates
https://developers.google.com/maps/documentation/javascript/examples/map-coordinates
https://developers.google.com/maps/documentation/javascript/examples/groundoverlay-simple
https://developers.google.com/maps/documentation/android-api/tileoverlay
https://codepen.io/d-sky/pen/JJqpYe
https://codepen.io/d-sky/pen/PKJzoO
https://www.ventusky.com/?p=9;71;1&l=temperature
https://квартиры-домики.рф/карта-цен


PS


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

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

https://habrahabr.ru/post/335638/


Метки:  

[Из песочницы] Размещение иконок на странице сайта. Делать проще, поддерживать легче

Понедельник, 14 Августа 2017 г. 17:33 + в цитатник
Все должно быть изложено так просто, как только возможно, но не проще.
А. Эйнштейн

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

HTML

menu

CSS

.bl_button__wrapp{
  width: 100%;
  margin: 5% auto;
  font-size: 30px;
  line-height: 34px;
  color: blue
}
.bl_button{
  position: relative;
  width: 150px;
  padding: 10px;
  margin: 0 auto;
  text-align: center;
  border: 1px solid #00f;
  cursor:pointer;
}

.fa-bars{
  position: absolute;
  left: 10px;
  font-size: 34px;
}
.bl_button__text{
  display: inline-block;
}


See the Pen bad button by Andry Zirka (@BlackStar1991) on CodePen.

Это стандартная форма описания кнопки. Я сам долгое время примерно так писал свой код. Данное написание особо практикуется теми, кто использует готовые иконочные шрифты на подобии FontAwesome
Небольшие трудности возникают если текст должен быть по центру, а иконка несколько смещена относительно текста. Но всё это прекрасно решаемо через свойство position:absolute; задаваемое иконке. Также бывают проблемы с позиционированием данной иконки при адаптивности кнопки, но это другая история.

Теперь я хотел бы описать свой метод оформления иконок в тексте страници (на примере всё того же FontAwesome).

HTML



CSS

.button_menu{
  width: 280px;
  margin-top: 5%;
  margin-left: 4%;

  font-size: 4em;
  color: blue;
  border: 1px solid #00f;
  
  outline:none; /* Убираем если вас это смущает по дизайну*/
  background:none;  /* Убираем если вас это смущает по дизайну*/
}

.button_menu__text{
  position:relative;
  width: 100%;
  display: inline-block;
  text-align: center;
  margin: 0 auto;
  padding: 10px;
}
.button_icon__menu:before{
  content: "\f0c9";
  font-family: FontAwesome;
  position: absolute;
  left: 0px;
  top: 14px;
}

See the Pen good button by Andry Zirka (@BlackStar1991) on CodePen.



Преимущества такого описания.

1) Кода стало меньше. (Это существенно облегчит вам жизнь на масштабных проектах).

2) Код стал семантически более верным. Если div(или любой другой тег) функционально у Вас выполняет назначение кнопки, то и делайте его через тег button *Иначе возможны проблемы, особенно с Apple устройствами для которых придется прописывать type=«button» для вашего не правильного тега.

3) span размещенный внутри button всегда выравнивается по центру. (*Можно сменить ему display: если вам важны внутренне отступы).

4) Как вы могли заметить, вся суть моего оформления в том что я выношу изображение иконки через псевдо класс :before (:after) и позиционирую его абсолютно. При этом у его родителя span установлен position:relative; (! Важно, чтобы для иконки присваивался отдельный класс).

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

6) Иконки, оформленные таким образом легко менять, особенно если вы используете препроцессоры (SASS, SCSS, LESS...), просто добавь нужный класс к нужному элементу.

Недостатки такого описания: (а куда же без них).

1) При использовании тега button довольно часто приходится сбрасывать или переопределять стили, иначе выглядит не очень.

outline:none; 
 background:none; 
 border:none; 

2) Для каждого родительского (span) допустимо одновременно отображать только две иконки, собственно на псевдокласс :before и :after.

3) Если вы, как и я, довольно часто в своих работах используете FontAwesome, вам чаще придется посещать их официальный сайт, что бы выучить Unicode каждой иконки



Это несколько сложнее чем просто прописать классы fa fa-bars. Здесь есть и полный список иконок

4) Поскольку я в написании своего CSS стараюсь придерживаться методологии, то у меня для родительского элемента может быть и довольно много классов



Но если вас не пугает 4-5 классов для элемента, тогда Welcome.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335632/


Метки:  

Emercoin снизит комиссии на транзакции в 100 раз

Понедельник, 14 Августа 2017 г. 17:28 + в цитатник


Блокчейн-платформа Эмер с собственной криптовалютой Emercoin снизит комиссии на транзакции и создание записей в блокчейне в 100 раз. Функциональная ценность монеты EMC увеличится стократно.

В настоящее время в сети Emer действует фиксированный размер комиссии на транзакции на уровне 0,01 EMC. По текущему курсу Emercoin это составляет $0,01 или около 60 копеек.
После сокращения комиссия на транзакции упадет до 0,0001 доллара или до 0,6 копеек (0,0001 EMC), а стоимость создания произвольных записей в блокчейне Emer составит 0,0005 EMC вместо прежних 0,05 EMC

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

Чтобы начать работать с Emercoin, выберете кошелек для вашей ОС ( Windows, Linux или Mac), так же доступен TestNet Emercoin`a монеты которого бесплатны и доступны любому.

Как это будет осуществлено технически?

По общим правилам, характерным для криптовалют:

  1. Будет предложен новый клиент Emercoin со сниженной комиссией.
  2. При достижении 95% консенсуса участников сети (950 блоков из 1000 последних), сеть перейдет на новые правила.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335630/


Метки:  

Ой, у меня задержка

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

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

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

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



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

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

Формирование задержки



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

  1. с сенсора камеры снимается изображение в видеопамять
  2. видео энкодер кладет сырое изображение в буфер кодирования
  3. алгоритм сжатия видео находит оптимальный способ компрессии нескольких видео кадров в буфере
  4. сжатый видеокадр отправляется в серверный буфер доставки видео (если такой есть)
  5. видеокадр передается по UDP или копируется в ядерный буфер TCP для отправки
  6. байты долетают до клиента и складываются в ядерный буфер приемки сетевых данных
  7. доходят до клиента
  8. возможно складываются в буфер сортировки кадров
  9. оттуда складываются при необходимости в буфер компенсации флуктуации скорости сети
  10. из него отправляются в декодер, который накапливает свой буфер для b-frames
  11. декодер декодирует кадр и отправляет его на отрисовку


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

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

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

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

Детали



Снятие с сенсора



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

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

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

Точную оценку по задержке здесь дать не готов.

Буфер кодирования



Энкодер занимается крайне ресурсоёмкой задачей, а так же жутко нагружает шину передачи данных между памятью и процессором. Ему надо перебрать разные комбинации вариантов сжатия видео, найти разницу между соседними кадрами и сделать кучу сложных математических вычислений. Учитывая, что FullHD видео на 25 кадрах в секунду — это порядка гигабита в секунду (100 мегабайт), нагрузка огромная. Но просьба не совершать классическую ошибку и не путать нагрузку на процессор с задержкой. Время, которое уходит на сжатие кадра всё равно меньше 1/fps (иначе уже можно не дергаться, всё равно ничего не получится), а задержку энкодер создает гораздо больше.

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

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


С этой задержкой можно играть, но прежде всего это будет приведет к росту битрейта. Есть хороший пост на покинувшем нас сайте от автора libx264 о low latency кодировании. Вот это оно.

Итого, здесь можно справиться за 1-2 кадра (по 40 мс каждый), а можно и потратить до 3-5 секунд, но сэкономить битрейт.

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

Буфер на сервере



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

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

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

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

Т.е. здесь всё напрямую зависит от протокола: если у нас на сервере HLS или DASH, то буферизация хотя бы сегмента (1-10 секунд) неизбежна. Если покадровый протокол, то не нужно, смело можно рассылать кадры всем клиентам по одному, но всё равно так делают редко.

Если мы получаем откуда-то например RTP (с камер RTSP/RTP), то теоретически можем раздавать клиентам сразу RTP пакеты по их получению. Это даст чумовое снижение задержки меньше одного фрейма. На практике этот подход реализуется редко, потому что создает огромную сложность программирования и резко сужает вариативность использования софта. Чаще всего видеостриминговые серверы работают с кадрами, очищенными от контейнеров и протоколов.

Здесь есть маленькая деталь: существует инициатива CMAF low latency. Суть идеи в том, что когда приходит опорный кадр (он же keyframe), то сервер анонсирует новый сегмент всем клиентам. Все клиенты срочно начинают его скачивать и тут они получают кадр за кадром через http progressive download.

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

Это пока инициатива и в разработке, но может стать интересным.

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

Сетевой буфер на отправку



Мы подошли к самой мякотке, камню преткновения и бесконечных метаний видеодоставки: UDP или TCP? Потери или непредсказуемые задержки? Или может совместить?

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

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

Увеличиваем ядерные буферы и быстро теряем контроль за скоростью скачивания — становится тяжело контролировать отправку кадров и на сервере становится непонятно: клиент скачивает видео или уже нет.

Если шлем по UDP, то надо решать, чего делать с потерей пакетов. Есть вариант с повторной пересылкой UDP пакетов (эдакий недо-TCP), но он требует буферизации на клиенте (см ниже). Есть вариант с организацией чего-то типа RAID-5 поверх сети: в каждый udp пакет кладется избыточность, позволяющая восстановить один пакет из, скажем, 5 (см FEC, Fountain Codes и т.п.). Это может требовать роста задержки на сервере для вычисления такой избыточности, а так же поднимает битрейт на 10-30%. Считается, что избыточность не требует экстра буфера на клиенте, или по крайней мере он будет 1-2 кадра, но не 5 секунд (125 кадров)

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

Вернемся в реальный мир.

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

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

R-UDP по факту сложен, замещает собой TCP, используется редко и хорошо применим там, где подойдет и HLS с его 30 секундами задержки. Есть опасность ввязаться в перереализацию TCP, что можно считать практически нерешимой задачей.

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

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


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

Доставка до клиента



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

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

Эта часть может как уложиться в 10 мс, так и растянуться на 300 мс (на таком RTT вообще сложно добиться приличной скорости).

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

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

Продолжение следует. В следующей публикации рассмотрим что происходит у клиента.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335208/


Метки:  

[recovery mode] Вызов управляемого кода из неуправляемого

Понедельник, 14 Августа 2017 г. 16:14 + в цитатник
image С задачей вызова неуправляемого кода из управляемого мы сталкиваемся довольно часто, и эта задача имеет простое решение в виде одного атрибута [DllImport] и небольшого набора дополнительных правил, которые хорошо изложены в MSDN. Обратная же задача встречается гораздо реже. В данной статье мы и рассмотрим небольшой пример, как это можно сделать. Его не стоит рассматривать как исчерпывающий, скорее лишь, как направление хода мыслей и концепцию. Итак, начнем.


Наш пример будет состоять из трех проектов:
  1. MixedLibrary — C++/CLI
  2. SimpleLibrary — C#
  3. Win32App — C++

image

Начнем с самого простого — SimpleLibrary. Эта библиотека содержит один простой сервис, который складывает два числа и выводит результат в консоль:

public class Service
    {
        public void Add(Int32 a, Int32 b)
        {
            Console.WriteLine("Hello from Managed Code!");
            Console.WriteLine(String.Format("Result: {0}", a + b));
        }
    }


Теперь перейдем к библиотеке MixedLibrary. Эта библиотека содержит в себе класс-обертку над нашим SimpleService. Содержимое файла CppService.h:

// Директивы препроцессора нужны, чтобы компилятор сгенерировал записи
// об экспорте класса из библиотеки
#ifdef INSIDE_MANAGED_CODE
#    define DECLSPECIFIER __declspec(dllexport)
#    define EXPIMP_TEMPLATE
#else
#    define DECLSPECIFIER __declspec(dllimport)
#    define EXPIMP_TEMPLATE extern
#endif


namespace MixedLibrary
{

	class DECLSPECIFIER CppService
	{
	public:
		CppService();
		virtual ~CppService();

	public:
		void Add(int a, int b);

	private:
		void * m_impl;
	};
}

И содержимое файла CppService.cpp:

#include "CppService.h"

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace SimpleLibrary;

namespace MixedLibrary
{
	CppService::CppService()
	{
		Service^ service = gcnew Service();
		m_impl = GCHandle::ToIntPtr(GCHandle::Alloc(service)).ToPointer();
	}

	CppService::~CppService()
	{
		GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_impl));
		handle.Free();
	}

	void CppService::Add(int a, int b)
	{
		GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_impl));
		Service^ service = safe_cast(handle.Target);
		service->Add(a, b);
	}
}


Также для компилируемости необходимо добавить директиву препроцессора INSIDE_MANAGED_CODE:

image

И последний штрих — наше обычное неуправляемое приложение:

#include "stdafx.h"

#pragma comment(lib, "../Debug/MixedLibrary.lib")

#include 
#include "../MixedLibrary/CppService.h"


using namespace std;
using namespace MixedLibrary;


int main()
{
	CppService* service = new CppService();
	service->Add(5, 6);

	cout << "press any key..." << endl;
	getchar();
}

И, конечно же, результат:

image

Автор: nikitam
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335620/


Метки:  

[Из песочницы] World Machine + UE4: Полный рабочий процесс

Понедельник, 14 Августа 2017 г. 15:07 + в цитатник
Привет, Хабр! Предлагаю вашему вниманию перевод статьи WorldMachine + UE4: Full Workflow.

Руслан Назиров показал, как можно создавать красивые ландшафты в World Machine и импортировать их в Unreal Engine 4. Руслан начал работать с Unreal Engine всего год назад, но уже сейчас демонстрирует удивительные результаты.

Процесс создания ландшафта для UE4


1. Создание нужного ландшафта в World Machine. Я использую библиотеку макросов GeoGlyph для ускорения процесса создания ландшафта.

image

2. Создание необходимых карт высот для слоев ландшафта. Вы можете использовать стандартные Erosion-выхода, такие как Flow, Wear или Deposition. Или можете использовать сторонние макросы, например, ReFlow из GeoGlyph. В этом случае, Вам надо будет присоединить эти карты к Splat Converter, чтобы обеспечить правильное расположение веса Splatmap.

image

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

image

4. Следующим шагом станет экспорт карт высот для ландшафта и слоев (Они понадобятся для правильного наложения материала на ландшафт в UE4)

image

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

image

6. Материал ландшафта обычно содержит несколько слоев. Вам нужно работать с каждым слоем отдельно.

image

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

image

image

8. Можно улучшить настройку слоев, добавив больше параметров и используя карты Ambient Occlusion, Roughness и Displacement, чтобы добавить большей детализации ландшафту.

image

9. Вы можете использовать зависящую от расстояния тесселяцию, чтобы кардинально увеличить производительность при использовании Displacement карты. Используйте код снизу для множителя тесселяции. Помните, что Вам нужно отключить чекбоксы Adaptive Tesselation (адаптивная тесселяция) и Crack Free Displacement (смещение без трещин) в параметрах материала.

image

10. Вместо ручной покраски травы, Вы можете использовать один из экспортируемых слоев из World Machine. Для этого используйте ноду Grass и задайте ей параметр Вашего слоя (Используйте то же имя, что и в ноде Landscape Layer Blend). Также Вам нужно создать ассет Landscape Grass Type, чтобы задать параметры для травы, такие как плотность, размер и другие. В целом, Вы можете использовать этот метод не только для травы, но и для камней, деревьев и других объектов на ландшафте.

image

image

11. Когда материал ландшафта готов, настало время импортировать сам ландшафт. Откройте вкладку Landscape в окне Modes. Выберите Import From File. Затем выберите созданный Вами материал ландшафта. После этого выберите карту высот для ландшафта, которую Вы создавали в World Machine. Создайте Layer Info для каждого слоя (Weight-Blended Layer). Для каждого Layer Info выберите нужную карту слоя, которую Вы делали в World Machine. Вы можете задать Scale (масштаб) ландшафту, если нужно. После всех этих действий нажмите Import и вы получите ландшафт с созданным Вами материалом.

image

image

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

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

https://habrahabr.ru/post/335610/


Метки:  

В разрезе: новостной агрегатор на Android с бэкендом. Система контроля конфигураций (Puppet)

Понедельник, 14 Августа 2017 г. 14:57 + в цитатник
Вводная часть (со ссылками на все статьи)

В ITIL (v3) среди описанных процессов есть 2 особенно интересных: «Процесс управления конфигурациями» и «Процесс управления изменениями», предназначенных для анализа и управления изменениями конфигураций систем. Для продолжения повествования нужно определиться, что такое «система». В это понятие входит огромное количество составляющих, влияющих (прямо или косвенно) на предоставление услуги:
  • серверы
    • настройки безопасности (пользователи, группы, права, межсетевые экраны);
    • установленные приложения и библиотеки;
    • настройки работы приложений (лимиты по дискрипторам, памяти, времени CPU и т.д.);
    • резервное копирование;

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

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


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


В итоге — среда для корректной работы вашего продукта выход из-под вашего контроля и имеющихся средств автоматизации и версионности.

Мотивация


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

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

Мотивация для разработчика-одиночки


С учётом мощной вводной части в предыдущем абзаце преимущества для разработчика-одиночки опишу доступнее и более кратко:
  • т.к. разработка осуществляется не ежедневно, как результат некоторые особенности развёртывания плавно улетучиваются по прошествии пары дней;
  • автоматизация для одиночки – самый надёжный напарник;
  • скорость выполнения работ, обеспечиваемая автоматизацией, позволяет не потерять «запал» и желание развивать проект (это очень важный специфичный момент).


Важная оговорка про ITIL


Не старайтесь брать, из описанных в ITIL процессов, все шаги которые там описаны, — ситуация будет хуже, чем до этого! Я знаю, как подобные шаги внедряются в некоторыъ банковских системах и к чему это приводит (особенно без автоматизации) – бюрократическая машина удушит любой динамично развивающийся проект/систему.

Puppet


В моём случае был выбран Puppet. При выборе между Chef и Ansible, выбор в пользу него был сделан с учётом хорошей документационной базы, хорошей поддержки, достаточно большого количества модулей (от разработчиков и сообщества), активного развития проекта и реализацией на Ruby (который более-менее мне знаком).

Откровенно говоря, кривая изучения для Puppet была вовсе не пологой. В связи с тем, что в разрабатываемой системе используется большое количество всяких элементов, каждый из них может быть настроен по-разному и всё это может быть развёрнуто на разных стендах – изучение инструмента потребовалось полное и тщательное. По мере изучения инструмента стали очевидны и некоторые его минусы (в большинстве случаев «by-design») и ограничения (хорошая статья о философии Puppet, поясняющая некоторые архитектурные решения). Так же по мере изучения и уже частичной реализации необходимых скриптов чуть больше узнал про Ansible в котором решены некоторые проблемы, имеющиеся в Puppet (что не отменят возможности наличия своих проблем, отсутствующих в Puppet). Так, что последующее повествование это не реклама Puppet, а описание возможностей и опыта использования.

Немного о Puppet


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

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

Группы ресурсов могут быть организованы в классы, которые являются более крупными единицами конфигурации. В то время как ресурс может описывать единственный файл/каталог или пакет, класс может описывать всё, что нужно для конфигурирования службы или приложения (включая необходимое количество пакетов, конфигурационных файлов, демонов/служб и задач обслуживания). Более маленькие классы могут объединяться в крупные, которые описывают целую системную роль – «сервер базы данных» или «рабочий узел кластера».

Пример класса с ресурсами внутри:
class apache (String $version = 'latest') {
  package {'httpd':
    ensure => $version, # Using the class parameter from above
    before => File['/etc/httpd.conf'],
  }
  file {'/etc/httpd.conf':
    ensure  => file,
    owner   => 'httpd',
    content => template('apache/httpd.conf.erb'), # Template from a module
  }
  service {'httpd':
    ensure    => running,
    enable    => true,
    subscribe => File['/etc/httpd.conf'],
  }
}

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

Примеры определения узлов Puppet:
node 'www1.example.com', 'www2.example.com', 'www3.example.com' {
  include common
  include apache, squid
}

node /^(foo|bar)\.example\.com$/ {
  include common
}


Факты и база данных Hiera. Перед тем как выполнить код Puppet выполняется сборка информации об узле, собранная информация оформляется в виде предопределённых фактов – переменных, которые можно использовать где угодно в коде. Hiera это встроенная «key-value» база данных. По-умолчанию в качестве источника данных используются файлы формата YAML или JSON, хотя возможно расширение для использования любого источника данных. В связи с её иерархичностью и возможностью изменения данных в зависимости от узла – её использование является неотъемлемой частью работы большинства модулей/классов.

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

Тем, кто планирует использовать Puppet в основном придётся заниматься созданием классов и иногда — модулей.

Варианты развёртывания


При внедрении Puppet возможны 2 варианта с централизованным хранением конфигурации и без него:
  • Централизованное хранение конфигурации: преимущества явно прослеживаются при наличии БОЛЬШОГО количества серверов. В этом случае на клиентские машины передаётся информация, касающиеся только самой машины, что так же обеспечивает некоторый уровень безопасности и минимизирует траффик.
  • Децентрализованное хранение конфигурации: обосновано при небольшом количестве серверов, при этом на машин должен быть полный комплект конфигурационных скриптов и файлов и при запуске агентов будет выполнена их компиляция и выполнения части касающейся данной машины. Реализуется обычной cron-задачей, запускаемой каждые 15 минут.


Мой скрипт выглядит примерно так:
#!/bin/sh

PUPPET_BIN='/opt/puppetlabs/bin/puppet'

# Ставим необходимые пакеты для старта
apt-get update &&  apt-get -y install git mc htop apt-transport-https nano wget lsb-release apt-utils curl python

# Первоначально осуществляем установку `puppet-agent`
if [ ! -d /etc/puppetlabs ]; then
  	rm *.deb.* *.deb # possible trash
	wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb && dpkg -i puppetlabs-release-pc1-xenial.deb
	apt-get update && apt-get -y install puppet-agent
fi

# Определяем тип `environment`
/opt/puppetlabs/bin/puppet config set environment $PUPPET_ENV
if [ ! -d /etc/puppetlabs/code/environments/$PUPPET_ENV ]; then
  cp -r /etc/puppetlabs/code/environments/production /etc/puppetlabs/code/environments/$PUPPET_ENV
fi

# Install puppet modules
$PUPPET_BIN module install puppetlabs-ntp
$PUPPET_BIN module install aco-oracle_java
$PUPPET_BIN module install puppetlabs-firewall
$PUPPET_BIN module install saz-ssh
$PUPPET_BIN module install saz-sudo
$PUPPET_BIN module install saz-limits
$PUPPET_BIN module install thias-sysctl
$PUPPET_BIN module install yo61-logrotate
$PUPPET_BIN module install puppetlabs-apt
$PUPPET_BIN module install puppet-archive

# git pull "deployment" project and go in it only if POVISION_NO_GIT_CLONE set to "true"
if [ ${POVISION_NO_GIT_CLONE:-"false"} = "true" ];
then
	echo "do nothing"
else
	LOCAL_REV=""
	if [ -f local_latest.sha1 ]; then
	  LOCAL_REV=`cat local_latest.sha1`
	fi
	REMOTE_REV=`git ls-remote --tags | grep "latest" | awk '{print $1}'`
	if [ $LOCAL_REV = $REMOTE_REV ]; then
	 exit 0
	fi
	 git fetch --all --tags --prune
	 git checkout -f tags/latest
fi

# replace puppet configs
cp puppet_config/hiera.yaml  /etc/puppetlabs/code/environments/$PUPPET_ENV/

# replace hiera db
rm /etc/puppetlabs/code/environments/$PUPPET_ENV/hieradata/*
cp -r $PUPPET_ENV/hieradata/*  /etc/puppetlabs/code/environments/$PUPPET_ENV/hieradata

# replace storyline_* modules
rm -r /etc/puppetlabs/code/environments/$PUPPET_ENV/modules/storyline_*
cp -r modules/*  /etc/puppetlabs/code/environments/$PUPPET_ENV/modules

# copy site.pp
cp $PUPPET_ENV/site.pp /etc/puppetlabs/code/environments/$PUPPET_ENV/manifests/site.pp

#echo "hostname:"
#hostname
$PUPPET_BIN apply /etc/puppetlabs/code/environments/$PUPPET_ENV/manifests/site.pp

echo $REMOTE_REV > local_latest.sha1


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

При запуске указанного скрипта:
  1. устанавливается сам клиент Puppet и необходимые пакеты
  2. инсталлируются необходимые модули Puppet
  3. сверяется изменение номера коммита для метки «latest» (делается при успешном интеграционном тестировании новой версии)
  4. заменяется конфигурация (hiera.yaml) БД Hiera Puppet в текущем окружении (переменная $PUPPET_ENV);
  5. заменяются YAML-файлы с данными для БД Hiera Puppet;
  6. копируются с заменой описания моих модулей;
  7. копируется конфигурация с узлами (серверами моей системы);
  8. вызывается применение всех тех настроек, что были скопированы/установлены ($PUPPET_BIN apply ….)


Список задач, которые выполняет клиент Puppet при запуске огромен (проверка и необходимое выполнение руками была бы просто невозможна):
  • выставляются лимиты на открытые файлы, задействованный объем памяти, свапирование и количество соединений;
  • настраивается ротация логов (как для системы, так и для моего приложения и необходимых ему сервисов);
  • создаются необходимые учётные записи для администрирования с необходимыми группами и полномочиями;
  • устанавливается и настраивается NTP-сервер;
  • устанавливается и настраивается SSH-сервер;
  • устанавливается Oracle JDK;
  • настраивается брандмауэр;
  • устанавливается и настраивается большое количество компонентов, необходимых для функционирования проекта или его компонента на данном конкретном узле.


Если кого-то заинтересует конкретная реализация какой-либо из задач: пишите – отпишу реализацию в комменте или добавлю в «Tips».

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

Tips


  • При разработке модуля не забывать писать код не только для добавления функции, но и для её отключения. При отсутствии такого функционала при переносе компонента на другой сервер у вас их будет 2: на новом и на старом месте — на старом потребуется удалять руками, что противоречит основной задаче по автоматизации управления конфигурациями;
  • Хорошие книги по Puppet для начинающих – Learning Puppet и Puppet 4 Essentials;
  • Хороший модуль для получения артефактов из nexus sonatype (https://github.com/cescoffier/puppet-nexus);
  • Максимальное количество параметров выносите в файлы-данные Hiera для легкости конфигурации узлов и достижения универсальности кода самих модулей.


Спасибо за внимание!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335608/


Метки:  

[Перевод] Охота на вредоносные npm-пакеты

Понедельник, 14 Августа 2017 г. 14:14 + в цитатник

Метки:  

Социальный Организм — как форма эффективного взаимодействия команды. Часть 2

Понедельник, 14 Августа 2017 г. 14:10 + в цитатник
С частью 1 можно ознакомиться, перейдя по ссылке

III Механизмы построения социального организма


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

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

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

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

1. Адаптация новых участников к среде обитания.


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

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

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

Когда человек попадает в новую команду желательно, чтобы он сначала на эмоциональном уровне окунулся в атмосферу новых и необычных ощущений. Он не должен сразу утонуть в водовороте информации и эмоций новых коллег. Наоборот – необходимо создать обстановку, когда ему самому придется прислушиваться к окружающим звукам (или тишине), заглядывать в новый окружающий его мир, как бы через дверную щелку. А за этой “дверью” для него должен оказаться очень интересный и загадочный мир, который не пугает своей новизной, а интригует. Возможно он попытается представить себя со стороны в этой обстановке и подберет для себя оптимальный стиль поведения в коллективе. Эти первые впечатления останутся в сознании надолго и помогут на начальном этапе не замечать, негативные аспекты, которые существуют практически в любой организации.

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

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

2. Снижение стресса Социального Организма при уходе участника


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

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

Еще раз хочу подчеркнуть, что мы говорим о ролях и функциях Социального Организма, а не трудовых ресурсов Организации. Это может быть: “Организатор Дней рожденья и неформальных тимбилдингов”, “Неравнодушный к душевному состоянию коллег”, “Защитник несправедливо обиженных”, “Социальный контролер” и т.д. Поэтому при уходе участника из коллектива нельзя приказом назначить кого-то исполнять его неформальные обязанности. Такие функции чаще всего берут на себя лидеры (а куда ж без них). В связи с этим, в команде должно быть достаточное количество людей, способных взвалить на себя новые обязанности и имеющих возможность и желание выполнять их. В противном случае архитектор Социального Организма вынужден будет сам нагрузить на себя “бесхозную” ответственность, принеся в жертву основную деятельность.

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

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

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

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


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

Это пожалуй одна из ключевых функций Социального Организма, позволяющая ему существовать. В одном из теоретических подходов к образованию сообществ (теория обмена) [6] важными аспектами образования групп называются такие условия, как: 1) Пространственная близость, 2) Взаимодействие и 3) Общие установки. Данный раздел, как раз касается последнего пункта.

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

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

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

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

В Соглашениях могут оговариваться:

  • Нормы поведения – свод моделей поведения, рекомендуемых участникам сообщества в различных ситуациях. (Сектор Рационального мира);
  • Общественные ценности — эталонные представления, одобряемые большинством: добро, справедливость, патриотизм и т.д. (Сектор Эмоционального мира);
  • Принципы — особо важные непоколебимые убеждения, определяющие своеобразные границы устанавливаемые для сообщества. (Сектор Политического мира);

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

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

Приведу примеры использования и игнорирования этой функции. В одной компании в которой я работал, руководство решило увеличить длительность рабочего дня для менеджеров с 8 до 9 и 10 часов соответственно, в зависимости от уровня должности сотрудника. Это новшество ввели без объяснения причин и различных мер мотивации. Просто высшее руководство посчитало для себя, что платят сотрудникам очень много и поэтому хотят получать большие производственные результаты. Естественно результат от этого не улучшился, а наоборот: люди стали больше болеть, увольняться, заниматься на работе своими личными делами. Противоположный пример, когда в ИТ фирмах люди работают на интересных проектах внеурочно, в том числе по ночам, чтобы успеть сдать вовремя результат и не подвести свою команду, команду партнеров и оправдать ожидания клиентов. В этой отрасли это стало уже нормой: «Ну все же вокруг так работают!».

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

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


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

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

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

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

В модели мотивации Хекмана и Олдхема [7], важное внимание уделяется таким характеристикам, как: «Ощущение важности» и «Ощущение ответственности». Если человек понимает, что его предложения могут улучшить жизнь всего сообщества и к тому же будут по достоинству оценены, он начинает ощущать важность своей деятельности (удовлетворяет потребность в признании). А это в свою очередь стимулирует его и дальше занимать проактивную позицию и брать на себя ответственность. Поэтому необходимо постоянно доносить до сознания участников Социального Организма позицию их причастности к жизни и судьбе сообщества, а еще важнее – пробуждать ответственность за него, и его развитие.

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

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

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

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

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

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

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

5. Перераспределение зон ответственности между участниками для повышения потенциала сообщества.


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

Еще одна полезная функция Социального Организма — перераспределение зон ответственности между участниками. Она является одним из способов саморегулирования эффективности его существования.

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

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

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

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

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

Для повышения качества взаимодействия участников Социального Организма, можно, например, пропагандировать использование в коллективе универсального правила взаимного обмена [8]. Это достаточно распространенное понятие в психологии. Суть его заключается в необходимости вызвать у коллеги чувство долга. Например, даря ему какой-то подарок или выполняя какую-то услугу. Ответная реакция происходит на бессознательном уровне. То есть если кто-то из членов сообщества принес например, печенки и предложил их всем, чаще всего в следующий раз кто-то другой угостит всех еще чем-то. А это в свою очередь будет вызывать чувство долга (в хорошем смысле этого слова) и на подсознательном уровне сплачивать коллектив.

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


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

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

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

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

Теория [7] советует в качестве мер воздействия на участников, для поддержания этой функции в группе, использовать следующие направления:

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

В сообществах для реализации этой функций, зачастую активно практикуют использование ритуалов. В данном контексте, я говорю не о религиозных ритуалах, а о неких коллективных обрядах, способствующих поднятию эмоционального настроя коллектива. Например: при успешном выполнении задач, все члены сообщества хлопают в ладоши друг другу и хвалят себя в слух. Подобные культы восходят к первобытному обществу и скрывают под собой двойственность явления: «На по¬верхности оказываются символ и ритуал, а в глубине – нерациональное и бессознательное» см. [9]. Но использование подобных методов сильно зависит от менталитета и уровня рационального интеллекта членов сообщества. Лично я, наблюдая за подобными явлениями, вспоминаю сцену из фильма «Безымянная звезда», в которой старшеклассницы хором повторяют, как мантру: «Ученицам младших и особенно, старших классов, категорически запрещено появляться на вокзале в дневное или вечернее время, но особенно в часы, когда проходит дизель электропоезд Бухарест — Синаи..»

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

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

Все эти мероприятия так или иначе направлены на Сплочение коллектива.

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

7. Подавление конфликтов в среде, поддержка здоровой конкуренции


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

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

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

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

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

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

Таким образом может происходить саморегулирование Социального Организма и пополнение или изменение кодекса правил и стандартов.

Но стоит помнить, что в таком саморегулируемом сообществе может возникнуть застой и снижение внешней конкурентоспособности, особенно на стадии развития организации — «Аристократизм» по И. Адизесу [4]. В этом случае, здоровые конфликты могут возродить конкуренцию в Социальном Организме и способствовать его развитию.

8. Повышение привлекательности пребывания участников в Социальном Организме


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

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

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

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

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

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

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

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

Список литературы


[1] Д. Гоулман, Эмоциональное лидерство. Искусство управления людьми на основе эмоционального интеллекта, 2014.
[2] Ф. Д. Питер, Эффективный руководитель, Москва: Манн, Иванов и Фербер, 2012.
[3] Г. Сненсер, Воспитание умственное, нравственное и физическое, 3-е изд ред., Либроком, 2012.
[4] И. Адизес, Управление жизненным циклом корпораций, Москва: Манн, Иванов и Фербер, 2014.
[5] Д. Оуэн, Как управлять людьми, Москва: Претекст, 2011.
[6] В. Лавриненко, Социология, Москва: ЮНИТИ-ДАНА, 2002.
[7] Н. Г.X.Боронова, Психология труда: конспект лекций, Научная книга, 2009.
[8] Р. Чалдини, Психология влияния, Питер, 2016.
[9] А. Черных, Ритуалы в медиатизированном обществе, Москва: Изд. дом Высшей школы экономики, 2012.
[10] В. В. Пономаренко, Управление конфликтами, Олимп, 2008.
[11] Г. Зиммель, Избранное. Проблемы социологии, Москва; Санкт-Петербург: Университетская книга, Центр гуманитарных инициатив, 2015.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335590/


Метки:  

[Из песочницы] Отсутствие полноценной многоязычности в 1С-Битрикс — неумение или плохое управление проектом?

Понедельник, 14 Августа 2017 г. 14:09 + в цитатник

Побочные стороны монопольного положения


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

Банально, но сейчас 2017 год и даже без философии о необходимости must-have функционала сама компания вроде бы как понимает и предпринимает попытки выйти на международные рынки. Ведь рано или поздно рынок России будет исчерпан, а рынки стран СНГ будут, если не полностью, то частично утеряны (о причинах дальше) или в лучшем случае опять же исчерпаны. Для этого компания постоянно добавляет другие языки для административной части, среди которых практически не используемые у нас – Португальский, Испанский, Китайский, Немецкий и др. Но насколько эта активность реально принесет результат, а не формально добавит красивые пунктики в рекламные брошюры и презентационные файлы маркетологов и продавцов этой CMS?

По понятным причинам, базисный язык системы – русский. Однако, время диктует свои условия, и теперь в независимых странах (бывших республиках СССР) существует острая необходимость отображения публичной части сайтов на национальных языках. За последние 25 с лишним лет уже выросло и подрастает новое поколение активных участников и пользователей электронной торговли, для которых национальные языки их стран являются основными. Подтверждением этого есть статья о статистике использование русского языка в странах СНГ. Кроме того, почти 1300 весомых голоса за введение украинского языка для лидера построения онлайн торговли в Украине. Показателен также очень высокий показатель голосов за полноценную многоязычность на сайте идей самого 1С-Битрикс. Для покорения Европы, США или большинства азиатских стран с их современной мультинациональностью без переключателя хотя бы между двумя языками никак.



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

Второй аргумент запуска мультиязычных интернет-ресурсов, особенно интернет-магазинов в странах СНГ – необходимость выхода на международные рынки, по разным причинам, социально-экономическая нестабильность, низкая покупательная способность отечественного покупателя по сравнению с западными, девальвация национальных валют в Украине, России, Белоруссии, Казахстане и других странах СНГ за последние 3 года и т.д.

Требования поддержки многоязычности для любой современной CMS – это совершенно очевидный и естественный факт. Конечно же, и у 1С-Битрикс мультиязычность заявлена, но уровень её реализации не совсем комфортный, вернее, совершенно некомфортный!

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

  • «Очень желательно как-то продумать возможность добавлять языковые версии элементов и секций в информационный блок (без волшебных заклинаний через свойства элемента и UF свойства разделов) … Предполагаю, что подобное решение очень сильно упростит жизнь всем», 2011 год.

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

  • «…… я много потерял в инвестициях времени на изучение Битрикса и возложения планов, но судя по всему, купленную лицензию и ГР использую на 2 второстепенных ИМ… Уверен, многие будут приходить к такому решению при такой ситуации с мультиязычностью.», 2017 год.

  • «… на дворе 17 год, вопрос актуален до сих пор», 2017 год.

На сегодня крупный многоязычный проект дешевле и перспективнее запустить на другой CMS, чем делать «костыли» на Битриксе. Даже бесплатные популярные CMS (Magento, OpenCart, Prestashop, Drupal, Wordpress) имеют полноценную поддержку мультиязычности. Полноценную – т.е. эффективную и рациональную по реализации и поддержке, когда компании не нужно 5-10% от бюджета заплатить за реализацию того, что должно идти из коробки, а также не нужно иметь контент-менеджера (ов) со ставкой выше среднего.

Пользователи CMS Битрикс кололись и плакали, но продолжали писать «костыли»


У 1С-Битрикс на сегодня есть два способа построения мультиязычных интернет-магазинов:

I. Независимое дублирование всей информации из одной админки, используя разные лицензии (платим за каждую после второй):

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

  2. Дублирование инфоблоков контента (новости, статьи, акции и др.).

  3. Необходимо иметь для каждого языка свои корректно настроенные независимые шаблоны.

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

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

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

  7. Возможно нанимаем и третью команду, после специалиста основных изменений и тестировщиков, которая попробует инфоблоки товаров для разных языков связать с одним справочником в системе учета (один из вариантов – создание отдельного массива кодификации позволяющего получать «правильное» количество проданного товара через украинский, русский и английский интерфейсы), например, 1С, интеграция с которой при родственных связях с 1С-Битрикс до сих пор не идеальна.

II. Эффективнее, но сложнее – с одним общим торговым каталогом в одном инфоблоке:

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

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

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

Заключение


Остается надеяться, что стратеги развития 1С-Битрикс, которые безусловно вдохновляются Magento, перенесут все лучшие идеи из этой действительно популярной в мировых масштабах CMS, а не будут пытаться продать побольше лицензий под соусом многосайтовости или заработать на многотысячной армии студий-партнеров, продолжающих дорабатывать решения из коробки для прежнего рынка. А тем временем будем наблюдать за увеличивающимся формально количеством поддерживаемых языков для back-end’а, т.е. административной части системы – маркетологи и project manager’ы любят такие KPI, тем более, что это дешево – всего-то перевести текстовый массив разовым исполнителем с фриланс-сайта, а публичная часть может подождать еще с десяток лет.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335604/



Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1095 1094 [1093] 1092 1091 ..
.. 1 Календарь