การตรวจสอบรายละเอียดข้อยกเว้นการหมดเวลาของ WCF


94

เรามีแอปพลิเคชันที่มีบริการ 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 อีกครั้ง


Jason - คุณเคยแก้ปัญหานี้หรือไม่? มันเป็นการตั้งค่า DefaultConnectionLimit หรือไม่
SFun28

2
@JasonKealey - ตรงกันข้ามกับคำถามอื่น ๆ อีกมากมายคุณไม่สามารถถูกกล่าวหาว่าไม่ได้พยายามด้วยตัวเองก่อนโพสต์คำถาม :) ฉันชอบที่คำถามของคุณมีรายละเอียดมากและมีรายละเอียดที่สำคัญทั้งหมด อาการที่คุณอธิบายดูเหมือนของฉันมากดังนั้นฉันหวังว่าการแก้ปัญหาจะเหมือนกันเช่นกัน :)
ØyvindBråthen

คำตอบ:


51

หากคุณใช้ไคลเอนต์. Net คุณอาจไม่ได้ตั้งค่า

//This says how many outgoing connection you can make to a single endpoint. Default Value is 2
System.Net.ServicePointManager.DefaultConnectionLimit = 200;

นี่คือคำถามดั้งเดิมและคำตอบWCF Service Throttling

อัปเดต :

การกำหนดค่านี้จะอยู่ในแอปพลิเคชันไคลเอนต์. Net อาจเริ่มต้นระบบหรือเมื่อใดก็ตาม แต่ก่อนที่จะเริ่มการทดสอบ

ยิ่งไปกว่านั้นคุณสามารถมีได้ในไฟล์ app.config เช่นเดียวกับต่อไปนี้

<system.net>
    <connectionManagement>
      <add maxconnection = "200" address ="*" />
    </connectionManagement>
  </system.net>

นี่ดูมีแนวโน้ม ฉันได้รวมสิ่งนี้ไว้เพื่อทดสอบในระหว่างการทดสอบความสามารถในการปรับขนาดครั้งต่อไป ดูเหมือนว่าเป็นการตั้งค่าแบบสุ่มที่จะทำให้มันพัง :) ขอบคุณสำหรับตัวชี้
Jason Kealey

1
@ Jason: หากคุณเป็นโปรแกรมเมอร์เซิร์ฟเวอร์คุณจะรู้ว่าการรักษาความสามารถในการปรับขนาดของเซิร์ฟเวอร์ในมือของคุณมีความสำคัญมากเพียงใดและยังเป็นผู้ที่กำลังประสบปัญหาการทำงานพร้อมกันแม้ว่าจะใช้งานข้างต้นแล้วก็ตาม โปรดหากคุณสามารถดูคำถามต่อไปนี้stackoverflow.com/questions/2637175/wcf-network-costในระยะสั้นฉันกำลังทุกข์ทรมานกับเวลาแฝง 31ms ระหว่างไคลเอนต์และเซิร์ฟเวอร์และจำเป็นต้องลดลง
Mubashar

3
ใช้เวลาเพียงหนึ่งปี แต่ในที่สุดฉันก็ทำการทดสอบความเครียดอีกครั้งในแอปพลิเคชันด้วยชุดค่าสถานะนี้ ปัญหานี้ได้รับการแก้ไขแล้วดังนั้นเราจึงให้คำตอบที่ดีที่สุดแก่คุณ ฉันไม่ต้องแปลกใจเลยว่านี่เป็นปริศนาชิ้นสุดท้ายที่จำเป็น แต่ต้องมีองค์ประกอบอื่น ๆ ทั้งหมดเพื่อให้แน่ใจว่าข้อผิดพลาดจะไม่เกิดขึ้น ขอบคุณมาก ๆ!
Jason Kealey

2
@Aris: ในแอปพลิเคชันไคลเอนต์. net เมื่อเริ่มต้นหรือที่ใดก็ตามที่คุณตั้งค่าการกำหนดค่าส่วนกลางของคุณหากคุณต้องการให้สามารถกำหนดค่าได้คุณสามารถเพิ่มในไฟล์กำหนดค่าได้เช่นเดียวกับ <system.net> <connectionManagement> <add maxconnection = "200" address = "*" /> </connectionManagement> </system.net>
Mubashar

3

