отслеживать информацию о посетителях по каждому запросу

Используя веб-формы Asp.net, я хочу отслеживать информацию о посетителях так же, как это делает Google Analytics. Конечно, для этой цели я могу использовать Google Analytics, но я хочу знать, как добиться того же с помощью Asp.net 3.5 и SQL Server 2008.

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

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

т. е. обычно это происходит, когда мы сохраняем данные в db, текущий запрос останавливается на конкретном статусе вызова SP и продвигается вперед, когда он завершает выполнение оператора SP или tsql. Я хочу следовать подходу «Вставить и забыть». Он должен вставляться в фоновом режиме, когда я передаю параметр конкретному событию или функции.

Я нашел ниже альтернативы для этого:
1. PageAsynchTask
2. BeginExecuteNonQuery
3. Метод Jquery Post и веб-сервис (но я не уверен в этом, и мне интересно, как мне это сделать)

Надеюсь, я правильно упомянул о своей проблеме.

Может ли кто-нибудь сказать мне, какой из них лучше подходит? Также дайте мне знать, если у вас есть другие идеи или лучший подход, чем указанный. Ваша помощь будет действительно оценена.


person Nilesh Thakkar    schedule 25.04.2011    source источник


Ответы (4)


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

Лучше всего просто писать в файлы журналов, используя какую-нибудь высокопроизводительную библиотеку журналов. Библиотеки ведения журналов оптимизированы для многопоточного ведения журналов. Они не производят вызовы ввода/вывода при каждом вызове. Журналы хранятся в буфере памяти и периодически сбрасываются. Вы должны использовать EntLib или Log4net для регистрации.

Вы можете использовать HttpModule, который перехватывает каждый GET, POST, а затем внутри HttpModule вы можете проверить, является ли Request.Url aspx или нет. Затем вы можете прочитать Request.Headers["__ASYNCPOST"] и посмотреть, является ли оно «истинным», что означает, что это асинхронное обновление UpdatePanel. Если все эти условия выполняются, вы просто регистрируете запрос в файле журнала, в котором хранится

Вы можете получить IP-адрес клиента из:

HttpContext.Current.Request.UserHostAddress; 
or 
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

Чтобы получить IP-адрес машины, а не прокси, используйте следующий код

HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

Однако вы не можете получить страну. Вам нужно будет зарегистрировать IP-адрес в своих файлах журнала, а затем обработать файлы журнала с помощью некоторого консольного приложения или задания, которое определит страну IP-адреса. Вам нужно получить некоторую базу данных IP-> Country, чтобы выполнить эту работу. Раньше я использовал http://www.maxmind.com/app/geoip_country.

Для размера экрана вам придется полагаться на некоторый javascript. Используйте javascript на каждой странице, который определяет размер экрана на стороне клиента и сохраняет его в файле cookie.

var screenW = 640, screenH = 480;
if (parseInt(navigator.appVersion)>3) {
 screenW = screen.width;
 screenH = screen.height;
}
else if (navigator.appName == "Netscape" 
    && parseInt(navigator.appVersion)==3
    && navigator.javaEnabled()
   ) 
{
 var jToolkit = java.awt.Toolkit.getDefaultToolkit();
 var jScreenSize = jToolkit.getScreenSize();
 screenW = jScreenSize.width;
 screenH = jScreenSize.height;
}

После того, как вы сохраните его в файле cookie (я не показывал этот код), вы можете прочитать размеры экрана из HttpModule с помощью Request.Cookies, а затем зарегистрировать его в файле журнала.

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

Это дает вам полное решение проблемы?

person oazabir    schedule 07.05.2011
comment
Вы должны хранить необработанные журналы в файлах журналов. Затем вы можете создать некоторую службу Windows или консольное приложение, которое обрабатывает необработанные журналы, а затем выполняет сопоставление IP -> Country, а затем сохраняет сводную информацию в базе данных. Я предлагаю не хранить каждое посещение в базе данных. лучше всего хранить ежедневную сводку или сводку по стране в базе данных и отображать ее на панели администратора. - person oazabir; 10.05.2011

