最近弄了個wcf的監控服務,偶爾監控到目標服務會報一個目標積極拒絕的錯誤。一開始覺得服務中止了,上服務器檢查目標服務好好的活着。因而開始查緣由。服務器
通常來講目標積極拒絕(TCP 10061)的異常主要是2種可能:併發
1:服務器關機或者服務關閉app
2:Client調用的端口錯誤或者服務器防火牆沒開相應的端口less
可是咱們的服務自己是能夠調用的,只是偶爾報這個錯誤,說明並非這2個問題形成的。繼續google,在stackoverflow上看到這樣一篇:傳送門socket
If this happens always, it literally means that the machine exists but that it has no services listening on the specified port, or there is a firewall stopping you. If it happens occasionally - you used the word "sometimes" - and retrying succeeds, it is likely because the server has a full 'backlog'. When you are waiting to be accepted on a listening socket, you are placed in a backlog. This backlog is finite and quite short - values of 1, 2 or 3 are not unusual - and so the OS might be unable to queue your request for the 'accept' to consume. The backlog is a parameter on the listen function - all languages and platforms have basically the same API in this regard, even the C# one. This parameter is often configurable if you control the server, and is likely read from some settings file or the registry. Investigate how to configure your server. If you wrote the server, you might have heavy processing in the accept of your socket, and this can be better moved to a separate worker-thread so your accept is always ready to receive connections. There are various architecture choices you can explore that mitigate queuing up clients and processing them sequentially. Regardless of whether you can increase the server backlog, you do need retry logic in your client code to cope with this issue - as even with a long backlog the server might be receiving lots of other requests on that port at that time. There is a rare possibility where a NAT router would give this error should it's ports for mappings be exhausted. I think we can discard this possibility as too much of a long shot though, since the router has 64K simultaneous connections to the same destination address/port before exhaustion.
大概意思就是若是這個錯誤是一直髮生的那麼多是服務器或者防火牆的問題,若是這個問題是「Sometime」發生的,那麼多是backlog的問題。backlog是tcp層面的請求隊列,當你調用socket發起請求的時候服務端會排成一個隊列,在高併發狀況下服務端來不及處理請求,那麼有些請求就被直接被丟棄,因而就報了目標積極拒絕TCP10061的異常。tcp
有了backlog因而繼續google關鍵字「WCF backlog」發現wcf binding配置確實有一個listenBacklog的項目,默認值是10,因而把服務的listenBacklog改爲100,問題搞定。高併發
對了添加listenBacklog屬性的時候有個注意的是必定要移除一個默認的endpoint <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />這個endpoint是用來給vs等發現元數據用的,若是這個不移走啓動服務的時候會報端口已經被監聽的錯誤。ui
參考:this
https://msdn.microsoft.com/en-us/library/ee377061(v=bts.10).aspx