หากคุณยังไม่ได้ลอง - ห่อหุ้มการดำเนินการ WCF ฝั่งเซิร์ฟเวอร์ของคุณในการลอง / บล็อกในที่สุดและเพิ่มการบันทึกเพื่อให้แน่ใจว่าจะกลับมาจริง

หากสิ่งเหล่านั้นแสดงว่าการดำเนินการเสร็จสิ้นขั้นตอนต่อไปของฉันคือไปที่ระดับล่างและดูที่เลเยอร์การขนส่งจริง

Wireshark หรือเครื่องมือจับแพ็กเก็ตอื่นที่คล้ายกันจะมีประโยชน์มากในจุดนี้ ฉันสมมติว่าสิ่งนี้กำลังทำงานบน HTTP บนพอร์ตมาตรฐาน 80

เรียกใช้ Wireshark บนไคลเอนต์ ในตัวเลือกเมื่อคุณเริ่มการจับภาพให้ตั้งค่าตัวกรองการจับภาพเป็นtcp http and host service.example.com ซึ่งจะช่วยลดปริมาณการเข้าชมที่ไม่เกี่ยวข้อง

หากทำได้ให้แก้ไขไคลเอ็นต์ของคุณเพื่อแจ้งเวลาเริ่มต้นที่แน่นอนของการโทรและเวลาที่หมดเวลา หรือเพียงแค่ตรวจสอบอย่างใกล้ชิด

เมื่อคุณได้รับข้อผิดพลาดคุณสามารถลากผ่านบันทึก Wireshark เพื่อค้นหาจุดเริ่มต้นของการโทร คลิกขวาที่แพ็กเก็ตแรกที่มีไคลเอนต์ของคุณโทรออก (ควรเป็น GET /service.svc หรือ POST /service.svc) และเลือก Follow TCP Stream

Wireshark จะถอดรหัสการสนทนา HTTP ทั้งหมดดังนั้นคุณจึงมั่นใจได้ว่า WCF ส่งการตอบกลับกลับมาจริงๆ


ฉันเข้าสู่ระบบเซิร์ฟเวอร์ - ไม่มีข้อผิดพลาดในตอนท้าย ตอนนี้ฉันใช้งาน WireShark เพื่อดูว่าฉันสามารถหาอะไรได้บ้าง เนื่องจากมีปริมาณการใช้งานสูงการวิเคราะห์จึงเป็นเรื่องยาก แต่ฉันจะรายงานกลับหากพบสิ่งใด
Jason Kealey

ฉันใช้งาน WireShark ในช่วงหกชั่วโมงที่ผ่านมาและรวบรวมเฟรมได้ 60k ลูกค้ารายนี้รายงานข้อยกเว้นเพียงรายการเดียวในวันนี้ ฉันเห็นการเชื่อมต่อ TCP ที่ระบุว่าเป็น RST (รีเซ็ต) เห็นได้ชัดว่าหลังจากส่งอีเมลแจ้งข้อผิดพลาดซึ่งอาจเป็น WCF ที่ยุติการเชื่อมต่อ ฉันบันทึก payload (525k) ลงในดิสก์ ฉันตรวจสอบแล้วว่ามีคำเรียกร้องอื่น ๆ 87 รายการที่มีน้ำหนักบรรทุกขนาดใกล้เคียงกัน ฉันเห็นการส่งซ้ำ TCP สองสามครั้ง แต่ก็เห็นบางอย่างในการโทรอื่น ๆ ด้วย (ซึ่งไม่ล้มเหลว) เริ่มสงสัยเกี่ยวกับสายฮาร์ดแวร์ + เครือข่ายของฉัน
Jason Kealey

แม้ในเครือข่ายท้องถิ่นการมี TCP Retransmits ไม่จำเป็นต้องแย่เสมอไป หากเป็นไปได้ที่จะเชื่อมต่อจุดสิ้นสุดสองจุดเข้ากับสวิตช์เดียวนั่นอาจคุ้มค่ากับการยิง แต่ฉันจะไม่หวังว่าจะแก้ไขได้ ถ้าคุณทำได้ - สร้างแอปพลิเคชันไคลเอนต์พื้นฐานที่ส่งผ่านการรับส่งข้อมูลไปมาที่เซิร์ฟเวอร์ของคุณและไม่มีอะไรอื่น วิธีนี้สามารถช่วยขจัดปัญหาในแอปพลิเคชันของคุณที่อาจทำให้หมดเวลา

