Комментарии 23
И если у вас 12 сервисов и есть необходимость динамического изменения конфигурации, то почему просто не использовать Consul или что-то подобное?
При этом у читалки XML из стандартного пакета есть проблемы, которые в принципе усложняют работу с ним, связанные прежде всего с плохой реакцией на опечатки в XML (которые в силу многословности XML не так уж редки), которые как раз дополнительно простимулировали нас уходить от него.
Читалку из .NETStandard для XML мы, честно скажу, не проверяли. У нее с обработкой опечаток дела обстоят лучше?
Consul и т.п. сервисы — да, была такая идея, и она, собственно говоря, никуда не делась, в будущем вполне возможно перейдем на какое-то единое решение, которое, кроме прочего, позволит конфигурировать не только указанные 12 серверов, но и все остальные сервисы, разрабатываемые у нас в компании. Но прямо сейчас это потребовало бы, по ощущениям, сильно больше телодвижений, чем просто выкинуть один способ работы с файликами конфигурации и заменить его на другой, всё остальное трогать нам сейчас не пришлось.
<config>
<param name="a" value="b"/>
<parameter name="a" value="b"/>
</config>
Просто будет документ в котором есть две ноды с разным названием.
Не то, чтобы я говорю, что вам не надо было переезжать на yaml, просто кажется что вы поменяли шило на мыло.
С другой стороны, если произошла унификация кода для работы с конфигами среди всех сервисов и проектов, то профит неоспорим.
так вот XML, от корого вы отказались, спокойно можно прочитать.
json/YAML конфиги даже на 500 стр уже читать и редактировать нереально.
если вы не знаете, что XML расширяется своими типами как только угодно, и вам было просто лень открыть гугл, прочитать, и дописать свой тип, который легко настраивается потом, для парсинга в тип при чтении, то это другой вопрос.
<setting name="MCXSettings" serializeAs="String">
<value>Inactive, ChartLen: 1000, PrintLen: 50, UseProxy: False</value>
</setting>
кто мешал сделать типа такого
<setting name="MCXSettings" serializeAs="String">
<CustomType>
<Inactive>
True
</Inactive>
<ChartLen>
1000
</ChartLen>
<PrintLen>
50
</PrintLen>
<UseProxy>
False
</UseProxy>
</CustomType>
</setting>
?
это занялоб несколько часов, а не недели гугления и боли. я б на месте заказчика за такое самоволосьтво не платил.
В этом проекте после перехода на YAML лично у меня тоже скорее положительные ощущения. Конфиги стали сильно меньше, опечатки в них исчезли, все проблемы стали видны сразу на старте приложения. Единственный сайд-эффект, который я пока наблюдал, то, что по началу табы, которые иногда получались вместо пробелов, портили чтение файла, но это не большая проблема, т.к. такие ошибки, как я уже сказал, сразу же всплывали на старте сервиса, плюс сама проблема достаточно легко решилась настройкой в редакторе.
Я может быть отстал от жизни, но для JSON/YAML общепризнанных стандартных форматов схем документов пока нет вроде бы.
Т.е. оставайтесь на XML, но сделайте конвертеры XML to YAML и обратно. Вручную правьте YAML. Храните и используйте — XML. Ну может быть за редким исключением, когда размер имеет архиважное значение, ужимайте в YAML. Хотя по-моему если использовать ZIP архивацию — вообще без разницы практически, будет ли предварительная стадия XML to YAML.
Такой подход облегчит вам экспорт-импорт и визуализацию на любые случаи жизни. XML всё-таки более распространён пока. Больше возможностей по трансформации в любые форматы — см. XSLT. Опять же — а есть ли уже что-то подобное для JSON/YAML?
В решении с YAML в том виде, как оно реализовано, получилось реальное упрощение чтения конфига глазами + более прозрачная работа парсера, вываливающая все встречающиеся ошибки явным образом.
Наверняка вы имеет ввиду только ошибки YAML стандарта. Но опечатка в имени параметра этот фильтр пройдёт. И пропущенный обязательный параметр, и неправильное значение (вне диапазона, допустим) — это всё тоже пройдёт незамеченным.
Самое лучшее описание API — то, которое умеет читать какой-нибудь парсер. Который может проверить документ на соответствие описанному стандарту. Так вот я и спрашиваю — есть ли подобное для JSON/YAML?
А то, что описание API так или иначе надо поддерживать… Ну что тут поделаешь — да, можно смотреть на это как на усложнение работы. И не делать эту часть работы. Какое-то время. Но когда вы сами начнёте путаться в своих конфигах и их версиях — вы об этой невыполненной части работы вспомните. Вздохнёте глубоко… И начнёте её делать. Имхо.
В статье как раз описывается как реализована проверка полноты и корректности конфига. Ошибки yaml синтаксиса вываливает yaml-читалка, а ошибки вида "не хватает такого-то параметра" или "этот параметр я не знаю" вываливает наш код. Описание формата у нашего кода конечно же есть, иначе зачем нам вообще этот конфиг, если мы не знаем, что из него брать. См. класс AppSettings в статье.
Насчёт схем формата, вынесенных в отдельный файл, наподобие xsd, я не задавался пока что таким вопросом, т.к. это было бы усложнение задачи поддержки конфигов. Нам в любом случае надо было бы и в коде поддерживать соответствие "такое-то поле мы используем вот здесь". Т.е. для добавления нового поля, например, нам потребовалось бы сделать это в xml, в xsd и в коде. Сейчас мы обходимся только добавлением в yml и в коде. Не вижу смысла усложнять работу
Т.е. вместо XML-ки с конфигами поддерживать еще и XSD-схемы для каждого вида серверов?
Желательно их автогенерировать, благо стандартный XmlSerializer это умеет. Впрочем, и в ручной поддержке актуальности схем я не вижу ничего страшного если новые настройки появляются не часто.
Да, XML многословен но не «плоский» как вы сказали а довольно легко поддерживающий иерархии.
У меня на проекте мы подумываем полностью отказаться от локальных конфигов в пользу централизованного сервиса. Да тот же Redis будет более удобен с минимальными настройками что бы хранить конфиги, а сервису /приложению нужно только знать как оттуда вычитать и какой десериализатор использовать (это может быть единственной настройкой которую как то нужно передать сервису). Локальные конфиг файлы будь-то XML/YAML/JSON/ini файл это большое зло.
XML не «плоский», плоская та структура, которую мы ранее для него предусматривали. Реализовать в нем вложенную структуру, конечно же, вполне можно было, но монструозность конфигов сильно увеличилась бы.
Получившиеся у нас сейчас конфиги хорошо читаются глазами.
Схему автор не использовал.
Тоже думаю хранить конфиги централизовано. (Руки еще не дошли до прода)
Вот только вопросы с выбором формата и инструмента ( read\write) остаются.
В идеале хочется следующего — приложение знает один единственный URL или иную точку входа и знает свой собственный тенант идентификатор (у нас малтитенатси) и этого хватает что бы вычитать свой конфиг и запуститься.
Раз в X минут приложение перечитывает конфиг файл.
JSON удобен тем что можно для разных версий приложения добавлять новые настройки и пока не меняется схема то все работает. Но это только мой Proof Of Concept и бизнес может просто не дать денег на это следуя правилу — «оно и так работает а как припечет то может тогда».
(Я говорил про конфиг для инициализации. Думаю брать напрямую из базы или через кеш со временем жизни(типа redis), если вдруг будет не доступен сервис с конфигами)
В любом случае, имея централизованный конфиг, его можно деплоить по тем же правилам, что и сам сервис, но отдельно от сервиса. Можно откатывать.
Очень удобно, если все это реализовать. Нужно ли — не знаю.
Может вы это и так уже делаете…
Как мы перевели конфигурирование наших сервисов с XML на YAML