gRPC — фреймворк от Google для удалённого вызова процедур


В деле удалённого вызова процедур дела уже давно обстоят в точности как в известном комиксе «14 стандартов» — чего только тут не напридумано: древние DCOM и Corba, странные SOAP и .NET Remoting, современные REST и AMQP (да, я знаю, что кое-что из этого формально не RPC, для того чтобы обсудить терминологию даже вот специальный топик недавно создали, тем ни менее всё это используется как RPC, а если что-то выглядит, как утка и плавает, как утка — ну, вы в курсе).

И конечно же, в полном соответствии со сценарием комикса, на рынок пришел Google и заявил что вот теперь наконец он создал ещё один, последний и самый правильный стандарт RPC. Google можно понять — продолжать в 21-ом веке гонять петабайты данных по старому и неэффективному HTTP+REST, теряя на каждом байте деньги — просто глупо. В то же время взять чужой стандарт и сказать «мы не смогли придумать ничего лучше» — совершенно не в их стиле.

Поэтому, встречайте, gRPC, что расшифровывается как «gRPC Remote Procedure Calls» — новый фреймворк для удалённого вызова процедур от Google. В этой статье мы поговорим о том, почему же он, в отличии от предыдущих «14 стандартов» всё-таки захватит мир (ну или хотя бы его часть), попробуем собрать билд gRPC под Windows + Visual Studio (и даже не говорите мне, что инструкция не нужна — в официальной документации упущено штук 5 важных шагов, без которых ничего не собирается), а также попробуем написать простенький сервис и клиент, обменивающиеся запросами и ответами.

Зачем нужен ещё один стандарт?

Прежде всего давайте оглянемся вокруг. Что мы видим? Мы видим REST + HTTP/1.1. Нет, есть всякое, но именно эта туча закрывает добрых три четверти небосвода клиент-серверных коммуникаций. Присмотревшись ещё чуть пристальнее, мы видим, что REST в 95% случаев вырождается в CRUD.

В итоге мы имеем:

  • Неэффективность протокола HTTP/1.1 — несжатые заголовки, отсутствие полноценной двусторонней связи, неэффективный подход к использованию ресурсов ОС, лишний трафик, лишние задержки.
  • Необходимость натягивать нашу модель данных и событий на REST+CRUD, что часто получается, как воздушный шарик на глобус и вынуждает Яндекс писать вот такие, бесспорно, очень хорошие статьи, которые, однако, были бы не нужны, если бы людям не приходилось думать «Чем же вызвать заклинание для призыва элементаля — PUT’ом или POST’ом? И какой же HTTP-код вернуть, чтобы он означал „Перейдите на 3 клетки вперёд и тяните новую карту“ ?»

Именно с этого места и начинается gRPC. Итак, из коробки мы имеем:

  • Protobuf в качестве инструмента описания типов данных и сериализации. Очень классная и хорошо зарекомендовавшая себя на практике штука. Собственно говоря, те, кому была нужна производительность — и раньше брали Protobuf, а дальше уже отдельно заморачивались транспортом. Теперь всё в комплекте.
  • HTTP/2 в качестве транспорта. И это невероятно мощный ход! Вся прелесть полного сжатия данных, контроля трафика, инициации событий с сервера, переиспользования одного cокета для нескольких параллельных запросов — красотища.
  • Статические пути — никаких больше «сервис/коллекция/ресурс/запрос? параметр=значение». Теперь только «сервис», а что внутри — описывайте в терминах вашей модели и её событий.
  • Никакого привязывания методов к HTTP-методам, никакого привязывания возвращаемых значений к HTTP-статусам. Пишите, что хотите.
  • SSL/TLS, OAuth 2.0, аутентификация через сервисы Google, плюс можно прикрутить свою (например, двухфакторную)
  • Поддержка 9-ти языков: C, C++, Java, Go, Node.js, Python, Ruby, Objective-C, PHP, C# плюс, конечно, никто не запрещает взять и реализовать свою версию хоть для брейнфака.
  • Поддержка gRPC в публичных API от Google. Уже работает для некоторых сервисов. Нет, REST-версии, конечно, тоже останутся. Но посудите сами, если у вас будет выбор — использовать, скажем, из мобильного приложения REST-версию, отдающие данные за 1 сек или с теми же затратами на разработку взять gRPC-версию, работающую 0.5 сек — что вы выберете? А что выберет ваш конкурент?