นอกจากนี้คุณยังกล่าวถึงการเห็นแพ็คเก็ต TCP Reset - เซิร์ฟเวอร์ส่งการตอบสนองใด ๆ ณ จุดนั้น (หรืออาจกำลังรอข้อมูลเพิ่มเติม) มีความล่าช้าที่เห็นได้ชัดระหว่าง RST และแพ็กเก็ตก่อนหน้านี้หรือไม่?

เซิร์ฟเวอร์เป็นแบบรีโมต ฉันกำลังวางแผนที่จะสร้างสภาพแวดล้อมการทดสอบในพื้นที่เพื่อดูว่าช่วยได้หรือไม่ สำหรับ RST จะถูกส่งไป 34 วินาทีหลังจากการส่งผ่าน TCP Retransmission ห้าครั้งสุดท้าย (ช่วงเวลา 1 ถึง 8 วินาทีระหว่างการส่งข้อมูลซ้ำ) นั่นทำให้คุณมีเบาะแสหรือไม่?
Jason Kealey

2

จาก: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

เพื่อหลีกเลี่ยงข้อผิดพลาดการหมดเวลานี้เราจำเป็นต้องกำหนดค่า คุณสมบัติOperationTimeoutสำหรับ Proxy ในรหัสไคลเอนต์ WCF การกำหนดค่านี้เป็นสิ่งใหม่ที่แตกต่างจากการกำหนดค่าอื่น ๆ เช่น Send Timeout, Receive Timeout เป็นต้นซึ่งฉันได้กล่าวถึงในตอนต้นของบทความ ในการตั้งค่าการกำหนดค่าคุณสมบัติการหมดเวลาการดำเนินการนี้เราต้องแคสต์พร็อกซีของเราเป็น IContextChannel ในแอปพลิเคชันไคลเอนต์ WCF ก่อนที่จะเรียกวิธีการทำสัญญาการดำเนินการ


ฉันได้ลองสิ่งนี้แล้ว ไม่ว่าฉันจะหมดเวลาเท่าไหร่มันก็ยังคงหมดเวลา แต่ก็ไม่สมเหตุสมผลเพราะการดำเนินการไม่นานและเนื่องจากไคลเอนต์อื่น ๆ ทั้งหมดที่ทำฟังก์ชันการสืบค้นเดียวกันในช่วงเวลานี้
Jason Kealey

การทดสอบของฉันพิสูจน์แล้วว่า OperationTimeout เพียงแค่ลบล้าง ReceiveTimeout จาก config ดังนั้นจึงไม่มีประโยชน์อะไรเลย
dudeNumber4

2

ฉันมีปัญหาที่คล้ายกันมาก ในอดีตปัญหานี้เกี่ยวข้องกับปัญหาการทำให้เป็นอนุกรม หากคุณยังคงประสบปัญหานี้คุณสามารถตรวจสอบได้หรือไม่ว่าคุณสามารถทำให้เป็นอนุกรมของวัตถุที่คุณส่งคืน โดยเฉพาะอย่างยิ่งถ้าคุณกำลังใช้อ็อบเจ็กต์ Linq-To-Sql ที่มีความสัมพันธ์จะมีปัญหาในการทำให้เป็นอนุกรมหากคุณใส่การอ้างอิงย้อนกลับบนอ็อบเจ็กต์ลูกไปยังอ็อบเจ็กต์พาเรนต์และทำเครื่องหมายการอ้างอิงด้านหลังนั้นเป็น DataMember

คุณสามารถตรวจสอบการทำให้เป็นอนุกรมได้โดยการเขียนแอปคอนโซลที่ทำให้เป็นอนุกรมและแยกสถานะออบเจ็กต์ของคุณโดยใช้ DataContractSerializer ที่ฝั่งเซิร์ฟเวอร์และวิธีการทำให้เป็นอนุกรมที่ไคลเอ็นต์ของคุณใช้ ตัวอย่างเช่นในแอปพลิเคชันปัจจุบันของเราเรามีทั้งไคลเอ็นต์ WPF และ Compact Framework ฉันเขียนแอปคอนโซลเพื่อตรวจสอบว่าฉันสามารถทำให้เป็นอนุกรมโดยใช้ DataContractSerializer และ deserialize โดยใช้ XmlDesserializer คุณอาจลองทำเช่นนั้น

