อะไรคือการ จำกัด จำนวนการเชื่อมต่อพร้อมกันที่แอปพลิเคชัน ASP.NET ของฉันสามารถทำกับบริการบนเว็บได้


90

ฉันมีแอปพลิเคชัน ASP.NET 4.0 ที่ทำงานบน IIS 7.5 บนเครื่อง Windows Server 2008 R2 Enterprise แบบ 64 บิตพร้อม RAM, CPU, ดิสก์และอื่น ๆ

ทุกคำขอของเว็บแอปพลิเคชัน ASP.NET จะทำการเชื่อมต่อกับบริการเว็บแบ็กเอนด์ (ผ่านซ็อกเก็ตดิบ) ซึ่งทำงานบนเครื่องเดียวกัน

ปัญหา:ดูเหมือนจะมีบางอย่าง จำกัด # ของการเชื่อมต่อพร้อมกันไปยังบริการเว็บแบ็กเอนด์ น่าสงสัยว่าจำนวนการเชื่อมต่อพร้อมกันจะเพิ่มขึ้นที่ 16

ฉันพบบทความสำคัญนี้จาก Microsoft ที่อธิบายวิธีปรับแต่งการตั้งค่าของ IIS เพื่อรองรับแอป ASP.NET ที่ร้องขอบริการเว็บจำนวนมาก: http://support.microsoft.com/?id=821268#tocHeadRef

ฉันทำตามคำแนะนำของบทความ แต่ก็ยังไม่มีโชค การตั้งค่าที่น่าสนใจเป็นพิเศษคือการmaxconnectionตั้งค่าซึ่งผมชนไปที่ 999 ด้วยซ้ำ

มีความคิดอะไรอีกที่สามารถควบคุมการเชื่อมต่อได้?

หมายเหตุ:เมื่อฉันตัด IIS ออกจากการผสมผสานและให้ลูกค้าเชื่อมต่อโดยตรงกับบริการเว็บแบ็กเอนด์มันจะเปิดการเชื่อมต่อได้มากเท่าที่ฉันต้องการอย่างมีความสุขดังนั้นฉันคิดว่าแบ็กเอนด์ไม่ใช่คอขวด ต้องเป็นบางอย่างใน IIS / ASP.NET-land

นี่คือส่วนที่เกี่ยวข้องmachine.configซึ่งฉันแน่ใจว่ากำลังอ่านโดยแอปพลิเคชัน (ยืนยันด้วยappcmd.exe):

<system.web>
    <processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
    <httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>

    <httpHandlers />

    <membership>
        <providers>
            <add name="AspNetSqlMembershipProvider"
                type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName="LocalSqlServer"
                enablePasswordRetrieval="false"
                enablePasswordReset="true"
                requiresQuestionAndAnswer="true"
                applicationName="/"
                requiresUniqueEmail="false"
                passwordFormat="Hashed"
                maxInvalidPasswordAttempts="5"
                minRequiredPasswordLength="7"
                minRequiredNonalphanumericCharacters="1"
                passwordAttemptWindow="10"
                passwordStrengthRegularExpression="" />
        </providers>
    </membership>

    <profile>
        <providers>
            <add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
                type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </providers>
    </profile>

    <roleManager>
        <providers>
            <add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
                type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <add name="AspNetWindowsTokenRoleProvider" applicationName="/"
                type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </providers>
    </roleManager>
</system.web>
<system.net>
    <connectionManagement>
        <add address="*" maxconnection="999"/>
    </connectionManagement>
</system.net>

@ DanB มีจุดที่ดีตรงนี้ - คุณวัดจำนวนการเชื่อมต่อพร้อมกันได้อย่างไร?
Jeremy McGee

@JeremyMcGee ฉันกำลังวัด # ของการเชื่อมต่อพร้อมกันโดยการเรียกใช้ TCPView บนเซิร์ฟเวอร์เพื่อดูจำนวนการเชื่อมต่อแบ็กเอนด์ที่ทำโดยกระบวนการของผู้ปฏิบัติงาน IIS
Rob Sobers

เว็บไคลเอ็นต์ทำงานบนเครื่องอิสระหรือเครื่องเดียวกันหรือไม่ (ตรวจสอบว่าไม่มีการควบคุมปริมาณฝั่งไคลเอ็นต์เกิดขึ้น)
Jeremy McGee

