Мы давно ничего не писали в наш блог и возвращаемся с рассказом о нашем новом проекте: Relap.io (relevant pages).
Мы запустили рекомендательный B2B-сервис Relap.io полтора года назад. Он облегчает жизнь редакции и читателям СМИ. В будние дни Relap.io обслуживает 15 млн уников и выдаёт 30 миллиардов рекомендаций в месяц.
Сейчас Relap.io крупнейшая рекомендательная платформа в Европе и Азии.
Взявшись за написание небольшого, но реального и растущего проекта, мы «на собственной шкуре» убедились, насколько важно то, чтобы программа не только хорошо работала, но и была хорошо организована. Не верьте, что продуманная архитектура нужна только большим проектам (просто для больших проектов «смертельность» отсутствия архитектуры очевидна). Сложность, как правило, растет гораздо быстрее размеров программы. И если не позаботиться об этом заранее, то довольно быстро наступает момент, когда ты перестаешь ее контролировать. Правильная архитектура экономит очень много сил, времени и денег. А нередко вообще определяет то, выживет ваш проект или нет. И даже если речь идет всего лишь о «построении табуретки» все равно вначале очень полезно ее спроектировать.
К моему удивлению оказалось, что на вроде бы актуальный вопрос: «Как построить хорошую/красивую архитектуру ПО?» — не так легко найти ответ. Не смотря на то, что есть много книг и статей, посвященных и шаблонам проектирования и принципам проектирования, например, принципам SOLID (кратко описаны тут, подробно и с примерами можно посмотреть тут, тут и тут) и тому, как правильно оформлять код, все равно оставалось чувство, что чего-то важного не хватает. Это было похоже на то, как если бы вам дали множество замечательных и полезных инструментов, но забыли главное — объяснить, а как же «проектировать табуретку».
Хотелось разобраться, что вообще в себя включает процесс создания архитектуры программы, какие задачи при этом решаются, какие критерии используются (чтобы правила и принципы перестали быть всего лишь догмами, а стали бы понятны их логика и назначение). Тогда будет понятнее и какие инструменты лучше использовать в том или ином случае.
Данная статья является попыткой ответить на эти вопросы хотя бы в первом приближении.
Последнее время на популярно-технических форумах я часто встречаю ожесточённые споры приверженцев и противников .NET. Эти споры, как правило, начинаются из-за недоразумения, и заканчиваются жестким троллингом, беседами “за жизнь” и сравнением радиусов и удельных плотностей материала различных сферических коней. Обе стороны силятся доказать и аргументировать, но ни одна не хочет посмотреть на предмет спора другими глазами. Хабрахабр не исключение, увы.
Накалу страстей такой беседы позавидовали бы религиозные фанатики. Единственное, что спасает противников от крестовых походов друг на друга, вооружившись вилами и LangSpec’ами — то, что они разделены интернетом.
Так жить нельзя, господа. Мне захотелось исправить эту ситуацию, и выступить с одной из сторон. Этим постом я попробую нанести сообществу непоправимую пользу и разобраться с мифами, на обсуждение которых, а не на взаимное членовредительство, к сожалению, и уходят силы спорщиков. А так как я в своё время перелез с C++ на C# и всё вокруг него, то я буду развенчивать негативные мифы, прибавлять позитива и всячески приукрашивать действительность — а как без этого. И — заметьте — это обойдется совершенно бесплатно для M$. Ну а сделать я это хочу в формате Q&A.
Продолжая тему JIT-компиляции .NET'a, сегодня мы рассмотрим диспетчеризацию методов у интерфейсов, generics (как классов, так и отдельных методов вместе с реальными сигнатурами); производить отладку релизных сборок с оптимизациями; разберемся с истинным предназначением типа System.__Canon (это не то, что Вы подумали).
При работе с Entity Framework, как и с любым другими ORM, часто возникают вопросы, связанные с его производительностью. Многие разработчики из-за незнания нюансов делают ошибки, приводящие к плохим результатам. Затем, во время анализа проблем и поиска решений, недостаточно разобравшись в вопросе, приходят к выводу, что улучшить ситуацию можно только переходом на другой ORM или отказом от него вообще. Хоть в некоторых ситуациях такое решение может оказаться разумным, зачастую не все так плохо — просто нужно знать нюансы. В этой статье я попытался собрать те подводные камни, с которыми мне чаще всего приходилось сталкиваться на практике.
Как-то я посчитал, что 1 минута простоя hh.ru в будни днем затрагивает около 30 000 пользователей. Мы постоянно решаем задачу снижения количества инцидентов и их длительности. Снизить количество проблем мы можем правильной инфраструктурой, архитектурой приложения — это отдельная тема, ее мы пока не будем брать во внимание. Поговорим лучше о том, как быстро понять, что происходит в нашей инфраструктуре. Тут как раз нам и помогает мониторинг.
В этой статье на примере hh.ru я расскажу и покажу, как покрыть мониторингом все слои инфраструктуры:
client-side метрики
метрики с фронтендов (логи nginx)
сеть (что можно добыть из TCP)
приложение (логи)
метрики базы данных (postgresql в нашем случае)
операционная система (cpu usage тоже может пригодиться)
В июне в Петербурге прошла третья по счету конференция DotNext, а уже через месяц в Москве пройдет четвертая — DotNext 2015 Moscow. Видеозаписи всех докладов и круглых столов питерской конференции мы опубликовали отдельным плейлистом на YouTube. Ну а чтобы вы не теряли время попусту и сразу начинали с самого сладкого — я заморочился с различной (не очень сложной) аналитикой и разобрал для вас десяток топовых докладов, тех, которым участники конференции поставили наивысшие оценки.
Как всегда, для наших оценок мы используем российскую академическую шкалу:
плохо — 2 балла
нормально — 3 балла
хорошо — 4 балла
отлично — 5 баллов
В этом посте я коротко расскажу о докладах, занявших в нашем рейтинге места с шестого по десятое. И начнем мы, как всегда, с конца.
10 место
Михаил Самарин, Futurice — Универсальные приложения для Windows 10
Средняя оценка: 4.19
Михаил — не только бизнес-директор финской компании Futurice, но еще и трижды Microsoft MVP, и поэтому имеет право выступать на конференциях чуть ли ни от имени Microsoft. Так получилось и на этот раз — Михаил выступил с обзорным докладом о том, как с выходом новой версии .NET и Windows 10 изменилась разработка под различные девайсы.
Как и было обещано, доклад получился обзорным. Сначала Михаил рассказал про инструменты разработки — Visual Studio 2015 и различных лицензиях на нее, Microsoft Expression Blend, изменениях в VS, которые появились для удобства разработки под мобильные устройства. Дальше речь пошла о новой схеме «версионирования» Windows, универсальных приложениях и решениях, которые принимает рантайм в зависимости от платформы, на которой выполняется приложение (теперь единый солюшен на все платформы, а не по одному для каждой). После этого речь пошла про различные расширения платформы и того, как система сборки работает с ними. Ну и ближе к концу речь пошла про адаптивный UI, физические и effective пиксели (теперь рекомендуется игнорировать физическое разрешение экрана, а использовать «эффективные» пиксели).
На московском DotNext Михаил обещает сделать доклад об использовании аппаратных API, доступных на мобильных платформах. Поскольку про мобильную разработку на .NET в России практически не рассказывают, будет особенно интересно его послушать. Так что ждем анонса.
Разработка Parallels Access потребовала создания геораспределенного сервиса, позволяющего безопасно устанавливать связь между компьютерами и мобильными клиентами пользователей в различных точках земного шара. Команда, которая над ним трудится, хочет поделиться полученным опытом в форме цитат, чтобы облегчить участь тем, кто только планирует создание своего клиент/серверного продукта, и погрузить в ностальгию профессионалов, имеющих за спиной дюжину успешных проектов:
В этой статье мы поговорим о сервисе GeoIP, который определяет геоданные по IP-адресу запроса, веб-сокетах, реализации polling сервера, AngularJS, Highcharts и проведем краткий анализ системы трекинга загрузки игрового клиента.
Сегодня я хочу рассказать о некоторых решениях проблем, которые возникают во время использования высоконагруженных систем. Все, о чем пойдет речь в этом материале, проверено на собственном опыте: я – Social Games Server Team Lead в компании Plarium, которая занимается разработкой социальных, мобильных, браузерных игр.
Для начала немного статистики. Plarium занимается разработкой игр с 2009 года. На данный момент наши проекты запущены во всех наиболее популярных социальных сетях («Вконтакте», «Мой мир», «Одноклассники», Facebook), несколько игр интегрированы в крупные игровые порталы: games.mail.ru, Kabam. Отдельно существует браузерная и мобильная (iOS) версии стратегии «Правила войны». В базах числятся более 80 миллионов пользователей (5 игр, локализация на 7 языках, 3 миллиона уникальных игроков в день), в итоге все наши серверы получают в среднем около 6500 запросов в секунду и 561 миллион запросов в сутки.
В качестве аппаратной платформы на боевых серверах в основном используются два серверных CPU с 4 ядрами (x2 HT), 32-64 GB RAM, 1-2 TB HDD. Серверы работают на базе Windows Server 2008 R2. Контент раздается через CDN с пропускной способностью до 5 Gbps.
Разработка ведется под .NET Framework 4.5 на языке программирования C#.
Учитывая специфику нашей работы, необходимо не только обеспечить стабильное функционирование систем, но и гарантировать, что они смогут выдержать большой скачок нагрузки. Увы, многие популярные подходы и технологии не выдерживают проверку высокой нагрузкой и быстро становятся узким местом в системе. Поэтому, проанализировав множество проблем, мы нашли оптимальные для нас (как мне кажется) пути их решения. Я расскажу, какие технологии мы выбрали, от каких отказались, и объясню, почему.
Микрософт с помощью пасьянса и косынки учила пользователей пользоваться мышью,
теперь с помощью windows 10 учит читать лицензионное соглашение.
После выхода windows 10 сразу появились сообщения о сборе информации о действиях пользователей и много обсуждений, что делать. Достаточно быстро пользователи составили список основных серверов, собирающих информацию и попытались их заблокировать через файл hosts. Но скептики сразу выдвинули здравое предположение, что MS мог предусмотреть этот метод и некоторые адреса прописать в коде. Тем более, что MS всегда может актуализировать адреса серверов через windows update.
В нашей компании начали появляться первые пользователи windows 10, и мы решили опробовать блокировку передачи телеметрии через встроенный windows firewall.
Я много раз сталкивался с задачей динамической генерации кода (например, при написании эффективного сериализатора или компилятора DSL). Это можно делать разными способами, какой из них лучший – дискуссия для отдельной статьи. По ряду причин я предпочитаю Reflection.Emit и CIL (Common Intermediate Language) и расскажу, с какими проблемами пришлось столкнуться на этом пути, а также об их решении: умной обертке над ILGenerator – GroboIL из библиотеки Graceful Emit.
Хочу отметить при этом, что иногда встречаются ситуации, когда у нас нет большого выбора: например, при написании сериализатора необходимо иметь доступ к приватным полям, и приходится использовать IL. Кстати, известный сериализатор protobuf-net содержит несколько сотен IL-инструкций.
Если вы ни разу не сталкивались с использованием IL-кода, то статья может показаться сложной для понимания, поскольку содержит много примеров кода с использованием IL. Для получения базовых знаний рекомендую прочитать статью Introduction to IL Assembly Language.
Наверное, многие из вас в своей практике сталкивались с задачей сбора почты с ряда ящиков. Зачем это может быть нужно? Наверное, потому что это универсальный механизм обмена данными между системами. Множество библиотек под любые языки, реализующих SMTP, POP3, IMAP, готовые решения по реализации стэка сообщений (как я сложно назвал почтовый ящик...) и т.д.
Неудивительно, что многие интеграционные задачи реализуются именно через почту. Тут в дело вступает некий сервис, который умеет эту почту быстро забирать, категоризировать и выполнять необходимые действия.
Кому достаточно приведенного ниже кода — дальше могут не читать:
foreach (var mailbox in mailboxes)
using (var client = new Pop3Client())
{
client.Connect(Hostname, Port, false);
client.Authenticate(User, Password);
var count = client.GetMessageCount();
for (var i = 0; i < count; i++)
{
Mail = client.GetMessage(i + 1);
var cat = SortMail(Mail);
DoSomething(Mail, cat);
}
}
Не так давно мы занялись проработкой книги "Writing High-Performance .NET code", которая до сих пор не переведена на русский язык, хотя ей и скоро год.
Нас, конечно, не удивило, что такую книгу уже растаскивают на цитаты, однако выяснилось, что уважаемый автор Бен Уотсон даже выложил на сайте «Codeproject» целую статью, написанную по мотивам одной из глав. К сожалению, объем этого материала слишком велик для хабропубликации, однако мы решили все-таки перевести первую часть статьи, чтобы вы могли оценить материал книги. Приглашаем к прочтению и к участию в опросе. Кроме того, если все-таки целесообразно перевести и вторую часть — пишите в комментариях, постараемся учесть ваши пожелания.
Начиная знакомство с nosql-базой Redis, практически в каждой статье ей посвященной, мы встречаем утверждение о том, что эта база невероятно быстро работает. Скорость работы действительно потрясающая, благодаря хранению данных в оперативной памяти.
Но представим ситуацию, когда Redis надрывается от нагрузки. Эта ситуация не редка. Что же в таком случае делать?
Добрый день! Не так давно прошла серия семинаров CLRium по новейшим технологиям и редко-раскрываемым темам CLRium #2. Мы собрали у себя в залах около 740 человек, что для нас является — фантастическим результатом. Сегодня хотелось представить вам свежие видеозаписи семинара и ссылки на репозитории спикеров:
Недавно сайт Fog Creek взял у меня интервью, и один из вопросов был связан с моими любимыми книгами по программированию, кодированию и разработке программ. Мне этот вопрос запомнился потому, что я давно себя считаю заядлым книжным ботаником. Книжный ботаник я потому, что безумно люблю книги о науке, компьютерах и программировании. Каждые несколько месяцев я уделяю день или два исследованию недавно изданной литературы и покупке наиболее понравившихся экземпляров. Я мог бы вечно разговаривать о своих любимых книгах. Ведь у меня их так много.
Меня настолько заинтересовал вопрос о книгах, что я решил начать новую серию статей на своём сайте catonmat о моих топ-100 книгах о программировании, программном обеспечении, науке, физике, математике и компьютерах. В каждой статье я буду размещать по пять книг, ведь разбивать огромное задачи на маленькие подзадачи — это самый простой способ их решать (GTD — get things done).
Взгляните на мою книжную полку, чтобы убедиться, что я настоящий ботаник:
Впервые я услышал о библиотеке MassTransit (MT) около года назад от экс-коллеги, зашедшего в наш офис для обмена опытом. Компания, в которую он устроился, использовала MT для уменьшения связности между модулями разрабатываемого ими сервиса и, поскольку высокая связность начала превращаться в проблему и для нас, чужой опыт оказался нам очень кстати. Помимо уменьшения связности путем перехода на событийную модель взаимодействия между модулями, MT пригодился нам и для распределения ресурсоемких задач между несколькими процессами.
C# довольно простой и гибкий язык. Вместе с .NET поставляется довольно много уже готовых классов, что делает его еще проще. Настолько, что вполне можно написать простой многопоточный HTTP-сервер для отдачи статического содержимого всего за 15 минут. Можно было бы использовать уже готовый класс HttpListener и управиться еще быстрее, но цель этой статьи — показать, как вообще можно сделать нечто подобное в C#.