นอกจากนี้หากคุณส่งคืนอ็อบเจ็กต์ Linq-To-Sql ที่มีคอลเลกชันชายน์คุณอาจพยายามตรวจสอบให้แน่ใจว่าคุณได้โหลดอ็อบเจ็กต์เหล่านั้นอย่างกระตือรือร้นที่ฝั่งเซิร์ฟเวอร์ บางครั้งเนื่องจากขี้เกียจโหลดวัตถุที่ถูกส่งคืนจะไม่ถูกเติมและอาจทำให้เกิดพฤติกรรมที่คุณเห็นว่าคำขอถูกส่งไปยังวิธีการบริการหลายครั้ง

หากคุณแก้ปัญหานี้ได้แล้วฉันชอบที่จะได้ยินว่าเพราะฉันติดอยู่กับมันด้วยเช่นกัน ฉันได้ตรวจสอบแล้วว่าปัญหาของฉันไม่ใช่การทำให้เป็นอนุกรมดังนั้นฉันจึงสูญเสีย

อัปเดต: ฉันไม่แน่ใจว่ามันจะช่วยคุณได้หรือไม่ แต่ Service Trace Viewer Tool เพิ่งแก้ปัญหาของฉันหลังจาก 5 วันของประสบการณ์ที่คล้ายกันกับของคุณ ด้วยการตั้งค่าการติดตามจากนั้นดู XML ดิบฉันพบข้อยกเว้นที่ทำให้เกิดปัญหาการจัดลำดับของฉัน มันเกี่ยวข้องกับอ็อบเจ็กต์ Linq-to-SQL ที่บางครั้งมีอ็อบเจ็กต์ลูกมากกว่าที่จะทำให้เป็นอนุกรมได้สำเร็จ การเพิ่มสิ่งต่อไปนี้ในไฟล์ web.config ของคุณควรเปิดใช้งานการติดตาม:

<sharedListeners>
    <add name="sharedListener"
         type="System.Diagnostics.XmlWriterTraceListener"
         initializeData="c:\Temp\servicetrace.svclog" />
  </sharedListeners>
  <sources>
    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
      <listeners>
        <add name="sharedListener" />
      </listeners>
    </source>
  </sources>

ไฟล์ผลลัพธ์สามารถเปิดได้ด้วย Service Trace Viewer Tool หรือใน IE เพื่อตรวจสอบผลลัพธ์


2

คุณกำลังปิดการเชื่อมต่อกับบริการ WCF ระหว่างคำขอหรือไม่? หากไม่เป็นเช่นนั้นคุณจะเห็นการหมดเวลาที่แน่นอนนี้ (ในที่สุด)


2

ฉันเพิ่งแก้ปัญหาได้พบว่าโหนดในไฟล์ App.config กำหนดค่าผิด

<client>
<endpoint name="WCF_QtrwiseSalesService" binding="wsHttpBinding" bindingConfiguration="ws" address="http://cntgbs1131:9005/MyService/TGE.ISupplierClientManager" contract="*">
</endpoint>
</client>

<bindings>
    <wsHttpBinding>
        <binding name="ws" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            <**security mode="None">**
                <transport clientCredentialType="None"></transport>
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

ยืนยันการกำหนดค่าของคุณในโหนด<security>ค่าแอตทริบิวต์ "โหมด" คือ "ไม่มี" หากค่าของคุณคือ "Transport" ข้อผิดพลาดจะเกิดขึ้น


สิ่งนี้ไม่ส่งผลกระทบต่อความปลอดภัย? หากเป็นเช่นนั้นอาจไม่ใช่วิธีแก้ปัญหาสำหรับการใช้งานจริงส่วนใหญ่
Veverke

0

คุณลองใช้clientViaเพื่อดูข้อความที่ส่งโดยใช้SOAP toolkitหรืออะไรทำนองนั้น? สิ่งนี้สามารถช่วยดูว่าข้อผิดพลาดมาจากตัวไคลเอนต์เองหรือจากที่อื่น