3
@JeremyMcGee เครื่องแยก. 1 การเชื่อมต่อไคลเอนต์เซิร์ฟเวอร์ต่อเครื่อง นอกจากนี้เราทราบดีว่าไม่มีการควบคุมปริมาณใด ๆ บนเครือข่ายเนื่องจากเมื่อเรากดแบ็กเอนด์โดยตรง (ซึ่งเกิดขึ้นผ่าน HTTP เช่นกัน) เราจะไม่พบปัญหาคอขวด
Rob Sobers

1
Rob คุณเคยหาวิธีแก้ปัญหานี้หรือไม่?
electronicKT

คำตอบ:


104

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

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

คุณสามารถลบข้อ จำกัด นี้ได้โดยเพิ่มส่วนการกำหนดค่าต่อไปนี้ในไฟล์ machine.config ของคุณ:

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

แน่นอนคุณสามารถเลือกจำนวนที่เหมาะสมกว่านี้ได้หากคุณต้องการเช่นการเชื่อมต่อพร้อมกัน 50 หรือ 100 รายการ แต่ข้างต้นจะเปิดได้สูงสุด คุณยังสามารถระบุที่อยู่เฉพาะสำหรับกฎการ จำกัด การเปิดด้านบนแทนที่จะระบุ "*" ซึ่งระบุที่อยู่ทั้งหมด

เอกสาร MSDN สำหรับ System.Net.connectionManagement

อีกหนึ่งแหล่งข้อมูลที่ยอดเยี่ยมสำหรับการทำความเข้าใจ ConnectManagement ใน. NET

หวังว่านี่จะช่วยแก้ปัญหาของคุณได้!

แก้ไข:อ๊ะฉันเห็นว่าคุณมีการจัดการการเชื่อมต่อที่กล่าวถึงในโค้ดของคุณด้านบน ฉันจะทิ้งข้อมูลข้างต้นไว้เนื่องจากเป็นข้อมูลที่เกี่ยวข้องกับผู้สอบถามในอนาคตที่มีปัญหาเดียวกัน อย่างไรก็ตามโปรดทราบว่าขณะนี้มีไฟล์ machine.config ที่แตกต่างกัน 4 ไฟล์ในเซิร์ฟเวอร์ล่าสุด!

NET Framework v2 ที่ทำงานภายใต้ทั้ง 32 บิตและ 64 บิตเช่นเดียวกับ. NET Framework v4 ที่ทำงานภายใต้ทั้ง 32 บิตและ 64 บิต ขึ้นอยู่กับการตั้งค่าที่คุณเลือกสำหรับพูลแอปพลิเคชันของคุณคุณสามารถใช้ไฟล์ machine.config ใดก็ได้จาก 4 ไฟล์เหล่านี้! โปรดตรวจสอบไฟล์ machine.config ทั้ง 4 ไฟล์โดยทั่วไปจะอยู่ที่นี่:

  • C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ CONFIG
  • C: \ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ CONFIG
  • C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Config
  • C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Config

ใช่ฉันครอบคลุมฐานนั้น ขอบคุณต่อไป @BenSwayne! ฉันตรวจสอบแล้วว่าฉันแก้ไขสิ่งที่ถูกต้องmachine.config(64-bit 4.0)
Rob Sobers

@RobSobers: ในกรณีนี้ฉันจะสงสัยเล็กน้อยเกี่ยวกับรหัสการใช้งาน บางทีคุณอาจจะหมดกระทู้หรืออะไร? คุณสามารถโยนรหัสการโทรของเว็บไซต์ TcpClient ลงในแอปคอนโซลและดูว่าคุณจะได้รับอัตราคำขอที่ดีขึ้นหรือไม่? สิ่งนี้จะพิสูจน์ได้ว่าเป็นการกำหนดค่าเฉพาะ IIS หรือการกำหนดค่า. NET ที่กว้างขึ้นหรือรหัสของคุณ
BenSwayne

บรรทัดนี้ไปอยู่ในเครื่องไคลเอนต์หรือไม่?
Uri Abramson

ขอบคุณการตั้งค่าของคุณรวมกับ processModel twekaing จากcodeproject.com/Articles/133738/… แก้ไข "ISAPI 'C: \ windows \ Microsoft.Net \ Framework \ v2.0.050727 \ aspnet_isapi.dll' รายงานว่าตัวเองไม่แข็งแรงด้วยเหตุผลต่อไปนี้ : ปัญหา 'ตรวจพบการหยุดชะงัก”
Zakos

