การแปลและการปรับJava Microservices: A Practical Guide ส่วนก่อนหน้าของคำแนะนำ:
- พื้นฐานไมโครเซอร์วิส และสถาปัตยกรรม
- การปรับใช้และการทดสอบไมโครเซอร์วิส
จะทำให้ Java microservice มีความยืดหยุ่นได้อย่างไร
โปรดจำไว้ว่าเมื่อคุณสร้างไมโครเซอร์วิส คุณจะต้องแลกเปลี่ยนการเรียกเมธอด JVM สำหรับการเรียก HTTP แบบซิงโครนัสหรือการส่งข้อความแบบอะซิงโครนัส แม้ว่าการเรียกเมธอดส่วนใหญ่จะรับประกันว่าจะเสร็จสมบูรณ์ (ยกเว้นการปิดระบบ JVM โดยไม่คาดคิด) การเรียกผ่านเครือข่ายก็ไม่น่าเชื่อถือตามค่าเริ่มต้น อาจใช้งานได้ แต่อาจไม่ทำงานด้วยเหตุผลหลายประการ เช่น เครือข่ายโอเวอร์โหลด มีการนำกฎไฟร์วอลล์ใหม่ไปใช้ และอื่นๆ หากต้องการดูว่าสิ่งนี้สร้างความแตกต่างได้อย่างไร มาดูตัวอย่าง BillingService กันรูปแบบความยืดหยุ่น HTTP/REST
สมมติว่าลูกค้าสามารถซื้อ eBook บนเว็บไซต์ของบริษัทของคุณได้ ในการดำเนินการนี้ คุณเพิ่งใช้ไมโครเซอร์วิสการเรียกเก็บเงินที่สามารถโทรหาร้านค้าออนไลน์ของคุณเพื่อสร้างใบแจ้งหนี้ PDF จริงได้ สำหรับตอนนี้ เราจะทำการเรียกนี้พร้อมกันผ่าน HTTP (แม้ว่าจะเหมาะสมกว่าที่จะเรียกใช้บริการนี้แบบอะซิงโครนัส เนื่องจากการสร้าง PDF ไม่จำเป็นต้องเกิดขึ้นทันทีจากมุมมองของผู้ใช้ เราจะใช้ตัวอย่างเดียวกันในครั้งต่อไป และดูความแตกต่าง)@Service
class BillingService {
@Autowired
private HttpClient client;
public void bill(User user, Plan plan) {
Invoice invoice = createInvoice(user, plan);
httpClient.send(invoiceRequest(user.getEmail(), invoice), responseHandler());
// ...
}
}
โดยสรุป นี่คือผลลัพธ์ที่เป็นไปได้สามประการของการเรียก HTTP นี้
- ตกลง: โทรสำเร็จ สร้างบัญชีสำเร็จแล้ว
- ล่าช้า: การโทรผ่านไปแล้ว แต่ใช้เวลานานเกินไปในการโทรให้เสร็จสิ้น
- ข้อผิดพลาด. การโทรล้มเหลว คุณอาจส่งคำขอที่เข้ากันไม่ได้ หรือระบบอาจไม่ทำงาน
รูปแบบความยืดหยุ่นในการรับส่งข้อความ
มาดูการสื่อสารแบบอะซิงโครนัสให้ละเอียดยิ่งขึ้น โปรแกรม BillingService ของเราอาจมีหน้าตาแบบนี้ โดยสมมติว่าเราใช้ Spring และ RabbitMQ สำหรับการส่งข้อความ ในการสร้างบัญชี ตอนนี้เราได้ส่งข้อความไปยังนายหน้าข้อความ RabbitMQ ของเรา ซึ่งมีผู้ปฏิบัติงานหลายคนรอข้อความใหม่ ผู้ปฏิบัติงานเหล่านี้สร้างใบแจ้งหนี้ PDF และส่งไปยังผู้ใช้ที่เหมาะสม@Service
class BillingService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void bill(User user, Plan plan) {
Invoice invoice = createInvoice(user, plan);
// преобразует счет, например, в json и использует его How тело messages
rabbitTemplate.convertAndSend(exchange, routingkey, invoice);
// ...
}
}
ข้อผิดพลาดที่อาจเกิดขึ้นดูแตกต่างออกไปเล็กน้อยในขณะนี้ เนื่องจากคุณจะไม่ได้รับการตอบสนองตกลงหรือข้อผิดพลาดในทันทีเหมือนกับที่คุณทำกับการเชื่อมต่อ HTTP แบบซิงโครนัสอีกต่อไป แต่เราอาจมีสถานการณ์ที่เป็นไปได้สามสถานการณ์ที่อาจผิดพลาด ซึ่งอาจก่อให้เกิดคำถามต่อไปนี้:
- พนักงานส่งและใช้ข้อความของฉันหรือไม่ หรือมันหายไป? (ผู้ใช้ไม่ได้รับใบแจ้งหนี้)
- ข้อความของฉันถูกส่งเพียงครั้งเดียวหรือไม่? หรือจัดส่งมากกว่าหนึ่งครั้งและดำเนินการเพียงครั้งเดียว? (ผู้ใช้จะได้รับใบแจ้งหนี้หลายใบ)
- การกำหนดค่า: จาก "ฉันใช้คีย์/ชื่อเส้นทางที่ถูกต้องสำหรับการแลกเปลี่ยน" เป็น "ตัวรับส่งข้อความของฉันได้รับการกำหนดค่าและบำรุงรักษาอย่างถูกต้องหรือคิวเต็มหรือไม่" (ผู้ใช้ไม่ได้รับใบแจ้งหนี้)
- หากคุณกำลังใช้งาน JMS เช่น ActiveMQ คุณสามารถแลกเปลี่ยนความเร็วเพื่อรับประกันคอมมิตแบบสองเฟส (XA)
- หากคุณใช้ RabbitMQ โปรดอ่านบทช่วยสอนนี้ก่อน จากนั้นจึงคิดอย่างรอบคอบเกี่ยวกับการยืนยัน การยอมรับข้อผิดพลาด และความน่าเชื่อถือของข้อความโดยทั่วไป
- บางทีอาจมีบางคนมีความเชี่ยวชาญในการกำหนดค่าเซิร์ฟเวอร์ Active หรือ RabbitMQ โดยเฉพาะอย่างยิ่งเมื่อใช้ร่วมกับการทำคลัสเตอร์และ Docker (ใครก็ได้ ;))
เฟรมเวิร์กใดจะเป็นทางออกที่ดีที่สุดสำหรับไมโครเซอร์วิส Java
ในอีกด้านหนึ่งคุณสามารถติดตั้งตัวเลือกยอดนิยมเช่นSpring Boot . ทำให้การสร้างไฟล์ .jar เป็นเรื่องง่ายมาก มาพร้อมกับเว็บเซิร์ฟเวอร์ในตัว เช่น Tomcat หรือ Jetty และสามารถทำงานได้อย่างรวดเร็วและทุกที่ เหมาะสำหรับการสร้างแอปพลิเคชันไมโครเซอร์วิส เมื่อเร็ว ๆ นี้ เฟรมเวิร์กไมโครเซอร์วิสพิเศษคู่หนึ่งKubernetesหรือGraalVMปรากฏขึ้น โดยได้รับแรงบันดาลใจบางส่วนจากการเขียนโปรแกรมแบบโต้ตอบ นี่คือคู่แข่งที่น่าสนใจบางส่วน: Quarkus , Micronaut , Vert.x , Helidon . ท้ายที่สุด คุณจะต้องเลือกเอง แต่เราสามารถให้คำแนะนำสองสามข้อที่อาจไม่ได้มาตรฐานอย่างสมบูรณ์ ยกเว้น Spring Boot เฟรมเวิร์กไมโครเซอร์วิสทั้งหมดมักจะวางตลาดอย่างรวดเร็วอย่างไม่น่าเชื่อ โดยเริ่มต้นแทบจะในทันที , พื้นที่หน่วยความจำเหลือน้อย และความสามารถในการขยายขนาดจนถึงระดับอนันต์ สื่อการตลาดมักมีกราฟิกที่น่าประทับใจซึ่งอวดแพลตฟอร์มที่อยู่ถัดจาก Spring Boot ยักษ์ใหญ่หรือต่อกัน ตามทฤษฎีแล้ว สิ่งนี้จะช่วยประหยัดความกังวลของนักพัฒนาที่สนับสนุนโปรเจ็กต์รุ่นเก่า ซึ่งบางครั้งอาจใช้เวลาโหลดหลายนาที หรือนักพัฒนาที่ทำงานบนคลาวด์ที่ต้องการเริ่ม/หยุดคอนเทนเนอร์ขนาดเล็กให้ได้มากที่สุดตามที่ต้องการภายใน 50 มิลลิวินาที อย่างไรก็ตาม ปัญหาคือเวลาเริ่มต้นใช้งาน Bare Metal (เทียม) และเวลาปรับใช้ซ้ำแทบจะไม่มีส่วนช่วยให้โครงการประสบความสำเร็จโดยรวมเลย อย่างน้อยสิ่งเหล่านี้มีอิทธิพลน้อยกว่าโครงสร้างพื้นฐานเฟรมเวิร์กที่แข็งแกร่ง เอกสารที่แข็งแกร่ง ชุมชน และทักษะนักพัฒนาที่แข็งแกร่ง ดังนั้นจึงควรพิจารณาด้วยวิธีนี้ดีกว่า: ถ้าจนถึงตอนนี้:- คุณปล่อยให้ ORM ของคุณทำงานอย่างแพร่หลาย โดยสร้างการสืบค้นหลายร้อยรายการสำหรับเวิร์กโฟลว์ง่ายๆ
- คุณต้องมีกิกะไบต์ไม่สิ้นสุดเพื่อใช้งานเสาหินที่ซับซ้อนปานกลาง
- คุณมีโค้ดมากมายและมีความซับซ้อนสูงมาก (เราไม่ได้พูดถึงการเริ่มต้นที่ช้าอย่างไฮเบอร์เนตในตอนนี้) ซึ่งแอปพลิเคชันของคุณใช้เวลาโหลดหลายนาที
ไลบรารีใดดีที่สุดสำหรับการโทร Java REST แบบซิงโครนัส
ในด้านเทคนิคระดับต่ำ คุณจะพบหนึ่งในไลบรารีไคลเอ็นต์ HTTP ต่อไปนี้: HttpClient ดั้งเดิมของ Java (ตั้งแต่ Java 11), HttpClient ของ ApacheหรือOkHttp โปรดทราบว่าฉันพูดว่า "อาจจะ" ที่นี่เพราะมีตัวเลือกอื่น ๆ ตั้งแต่ไคลเอนต์ JAX-RS เก่าที่ดีไปจนถึง ไคลเอนต์ WebSocketสมัยใหม่ ไม่ว่าในกรณีใด แนวโน้มคือการสร้างไคลเอนต์ HTTP โดยไม่ต้องเล่นซอกับการโทร HTTP ด้วยตัวเอง ในการทำเช่นนี้ คุณต้องดู โปรเจ็กต์ OpenFeignและเอกสารประกอบของโปรเจ็กต์เป็นจุดเริ่มต้นสำหรับการอ่านเพิ่มเติมโบรกเกอร์ที่ดีที่สุดสำหรับการส่งข้อความ Java แบบอะซิงโครนัสคืออะไร
เป็นไปได้มากว่าคุณ จะ พบกับActiveMQ (Classic หรือ Artemis) ยอดนิยม , RabbitMQหรือKafka- ActiveMQ และ RabbitMQ เป็นโบรกเกอร์ข้อความแบบดั้งเดิมที่ครบครัน พวกเขาเกี่ยวข้องกับการมีปฏิสัมพันธ์ของ "โบรกเกอร์ที่ชาญฉลาด" และ "ผู้ใช้ที่โง่เขลา"
- ในอดีต ActiveMQ มีประโยชน์ในการอินไลน์ที่ง่ายดาย (สำหรับการทดสอบ) ซึ่งสามารถบรรเทาได้ด้วยการตั้งค่า RabbitMQ/Docker/TestContainer
- Kafka ไม่สามารถเรียกได้ว่าเป็นนายหน้า “อัจฉริยะ” แบบดั้งเดิมได้ แต่เป็นที่เก็บข้อความที่ค่อนข้าง "โง่" (ไฟล์บันทึก) ที่ต้องใช้ผู้บริโภคที่ชาญฉลาดในการประมวลผล
ฉันสามารถใช้ไลบรารีใดเพื่อทดสอบไมโครเซอร์วิสได้
มันขึ้นอยู่กับสแต็คของคุณ หากคุณมีการปรับใช้ระบบนิเวศของ Spring ก็ควรใช้เครื่องมือเฉพาะของเฟรมเวิร์ก หาก JavaEE เป็นสิ่งที่คล้ายกับArquillian มันอาจจะคุ้มค่าที่จะดู Docker และ ไลบรารี Testcontainers ที่ดีจริงๆ ซึ่งช่วยให้ตั้งค่าฐานข้อมูล Oracle ได้อย่างง่ายดายและรวดเร็วสำหรับการพัฒนาในพื้นที่หรือการทดสอบการรวมระบบ สำหรับการทดสอบจำลองเซิร์ฟเวอร์ HTTP ทั้งหมด โปรดดูที่Wiremock หากต้องการทดสอบการส่งข้อความแบบอะซิงโครนัส ให้ลองใช้ ActiveMQ หรือ RabbitMQ จากนั้นเขียนการทดสอบโดยใช้Awaitility DSL นอกจากนี้ เครื่องมือตามปกติทั้งหมดของคุณยังถูกนำมาใช้- Junit , TestNGสำหรับAssertJและMockito โปรดทราบว่านี่ไม่ใช่รายการทั้งหมด หากคุณไม่พบเครื่องมือที่คุณชื่นชอบที่นี่ โปรดโพสต์ไว้ในส่วนความคิดเห็นจะเปิดใช้งานการบันทึกสำหรับไมโครเซอร์วิส Java ทั้งหมดได้อย่างไร
การบันทึกในกรณีของไมโครเซอร์วิสเป็นหัวข้อที่น่าสนใจและค่อนข้างซับซ้อน แทนที่จะมีไฟล์บันทึกเพียงไฟล์เดียวที่คุณสามารถจัดการโดยใช้คำสั่ง less หรือ grep ได้ ตอนนี้คุณมีไฟล์บันทึก n ไฟล์แล้ว และคุณต้องการไม่ให้ไฟล์เหล่านั้นกระจัดกระจายเกินไป บทความนี้จะอธิบายคุณลักษณะของระบบนิเวศการตัดไม้ไว้อย่างดี(เป็นภาษาอังกฤษ) อย่าลืมอ่านและให้ความสนใจกับส่วนการบันทึกแบบรวมศูนย์จากมุมมองของไมโครเซอร์วิส ในทางปฏิบัติ คุณจะพบกับแนวทางที่แตกต่างกัน: ผู้ดูแลระบบจะเขียนสคริปต์บางตัวที่รวบรวมและรวมไฟล์บันทึกจากเซิร์ฟเวอร์ต่างๆ ให้เป็นไฟล์บันทึกเดียว และนำไปไว้ในเซิร์ฟเวอร์ FTP เพื่อดาวน์โหลด การเรียกใช้ชุดค่าผสม cat/grep/unig/sort ในเซสชัน SSH แบบขนาน นี่คือสิ่งที่ Amazon AWS ทำ และคุณสามารถแจ้งให้ผู้จัดการของคุณทราบได้ ใช้เครื่องมือเช่นGraylogหรือELK Stack (Elasticsearch, Logstash, Kibana)ไมโครเซอร์วิสของฉันค้นหาซึ่งกันและกันได้อย่างไร
จนถึงขณะนี้ เราได้สันนิษฐานว่าไมโครเซอร์วิสของเรารู้จักกันและรู้ IPS ที่เกี่ยวข้อง พูดคุยเกี่ยวกับการกำหนดค่าแบบคงที่ ดังนั้น กลุ่มธนาคารขนาดใหญ่ของเรา [ip = 192.168.200.1] รู้ว่าจำเป็นต้องสื่อสารกับเซิร์ฟเวอร์ความเสี่ยง [ip = 192.168.200.2] ซึ่งได้รับการฮาร์ดโค้ดไว้ในไฟล์คุณสมบัติ อย่างไรก็ตาม คุณสามารถทำให้สิ่งต่างๆ มีชีวิตชีวามากขึ้นได้:- ใช้เซิร์ฟเวอร์การกำหนดค่าบนคลาวด์ซึ่งไมโครเซอร์วิสทั้งหมดดึงการกำหนดค่าของตนแทนที่จะปรับใช้ไฟล์ application.properties บนไมโครเซอร์วิสของตน
- เนื่องจากอินสแตนซ์บริการของคุณสามารถเปลี่ยนตำแหน่งแบบไดนามิกได้ จึงคุ้มค่าที่จะดูบริการที่รู้ว่าบริการของคุณอยู่ที่ไหน IP ของพวกเขาคืออะไร และวิธีกำหนดเส้นทาง
- เมื่อทุกอย่างเป็นแบบไดนามิก ปัญหาใหม่ๆ ก็เกิดขึ้น เช่น การเลือกตั้งผู้นำโดยอัตโนมัติ ใครคือผู้เชี่ยวชาญที่ทำงานบางอย่างเพื่อไม่ให้ประมวลผลซ้ำสองครั้ง เป็นต้น ใครจะมาแทนที่ผู้นำเมื่อเขาล้มเหลว? การเปลี่ยนทดแทนเกิดขึ้นบนพื้นฐานใด?
จะจัดระเบียบการอนุญาตและการรับรองความถูกต้องโดยใช้ Java microservices ได้อย่างไร
หัวข้อนี้ก็คุ้มค่ากับเรื่องราวที่แยกจากกัน อีกครั้ง ตัวเลือกมีตั้งแต่การตรวจสอบสิทธิ์ HTTPS พื้นฐานแบบฮาร์ดโค้ดพร้อมเฟรมเวิร์กความปลอดภัยที่กำหนดเอง ไปจนถึงการเรียกใช้การติดตั้ง Oauth2 ด้วยเซิร์ฟเวอร์การอนุญาตของตัวเองฉันจะแน่ใจได้อย่างไรว่าสภาพแวดล้อมทั้งหมดของฉันเหมือนกัน
สิ่งที่เป็นจริงสำหรับการปรับใช้โดยไม่มีไมโครเซอร์วิสก็เป็นจริงเช่นกันสำหรับการปรับใช้ด้วยไมโครเซอร์วิส ลองใช้ Docker/Testcontainers และ Scripting/Ansible ร่วมกันไม่มีคำถาม: สั้น ๆ เกี่ยวกับ YAML
ขอหลีกหนีจากไลบรารีและปัญหาที่เกี่ยวข้องสักครู่แล้วมาดู Yaml กันแบบคร่าวๆ รูปแบบไฟล์นี้ใช้โดยพฤตินัยเป็นรูปแบบสำหรับ "การเขียนการกำหนดค่าเป็นโค้ด" มันยังถูกใช้โดยเครื่องมือง่ายๆ เช่น Ansible และยักษ์ใหญ่อย่าง Kubernetes หากต้องการสัมผัสกับความเจ็บปวดจากการเยื้อง YAML ให้ลองเขียนไฟล์ Ansible แบบง่ายและดูว่าคุณต้องแก้ไขไฟล์มากน้อยเพียงใดจึงจะทำงานได้ตามที่คาดไว้ และแม้ว่ารูปแบบจะได้รับการสนับสนุนจาก IDE หลัก ๆ ทั้งหมดก็ตาม! หลังจากนั้นกลับมาอ่านคู่มือนี้ให้จบYaml:
- is:
- so
- great
แล้วธุรกรรมแบบกระจายล่ะ? การทดสอบประสิทธิภาพ? หัวข้ออื่น ๆ ?
สักวันหนึ่งในคู่มือฉบับต่อๆ ไป สำหรับตอนนี้นั่นคือทั้งหมดที่ อยู่กับเรา!ปัญหาเชิงแนวคิดกับไมโครเซอร์วิส
นอกจากปัญหาเฉพาะของไมโครเซอร์วิสใน Java แล้ว ยังมีปัญหาอื่นๆ อีก เช่น ที่ปรากฏในโปรเจ็กต์ไมโครเซอร์วิสใดๆ ส่วนใหญ่เกี่ยวข้องกับองค์กร ทีม และฝ่ายบริหารส่วนหน้าและส่วนหลังไม่ตรงกัน
ความไม่ตรงกันของส่วนหน้าและส่วนหลังเป็นปัญหาที่พบบ่อยมากในโปรเจ็กต์ไมโครเซอร์วิสจำนวนมาก มันหมายความว่าอะไร? เฉพาะในเสาหินเก่าที่ดีเท่านั้น นักพัฒนาเว็บอินเตอร์เฟสมีแหล่งข้อมูลเฉพาะแหล่งเดียวในการรับข้อมูล ในโครงการไมโครเซอร์วิส นักพัฒนาส่วนหน้าก็ไม่มีแหล่งข้อมูลที่จะรับข้อมูล ลองจินตนาการว่าคุณกำลังสร้างโปรเจ็กต์ไมโครเซอร์วิส IoT (Internet of Things) ใน Java สมมติว่าคุณจัดการเครื่องจักรจีโอเดติกและเตาเผาอุตสาหกรรมทั่วยุโรป และเตาอบเหล่านี้จะส่งข้อมูลอัปเดตเกี่ยวกับอุณหภูมิและสิ่งที่คล้ายกันถึงคุณเป็นประจำ ไม่ช้าก็เร็ว คุณอาจต้องการค้นหาเตาอบใน UI ผู้ดูแลระบบ อาจใช้ไมโครเซอร์วิส "การค้นหาเตา" ขึ้นอยู่กับว่าแบ็กเอนด์คู่หูของคุณใช้ กฎหมาย การออกแบบที่ขับเคลื่อนด้วยโดเมนหรือไมโครเซอร์วิสอย่างเคร่งครัดเพียงใด ไมโครเซอร์วิส “ค้นหาเตาอบ” อาจส่งคืนเฉพาะ ID ของเตาอบเท่านั้น ไม่ใช่ข้อมูลอื่นๆ เช่น ประเภท รุ่น หรือตำแหน่ง ในการดำเนินการนี้ นักพัฒนาส่วนหน้าจะต้องทำการเรียกเพิ่มเติมหนึ่งครั้งหรือหลายครั้ง (ขึ้นอยู่กับการใช้งานเพจ) ในไมโครเซอร์วิส “รับข้อมูล Furnace” ด้วย ID ที่พวกเขาได้รับจากไมโครเซอร์วิสแรก และถึงแม้ว่านี่จะเป็นเพียงตัวอย่างง่ายๆ แม้ว่าจะนำมาจากโครงการจริง (!) แต่ก็แสดงให้เห็นถึงปัญหาต่อไปนี้: ซูเปอร์มาร์เก็ตได้รับความนิยมอย่างมาก นั่นเป็นเพราะว่าคุณไม่จำเป็นต้องเดินทางไปซื้อผัก น้ำมะนาว พิซซ่าแช่แข็ง และกระดาษชำระถึง 10 แห่ง ให้คุณไปที่เดียวแทน ง่าย และเร็วขึ้น เช่นเดียวกับนักพัฒนาส่วนหน้าและไมโครเซอร์วิสความคาดหวังของฝ่ายบริหาร
ฝ่ายบริหารมีความรู้สึกเข้าใจผิดว่าตอนนี้พวกเขาจำเป็นต้องจ้างนักพัฒนาจำนวนไม่สิ้นสุดสำหรับโปรเจ็กต์ (ที่ครอบคลุม) เนื่องจากนักพัฒนาสามารถทำงานได้อย่างอิสระโดยแยกจากกันโดยแต่ละคนบนไมโครเซอร์วิสของตนเอง จำเป็นต้องมีการผสานรวมเพียงเล็กน้อยในตอนท้ายสุด (ก่อนเปิดตัวไม่นาน) ที่จริงแล้วแนวทางนี้เป็นปัญหาอย่างมาก ในย่อหน้าต่อไปนี้ เราจะพยายามอธิบายว่าทำไม“ชิ้นเล็ก” ไม่ได้เท่ากับ “ชิ้นที่ดีกว่า”
มันจะเป็นความผิดพลาดครั้งใหญ่ที่จะสรุปว่าโค้ดที่แบ่งออกเป็น 20 ส่วนจะต้องมีคุณภาพสูงกว่าโค้ดทั้งชิ้น แม้ว่าเราจะยึดถือคุณภาพจากมุมมองด้านเทคนิคเพียงอย่างเดียว บริการส่วนบุคคลของเราอาจยังคงเรียกใช้การสืบค้นแบบ Hibernate 400 รายการเพื่อเลือกผู้ใช้จากฐานข้อมูล โดยข้ามเลเยอร์ของโค้ดที่ไม่รองรับ เรากลับมาที่คำพูดของ Simon Brown อีกครั้ง: หากคุณล้มเหลวในการสร้างเสาหินอย่างถูกต้อง การสร้างไมโครเซอร์วิสที่เหมาะสมจะเป็นเรื่องยาก มักจะสายไปมากที่จะพูดถึงความทนทานต่อข้อผิดพลาดในโครงการไมโครเซอร์วิส มากเสียจนบางครั้งมันก็น่ากลัวที่จะเห็นว่าไมโครเซอร์วิสทำงานอย่างไรในโครงการจริง เหตุผลก็คือนักพัฒนา Java ไม่พร้อมที่จะศึกษาความทนทานต่อข้อผิดพลาด ระบบเครือข่าย และหัวข้ออื่นๆ ที่เกี่ยวข้องในระดับที่เหมาะสมเสมอไป “ชิ้นส่วน” นั้นมีขนาดเล็กกว่า แต่ “ชิ้นส่วนทางเทคนิค” นั้นใหญ่กว่า ลองนึกภาพทีมไมโครเซอร์วิสของคุณถูกขอให้เขียนไมโครเซอร์วิสทางเทคนิคสำหรับการเข้าสู่ระบบฐานข้อมูล ในลักษณะนี้:@Controller
class LoginController {
// ...
@PostMapping("/login")
public boolean login(String username, String password) {
User user = userDao.findByUserName(username);
if (user == null) {
// обработка варианта с несуществующим пользователем
return false;
}
if (!user.getPassword().equals(hashed(password))) {
// обработка неверного пароля
return false;
}
// 'Ю-ху, залогинorсь!';
// установите cookies, делайте, что угодно
return true;
}
}
ตอนนี้ทีมของคุณอาจตัดสินใจ (และบางทีอาจโน้มน้าวนักธุรกิจด้วยซ้ำ) ว่าทั้งหมดนี้เรียบง่ายและน่าเบื่อเกินไป แทนที่จะเขียนบริการเข้าสู่ระบบ ควรเขียนไมโครเซอร์วิส UserStateChanged ที่มีประโยชน์จริงๆ โดยไม่มีผลกระทบทางธุรกิจที่แท้จริงและเป็นรูปธรรม และเนื่องจากในปัจจุบัน บางคนปฏิบัติต่อ Java เหมือนไดโนเสาร์ มาเขียนไมโครเซอร์วิส UserStateChanged ของเราใน Erlang ที่ทันสมัยกันดีกว่า และลองใช้ต้นไม้สีแดงดำสักแห่งดู เพราะ Steve Yegge เขียนไว้ว่าคุณต้องรู้จักต้นไม้เหล่านี้จากภายในสู่ภายนอกจึงจะสมัครกับ Google ได้ จากมุมมองการบูรณาการ การบำรุงรักษา และการออกแบบโดยรวม สิ่งนี้แย่พอๆ กับการเขียนโค้ดสปาเก็ตตี้หลายชั้นภายในหินใหญ่ก้อนเดียว ตัวอย่างที่ประดิษฐ์และธรรมดา? นี่เป็นเรื่องจริง อย่างไรก็ตามสิ่งนี้สามารถเกิดขึ้นได้ในความเป็นจริง
ชิ้นส่วนน้อยลง - ความเข้าใจน้อยลง
จากนั้น คำถามก็เกิดขึ้นตามธรรมชาติเกี่ยวกับการทำความเข้าใจระบบโดยรวม กระบวนการและขั้นตอนการทำงานของระบบ แต่ในขณะเดียวกัน คุณในฐานะนักพัฒนาจะต้องรับผิดชอบเฉพาะการทำงานกับไมโครเซอร์วิสที่แยกออกมา [95: ล็อกอิน-101: updateUserProfile] มันสอดคล้องกับย่อหน้าก่อนหน้า แต่ขึ้นอยู่กับองค์กรของคุณ ระดับความไว้วางใจและการสื่อสาร สิ่งนี้อาจทำให้เกิดความสับสน การยักไหล่ และตำหนิได้มาก หากมีการเสียหายโดยไม่ได้ตั้งใจในห่วงโซ่ไมโครเซอร์วิส และไม่มีใครที่จะรับผิดชอบอย่างเต็มที่ต่อสิ่งที่เกิดขึ้น และไม่ใช่เรื่องของความไม่ซื่อสัตย์เลย ในความเป็นจริงการเชื่อมต่อส่วนต่าง ๆ และเข้าใจจุดยืนในภาพรวมของโครงการเป็นเรื่องยากมากการสื่อสารและการบริการ
ระดับของการสื่อสารและการบริการขึ้นอยู่กับขนาดของบริษัทเป็นอย่างมาก อย่างไรก็ตาม ความสัมพันธ์โดยทั่วไปนั้นชัดเจน ยิ่งมากเท่าไรก็ยิ่งมีปัญหามากขึ้นเท่านั้น- ใครเป็นผู้ดำเนินการไมโครเซอร์วิส #47
- พวกเขาเพิ่งปรับใช้ไมโครเซอร์วิสเวอร์ชันใหม่ที่เข้ากันไม่ได้หรือไม่? เอกสารนี้อยู่ที่ไหน?
- ฉันต้องพูดคุยกับใครเพื่อขอฟีเจอร์ใหม่
- ใครจะสนับสนุนไมโครเซอร์วิสนั้นใน Erlang หลังจากที่มีเพียงคนเดียวที่รู้ภาษานี้ออกจากบริษัท
- ทีมไมโครเซอร์วิสของเราทั้งหมดไม่เพียงทำงานในภาษาการเขียนโปรแกรมที่แตกต่างกัน แต่ยังทำงานในเขตเวลาที่ต่างกันด้วย! เราจะประสานงานทั้งหมดนี้อย่างถูกต้องได้อย่างไร?
GO TO FULL VERSION