IIS Hosted 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 Test Client, работещ на моята локална машина. Също така забелязах, че когато в това състояние сървърът не може да преглежда мрежовите файлови ресурси - влязох отдалечено и се опитах да намеря свързана с мрежата папка за съхранение, тя не успява да се свърже. МОГА обаче да се обаждам КЪМ този сървър, напр. Мога да отворя тестов клиент на WCF и да се свържа с централната WCF услуга и да извикам неговите методи за ping. Комуникациите са разрешени IN, но не и OUT от сървъра.

Няколко интересни точки:

В състояние на грешка връзките КЪМ сървъра могат да бъдат направени, но не и ОТ сървъра.

Всяка от моите услуги (Централна 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