@BenSwayne แนวคิดเดียวกันนี้ใช้กับการเชื่อมต่อ SMTP ด้วยหรือไม่ ฉันกำลังออกแบบแอปพลิเคชันการส่งอีเมลจำนวนมากดังนั้นคุณสมบัติConnectionManagementนี้จะเป็นประโยชน์ในการส่งอีเมลจำนวนมากเช่นกัน (โดยใช้มัลติเธรดสำหรับฟังก์ชันmail.send )
vibs2006

7

ฉันรู้ว่าคำถามอาจค่อนข้างเก่า แต่คุณบอกว่าแบ็กเอนด์ทำงานบนเซิร์ฟเวอร์เดียวกัน นั่นหมายถึงพอร์ตอื่นซึ่งอาจเป็นพอร์ตอื่นที่ไม่ใช่พอร์ตเริ่มต้น 80

ฉันได้อ่านมาว่าเมื่อคุณใช้องค์ประกอบการกำหนดค่า "connectionManagement" คุณต้องระบุหมายเลขพอร์ตหากแตกต่างจากค่าเริ่มต้น 80

ลิงค์: การตั้งค่า maxConnection อาจไม่ทำงานแม้กระทั่ง autoConfig = false ใน ASP.NET

ประการที่สองหากคุณเลือกใช้การกำหนดค่าเริ่มต้น (ที่อยู่ = "*") ขยายด้วยค่าเฉพาะแบ็กเอนด์ของคุณเองคุณอาจพิจารณาใส่ค่าเฉพาะก่อน! มิฉะนั้นหากมีการร้องขอ * จะจับคู่ก่อนและใช้ค่าเริ่มต้นของการเชื่อมต่อ 2 รายการ เช่นเดียวกับเมื่อคุณใช้ส่วนใน web.config

LINK: <remove> องค์ประกอบสำหรับการจัดการการเชื่อมต่อ (การตั้งค่าเครือข่าย)

หวังว่ามันจะช่วยใครบางคน


5

เป็นไปได้หรือไม่ที่คุณกำลังใช้การอ้างอิงบริการเว็บที่ใช้ WCF ตามค่าเริ่มต้นServiceThrottlingBehavior.MaxConcurrentCallsคือ 16

คุณสามารถลองอัปเดต<serviceThrottling>องค์ประกอบพฤติกรรมการอ้างอิงบริการของคุณ

<serviceThrottling
    maxConcurrentCalls="999" 
    maxConcurrentSessions="999" 
    maxConcurrentInstances="999" />

(โปรดทราบว่าฉันขอแนะนำการตั้งค่าด้านบน) ดูMSDNสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีกำหนดค่า<behavior>องค์ประกอบที่เหมาะสม


ฉันหวังว่าเราจะเป็น แต่เราไม่ใช่ บริการที่กำลังใช้อยู่กำลังทำงานใน Apache / Python / mod_wsgi บนเครื่องอื่นและตามที่ Rob กล่าวไว้ชัดเจนว่าไม่ใช่ปัญหา
Benjamin Pollack

การอ้างอิงบริการอยู่บนไคลเอนต์ ลูกค้าของคุณใช้บริการ Apache อย่างไร?
John Saunders

เช่นเดียวกับที่ John กล่าวว่าการควบคุมปริมาณถูกกำหนดไว้ที่ลูกค้าที่ใช้บริการเว็บ บางทีวลี "พฤติกรรมการบริการของคุณ" อาจทำให้เข้าใจผิดได้เล็กน้อย มันสมเหตุสมผลกว่าเมื่อวลีว่า "พฤติกรรมอ้างอิงบริการของคุณ" หรือไม่
Ruben

@john มันถูกใช้ผ่าน a TcpClient(บริการจะหยุดการทำงานของ binary blobs ที่กำหนดเองไม่ใช่ WCF / SOAP หรือสิ่งที่คล้ายกัน) ตัวเลือกการกำหนดค่าเหล่านี้ดูเหมือนจะส่งผลกระทบต่อคุณอย่างแท้จริงหากคุณใช้ServiceHostไม่ใช่TcpClient; ฉันพลาดอะไรไปรึเปล่า?
Benjamin Pollack

ทำไมไม่ใช้ "เพิ่มการอ้างอิงบริการ"
John Saunders

3