Первый подход выглядит хорошо. (И я рекомендую это.) Но у него есть 2 недостатка:

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

Второй подход выглядит неудобным и может привести к ошибкам. (Вы должны следить за ситуацией, когда ваша страница отображается быстрее, чем обрабатывается ваш запрос. Я не уверен, что произойдет, если ваш запрос не будет завершен, когда объект вашей страницы будет уничтожен, а сборщик мусора продолжит работу finalize()... но я полагаю, ничего хорошего. Вы можете избежать этого, дождавшись IAsyncResult.IsCompleted после рендеринга, но это неудобно.)

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

Лично я хотел бы реализовать ведение журнала в BeginRequest, чтобы избежать дублирования кода, но вам нужен IsPostback... Тем не менее, может быть обходной путь.

person Dmitry    schedule 26.04.2011
comment
Я ценю ваше время, потраченное на ответ на мой вопрос. - person Nilesh Thakkar; 26.04.2011
comment
Я ценю ваше время, потраченное на ответ на мой вопрос. Я знал о втором пункте для первого подхода, но первый пункт может быть проблемой, как вы сказали. Второй подход я никогда не использовал, но проверю. Я отказался от идеи использования третьего подхода. Как вы сказали, я могу сделать это в BeginRequest, но я думаю, что сеанс недоступен в этом событии, поэтому, если я хочу отследить информацию о пользователе, это мне не поможет. Я думаю, что мне нужно использовать Application_PreRequestHandlerExecute, так как сеанс будет доступен в этом. Я прочитал эту статью. - person Nilesh Thakkar; 26.04.2011
comment
Я по-прежнему открыт для других идей и лучшего подхода. - person Nilesh Thakkar; 26.04.2011

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

для этого вам нужно создать веб-службу для выполнения операций с базой данных или вы можете использовать ее для всей обработки событий.

со стороны сервера вы должны вызывать веб-службу асинхронно, как это

Объявить частного делегата

private delegate void ReEntryDelegate(long CaseID, string MessageText);

Теперь метод будет содержать вызов веб-сервиса, подобный этому

WebServiceTest.Notification service = new WebServiceTest.Notification();
IAsyncResult handle;
ReEntryDelegate objAscReEntry = new ReEntryDelegate(service.ReEntryNotifications);
handle = objAscReEntry.BeginInvoke(CaseID, MessageText, null, null);
break;

И значения переменных будут переданы методом здесь (CaseID,MessageText)

Надеюсь, это ясно для вас

Всего наилучшего

person Bhaarat    schedule 04.05.2011

Говоря о серверной части, если вы работаете на IIS и вам не нужна абсолютная информация в реальном времени, я рекомендую вам использовать журналы IIS.

Нет ничего быстрее этого, так как он был оптимизирован для производительности, начиная с IIS 1.0.

Вы можете добавить в эти журналы свою собственную информацию (HttpRequest.AppendToLog), они имеют стандартный формат, есть API, если вы хотите делать с ним пользовательские вещи (но вы все равно можете использовать анализатор текста, если хотите), и есть множество бесплатных инструментов, например < href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en" rel="nofollow">парсер журналов Microsoft, может передавать данные в базу данных SQL (среди прочего).

person Simon Mourier    schedule 04.05.2011
comment
Спасибо Саймон за ответ. Файл журнала IIS содержит слишком много информации, чем требуется, меня не беспокоит, если к определенному изображению обращаются несколько раз, и становится сложно, когда ваши данные разбросаны по файлам. Мы, конечно, можем анализировать файлы журналов с помощью упомянутой вами утилиты или других доступных в сети. Было бы трудно увидеть активность в рамках отдельного сеанса и возвращение какого-либо посетителя. Response.AppendToLog добавляет детали в URI, и если мы ожидаем другой параметр, будет ограничение по длине. Я рассматриваю это как последний вариант. Еще раз спасибо за ваш неоценимый вклад. - person Nilesh Thakkar; 08.05.2011