โหลดการทดสอบ: วิธีการสร้างคำขอต่อวินาที?


14

ฉันมีส่วนประกอบเซิร์ฟเวอร์ที่รันบน Zeroc-ICE เมื่อฉันต้องการโหลดทดสอบฉันคิดว่าการใช้ไลบรารีคู่ขนานเพื่อสร้างคำขอหลายรายการจะทำ แต่มันก็จบลงด้วยวิธีนั้น การใช้ไลบรารีParallel (Parallel.For)จาก C # นั้นง่ายกว่า แต่ดูเหมือนว่าจะไม่ได้สร้างทุกอย่างขนานกันในทันที ดังนั้นจึงไม่สามารถกำหนดคำจำกัดความสำหรับการสร้างคำขอ N ต่อวินาที ฉันควรทำอย่างไร ฉันคิดว่าทุกคนที่ต้องการทำการทดสอบการโหลดก่อนจะคิดเกี่ยวกับเรื่องนี้

  1. วิธีที่มีประสิทธิภาพในการสร้างคำขอ N ในเวลาจริงต่อวินาทีคืออะไร?

  2. ตำนานอีกเรื่องเกี่ยวกับการเขียนโปรแกรมแบบขนาน โปรดให้ความกระจ่างแก่เราถ้าคุณใช้รูปแบบการเขียนโปรแกรมแบบขนานใน C # หรือ. Net โดยทั่วไป ลองนึกภาพฉันมี 5 กระบวนการ จะเริ่มต้นกระบวนการทั้งห้าในเวลาเดียวกันได้อย่างไร การบริโภคทรัพยากรหมายถึงอะไร ฉันได้ลองอ่านเนื้อหาที่มีอยู่มากมายในเน็ต แต่ฉันได้รับคำถามมากขึ้นกว่าที่พวกเขาเป็นคำตอบสำหรับคำถามของฉัน

  3. ฉันใช้ Parallel.For และสร้างเธรด N และเวลาที่วัดได้ จากนั้นฉันก็ลองสิ่งเดียวกันโดยใช้ Task.Factory.start สำหรับการแจงนับงาน เวลาที่วัดแตกต่างกัน ดังนั้นอะไรคือความแตกต่างระหว่างการใช้สิ่งเหล่านี้ เมื่อใดที่ฉันควรใช้คลาสที่เกี่ยวข้องและมีจุดประสงค์อะไรกันแน่ เรามักจะมีความมั่งคั่งมากมาย แต่เพียงว่าเราไม่รู้วิธีแยกความแตกต่างจากสิ่งอื่น นี่เป็นกรณีเช่นนี้สำหรับฉันไม่สามารถค้นหาสาเหตุที่ฉันไม่ควรใช้จากอีกกรณีหนึ่ง

  4. ฉันใช้คลาสนาฬิกาจับเวลาเพื่อวัดเวลาเหล่านี้ซึ่งอ้างว่าดีที่สุด ในสถานการณ์ของฉันโหลดการทดสอบส่วนประกอบสิ่งที่จะเป็นวิธีการวัดเวลาของการตอบสนอง นาฬิกาจับเวลาน่าจะเป็นทางออกที่ดีที่สุดสำหรับฉัน ความคิดเห็นใด ๆ ยินดีต้อนรับ

ps: มีเครื่องมือทดสอบโหลดมากมายสำหรับเว็บแอปพลิเคชัน Mine เป็นกรณีที่กำหนดเองของส่วนประกอบเซิร์ฟเวอร์ และคำถามของฉันเกี่ยวข้องกับการสร้างเธรด N เพิ่มเติมต่อวินาที

ความคิดเห็นทั้งหมดยินดีต้อนรับ อย่าคิดว่ามันไม่ใช่คำถามการเขียนโปรแกรม แน่นอนว่ามันคือ มันควรจะส่งเสียงระฆังสำหรับโปรแกรมเมอร์ที่ต้องการ QE stuff ด้วยตัวเองเพื่อทราบประสิทธิภาพของผลิตภัณฑ์ของเขาด้วยตัวเองฉันลองใช้ตัวเลือกมากมายแล้วต้องย้อนกลับไปทำยังไงดี?


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

