Управление журналами чата, с точки зрения производительности - PullRequest
0 голосов
/ 21 декабря 2011

У меня есть приложение, получающее сообщения из разных источников (чаты и частные чаты).Можно открыть несколько экземпляров приложения, и конечный результат должен быть похож на следующий сценарий:

Desired data flow

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

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

Кроме того, мой текущий подход к написанию строк следующий:

public void Write(string message)
    {
        using (var writer = new StreamWriter(_fileName, File.Exists(_fileName)))
            writer.WriteLine(message);
    }

Что, учитывая, что журналы постоянно пишутся,Возможно, это не самое эффективное решение.

Подводя итог, я задаю следующие вопросы:

  • Как создать уникальную папку / базу данных журнала, поддерживая их формат (простой текст), но решаявышеупомянутая проблема с дубликатами / доступом?
  • Как улучшить, если возможно, метод письма?Помните, что журналы должны постоянно записываться, но закрытие StreamWriter при выходе из приложения не будет правильным решением, поскольку приложение должно работать в течение длительного времени.

Спасибо.

Ответы [ 4 ]

1 голос
/ 21 декабря 2011

Я бы придумал простое решение, которое могло бы соответствовать вашим потребностям, но не совсем уверен.

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

0 голосов
/ 22 декабря 2011

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

Когда пользователи входят в комнату чата, комната чата будет передавать объект регистратора пользователям.

Таким образом, все пользователи будут использовать один и тот же регистратор.Тогда возникает проблема: 1 потребитель (регистратор) и несколько производителей (все те пользователи, которые хотят войти).

См. мой ответ на это сообщение:

Запись в FileOutputStream из нескольких потоков в Java

здесь

https://stackoverflow.com/a/8422621/1007845

0 голосов
/ 21 декабря 2011

Не уверен, если я напишу это как ответ или комментарий, но, возможно, понадобится комната:

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

  • Вы создаете два приложения: LogWriter, который является одиночным и расположен в нижней части вашего эскиза
  • LogProcessor, который является экземплярами приложения вваш эскиз.
  • При запуске экземпляра LogProcessor он порождает LogWriter или подключается к нему, если он уже запущен.
  • LogProcessor обрабатывает входящие запросы журнала, может быть, предварительно обрабатывает их, если вам нужночтобы сделать это, затем отправляет их в LogWriter в виде набора меток времени, ChatroomID, UserID (не обязательно должен быть уникальным), текста и, возможно, хэша для упрощения дедупликации.При вычислении хэша в экземплярах лучше использовать несколько ядер
  • LogWriter хранит список зависаний, отсортированный по метке времени, содержащий хэши, поэтому он может быстро отбрасывать дублирующиеся элементы
  • ДляОстальные элементы LogWriter определяет путь к файлу журнала.Если поток уже открыт для этого пути, он записывает элемент, обновляет метку времени LastUsed для этого потока и выполняется
  • Если поток не открыт, LogWriter открывает его, а затем записывает.
  • Если достигнуто максимальное количество потоков, он закрывает самый старый поток (как в соответствии с вышеупомянутой меткой времени LastUsed) и вместо этого открывает необходимый новый поток.
0 голосов
/ 21 декабря 2011

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

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