Сборка gRPC

Нам понадобитья:

  • Git
  • Visual Studio 2013 + Nuget
  • CMake

Забираем код

  1. Забираем репозипорий gRPC с Гитхаба
  2. Выполняем команду
    git submodule update --init 

    — это нужно для того, чтобы скачать зависимости (protobuf, openssl и т.д.).

Собираем Protobuf

  • Переходим в папку grpc\third_party\protobuf\cmake и создаём там папку build, переходим в неё.
  • Выполняем команду
    cmake -G «Visual Studio 12 2013» -DBUILD_TESTING=OFF…
  • Открываем созданный на предыдущем шаге файл protobuf.sln в Visual Studio и собираем (F7).
    На этом этапе мы получаем ценные артефакты — утилиту protoc.exe, которая понадобиться нам для генерации кода сериализации\десериализации данных и lib-файлы, которая будут нужны при линковке gRPC.
  • Копируем папку grpc\third_party\protobuf\cmake\build\Debug в папку grpc\third_party\protobuf\cmake.
    Ещё раз — папку Debug нужно скопировать на 1 уровень выше. Это какая-то неконсистентность в документациях gRPC и Protobuf. В Protobuf говорится, что всё билдить надо в папке build, а вот исходники проектов gRPC ничего об этой папке не знают и ищут библиотеки Protobuf прямо в grpc\third_party\protobuf\cmake\Debug

Собираем gRPC

  1. Открываем файл grpc\vsprojects\grpc_protoc_plugins.sln и собираем его.
    Если вы верно прошли сборку Protobuf на предыдущем этапе — всё должно пройти гладко. Теперь у вас есть плагины к protoc.exe, которые позволяют ему не только генерировать код сериализации\десериализации, но и добавлять в него функционал gRPC (собственно говоря, удалённый вызов процедур). Плагины и protoc.exe нужно положить в одну папку, например, в grpc\vsprojects\Debug.
  2. Открываем файл grpc\vsprojects\grpc.sln и собираем его.
    По ходу сборку должен запуститься Nuget и скачать необходимые зависимости (openssl, zlib). Если у вас нет Nuget или он почему-то не скачал зависимости — будут проблемы.
    По окончанию билда у нас появятся все необходимые библиотеки, которые мы сможем использовать в нашем проекте для коммуникаций через gRPC.

Наш проект

Давайте напишем такой себе API для Хабрахабра с применением gRPC
Методы у нас будут такие:

  • GetKarma будет получать строку с именем пользователя, а возвращать дробное число со значением его кармы
  • PostArticle будет получать запрос на создание новой статьи со всеми её метаданными, а возвращать результат публикации — структуру со ссылкой на статью, временем публикации ну и текстом ошибки, если публикация не удалась

Это всё нам нужно описать в терминах gRPC. Это будет выглядеть как-то так (описание типов можно посмотреть в документации на protobuf):

syntax = "proto3";  package HabrahabrApi;  message KarmaRequest {   string username = 1; }  message KarmaResponse {   string username = 1;   float karma = 2; }  message PostArticleRequest {   string title = 1;   string body = 2;   repeated string tag = 3;    repeated string hub = 4;  }  message PostArticleResponse {   bool posted = 1;   string url = 2;   string time = 3;   string error_code = 4; }	  service HabrApi {   rpc GetKarma(KarmaRequest) returns (KarmaResponse) {}   rpc PostArticle(PostArticleRequest) returns (PostArticleResponse) {} } 

Переходим в папку grpc\vsprojects\Debug и запускаем там 2 команды (кстати, обратите внимание, в официальной документации в этом месте ошибка, неверные аргументы):

protoc --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe habr.proto protoc --cpp_out=. habr.proto  

На выходе мы получим 4 файла:

  • habr.pb.h
  • habr.pb.cc
  • habr.grpc.pb.h
  • habr.grpc.pb.cc

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