"อินสแตนท์เดียวกัน" หมายความว่าอย่างไร ฉันสงสัยว่าคุณสามารถบังคับ TPL หรือ PLinq ไม่ว่าจะด้วยวิธีใดก็ตาม
Gert Arnold

คำถามของฉันเกี่ยวกับการสร้างคำขอ N ต่อวินาที ดังนั้นทันทีในสถานการณ์นี้มีความหมายต่อความเข้าใจของฉันในการใช้ขนานจะเริ่มหัวข้อในแบบคู่ขนาน
King

คุณทำการวิเคราะห์ตามลำดับหรือไม่?

3
อาจเกี่ยวข้องกับการเขียนโปรแกรม แต่มีคำถามมากเกินไปในโพสต์ของคุณ (อย่างน้อย 4) ฉันจะลดมันลงในคำถามเดียวที่คุณต้องการถามก่อนที่มันจะถูกปิดเพราะมันกว้างเกินไป ให้ข้อมูลที่เกี่ยวข้องเช่น 10000 ที่คุณเพิ่งพูดถึงจำนวนแกนในเครื่องทดสอบของคุณ) การแสดงรหัสมักจะช่วยได้
Gert Arnold

คำตอบ:


10

ฉันไม่มีคำตอบทั้งหมด หวังว่าฉันสามารถหลั่งบางแสงกับมัน

เพื่อทำให้งบก่อนหน้าของฉันง่ายขึ้นเกี่ยวกับเธรดของ. NET เพียงแค่รู้ว่า Parallel Library ใช้งานและค่าเริ่มต้น TaskScheduler สำหรับงานใช้ ThreadPool ยิ่งคุณไปในลำดับชั้น (ThreadPool อยู่ที่ด้านล่าง) ยิ่งมีค่าใช้จ่ายมากขึ้นเมื่อคุณสร้างรายการ ค่าใช้จ่ายพิเศษนั้นไม่ได้หมายความว่าจะช้า แต่ก็ดีที่จะรู้ว่ามี ในที่สุดประสิทธิภาพของอัลกอริทึมของคุณในสภาพแวดล้อมแบบมัลติเธรดนั้นมาจากการออกแบบ สิ่งที่ทำงานได้ดีตามลำดับอาจไม่ทำงานพร้อมกัน มีปัจจัยหลายอย่างที่เกี่ยวข้องกับการให้กฎแก่คุณอย่างหนักและรวดเร็วซึ่งพวกเขาเปลี่ยนไปตามสิ่งที่คุณพยายามจะทำ เนื่องจากคุณกำลังติดต่อกับคำขอเครือข่ายฉันจะลองและยกตัวอย่างเล็กน้อย

ให้ฉันบอกว่าฉันไม่เชี่ยวชาญกับซ็อกเก็ตและฉันรู้ว่าไม่มีอะไรเกี่ยวกับ Zeroc-Ice ฉันรู้เกี่ยวกับการทำงานแบบอะซิงโครนัสเล็กน้อยและนี่คือที่ที่จะช่วยคุณได้จริงๆ ถ้าคุณส่งคำขอซิงโครนัสผ่านซ็อกเก็ตเมื่อคุณโทรSocket.Receive()เธรดของคุณจะบล็อกจนกว่าจะได้รับคำขอ มันไม่ดี เธรดของคุณไม่สามารถทำการร้องขอได้อีกต่อไปตั้งแต่ถูกบล็อค ใช้ Socket.Beginxxxxxx () คำขอ I / O จะทำและใส่ในคิว IRP สำหรับซ็อกเก็ตและด้ายของคุณจะยังคงดำเนินต่อไป ซึ่งหมายความว่าเธรดของคุณสามารถสร้างคำขอได้หลายพันรายการโดยไม่ต้องปิดกั้นเลย!