คุณได้พยายามตั้งค่าคุณสมบัติDefaultConnectionLimitแบบคงที่โดยทางโปรแกรมหรือไม่?

นี่คือแหล่งข้อมูลที่ดีเกี่ยวกับอาการปวดหัวที่แท้จริง ... การใช้เธรด ASP.NET บน IIS 7.5, IIS 7.0 และ IIS 6.0พร้อมการอัปเดตสำหรับกรอบงาน 4.0


ฉันคิดว่ามันไม่สำคัญ แต่ฉันจะลองต่อไป
Rob Sobers

นี่คือวิธีที่เราแก้ไขเมื่อไม่กี่ปีก่อน เรามีปัญหาที่เกิดขึ้นพร้อมกันและสิ่งนี้ดูเหมือนจะชัดเจนขึ้น Net.ServicePointManager.DefaultConnectionLimit = 1000 คือสิ่งที่เราใช้ คุณต้องตั้งค่าก่อนสร้างคลาสการเชื่อมต่อ
Brain2000

2

ดูส่วน "เธรด" ของหน้านี้: http://msdn.microsoft.com/en-us/library/ff647786.aspxร่วมกับส่วน "การเชื่อมต่อ"

คุณได้ลองเพิ่มแอตทริบิวต์ maxconnection ของการตั้งค่า processModel ของคุณแล้วหรือยัง?


ใช่ฉันมี. แต่บทความที่คุณอ้างถึงนั้นชี้ให้เห็นถึงสิ่งที่น่าสนใจซึ่งเคยมีบทความอื่น ๆ ในหัวข้อนี้ถูกละเลยที่จะกล่าวถึงนั่นคือmaxconnectionแอตทริบิวต์นี้ใช้ไม่ได้กับการเรียกใช้บริการเว็บในพื้นที่ ในกรณีนี้บริการเว็บเป็นแบบโลคัล แต่เรามีปัญหาเดียวกันในสภาพแวดล้อมอื่นที่บริการไม่ได้อยู่ในพื้นที่
Rob Sobers

@RobSobers - ฉันคิดว่าลิงค์ด้านบนนี้ควรค่าแก่การดูครั้งที่สอง ตรวจสอบส่วนที่เกี่ยวกับminLocalRequestFreeThreads- กระบวนการของผู้ปฏิบัติงานนี้ใช้การตั้งค่านี้เพื่อจัดคิวคำขอจาก localhost (โดยที่เว็บแอปพลิเคชันเรียกใช้บริการเว็บบนเซิร์ฟเวอร์เดียวกัน ) หากจำนวนเธรดที่มีอยู่ในเธรดพูลต่ำกว่าหมายเลขนี้ การตั้งค่านี้คล้ายกับ minFreeThreads แต่จะใช้กับคำขอที่ใช้ localhostเท่านั้น
Ahmad

@ Ahmad Yup ฉันตั้งไว้minLocalRequestFreeThreadsเช่นกัน (ดูของฉันmachine.configในคำถาม
Rob Sobers

0

หากไม่ได้กำหนดไว้ในบริการเว็บหรือแอปพลิเคชันหรือเซิร์ฟเวอร์ (apache หรือ IIS) ที่โฮสต์สิ้นเปลืองบริการเว็บคุณสามารถสร้างการเชื่อมต่อได้ไม่สิ้นสุดจนกว่าจะล้มเหลว


0

ขณะทำการทดสอบประสิทธิภาพการวัดที่ฉันใช้คือ RPS นั่นคือจำนวนคำขอต่อวินาทีที่เซิร์ฟเวอร์สามารถให้บริการได้ภายในเวลาแฝงที่ยอมรับได้

ในทางทฤษฎีเซิร์ฟเวอร์หนึ่งเครื่องสามารถเรียกใช้คำขอได้มากเท่า ๆ กันตามจำนวนคอร์เท่านั้น ..

ดูเหมือนว่าปัญหาจะไม่ใช่แบบจำลองเธรดของ ASP.net เนื่องจากอาจให้บริการได้หลายพัน rps ดูเหมือนว่าปัญหาอาจเกิดจากแอปพลิเคชันของคุณ คุณใช้ไพรมารีซิงโครไนซ์หรือไม่

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

หากสิ่งนี้ไม่ได้ทำให้บางสิ่งบางอย่างเกิดขึ้นคุณอาจต้องการสร้างโปรไฟล์รหัสของคุณโดยใช้ Visual Studio หรือ Redgate profiler

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.