Давайте уже создадим проект!

  1. Создаём в Visual Studio новый solution, назовём его HabrAPI.
  2. Добавляем в него два консольных приложения — HabrServer и HabrClient.
  3. Добавляем в них сгенерированные на предыдущем шаге h и сс-файлы. В сервер надо включать все 4, в клиент — только habr.pb.h и habr.pb.cc.
  4. Добавляем в настройках проектов в Additional Include Directories путь к папкам grpc\third_party\protobuf\src и grpc\include
  5. Добавляем в настройках проектов в Additional Library Directories путь к grpc\third_party\protobuf\cmake\Debug
  6. Добавляем в настройках проектов в Additional Dependencies библиотеку libprotobuf.lib
  7. Выставляем тип линковки таким же, с каким был собран Protobuf (свойство Runtime Library на вкладке Code Generation). В этом месте может оказаться, что вы не собрали Protobuf в нужной вам конфигурации, и придётся вернуться и пересобрать его. Я выбирал и там и там /MTd.
  8. Добавляем через Nuget зависимости на zlib и openssl.

Теперь у нас всё собирается. Правда, ничего пока ещё не работает.

Клиент

Здесь всё просто. Во-первых, нам нужно создать класс, унаследованный от заглушки, сгенерированной в habr.pb.h. Во-вторых, реализовать в нём методы GetKarma и PostArticle. В-третьих, вызывать их и, к примеру, выводить результаты в консоль. Получится как-то так:

#include <iostream> #include <memory> #include <string>  #include <grpc/grpc.h> #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> #include <grpc++/credentials.h> #include "habr.grpc.pb.h"  using grpc::Channel; using grpc::ChannelArguments; using grpc::ClientContext; using grpc::Status; using HabrahabrApi::KarmaRequest; using HabrahabrApi::KarmaResponse; using HabrahabrApi::PostArticleRequest; using HabrahabrApi::PostArticleResponse; using HabrahabrApi::HabrApi;  class HabrahabrClient {  public:   HabrahabrClient(std::shared_ptr<Channel> channel)       : stub_(HabrApi::NewStub(channel)) {}    float GetKarma(const std::string& username) {     KarmaRequest request;     request.set_username(username);     KarmaResponse reply;     ClientContext context;      Status status = stub_->GetKarma(&context, request, &reply);     if (status.ok()) {       return reply.karma();     } else {       return 0;     }   }    bool PostArticle(const std::string& username) {     PostArticleRequest request;     request.set_title("Article about gRPC");     request.set_body("bla-bla-bla");     request.set_tag("UFO");     request.set_hab("Infopulse");     PostArticleResponse reply;     ClientContext context;      Status status = stub_->PostArticle(&context, request, &reply);     return status.ok() && reply.posted();   }   private:   std::unique_ptr<HabrApi::Stub> stub_; };  int main(int argc, char** argv) {   HabrahabrClient client(       grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(),                           ChannelArguments()));   std::string user("tangro");   std::string reply = client.GetKarma(user);   std::cout << "Karma received: " << reply << std::endl;    return 0; }  

Сервер

С сервером похожая история — мы наследуемся от класса сервиса, сгенерированного в habr.grpc.pb.h и реализуем его методы. Дальше мы запускаем слушателя на определённом порту, ну и ждём клиентов. Как-то вот так:

#include <iostream> #include <memory> #include <string>  #include <grpc/grpc.h> #include <grpc++/server.h> #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc++/server_credentials.h> #include "habr.grpc.pb.h"  using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; using HabrahabrApi::KarmaRequest; using HabrahabrApi::KarmaResponse; using HabrahabrApi::PostArticleRequest; using HabrahabrApi::PostArticleResponse; using HabrahabrApi::HabrApi;  class HabrahabrServiceImpl final : public HabrApi::Service {   Status GetKarma(ServerContext* context, const KarmaRequest* request,                   KarmaResponse* reply) override {     reply->set_karma(42);     return Status::OK;   }    Status PostArticle(ServerContext* context, const PostArticleRequest* request,                   PostArticleResponse* reply) override {     reply->set_posted(true);     reply->set_url("some_url");      return Status::OK;   } };  void RunServer() {   std::string server_address("0.0.0.0:50051");   HabrahabrServiceImpl service;    ServerBuilder builder;   builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());   builder.RegisterService(&service);   std::unique_ptr<Server> server(builder.BuildAndStart());   std::cout << "Server listening on " << server_address << std::endl;   server->Wait(); }  int main(int argc, char** argv) {   RunServer();    return 0; } 

