Хороший дизайн для Прозрачного SMTP Proxy сервера в C # - PullRequest
4 голосов
/ 10 марта 2011

Если вы спроектировали прозрачный SMTP-прокси в C # (.net 4) для удовлетворения следующих начальных требований

  • Хорошо масштабируется
  • Регистрирует весь трафик в базе данных
  • Можно легко расширить, скажем, для вложений в антивирусное сканирование

Учитывая эти факторы в целом, как бы выглядел ваш дизайн?Вы бы создали конкретные классы Listener, Sender и logger или что-то более абстрактное?И вы бы использовали обратные вызовы, потоки или процессы и почему?

Ответы [ 2 ]

7 голосов
/ 17 марта 2011

Это нетривиальное приложение. Некоторые идеи, которые должны помочь:

Масштабируемость SMTP

В целом, масштабирование сетевого приложения означает возможность масштабирования (как на большем количестве машин), а не на увеличение (более дорогая машина). Это означает, что несколько серверов могут обрабатывать запросы SMTP. Обратите внимание, что для этого, вероятно, потребуется поддержка на сетевом уровне (маршрутизаторы, которые могут распространять сообщения в «ферму SMTP»).

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

Что касается процессов, я думаю, что один процесс (скорее всего, служба Windows) с несколькими потоками для каждого SMTP-сервера - это хороший путь.

Масштабируемость базы данных

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

Надежность SMTP

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

Надежность базы данных

Чтобы сделать базу данных надежной, вам также потребуется выполнить некоторую кластеризацию. Это не дешево и не тривиально (но было сделано несколько раз с несколькими платформами баз данных).

Очередь

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

Расширяемость

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

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

С точки зрения добавления поддержки подключаемого модуля вы можете использовать что-то вроде MEF (Managed Extensibility Framework).

Изобретая колесо

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

0 голосов
/ 19 марта 2011

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

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

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

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

Расширяемость Я бы не стал так много думать. Достижение масштабируемости и надежности НАМНОГО сложнее и, следовательно, гораздо важнее правильно понять. Расширяемость - это просто возможность подключить дополнительные шаги по пути, и вы можете добавить швы для этого, когда базовая система на месте или когда вы начинаете добавлять функциональность, которая, по вашему мнению, должна быть дополнительной, но встроенной.

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