เรามีแอปพลิเคชันที่มีบริการ WCF (* .svc) ที่ทำงานบน IIS7 และลูกค้าหลายรายสอบถามบริการ เซิร์ฟเวอร์กำลังเรียกใช้ Win 2008 Server ไคลเอนต์กำลังเรียกใช้เซิร์ฟเวอร์ Windows 2008 Server หรือ Windows 2003 ฉันได้รับข้อยกเว้นดังต่อไปนี้ซึ่งในความเป็นจริงแล้วฉันได้เห็นว่าเกี่ยวข้องกับปัญหา WCF ที่อาจเกิดขึ้นจำนวนมาก
System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
ฉันได้เพิ่มระยะหมดเวลาเป็น 30 นาทีและยังเกิดข้อผิดพลาด สิ่งนี้บอกฉันว่ามีอย่างอื่นอยู่ระหว่างการเล่นเนื่องจากปริมาณข้อมูลไม่สามารถใช้เวลา 30 นาทีในการอัปโหลดหรือดาวน์โหลด
ข้อผิดพลาดมาและไป ในขณะนี้เป็นบ่อยขึ้น ดูเหมือนจะไม่สำคัญว่าฉันมีไคลเอนต์ 3 เครื่องที่ทำงานพร้อมกันหรือ 100 เครื่อง แต่ก็ยังคงเกิดขึ้นนาน ๆ ครั้ง ส่วนใหญ่ไม่มีการหมดเวลา แต่ฉันยังได้รับไม่กี่ต่อชั่วโมง ข้อผิดพลาดมาจากวิธีการใด ๆ ที่เรียกใช้ หนึ่งในวิธีการเหล่านี้ไม่มีพารามิเตอร์และส่งคืนข้อมูลเล็กน้อย อีกข้อมูลหนึ่งใช้ข้อมูลจำนวนมากเป็นพารามิเตอร์ แต่ดำเนินการแบบอะซิงโครนัส ข้อผิดพลาดมักเกิดจากไคลเอนต์และไม่อ้างอิงโค้ดใด ๆ บนเซิร์ฟเวอร์ในการติดตามสแต็ก มันมักจะลงท้ายด้วย:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
บนเซิร์ฟเวอร์: ฉันได้ลอง (และมี) การตั้งค่าการผูกต่อไปนี้:
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
ดูเหมือนจะไม่ส่งผลกระทบ
ฉันได้ลอง (และปัจจุบันมี) การตั้งค่าการควบคุมปริมาณดังต่อไปนี้:
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentInstances="1500" maxConcurrentSessions="1500"/>
ดูเหมือนจะไม่ส่งผลกระทบ
ขณะนี้ฉันมีการตั้งค่าต่อไปนี้สำหรับบริการ WCF
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
ฉันวิ่งไปด้วย ConcurrencyMode.Multiple
สักพัก แต่ข้อผิดพลาดยังคงเกิดขึ้น
ฉันได้ลองรีสตาร์ท IIS รีสตาร์ท SQL Server พื้นฐานรีสตาร์ทเครื่อง สิ่งเหล่านี้ดูเหมือนจะไม่ส่งผลกระทบ
ฉันได้ลองปิดไฟร์วอลล์ Windows แล้ว ดูเหมือนจะไม่ส่งผลกระทบ
ในไคลเอนต์ฉันมีการตั้งค่าเหล่านี้:
maxReceivedMessageSize="2147483647"
<system.net>
<connectionManagement>
<add address="*" maxconnection="16"/>
</connectionManagement>
</system.net>
ลูกค้าของฉันปิดการเชื่อมต่อ:
var client = new MyClient();
try
{
return client.GetConfigurationOptions();
}
finally
{
client.Close();
}
ฉันได้เปลี่ยนการตั้งค่ารีจิสทรีเพื่ออนุญาตการเชื่อมต่อขาออกเพิ่มเติม:
MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
ตอนนี้ฉันเพิ่งลอง SvcTraceViewer.exe ฉันจัดการเพื่อตรวจจับหนึ่งข้อยกเว้นในส่วนท้ายไคลเอนต์ ฉันเห็นว่าระยะเวลา 1 นาที เมื่อดูที่การติดตามฝั่งเซิร์ฟเวอร์ฉันเห็นว่าเซิร์ฟเวอร์ไม่ทราบถึงข้อยกเว้นนี้ ระยะเวลาสูงสุดที่ฉันเห็นคือ 10 วินาที
ฉันได้ดูการเชื่อมต่อฐานข้อมูลที่ใช้งานอยู่โดยใช้ไฟล์ exec sp_who
บนเซิร์ฟเวอร์ ฉันมีเพียงไม่กี่ (2-3) ฉันได้ดูการเชื่อมต่อ TCP จากไคลเอนต์หนึ่งโดยใช้ TCPview โดยปกติจะอยู่ที่ประมาณ 2-3 และฉันได้เห็นถึง 5 หรือ 6
พูดง่ายๆคือฉันนิ่งงัน ฉันได้ลองทุกอย่างที่หาได้แล้วและจะต้องขาดสิ่งที่เรียบง่ายมากที่ผู้เชี่ยวชาญ WCF จะสามารถมองเห็นได้ มันเป็นความรู้สึกของฉันที่รู้สึกว่ามีบางอย่างปิดกั้นไคลเอ็นต์ของฉันที่ระดับต่ำ (TCP) ก่อนที่เซิร์ฟเวอร์จะได้รับข้อความจริงและ / หรือมีบางอย่างเข้าคิวข้อความที่ระดับเซิร์ฟเวอร์และไม่ยอมให้ประมวลผล
หากคุณมีตัวนับการแสดงใด ๆ ที่ฉันควรดูโปรดแจ้งให้เราทราบ (โปรดระบุว่าค่าใดไม่ดีเนื่องจากตัวนับเหล่านี้บางตัวถอดรหัสได้ยาก) นอกจากนี้ฉันจะบันทึกขนาดข้อความ WCF ได้อย่างไร ในที่สุดมีเครื่องมือใดบ้างที่จะช่วยให้ฉันทดสอบว่าฉันสามารถสร้างการเชื่อมต่อระหว่างไคลเอนต์และเซิร์ฟเวอร์ของฉันได้กี่รายการ (ไม่ขึ้นอยู่กับแอปพลิเคชันของฉัน)
ขอบคุณที่สละเวลา!
ข้อมูลเพิ่มเติมเพิ่ม 20 มิถุนายน:
แอปพลิเคชัน WCF ของฉันทำสิ่งที่คล้ายกับสิ่งต่อไปนี้
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
เมื่อใช้ WireShark ฉันเห็นว่าเมื่อเกิดข้อผิดพลาดฉันมีการส่งข้อมูล TCP ห้าครั้งตามด้วยการรีเซ็ต TCP ในภายหลัง ฉันเดาว่า RST มาจาก WCF ฆ่าการเชื่อมต่อ รายงานข้อยกเว้นที่ฉันได้รับมาจากการหมดเวลาของขั้นตอนที่ 3
ฉันค้นพบสิ่งนี้โดยดูที่สตรีม tcp "tcp.stream eq 192" จากนั้นฉันขยายตัวกรองเป็น "tcp.stream eq 192 และ http และ http.request.method eq POST" และเห็น 6 POST ในระหว่างสตรีมนี้ สิ่งนี้ดูแปลกดังนั้นฉันจึงตรวจสอบด้วยสตรีมอื่นเช่น tcp.stream eq 100 ฉันมีสามโพสต์ซึ่งดูเหมือนจะปกติกว่าเล็กน้อยเพราะฉันกำลังโทรสามครั้ง อย่างไรก็ตามฉันจะปิดการเชื่อมต่อทุกครั้งหลังการโทร WCF ดังนั้นฉันจึงคาดว่าจะมีการโทรหนึ่งครั้งต่อสตรีม (แต่ฉันไม่รู้มากเกี่ยวกับ TCP)
เมื่อตรวจสอบเพิ่มเติมอีกเล็กน้อยฉันได้ทิ้งการโหลดแพ็กเก็ต http ลงในดิสก์เพื่อดูว่าทั้งหกสายนี้อยู่ที่ไหน
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
ฉันเดาว่าไคลเอนต์พร้อมกันสองเครื่องกำลังใช้การเชื่อมต่อเดียวกันนั่นคือเหตุผลที่ฉันเห็นรายการที่ซ้ำกัน อย่างไรก็ตามฉันยังมีปัญหาอีกเล็กน้อยที่ไม่สามารถเข้าใจได้:
ก) เหตุใดแพ็กเก็ตจึงเสียหาย สุ่มเครือข่ายฟลุ๊ค - อาจจะ? โหลดถูก gzipped โดยใช้โค้ดตัวอย่างนี้: http://msdn.microsoft.com/en-us/library/ms751458.aspx - โค้ดอาจเป็นบั๊กกี้นาน ๆ ครั้งเมื่อใช้พร้อมกันหรือไม่ ฉันควรทดสอบโดยไม่มีไลบรารี gzip
b) เหตุใดฉันจึงเห็นขั้นตอนที่ 1 และขั้นตอนที่ 2 กำลังทำงานหลังจากการดำเนินการที่เสียหายหมดเวลา สำหรับฉันดูเหมือนว่าการดำเนินการเหล่านี้ไม่ควรเกิดขึ้น บางทีฉันอาจไม่ได้ดูสตรีมที่ถูกต้องเพราะความเข้าใจเกี่ยวกับ TCP มีข้อบกพร่อง ฉันมีกระแสอื่น ๆ ที่เกิดขึ้นในเวลาเดียวกัน ฉันควรตรวจสอบสตรีมอื่น ๆ - การดูสตรีม 190-194 อย่างรวดเร็วแสดงให้เห็นว่า Step3 POST มีข้อมูลเพย์โหลดที่เหมาะสม (ไม่เสียหาย) ผลักดันให้ฉันไปดูห้องสมุด gzip อีกครั้ง