บทความนี้ส่วนใหญ่ศึกษาคำอธิบายโดยละเอียดเกี่ยวกับตัวอย่างกลไกการลองใหม่ของการเขียนโปรแกรม Java และตัวอย่างรหัสที่เกี่ยวข้องที่ใช้ร่วมกัน บรรณาธิการคิดว่ามันค่อนข้างดีและมีค่าอ้างอิงบางอย่าง เพื่อนที่ต้องการมันสามารถอ้างถึงมันได้
ฟังก์ชั่นจะต้องนำไปใช้ในแอปพลิเคชัน: ข้อมูลจะต้องอัปโหลดไปยังบริการจัดเก็บข้อมูลระยะไกลและการดำเนินการอื่น ๆ จะดำเนินการเมื่อการประมวลผลแบบส่งคืนสำเร็จ ฟังก์ชั่นนี้ไม่ซับซ้อนและแบ่งออกเป็นสองขั้นตอน: ขั้นตอนแรกคือการเรียกใช้เครื่องห่อตรรกะของบริการระยะไกลเพื่อส่งคืนผลการประมวลผลไปยังวิธีการประมวลผล ขั้นตอนที่สองคือการได้รับผลลัพธ์ของขั้นตอนแรกหรือจับข้อยกเว้น หากมีข้อผิดพลาดหรือข้อยกเว้นเกิดขึ้นตรรกะการอัปโหลดจะถูกลองใหม่มิฉะนั้นการดำเนินการเชิงตรรกะจะดำเนินต่อไป
ขึ้นอยู่กับตรรกะการอัพโหลดปกติตรรกะของฟังก์ชั่นจะดำเนินการโดยการตัดสินว่าผลการส่งคืนหรือการฟังการตัดสินใจข้อยกเว้นคือการลองใหม่ ในเวลาเดียวกันเพื่อที่จะแก้ปัญหาการดำเนินการที่ไม่ถูกต้องของการลองใหม่ทันที (สมมติว่าข้อยกเว้นเกิดจากความไม่แน่นอนของการดำเนินการภายนอก) ตรรกะของฟังก์ชั่นจะถูกกำหนดอีกครั้งสำหรับเวลาหน่วงเวลาที่กำหนด
โมฆะสาธารณะ CommonRetry (MAP <String, Object> DataMap) พ่น InterruptedException {MAP <String, Object> parammap = maps.newHashMap (); parammap.put ("tablename", "creativetable"); parammap.put ("ds", "20160220"); parammap.put ("datamap", datamap); ผลลัพธ์บูลีน = false; ลอง {result = uploadtoodps (parammap); if (! ผลลัพธ์) {thread.sleep (1,000); uploadtoodps (parammap); // ลองครั้งเดียว}} catch (exception e) {thread.sleep (1000); uploadtoodps (parammap); // ลองครั้งเดียว}}โซลูชันข้างต้นอาจยังไม่ถูกต้องสำหรับการลองใหม่ ในการแก้ปัญหานี้ให้พยายามเพิ่มจำนวนการลองใหม่และช่วงเวลาลองลองใหม่เพื่อให้ได้ความเป็นไปได้ในการเพิ่มการลองใหม่ที่ถูกต้อง
โมฆะสาธารณะ CommonRetry (MAP <String, Object> DataMap) พ่น InterruptedException {MAP <String, Object> parammap = maps.newHashMap (); parammap.put ("tablename", "creativetable"); parammap.put ("ds", "20160220"); parammap.put ("datamap", datamap); ผลลัพธ์บูลีน = false; ลอง {result = uploadtoodps (parammap); if (! ผลลัพธ์) {reuploadtoodps (parammap, 1000l, 10); // ล่าช้าหลายครั้ง retry}} catch (ข้อยกเว้น e) {reuploadtoodps (parammap, 1000l, 10); // ล่าช้าหลายครั้ง}}}}}}}}}มีปัญหาเกี่ยวกับการแก้ปัญหา 1 และโซลูชัน 2: ตรรกะปกติและตรรกะการลองลองใหม่อย่างมาก ตรรกะการลองใหม่ขึ้นอยู่กับผลการดำเนินการของตรรกะปกติและทริกเกอร์การลองใหม่แบบพาสซีฟสำหรับผลลัพธ์ที่คาดหวังของตรรกะปกติ สาเหตุที่แท้จริงของการลองใหม่มักถูกครอบงำโดยตรรกะที่ซับซ้อนซึ่งอาจนำไปสู่ความเข้าใจที่ไม่สอดคล้องกันเกี่ยวกับปัญหาที่จะแก้ปัญหาสำหรับการดำเนินการและการบำรุงรักษาที่ตามมา การลองใหม่เป็นเรื่องยากที่จะรับประกันและไม่เอื้อต่อการดำเนินงานและการบำรุงรักษาเนื่องจากการออกแบบใหม่ขึ้นอยู่กับข้อยกเว้นตรรกะปกติหรือลองชิมสาเหตุของการคาดเดา
ดังนั้นมีวิธีแก้ปัญหาที่สามารถใช้ในการแยกตรรกะปกติและตรรกะลองอีกครั้งและในเวลาเดียวกันก็สามารถให้โซลูชันที่เป็นมาตรฐานอีกครั้งได้หรือไม่? คำตอบคือ: นั่นคือเครื่องมือลองใหม่ตามรูปแบบการออกแบบตัวแทน เราพยายามใช้เครื่องมือที่เกี่ยวข้องเพื่อสร้างสถานการณ์ด้านบนขึ้นใหม่
คำจำกัดความเฉพาะของรูปแบบการออกแบบคำสั่งไม่ได้อธิบาย เหตุผลหลักคือรูปแบบคำสั่งสามารถทำให้ตรรกะการทำงานของอินเตอร์เฟสเสร็จสมบูรณ์โดยการดำเนินการวัตถุและในเวลาเดียวกันการห่อหุ้มภายในของตรรกะการลองใหม่จะไม่ได้รับรายละเอียดการใช้งาน สำหรับผู้โทรมันคือการดำเนินการของตรรกะปกติและบรรลุเป้าหมายของการ decoupling โปรดดูการใช้งานฟังก์ชั่นเฉพาะ (โครงสร้างแผนภาพคลาส)
IRETRY เห็นด้วยกับอินเทอร์เฟซการอัปโหลดและการลองใหม่ซึ่งใช้ ODPSRETRY-like ห่อหุ้มตรรกะการอัปโหลด ODPS และห่อหุ้มกลไกการลองใหม่และกลยุทธ์การลองใหม่ในเวลาเดียวกัน ในเวลาเดียวกันใช้วิธีการกู้คืนเพื่อดำเนินการกู้คืนในตอนท้าย
LogicClient ผู้โทรของเราไม่จำเป็นต้องให้ความสนใจกับการลองใหม่ มันใช้ฟังก์ชั่นอินเทอร์เฟซการประชุมผ่าน retryer retryer ในเวลาเดียวกัน retryer จำเป็นต้องตอบสนองและประมวลผลตรรกะการลองใหม่ การประมวลผลการลองใหม่ที่เฉพาะเจาะจงของ retryer จะถูกส่งมอบไปยังระดับการใช้งานอินเทอร์เฟซที่แท้จริง ด้วยการใช้โหมดคำสั่งตรรกะปกติและตรรกะการลองใหม่จะถูกแยกออกอย่างสง่างามและในเวลาเดียวกันตรรกะปกติและตรรกะการลองใหม่จะถูกคั่นด้วยการสร้างบทบาทของ retryers เพื่อให้การปรับขนาดได้ดีขึ้น
Spring-Retry เป็นชุดเครื่องมือโอเพนซอร์สซึ่งมีอยู่ในปัจจุบันรุ่น 1.1.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2.2 ในเวลาเดียวกันลองใช้อินสแตนซ์การดำเนินการอีกครั้งเพื่อให้แน่ใจว่ามีความปลอดภัยของเธรด ตัวอย่างการดำเนินการเฉพาะมีดังนี้:
การอัปโหลดโมฆะสาธารณะ (แผนที่สุดท้าย <สตริง, วัตถุ> แผนที่) พ่นข้อยกเว้น {// สร้างอินสแตนซ์เทมเพลตลองรีย์ retryTemplate retryTemplate = ใหม่ retryTemplate (); // ตั้งค่านโยบายการลองใหม่ส่วนใหญ่ตั้งค่าการตอบกลับนโยบาย simpleeretryPolicy = new SimpleLetryPolicy (3, คอลเลกชัน <class <? ขยายได้>, boolean> singletonmap (exception.class, true)); // ตั้งค่านโยบายการดำเนินการทางเลือกลองใหม่ส่วนใหญ่ตั้งค่าช่วงเวลาการลองใหม่ retry rementbackOffPolicy fixedbackOffPolicy = ใหม่ reamixbackOffPolicy (); คงที่ backOffPolicy.SetBackOffPeriod (100); retrytemplate.setRetryPolicy (นโยบาย); retryTemplate.SetBackOffPolicy (reamiedBackOffPolicy); // retrycallback ลองใหม่อินสแตนซ์การโทรกลับเพื่อห่อตรรกะตรรกะปกติการดำเนินการครั้งแรกและการดำเนินการใหม่ทั้งหมดลอจิกทั้งหมดนี้ retrycallback <วัตถุข้อยกเว้น> retrycallback = ใหม่ retrycallback <วัตถุข้อยกเว้น> () {// retrycontext System.out.println ("ทำอะไรบางอย่าง"); ข้อยกเว้น e = uploadtoodps (แผนที่); System.out.println (context.getRetryCount ()); โยน e; // ให้ความสนใจเป็นพิเศษถึงจุดนี้ รูทของการลองใหม่จะถูกส่งคืนผ่านข้อยกเว้น}}; // ดึงกระบวนการลองใหม่ตามปกติจะสิ้นสุดหรือถึงขีด จำกัด บนลองอีกครั้ง ขั้นสุดท้าย RecoveryCallback <Object> RecoveryCallback = ใหม่ RecoveryCallback <Object> () {วัตถุสาธารณะกู้คืน (บริบท retryContext) โยนข้อยกเว้น {System.out.println ("การดำเนินการกู้คืน"); คืนค่า null; - ลอง {// ดำเนินการวิธีการดำเนินการโดย retryTemplate เพื่อเริ่มต้นการดำเนินการเชิงตรรกะของ retryTemplate.execute (retryCallback, RecoveryCallback); } catch (exception e) {e.printstacktrace (); -หลังจากวิเคราะห์รหัสเคสแล้ว retrytemplate จะถือว่าบทบาทของผู้ดำเนินการลองอีกครั้ง มันสามารถตั้งค่า SimpleeretryPolicy (นโยบายการลองใหม่, ตั้งค่าขีด จำกัด บน, retry retry retity retity), rementbackoffpolicy (นโยบายการโทรกลับคงที่ตั้งค่าช่วงเวลาสำหรับการโทรกลับอีกครั้ง) RetryTemplate ดำเนินการผ่านการดำเนินการและสองอินสแตนซ์คลาสคือ retryCallback และ RecoveryCallback จะต้องเตรียมอินสแตนซ์คลาสสองรายการ อดีตสอดคล้องกับอินสแตนซ์ตรรกะการโทรกลับอีกครั้งและห่อหุ้มการทำงานปกติ RecoveryCallback ใช้อินสแตนซ์การดำเนินการกู้คืนในตอนท้ายของการดำเนินการทั้งหมด
การดำเนินการของ retrytemplate คือเธรดที่ปลอดภัยและตรรกะการใช้งานใช้ ThreadLocal เพื่อบันทึกบริบทการดำเนินการ retryContext ของแต่ละอินสแตนซ์การดำเนินการ
แม้ว่าเครื่องมือสปริง-รีเฟรชสามารถใช้งานได้อย่างสง่างาม แต่ก็มีการออกแบบที่ไม่เป็นมิตรสองอย่าง: หนึ่งคือเอนทิตีลองใหม่นั้น จำกัด อยู่ที่คลาสย่อยที่สามารถขยายได้แสดงให้เห็นว่าการลองใหม่มีจุดมุ่งหมายที่ข้อยกเว้นการใช้งานที่เร็วในการออกแบบ อีกประการหนึ่งคือวัตถุการยืนยันที่ลองทำซ้ำสาเหตุของการใช้อินสแตนซ์ข้อยกเว้นข้อยกเว้นของ dowithretry ซึ่งไม่สอดคล้องกับการออกแบบการส่งคืนของการยืนยันภายในปกติ
ผู้สนับสนุนการลองใหม่ของฤดูใบไม้ผลิลองใหม่ในคำอธิบายประกอบ ลอจิกลองดำเนินการแบบซิงโครนัส "ความล้มเหลว" ของการลองใหม่มีการกำหนดเป้าหมายไปที่การโยนได้ หากคุณต้องการตรวจสอบว่าคุณจำเป็นต้องลองใหม่ตามสถานะที่แน่นอนของค่าผลตอบแทนคุณอาจจะสามารถตัดสินค่าคืนได้ด้วยตัวเองแล้วโยนข้อยกเว้นอย่างชัดเจน
นามธรรมของฤดูใบไม้ผลิสำหรับการลองใหม่
"บทคัดย่อ" เป็นคุณภาพที่จำเป็นสำหรับโปรแกรมเมอร์ทุกคน สำหรับฉันที่มีคุณสมบัติปานกลางไม่มีวิธีที่ดีกว่าในการปรับปรุงมากกว่าการเลียนแบบและทำความเข้าใจกับซอร์สโค้ดที่ยอดเยี่ยม ในการทำเช่นนี้ฉันเขียนตรรกะหลักของมันอีกครั้ง ... ลองมาดูสิ่งที่เป็นนามธรรมของ Spring Retry สำหรับ "retry"
อินเทอร์เฟซที่เกี่ยวข้องกับสปริง retry.jpg
เครื่องมือ Guava retryer นั้นคล้ายคลึงกับสปริง-รีเฟรช มันห่อการลองใหม่แบบตรรกะปกติโดยการกำหนดบทบาทของ retryer อย่างไรก็ตาม Guava retryer มีคำจำกัดความนโยบายที่ดีกว่า บนพื้นฐานของการสนับสนุนจำนวนเวลาลองลองใหม่และการควบคุมความถี่ลองใหม่มันสามารถเข้ากันได้กับคำจำกัดความแหล่งที่มาลองใหม่ที่รองรับข้อยกเว้นหลายอย่างหรือวัตถุเอนทิตีที่กำหนดเองทำให้ฟังก์ชั่นการลองใช้ความยืดหยุ่นมากขึ้น Guava retryer ยังปลอดภัยเช่นกัน ตรรกะการโทรเข้าใช้วิธีการโทรของ java.util.concurrent.callable รหัสตัวอย่างมีดังนี้:
โมฆะสาธารณะ uploadodps (แผนที่สุดท้าย <สตริงวัตถุ> แผนที่) {// retryerBuilder สร้างอินสแตนซ์ลองรีไซเคิลใหม่คุณสามารถตั้งค่าแหล่งที่มาลองใหม่และรองรับแหล่งที่มาลองหลายครั้ง .ReterIfexception () .// Set Exception retry Source retryifresult (ใหม่ predicate <boolean> () {// ตั้งค่าเซ็กเมนต์ที่กำหนดเอง retry แหล่งที่มา @Override บูลีนสาธารณะใช้ (สถานะบูลีน) {// หมายเหตุพิเศษ .WithStopstrategy (Stopstrategies.stopafterattempt (5)) // ตั้งค่าใหม่ 5 ครั้งและคุณยังสามารถตั้งค่าเวลาหมดเวลาลองใหม่ได้ด้วย Withwaitstrategy (Waitstrategies.fixedWait (100L, TimeUnit.milliseconds). java.util.concurrent.callable <v> ดังนั้นการดำเนินการเป็น boolean แบบเธรดที่ปลอดภัย = retryer.call (callable ใหม่ <boolean> () {@Override Public Boolean Call () โยนข้อยกเว้น {ลอง {// หมายเหตุพิเศษ ข้อยกเว้น (e);}}}); } catch (executionException e) {} catch (retryException ex) {}}การวิเคราะห์หลักการรหัสตัวอย่าง:
RetryerBuilder เป็นผู้สร้างโรงงานที่สามารถปรับแต่งแหล่งที่มาลองใหม่และสามารถรองรับแหล่งที่มาใหม่ได้หลายแหล่งสามารถกำหนดค่าจำนวนเวลาลองใหม่หรือการหมดเวลาลองใหม่และสามารถกำหนดค่าช่วงเวลารอคอยเพื่อสร้างอินสแตนซ์ของ Retryer Retryer
แหล่งที่มาของ retryerbuilder สนับสนุนวัตถุข้อยกเว้นและวัตถุยืนยันที่กำหนดเองและตั้งค่าผ่าน retryifexception และ retryifresult มันรองรับหลาย ๆ และเข้ากันได้ในเวลาเดียวกัน
การกำหนดค่าเวลารอการรอคอยและการลองใหม่ของ retryerBuilder จะถูกนำมาใช้โดยใช้คลาสนโยบายที่แตกต่างกันและคุณสมบัติเวลารอคอยสามารถรองรับโหมดช่วงเวลาที่ไม่ได้รับความสนใจและคงที่
retryer เป็นอินสแตนซ์ของ retryer ซึ่งดำเนินการตรรกะการดำเนินการผ่านวิธีการโทรและห่อหุ้มการดำเนินการใหม่
สามัญชนที่สง่างามและหลักการ
ปกติและลองใหม่อย่างสง่างามลองอีกครั้งยืนยันว่าอินสแตนซ์แบบมีเงื่อนไขหรืออินสแตนซ์ข้อยกเว้นเชิงตรรกะเป็นสื่อสำหรับการสื่อสารระหว่างทั้งสอง
เห็นด้วยกับช่วงเวลาลองใหม่กลยุทธ์การลองใหม่ที่แตกต่างและกำหนดเวลาหมดเวลาลองใหม่เพื่อให้มั่นใจว่าประสิทธิภาพของการลองใหม่และความมั่นคงของกระบวนการลองใหม่
ทั้งหมดใช้รูปแบบการออกแบบคำสั่งและการดำเนินการเชิงตรรกะที่สอดคล้องกันจะเสร็จสมบูรณ์โดยการมอบหมายวัตถุลองใหม่และใช้ตรรกะลองใช้ใหม่ภายใน
เครื่องมือในฤดูใบไม้ผลิและ Guava-Treyer นั้นมีทั้งการลองใหม่อย่างปลอดภัยและสามารถรองรับความถูกต้องของตรรกะการลองใหม่ในสถานการณ์ธุรกิจพร้อมกัน
สถานการณ์ที่ใช้บังคับสำหรับการลองใหม่อย่างสง่างาม
มีสถานการณ์การพึ่งพาที่ไม่เสถียรในตรรกะการทำงานและจำเป็นต้องใช้ลองใหม่เพื่อให้ได้ผลลัพธ์ที่คาดหวังหรือพยายามที่จะแสดงตรรกะใหม่โดยไม่สิ้นสุดทันที ตัวอย่างเช่นการเข้าถึงอินเทอร์เฟซระยะไกลการเข้าถึงข้อมูลการตรวจสอบการอัปโหลดข้อมูล ฯลฯ
มีสถานการณ์ที่จำเป็นต้องลองใหม่สำหรับสถานการณ์ข้อยกเว้นและในเวลาเดียวกันก็หวังว่าจะแยกแยะตรรกะปกติและตรรกะลองอีกครั้ง
สำหรับการโต้ตอบบนพื้นฐานของสื่อข้อมูลแผนการลองใหม่สามารถพิจารณาในสถานการณ์ที่ต้องใช้การสำรวจซ้ำเพื่อตรวจจับตรรกะการดำเนินการ
ข้างต้นเป็นคำอธิบายโดยละเอียดทั้งหมดของตัวอย่างกลไกการลองใหม่ของ Java Programming ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!