Пользователь
0,0
рейтинг
25 декабря 2014 в 13:55

Разработка → Первые шаги к онлайн-офису на Linux или как мы портировали под Mono (о сложностях и их преодолении)



Вчера мы выпустили ONLYOFFICE под Linux и спешим поделиться не только новостями, но и полезной информацией для тех, кто, как и мы, 5 лет назад оказался в собственной ловушке под названием «ASP.Net»

Попытки портировать приложение на Unix с использованием проекта Mono мы начали предпринимать еще 4 года назад, однако, долгое время у нас ничего не получалось, поскольку на тот момент Mono сильно отставал по функционалу при портировании с .Net под Windows. В частности, в Mono была сильно урезана поддержка wcf, а также плохо работал asp.net mvc. Впрочем, к счастью разработчиков все эти годы проект Mono активно развивался — добавилась поддержка .Net 4.0 и .Net 4.5, так что весной 2013 мы решили возобновить работу.

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

Основные сложности при портировании на Mono



1. Работа с файловой системой


Что происходит: сайт не открывается, картинки не отображаются или отображаются некорректно. Сейчас проблема подробно описана на официальном сайте Mono Project.

В чем дело: в Windows прямой и обратный слеш — это одно и тоже, а в Unix — два совершенно разных пути. В Windows пути нечувствительны к регистру, а в Unix — это разные имена.
Как решить проблему:
  • замена всех строк с путями и разделителями директорий в них на работу через класс Path. Использование везде Path.Combilne и Path.DirectorySeparatorChar.
  • проверка всех css и аналогичная корректировка путей для работы под обеими системами.
  • использование в Mono переменной окружения MONO_IOMAP=all для работы под Mono с путями с возможностью игнорирования регистра символов.

2. Незакрывающиеся транзакции


Что происходит: незакрывающиеся транзакции в базе данных MySQL.
В чем дело: к сожалению, так и не выяснили до конца (есть предположения?)
Как решили: добавили параметр в строке подключения AutoEnlist=false

3. Различия в работе xml Mono сериализаторов


Что происходит: различие в xml представлении полей со значением null и исключение в mono сериализаторе при использовании пустых namespace в xml.
Как решили: Убрали wcf сервис модуля «Документы» и заменили на webapi.

4. Утечки памяти


Что происходит: утечка памяти при использовании mod_mono_server для apache2. Например, при вставке новых данных в HttpRuntime.Cache с ключом, который уже есть в кеше, Mono, в отличие от .NET, не освобождает память занятую предыдущими данными.
В чем было дело: все ещё загадка для нас.
Как решили: для решения данной проблемы требуется явно удалять старые данные перед вставкой новых. Мы в свою очередь перешли на nginx, где подобной проблемы не наблюдалось.

5. Исключения типа NullReferenceException


Что происходит: в WCF-сервисе при обращении к членам класса ConfigurationManager возникал NullReferenceException, если ранее мы где-либо перезаписывали свойство HttpContext.Current.
В чем дело: если вручную выставить в не веб-приложении HttpContext.Current, то mono начинает использовать вместо ConfigurationManager — WebConfigurationManager, что приводит к исключениям в не веб-приложении.
Как решили: избавились от установки вручную HttpContext.Current.

6. Несовместимость Microsoft версии и HTTP WCF


В чем дело: HTTP WCF Mono сервис имеет много мелких различий по сравнению с Microsoft версией (например, небольшие различия в xml при сериализации; в mono версии расширения нельзя указать через атрибуты, только через конфигурационный файл; отсутсвует HttpContext.Current, и так далее).
Как решили: переписали HTTP WCF сервис документов на версию, основанную на Web API.

7. Падение SignalR-сервера при нагрузочном тестировании


В чем дело: при обмене сообщениями в чате, встроенном в страницу, мы используем библиотеку ASP.NET SignalR. При портировании ONLYOFFICE под Mono нам хотелось бы и там использовать данную библиотеку. Она поддерживает несколько типов транспортов для передачи данных: websockets, long polling, forever frame, server sent events. Наиболее предпочтительной для нас является технология вебсокетов, которую мы используем в нашей Saas-версии. К сожалению, на данный момент SignalR не позволяет использовать вебсокеты под Mono, поэтому была предпринята попытка в качестве транспорта использовать Long Polling. Но на этапе нагрузочного тестирования SignalR-сервер падал с исключением System.IO.IOException: «Too many open files» — примерно после тысячи подключений клиентов. При последующем изучении проблемы была замечена утечка сокетов на SignalR-сервере после дисконекта клиента, о чем мы сообщили разработчикам SignalR. Надеемся в следующей версии SignalR данная проблема будет решена.
Как решили: другие транспорты не подходят для решения наших задач по разным причинам, поэтому на данный момент для версии под Mono нам пришлось отключить чат, работающий через SignalR.

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