หากฉันเข้าใจคุณถูกต้องคุณกำลังใช้การโทรผ่าน Zeroc-Ice ในรหัสการทดสอบของคุณไม่ใช่การพยายามเข้าถึงจุดปลาย http จริง ๆ หากเป็นกรณีนี้ฉันสามารถยอมรับได้ว่าฉันไม่รู้ว่า Zeroc-Ice ทำงานอย่างไร ฉันจะอย่างไรก็ตามขอแนะนำดังต่อไปนี้คำแนะนำที่ระบุไว้ที่นี่Consider Asynchronous Method Invocation (AMI)โดยเฉพาะอย่างยิ่งในส่วนที่: หน้าแสดงสิ่งนี้:

โดยการใช้ AMI ไคลเอนต์คืนเธรดของตัวควบคุมทันทีที่มีการส่งการร้องขอ (หรือถ้าไม่สามารถส่งได้ทันทีถูกเข้าคิว), อนุญาตให้ไคลเอนต์ใช้เธรดนั้นเพื่อทำงานที่มีประโยชน์อื่น ๆ ในเวลาเฉลี่ย .

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

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

var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
    // The thread blocks here waiting for the response.
    // That slows down your loop and you're just wasting
    // CPU cycles that could instead be sending/receiving more objects
    MyObjectPrx obj = iceComm.stringToProxy("whateverissupposedtogohere");
    obj.DoStuff();
}

วิธีที่ดีกว่า:

public interface MyObjectPrx : Ice.ObjectPrx
{
    Ice.AsyncResult GetObject(int obj, Ice.AsyncCallback cb, object cookie);
    // other functions
}

public static void Finished(Ice.AsyncResult result)
{
    MyObjectPrx obj = (MyObjectPrx)result.GetProxy();
    obj.DoStuff();
}

static void Main(string[] args)
{
    // threaded code...
    var iterations = 100000;
    for (int i = 0; i < iterations; i++)
    {
        int num = //whatever
        MyObjectPrx prx = //whatever
        Ice.AsyncCallback cb = new Ice.AsyncCallback(Finished);
        // This function immediately gets called, and the loop continues
        // it doesn't wait for a response, it just continually sends out socket
        // requests as fast as your CPU can handle them.  The response from the
        // server will be handled in the callback function when the request
        // completes.  Hopefully you can see how this is much faster when 
        // sending sockets.  If your server does not use an Async model 
        // like this, however, it's quite possible that your server won't 
        // be able to handle the requests
        prx.GetObject(num, cb, null);
    }
}

โปรดทราบว่ามีเธรดเพิ่มเติม! = ประสิทธิภาพที่ดีขึ้นเมื่อพยายามส่งซ็อกเก็ต (หรือทำสิ่งใด ๆ ) เธรดไม่ได้ใช้เวทมนตร์ในการที่พวกเขาจะแก้ไขปัญหาใด ๆ ที่คุณกำลังทำอยู่โดยอัตโนมัติ ตามหลักแล้วคุณต้องการ 1 เธรดต่อคอร์เว้นแต่ว่าเธรดใช้เวลาส่วนใหญ่ในการรอคอยจากนั้นคุณสามารถพิสูจน์ได้ว่ามีมากขึ้น การรันแต่ละคำร้องขอในเธรดของตนเองเป็นแนวคิดที่ไม่ดีเนื่องจากสวิตช์บริบทจะเกิดขึ้นและสิ้นเปลืองทรัพยากร (หากคุณต้องการเห็นทุกสิ่งที่ฉันเขียนเกี่ยวกับเรื่องนี้ให้คลิกแก้ไขและดูการแก้ไขที่ผ่านมาของโพสต์นี้ฉันลบออกเนื่องจากดูเหมือนว่าจะทำให้เกิดปัญหาหลักในมือเท่านั้น)

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

ฉันหวังว่าจะช่วย


ทำไมคุณถึงพูดถึงเรื่องการแสดงอย่างมาก? ดูเหมือนจะไม่เป็นอย่างที่ OP ต้องการ
svick

1
@svick ดูดีโพสต้นฉบับมี 4 คำถามเดิมและพวกเขาถามคำถามเกี่ยวกับประสิทธิภาพของการทำงานแบบขนานกับงานแล้วมันก็ถูกแก้ไขและตอนนี้พวกเขากลับมาดังนั้นสิ่งที่คุณอ่านเป็นผลมาจากที่ ในที่สุดแม้ว่าคำถามของเขาจะต้องเกี่ยวข้องกับการแสดงในขณะที่เขามีความคิดทั่วไปที่ถูกต้อง แต่ดูเหมือนจะขาดในการดำเนินการของเขา ฉันเชื่อว่าคำตอบที่ชัดเจนในตอนท้ายตอบคำถามที่เขาไม่ได้แก้ไข
Christopher Currens

