Размещенная в IIS служба WCF не перерабатывает TCP-порты. Недостаточно ресурсов winsock.

У меня есть служба WCF, размещенная на IIS 7, которая успешно работает в течение определенного периода времени, а затем не может связаться с другими сетевыми местоположениями (я подозреваю, что нет доступных TCP-портов для подключения к внешнему миру)

Предыстория приложения:

Моя система перекодирует большие медиафайлы (что требует времени). У меня есть централизованно размещенная служба WCF, которая находится на сервере A и будет называться «Центральная служба WCF». Затем у меня есть много клиентских сервисов, которые фактически перекодируют медиафайлы на разных серверах: B, C, D, E, F и так далее, которые будут называться «сервисами клиентского процессора». Центральная служба WCF управляет тем, какая служба клиентского процессора отправляет «задания перекодирования» для обработки. Каждая из этих служб клиентского процессора является автономной службой WCF, они в основном выполняют длительный процесс и опрашиваются центральной службой WCF, проверяя процент выполнения задания. Таким образом, центральная служба WCF открывает множество подключений к этим клиентам, чтобы опрашивать их о ходе выполнения работы, опрос для каждого из клиентов происходит примерно раз в 2–3 секунды.

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

public ClientProcessorClient getClientByaddress(string address)
{
    Binding bidning = new NetTcpBinding(SecurityMode.None);
    return new ClientProcessorClient(bidning, new EndpointAddress(address));
}

public void pollJobs()
{
    foreach (string clientAddress in clients)
    {
        ClientProcessorClient client = getClientByaddress(clientAddress);
        int progress = client.GetProgress();
        client.Close();
        // Do stuff with progress
    }
}

Что происходит, когда он ломается:

Я могу отправить множество заданий перекодирования в центральную службу WCF, и она отправляет задания клиентам, успешно обновляя прогресс и т. Д. Примерно через час обработки сервер, на котором размещена центральная служба WCF, перестает работать должным образом. Центральная служба WCF Insufficient winsock resources available to complete socket connection initiation. выдает ошибки при попытке связаться с клиентскими службами WCF. Все клиентские службы WCF доступны для проверки связи с тестового клиента WCF, запущенного на моем локальном компьютере. Также я заметил, что, когда в этом состоянии сервер не может просматривать сетевые файловые ресурсы - я вошел в систему удаленно и попытался найти папку сетевого хранилища, она не может подключиться. Однако я МОГУ совершать звонки НА этот сервер, например. Я могу открыть тестовый клиент WCF, подключиться к центральной службе WCF и вызвать его методы ping. Связь с сервера разрешена ВХОДЯЩАЯ, но НЕ ВЫХОДЯЩАЯ.

Несколько интересных мест:

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

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

Центральная служба WCF размещена в IIS 7, и повторное использование пула приложений отключено.

К сожалению, именованный канал не подходит (клиенты и серверы находятся на разных машинах)

Мои мысли / вопросы

Все признаки указывают на то, что на сервере заканчиваются сокеты TCP. Правильно ли я настраиваю WCF ClientProcessorClient? Правильно ли я утилизирую их? Мне нужно заключить их в using оператор? Кто-нибудь знает, как я могу отладить / диагностировать, где возникает проблема?

Спасибо


person user989056    schedule 12.04.2012    source источник


Ответы (1)


Хорошо это или плохо, но Microsoft решила реализовать логику прокси-сервера службы WCF (либо ClientBase, либо напрямую из ChannelFactory), чтобы разрешить создание исключений в методе Close (). Я считаю, что все, что делает метод Dispose (), - это вызов Close (), но я никогда не пытался просмотреть исходный код. Если прокси находится в неисправном состоянии, необходимо вызвать Abort (), чтобы освободить ресурсы (например, сеансы TCP).

Подразумевается, что прокси-сервер службы WCF не освобождает ресурсы до тех пор, пока вызов Close () или Abort () не завершится успешно. Взгляните на это сообщение в блоге, чтобы узнать, как правильно закрытие экземпляра прокси.

person Sixto Saez    schedule 12.04.2012
comment
Я протестирую это в ближайшее время, хотя я почти уверен, что Close() действительно работает каждый раз, поэтому «не должно» оставаться открытых сокетов, исходя из того, что вы только что сказали. - person user989056; 15.04.2012