Что мы имеем в итоге


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



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

Тренд на Docker


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

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

Онлайн-редакторы документов на Linux — Coming Soon


Большая часть бекэнда редакторов документов ONLYOFFICE написана на С++, поэтому перевод приложения под Linux осуществляется иными методами.

Например, недавно мы закончили работу с элементами, отвечающими за конвертацию форматов документов. Основная сложность здесь состоит в том, чтобы избавиться от компонентов ActiveX и ATL.

Чтобы реализовать задуманное, необходимо было осуществить четыре шага:
  • Избавиться от контейнеров ATL (таких как списки, массивы и т.д) и использовать вместо них STL
  • Переписать CString — класс для работы со строками — для других платформ.
  • Избавиться от платформозависимых вызовов API и, где необходимо, использовать сторонние библиотеки (например, написали враппер над библиотекой cURL для закачки картинок, вместо WinInet — части WinAPI для работы с сетью).
  • Уйти от ActiveX и собрать LIB'ы вместо COM-библиотек, а также исполняемые файлы, использующие эти либы.

В ближайшие планы входит разработка десктопных офисных приложений под популярные ОС, поэтому для сборки мы использовали qmake из фреймворка Qt Framework. К тому же IDE QtCreator показалась наиболее удобным вариантом для разработки и отладки кода.

* * *

Если бы мы начинали разработку продукта сегодня, то конечно, обратились бы к ASP.NET vNext, который анонсировали как раз к окончанию процесса портирования ONLYOFFICE (о несправедливый мир разработки!). Впрочем, дело уже сделано, а планы, как всегда, наполеоновские. В следующем году мы выпускаем открытый онлайн-офис под Linux, а значит сможем наконец помериться силами с OpenOffice на их же территории. Впрочем, это уже совсем другая история, о которой мы подробнее расскажем в январе.

А пока что наша команда поздравляет всех с наступающим Новым Годом!
ps. Кто душой уже на каникулах, а телом в офисе, может скоротать часы, посчитав всех пингвинов на фотке (наши сотрудники не в счёт ;)

