Отключить (вежливо) веб-сайт, когда сервер sql находится в автономном режиме - PullRequest
3 голосов
/ 18 сентября 2008

Я работаю в колледже и занимаюсь разработкой сайта ASP.NET со множеством отчетов о студентах, статистике посещаемости ... Основой для данных является серверная БД MSSQL, которая является серверной частью нашей системы управления студентами , По утрам в четверг проводится регулярное техническое обслуживание в течение неизвестного периода времени (в зависимости от того, что должно быть сделано).

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

Надеюсь, что-то может быть реализовано глобально, а не на странице.

Ответы [ 8 ]

12 голосов
/ 18 сентября 2008

Перетащите html-файл с именем app_offline.htm в корень вашего виртуального каталога. Все просто.

Скотт Гатри на предмет и дружественные ошибки.

1 голос
/ 18 сентября 2008

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

void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
 string sPage = Request.ServerVariables["SCRIPT_NAME"];
 if (!sPage.EndsWith("Maintenance.aspx", StringComparison.OrdinalIgnoreCase))
 {
  //test the database connection
  //if it fails then redirect the user to Maintenance.aspx
  string connStr = ConfigurationManager.ConnectionString["ConnectionString"].ConnectionString;
  SqlConnection conn = new SqlConnection(connStr);
  try
  {
   conn.Open();
  }
  catch(Exception ex)
  {
   Session["DBException"] = ex;
   Response.Redirect("Maintenance.aspx");
  }
  finally
  {
   conn.Close();
  }
 }
}
1 голос
/ 18 сентября 2008

Что происходит сейчас, когда сайт не работает и кто-то пытается его открыть? Вызывает ли ADO.NET конкретное исключение, которое вы можете перехватить, а затем перенаправить на страницу «Вниз сайта»?

Вы можете добавить файл «Global.asax» в проект и в его коде добавить обработчик события «Application_Error». Он будет срабатывать всякий раз, когда исключение выдается и остается невосприимчивым из любой точки вашего веб-приложения. Например, в C #:

protected void Application_Error(object sender, EventArgs e)
{
    Exception e = Server.GetLastError().GetBaseException();
    if(e is SqlException)
    {    
        Server.ClearError();
        Server.Transfer("~/offline.aspx");
    }
} 

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

РЕДАКТИРОВАТЬ: Я понимаю, что вы говорите, petebob.

1 голос
/ 18 сентября 2008

Страница "offline.html" не будет работать, если пользователь уже перемещался по сайту, или если он обращается к сайту по закладке / внешней ссылке на определенную страницу.

Решение, которое я использую, заключается в создании второго веб-сайта с тем же адресом (IP-адрес или заголовок (и) узла), но по умолчанию он отключен. Когда веб-сайт не работает, сценарий деактивирует «настоящий» веб-сайт и вместо него включает «обслуживающий» веб-сайт. Когда он возвращается в онлайн, другой скрипт переключается обратно на «настоящий» веб-сайт.

Веб-сайт "обслуживания" находится в другом корневом каталоге, с одной страницей с сообщением (и всеми необходимыми файлами изображений / css)

Чтобы такое же сообщение отображалось на любой странице, на веб-сайте «техобслуживания» установлен обработчик ошибок 404, который перенаправит любой запрос на ту же страницу «Веб-сайт не обслуживается».

1 голос
/ 18 сентября 2008

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

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

Код Джеймса забывает закрыть соединение, вероятно, должно быть:

try
{
   conn.Open();
}
catch(Exception ex)
{
   Session["DBException"] = ex;
   Response.Redirect("Maintenance.aspx");
}
finally
{
   conn.Close();
}
0 голосов
/ 18 сентября 2008

Чуть более элегантной версией проверки БД на каждой странице будет проверка в файле Global.asax или создание главной страницы, от которой наследуются все другие страницы.

Предложение о наличии онлайн-сайта и офлайн-сайта действительно хорошо, но оно действительно применимо, если у вас есть ограниченное количество сайтов для управления на сервере.

РЕДАКТИРОВАТЬ: Черт, другие ответы с этими предложениями пришли после того, как я загрузил страницу. Мне нужно не забыть обновить перед ответом:)

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

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

Я знаю, что одним из способов является проверка флага на каждой странице, но я надеюсь избежать его. Не могу ли я что-то сделать со страницей global.asax, на самом деле, я думаю, что публикация затронула мой мозг:

Думаю, я мог бы добавить в Application_BeginRequest немного кода для проверки состояния SQL, а затем перенаправить:

HttpContext context = HttpContext.Current;
     if (!isOnline())
     {
        context.Response.ClearContent();
        context.Response.Write("<script language='javascript'>" + 
"top.location='" + Request.ApplicationPath + "/public/Offline.aspx';</scr" + "ipt>");
     } 

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

...