существует ли язык защиты от стихийных бедствий? - PullRequest
41 голосов
/ 10 сентября 2009

При создании системных служб, которые должны иметь высокую надежность, я часто заканчиваю тем, что пишу множество «отказоустойчивых» механизмов в случае таких вещей, как: потеря связи (например, связь с БД), что произойдет, если питание теряется, а служба перезапускается .... как собирать куски и продолжать правильно (и помнить, что при подборе кусков сила может снова уйти ...) и т. д. и т. д.

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

Это уже существует? Если так, где я могу найти это? Если нет, то почему это не может быть реализовано? Мне кажется, это очень удобно для критических систем.

p.s. В случае потери соединения с БД это будет означать, что возникла проблема, и необходимо ручное вмешательство. В тот момент, когда соединение восстановится, оно продолжит с того места, где остановилось.

EDIT: Поскольку обсуждение, похоже, прошло, позвольте мне добавить несколько моментов (пока я жду, прежде чем смогу добавить награду к вопросу)

Отклик Эрланга сейчас, похоже, самый высокий. Я знаю об Эрланге и читал прагматичную книгу Армстронга (основного создателя). Это все очень хорошо (хотя функциональные языки заставляют мою голову вращаться при всей рекурсии), но бит «отказоустойчивый» не приходит автоматически. Отнюдь не. Erlang предлагает множество супервизоров и других методологий для контроля процесса и его перезапуска в случае необходимости. Тем не менее, чтобы правильно сделать что-то, что работает с этими структурами, вам нужно быть настоящим гуру erlang, и вам нужно, чтобы ваше программное обеспечение соответствовало всем этим фреймворкам. Кроме того, если питание падает, программист тоже должен собрать кусочки и попытаться восстановить при следующем запуске программы

То, что я ищу, является чем-то гораздо более простым:

Представьте себе язык (такой простой, как, например, PHP), где вы можете делать такие вещи, как запросы к БД, выполнять над ними действия, выполнять операции с файлами, выполнять операции с папками и т. Д.

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

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

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

EDIT: Кажется (судя по всем комментариям и ответам), что такой системы не существует. И, вероятно, не будет в ближайшем обозримом будущем из-за невозможности получить (почти?) Право.

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

(или подход к контрольной точке, как указал один из комментаторов (как в видеоигре). Установите контрольную точку .... и, если программа умрет, перезапустите здесь в следующий раз.)

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

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

Всем спасибо за вклад и отличные идеи.

Ответы [ 28 ]

1 голос
/ 10 сентября 2009

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

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

0 голосов
/ 15 сентября 2009

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

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

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

Виртуальные машины вообще предназначены для такого рода вещей. Вы можете использовать API поставщиков VM (vmware..et al) для управления периодическими контрольными точками в вашем приложении.

В частности, VMWare имеет функцию воспроизведения (Enhanced Execution Record), которая записывает ВСЕ и позволяет воспроизводить момент времени. Очевидно, что при таком подходе наблюдается огромный спад производительности, но он будет соответствовать требованиям. Я бы просто позаботился о том, чтобы на ваших дисках был кэш записи с батарейным питанием.

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

0 голосов
/ 16 сентября 2009
  • Во-первых, реализовать отказоустойчивое приложение. Один, где, где, если у вас есть 8 функций и 5 режимов отказов, вы провели анализ и тестирование, чтобы продемонстрировать, что все 40 комбинаций работают так, как задумано (и по желанию конкретного клиента: ни одна из них, вероятно, не согласится).
  • во-вторых, добавьте язык сценариев поверх поддерживаемого набора отказоустойчивых функций. Оно должно быть как можно ближе к состоянию без состояния, так что почти наверняка что-то не полное по Тьюрингу.
  • наконец, выясните, как обрабатывать восстановление и исправление состояния языка сценариев, адаптированного к каждому режиму сбоя.

И да, это в значительной степени ракета наука .

0 голосов
/ 19 сентября 2009

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

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

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

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

0 голосов
/ 19 сентября 2009

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

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

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

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

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

0 голосов
/ 15 сентября 2009

Если вы хотите сохранить информацию о программе, где бы вы ее сохранили?

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

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

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

0 голосов
/ 18 сентября 2009

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

Очевидно, что разработка веб-контента на C довольно медленнее, чем на языке сценариев, но он будет работать лучше и будет более стабильным (если вы, конечно, напишите хороший код:).

Реально, я бы написал это на Ruby (или PHP или что-то еще), и чтобы что-то вроде Delayed Job (или cron или любого другого планировщика) запускало его так часто, потому что мне не нужно было бы что-либо обновлять в тактовом цикле.

Надеюсь, что это имеет смысл.

0 голосов
/ 18 сентября 2009

Windows Workflow Foundation может решить вашу проблему. Он основан на .Net и графически оформлен как рабочий процесс с состояниями и действиями.

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

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

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

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

...