1
ฉันถูกบังคับให้ลดคำถามของฉันเพราะพวกเขาต้องการที่จะลงคะแนนให้ปิด ตอนนี้ดูเหมือนว่ามันถูกต้องที่นี่เพื่อมีพวกเขา @ChristopherCurrens +1 จุดที่ดีสำหรับความแตกต่างกับ threadpool กับงาน นั่นทำให้ฉันเข้าใจมากขึ้น แต่ฉันยังคงติดอยู่ว่าการสร้างคำขอ N ต่อวินาทีเป็นไปได้จริง ๆ ? อะไรคือวิธีที่ดีที่สุดในการทำเช่นนั้น?
King

@King - ฉันคิดว่าฉันไม่ชัดเจนอย่างที่ฉันคิด ย่อหน้า 3-4 ล่าสุดที่ฉันคิดว่าจะช่วยคุณ ฉันคิดว่าคุณใช้วงแปลก ๆ มาแล้ว หากคุณทำเช่นนั้นปัญหาคือว่าซ็อกเก็ตของคุณส่ง / รับกำลังบล็อกและทำให้คำขอของคุณช้าลง บางทีฉันอาจหาเวลาโพสต์โค้ดหลอกบางตัวอย่าง
Christopher Currens

ฉันไม่มีปัญหาในการส่งพวกเขาจริง ๆ ผ่าน ICE ปัญหาคือสิ่งที่กำหนดการใช้งานที่จะสร้างคำขอ N และสิ่งที่สามารถพูดได้จริงกับหมายเลขนั้น N
King

2

ฉันจะข้ามคำถาม 1) และได้รับใน # 2 เนื่องจากโดยทั่วไปเป็นวิธีที่ยอมรับได้เพื่อบรรลุสิ่งที่คุณกำลังมองหา ในอดีตเพื่อให้ได้nข้อความต่อวินาทีคุณสามารถสร้างกระบวนการเดียวที่จะเปิดp AppDomains โดยทั่วไปแล้ว AppDomain แต่ละตัวจะเริ่มเรียกใช้ลูปการร้องขอเมื่อถึงเวลาที่กำหนด (โดยใช้ตัวจับเวลา) เวลานี้ควรจะเหมือนกันสำหรับแต่ละ AppDomain เพื่อให้แน่ใจว่าพวกเขาเริ่มกดเซิร์ฟเวอร์ของคุณในเวลาเดียวกัน

สิ่งนี้จะทำงานเมื่อส่งคำขอของคุณ:

WaitCallback del = state => 
{ 
    ManualResetEvent[] resetEvents = new ManualResetEvent[10000]; 
    WebClient[] clients = new WebClient[10000]; 

    for (int index = 0; index < 10000; index++) 
    { 
        resetEvents[index] = new ManualResetEvent(false); 
        clients[index] = new WebClient(); 

        clients[index].OpenReadCompleted += new OpenReadCompletedEventHandler (client_OpenReadCompleted); 

        clients[index].OpenReadAsync(new Uri(@"<REQUESTURL>"), resetEvents[index]); 
    } 

    bool succeeded = ManualResetEvent.WaitAll(resetEvents, 10000); 
    Complete(succeeded); 

    for (int index = 0; index < 10000; index++) 
    { 
        resetEvents[index].Dispose(); 
        clients[index].Dispose(); 
    } 
}; 

while(running)
{
    ThreadPool.QueueUserWorkItem(del);
    Thread.Sleep(1000);
}

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

สำหรับคำถามที่สามของคุณให้ลิงค์นี้อ่านhttp://www.albahari.com/threading/

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


2
คุณมีเหตุผลอะไรที่จะต้องสร้าง AppDomain แยกต่างหากที่นี่ ดูเหมือนว่าไม่จำเป็นเลย
svick