@Galkinator
карма
30,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (24)

  • 0
    www.onlyoffice.com/ru/server.aspx

    Server Error in '/ru' Application.
    The resource cannot be found.

    Не получается скачать серверную версию.
  • +4
    Спасибо за интересную статью.
    Я в работе тоже встретился с проблемой не закрывающихся транзакций к MySQL, но к сожалению так и не нашёл решения. Судя по багтраку, проблема известна и встречается крайне часто. Обещали исправить, но до сих пор встречается и очень часто.
  • +5
    Отлично! Спасибо вам за такую обширную работу. Кросплатформенность — сложная, но вместе с тем укрепляющая ядро проекта вещь.
    Надеюсь, в новом году число ваших клиентов приумножится =) с наступающим!
  • +4
    К сожалению, на данный момент SignalR не позволяет использовать вебсокеты под Mono, поэтому была предпринята попытка в качестве транспорта использовать Long Polling.

    Пилю понемногу OWIN-сервер на базе фейсбучного proxygen. Учитывая, что proxygen вебсокеты поддерживает, тут они тоже будут, когда более-менее стабилизируется всё остальное. Пока на живом проекте это дело не использовалось, но на локалхосте удалось из WebApi на нём выжать 22K запросов в секунду. Если интересно, можете присоединяться.

    В чем дело: HTTP WCF Mono сервис имеет много мелких различий по сравнению с Microsoft версией (например, небольшие различия в xml при сериализации; в mono версии расширения нельзя указать через атрибуты, только через конфигурационный файл; отсутсвует HttpContext.Current, и так далее).
    WCF скоро скопипастят из .NET 4.6, прогресс копипасты можно смотреть тут, а при желании просто собрать самостоятельно и таскать за собой нужную реализацию.
  • 0
    Пару лет назад пришлось приводить в чувства проект под моно, доставшийся «в наследство». Сделал вывод — моно не подходит, на тот момент он был слишком сырой. Не думаю, что за это время что-то изменилось. Приложение было серверным и падало на продакшене где-то раз в два дня в коредамп. Установить истиную причину падений так и не удалось, хорошо что заказчика устроил перезапуск.

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

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

    С тех пор для меня решен вопрос «mono vs java». Если надо делать что-то под линукс — моно даже не рассматриваю как серьезную альтернативу.
    • 0
      И все хорошо, но стактрейсы оно показывало урезано — без номеров строк и имен процедур.
      переменная окружения MONO_OPTIONS=--debug включает загрузку символов. Если они в pdb, то их надо сконвертить в mdb специальной утилитой.
      Шарпдевелоп тогда вообще не умел делать проекты для xsp2, как сейчас — не знаю.
      MonoDevelop сто лет как умеет под XSP запускать, вероятно, у вас что-то было недоустановлено.
      И еще там запомнился странный баг компилятора. Если в одном из файлов проекта в определенном месте добавить пробел — в шарпдевелопе под линуксом оно не собиралось. В последующих версиях, я пробовал — этот баг уже исправили, но все равно сам факт такого бага выглядит странным.
      Не понимаю, зачем собирать чем-то кроме студии, но вам виднее.

      Ещё есть мнение, что вы зачем-то его запускали на Mono 2.6 при живом 2.10.8 (это же 2 года назад было, верно?) да ещё и с Boehm вместо GC.
      • 0
        Насколько помню, студия делала mdb, а моно их просто не читало, хотя опцию --debug включал. Но инфа не 100%, т.к. это было давно. Делал еще какой-то финт ушами, но уже не помню что. Было это не менее, чем 2 года назад — т.е., так давно что уже точно неприпомню когда.

        По этой же причине версию моно тоже не помню, могу лишь сказать что ставил самую последнюю на тот момент. Помню, что ставил из пакетов, с исходниками не возился. Поэтому какой там GC стоял — тоже сказать не могу.
        • 0
          Студия не умеет писать mdb, только pdb. Есть специальная утилита pdb2mdb, её надо натравливать. В штатных репозиториях очень долгое время был 2.6 в то время как в разных PPA и прочем были более свежие и рабочие версии.
    • 0
      В этом году Microsoft многих удивил, открыв исходники .NET Core. Обещали открыть Runtime в 2015, были слухи о слиянии C# и Mono. Поэтому на данный момент всё может быть не так плохо (сам с C#/Mono не работаю, только новости пробегаю глазами).
      • –2
        Честно говоря, глядя на то, как работает скайп под линуксом — я бы неособо надеялся, что в ближайшем обозримом будущем под линуксом будет полноценный стабильный шарп.
        • 0
          Вы путаете компанию, которая пилит Скайп, и принадлежит МС и сам МС. Даже внутри МС каждая команда может сама выбирать свой стиль и подход к разработке. Это совершенно разные команды разработки. В свете открытия исходников и возможности к выходу следующей студии переехать на кроссплатформенный стек — для меня Java потеряла всякий смысл и интерес. Как и для нескольких проектов о которых я знаю. А если товарищ kekekeks допилит свои биндинги для OWIN — вообще будет сказка)
          • 0
            Если не хочется ждать этих биндингов, можно пока вот эту штуку на базе libevent/evhttp использовать, вебсокетов нет и не планируется, зато в продакшне уже больше года крутится. Оно, правда, для NancyFx преимущественно делалось, но перед конфой .NEXT я туда докрутил OWIN-хост. С WebApi использовать так.
            • 0
              У меня все проекты используют MVC+WebApi. Пока максимально отвязался от Sytem.Web, перенес все модули в OWIN middleware и жду порта) Но спасибо за наводку. Попробую в одном из своих личных проектов.
      • 0
        Там не будет слияния как такового — в Mono будут перетаскиваться куски дотнета, которые не прибиты гвоздями к Win32 API.
    • НЛО прилетело и опубликовало эту надпись здесь
      • –2
        Ясно. Ну что ж. Значит, развивается моно!

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

        Посмотрим, что будет дальше. Пока будущее моно неясно, а настоящее ненастолько светлое, чтоб можно было на эту технологию перейти.
  • 0
    Но на этапе нагрузочного тестирования SignalR-сервер падал с исключением System.IO.IOException: «Too many open files» — примерно после тысячи подключений клиентов.


    Почитайте про ulimit — проблема возможно решится без правки SignalR
    • +3
      Дело в том, что происходит утечка сокетов, а не просто сервер упирается в ограничения по открытым сокетам. ulimit только отсрочит падение сервера.
  • –5
    Какую боль вы решаете? Пока я вижу, что вы боль создаёте. А это плохо — карму портит.
  • 0
    Не могли бы вы уточнить версию mono, версию asp.net mvc,… Давно хочу поиграться с asp.net mvc под mono.
    • 0
      Инфраструктура именно ASP.NET работает не очень хорошо и местами подтормаживает. Лучше играйте пока с WebAPI, ServiceStack, NancyFx и прочими фреймворками, умеющими хоститься поверх OWIN, там всё практически идеально. В vNext это исправят, перетащив ASP.NET MVC и WebPages на OWIN, но пока оно в ранней бете.
  • +4
    Интересно, а насколько в итоге получились соизмеримы трудозатраты на портирование и коммерческий выхлоп от этого?
  • +1
    В ближайшие планы входит разработка десктопных офисных приложений под популярные ОС, поэтому для сборки мы использовали qmake из фреймворка Qt Framework.

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

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