คุณรู้หรือไม่ว่ามีเครื่องมือใดที่ใหม่กว่าชุดเครื่องมือ SOAP ที่เลิกใช้แล้วซึ่งจะทำให้ฉันสามารถบันทึกข้อมูลนี้ในการเรียก WCF ได้ง่ายขึ้น
Jason Kealey

SOAP Toolkitคือdeprecated
Kiquenet

0

คุณตรวจสอบร่องรอย WCF หรือไม่ WCF มีแนวโน้มที่จะกลืนข้อยกเว้นและส่งคืนเฉพาะข้อยกเว้นสุดท้ายซึ่งเป็นระยะหมดเวลาที่คุณได้รับเนื่องจากจุดสิ้นสุดไม่ได้ส่งคืนสิ่งที่มีความหมาย


ฉันลอง SvcTraceViewer และข้อยกเว้นเดียวที่รายงานคือการหมดเวลา (บนไคลเอนต์) ไม่มีการรายงานบนเซิร์ฟเวอร์
Jason Kealey

เปิดตัวเลือกทั้งหมดในการติดตามคุณอาจไม่ได้เปิดตัวเลือกการติดตามทั้งหมด ตรวจสอบทั้งการติดตามเหตุการณ์และไฟล์การติดตามข้อความ
Miki Watts

0

นอกจากนี้คุณจะได้รับข้อผิดพลาดนี้หากคุณส่งอ็อบเจ็กต์กลับไปยังไคลเอนต์ที่มีคุณสมบัติของ enum ชนิดที่ไม่ได้ตั้งค่าตามค่าเริ่มต้นและ enum นั้นไม่มีค่าที่แมปกับ 0 นั่นคือ enum MyEnum{ a=1, b=2};


0

ดูเหมือนว่าข้อความยกเว้นนี้จะค่อนข้างทั่วไปและสามารถรับได้เนื่องจากสาเหตุหลายประการ เราพบสิ่งนี้ในขณะที่ปรับใช้ไคลเอนต์บนเครื่อง Windows 8.1 ไคลเอนต์ WCF ของเราทำงานภายในบริการ windows และสำรวจบริการ WCF อย่างต่อเนื่อง บริการ windows ทำงานภายใต้ผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบ ปัญหานี้ได้รับการแก้ไขโดยการตั้งค่า clientCredentialType เป็น "Windows" ในการกำหนดค่า WCF เพื่อให้การรับรองความถูกต้องสามารถส่งผ่านได้ดังต่อไปนี้:

      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>

0

ฉันไม่ใช่ผู้เชี่ยวชาญ WCF แต่ฉันสงสัยว่าคุณไม่ได้พบกับการป้องกัน DDOS บน IIS ฉันรู้จากประสบการณ์ว่าหากคุณเรียกใช้การเชื่อมต่อพร้อมกันจำนวนมากจากไคลเอนต์เดียวไปยังเซิร์ฟเวอร์ในบางจุดเซิร์ฟเวอร์จะหยุดตอบสนองต่อการโทรเนื่องจากสงสัยว่าจะมีการโจมตี DDOS นอกจากนี้ยังจะเปิดการเชื่อมต่อไว้จนกว่าจะหมดเวลาเพื่อให้ไคลเอนต์ช้าลงในการโจมตีของเขา

อย่างไรก็ตามการเชื่อมต่อหลายเครื่องที่มาจากเครื่องอื่น / IP ไม่น่าจะเป็นปัญหา

มีข้อมูลเพิ่มเติมในโพสต์ MSDN นี้:

http://msdn.microsoft.com/en-us/library/bb463275.aspx

ตรวจสอบ Sproperty MaxConcurrentSession


ฉันรู้สึกว่านี่คือสิ่งที่เกิดขึ้นจากทุกสิ่งที่ฉันเห็นอย่างไรก็ตามฉันมี (บนเซิร์ฟเวอร์): <serviceThrottling maxConcurrentCalls = "150" maxConcurrentInstances = "150" maxConcurrentSessions = "150" /> <serviceDebug includeExceptionDetailInFaults = "true" /> จะมีการตรวจสอบประสิทธิภาพหรือบันทึก IIS ที่ฉันสามารถตรวจสอบเพื่อดูว่าเกิดเหตุการณ์นี้ขึ้นหรือไม่
Jason Kealey
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.