0

อย่ารำคาญกับกระทู้ถ้า N มีขนาดเล็กพอสมควร หากต้องการสร้างคำขอ N ต่อวินาทีให้ใช้เวลานาฬิกาแขวน ( DateTime.Now) ใช้เวลาทั้งก่อนและหลังการร้องขอจากนั้นเพิ่ม a Sleepเพื่อหน่วงเวลาการร้องขอถัดไป

ตัวอย่างเช่นด้วย N = 5 (200 ms):

Before request: 12:33:05.014
After request: 12:33:05.077
Sleep(137)
Before request: 12:33:05.214
After request: 12:33:05.271
Sleep(131)

มันไม่สมบูรณ์แบบ คุณอาจพบว่าSleepไม่ถูกต้อง คุณสามารถเก็บจำนวนการเบี่ยงเบนที่ทำงานอยู่ (ก่อนคำขอ X'th เวลาควรเป็น X-1 / N ในภายหลัง) และปรับระยะเวลาสลีปตามลำดับ

เมื่อ N มีขนาดใหญ่เกินไปคุณเพียงแค่สร้าง M thread และให้แต่ละเธรดสร้างคำขอ N / M ในรูปแบบเดียวกัน


ฉันต้องสร้างคำขอจำนวนมาก ดังนั้นนี่เป็นตัวเลือกไม่ได้เพราะมันจะดื่มหน่วยความจำของฉัน (4GB RAM) ก่อนหน้า 100 เธรด
King

ฉันได้สร้างคำขอ 20.000 คำขอต่อวินาทีจากเธรดเดียวโดยเป็นรหัส 250K คุณมี CPU ไม่เพียงพอที่จะเรียกใช้ 100 เธรดแล้ว (คลาสของเครื่องนั้นไม่มีขนาด 4GB) ปัญหาต่อไปคือการผลักดันคำขอทั้งหมดนั้นออกไป คุณมี 10 Gbit / s Ethernet ระหว่างผู้สร้างโหลดและเซิร์ฟเวอร์ของคุณหรือไม่ ดังนั้นคุณอาจต้องการตรวจสอบข้อกำหนดที่แท้จริงของคุณ
MSalters

เพื่อชี้แจงฉันมีบางอย่างเช่น 20+ Gbps นั่นไม่ใช่ปัญหา เกี่ยวกับคลาสของเครื่องจักรคุณจะอ้างอิงถึงอะไร จำนวนโปรเซสเซอร์?
King

@King: เพื่อผลักดันเธรด 100 เธรดฉันต้องการเครื่อง 48 คอร์ SGI ขายเครื่องจักรที่มีหลายคอร์นั้นตัวอย่างเช่น แต่สำหรับเครื่องที่คุณมักจะได้รับ 32GB หรือมากกว่านั้น
MSalters

0

วิธีที่ง่ายที่สุดในการทดสอบโหลดสำหรับโครงการ. NET ใด ๆ คือการซื้อ Ultimate Studio รุ่น Visual สิ่งนี้มาพร้อมกับเครื่องมือทดสอบที่ผสานรวมเพื่อช่วย preform การทดสอบทุกประเภทรวมถึงการทดสอบโหลด การทดสอบโหลดสามารถ preform โดยการสร้างผู้ใช้เสมือนไม่ว่าจะบนพีซีเครื่องเดียวหรือกระจายในหลาย ๆ เครื่องสำหรับผู้ใช้จำนวนมากนอกจากนี้ยังมีโปรแกรมขนาดเล็กที่สามารถติดตั้งบนเซิร์ฟเวอร์เป้าหมายเพื่อส่งคืนข้อมูลเพิ่มเติมในช่วงเวลาของการทดสอบ

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


0

หากคุณต้องการให้เธรด X ทั้งหมดเข้าสู่ทรัพยากรของคุณในเวลาเดียวกันคุณสามารถใส่แต่ละเธรดไว้ข้างหลังสลักนับถอยหลังและระบุช่วงเวลารอสั้น ๆ ระหว่างการตรวจสอบสัญญาณ

C # มีการนำไปใช้ (http://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx)

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

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

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