Удачи вам в использовании gRPC.

ссылка на оригинал статьи http://habrahabr.ru/post/265805/

Рецензия на книгу Тома Демарко «Deadline. Роман об управлении проектами»

Пособие по управлению проектами в жанровой обертке шпионского детектива.

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

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

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

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

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

Кому и зачем читать?

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

Цитата

«Основы здравого смысла:
1. У проекта должно быть два срока сдачи — запланированный и желаемый.
2. Эти сроки должны быть разными».

ссылка на оригинал статьи http://megamozg.ru/post/18978/

GameKid — клон Game Boy из Raspberry Pi

Многие любители электроники и старых консольных игрушек уже давно используют Raspberry Pi для запуска эмулятора консолей разного типа. Эмуляторы, особенно универсальные, позволяют играть в игры самых разных консолей, включая очень старые и редкие. В число популярных аппаратных платформ, которые эмулируются, входит и Game Boy. Именно его решили воссоздать умельцы, использовав как Raspberry Pi, так и распечатанный на 3D принтере корпус.

Идея воссоздать ретро-гаджет из новых электронных компонентов пришла в голову двум братьям как раз на Рождество. После нескольких недель работы на свет появился GameKid. Для запуска игрушек под Game Boy на этой консоли братья решили использовать программную среду RetroPie.

Корпус GameKid довольно сильно похож на предтечу. Здесь есть четыре фронтальные кнопки, для управления игровым процессом, D-Pad, кнопки старт и select. Кроме того, есть встроенные динамики и гнездо для подключения наушников. При желании пользователь такой портативной игровой консоли может подключить телевизор через HDMI-порт. Кроме того, есть и четыре USB-порта, которые позволяют подключить стандартные игровые контроллеры. При подключении к ТВ или монитору такая возможность будет весьма кстати.

Внутри, кроме Raspberry Pi 2 с RetroPie, есть 16 ГБ карта памяти, ROM с аудиотреками и MP3. Сейчас братья собирают средства на этот проект, на краудфандинговом сайте Kickstarter, и при желании заказать девайс можно за $139. В принципе, дороговато, но возможности у комплекта гораздо более продвинутые, чем у обычного GameBoy. Да, картриджи здесь не используются, для игры нужно загрузить в память консоли сотни игрушек, и можно наслаждаться.

ссылка на оригинал статьи http://geektimes.ru/post/261154/

Плавные движения робота позволяют снизить энергопотребление на 40%

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

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

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

Большинство промышленных роботов, роботизированных станков с манипуляторами и тому подобных систем двигаются без сглаживания. Исследователи (работу которых, в частности, поддерживает General Motors) указывают, что использование алгоритмов сглаживания движений позволит производствам экономить значительные средства в результате более энергоэффективной работы производственных систем. 40% экономии — это огромные средства, в масштабах крупного предприятия.

ссылка на оригинал статьи http://geektimes.ru/post/261152/

Фобии человека, работающего в IT

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

Нет, я не боюсь опоздать на транспорт, на встречу или ужин, ведь опоздания такого типа давно и крепко вошли в мою привычную среду обитания (тут можно начинать осуждать). Я боюсь не успеть узнать. Узнать то, что прежде никогда не знал, но очень хочу. Меня страшно пугает, что с каждым днем списки с намеченными к прочтению книгами, статьями и прочим обучающим и познавательным контентом — растут как снежный ком. Кто-то скажет: «а ты прокрастинируй поменьше и все будешь успевать». Но нет, это не прокрастинация. С этим дрянным делом мы уже встречались и отлично знаем врага в лицо. В этом деле он нам и не помеха вовсе. Я банально не успеваю. И будь в сутках все 50 часов, а не 24, я бы тоже не успевал.

Это все очень странно, но в период информационного «передоза», я испытаваю «информационное голодание».

Pocket валится от ссылок, в Evernote сотни заметок с полезнейшей информацией, а в папку «почитаю потом» в Bookmate — вообще страшно заходить.

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

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

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

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

Так что же это?

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

Фобию можно победить. А как победить это? Я прекрасно понимаю, и не ставлю цель выучить все и вся, но упустить что-то важное — считаю непростительным.

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

ссылка на оригинал статьи http://megamozg.ru/post/18976/