ประโยชน์ในการพัฒนาของการใช้ Docker เป็นโมฆะเมื่อใช้ Java เมื่อเปรียบเทียบกับภาษาอื่น ๆ ใกล้กับระบบปฏิบัติการ Unix หรือไม่?


53

ฉันมีเพื่อนที่พูดว่า:

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

ตอนนี้สิ่งนี้จะเป็นจริงถ้านักพัฒนาเขียน Ruby, PHP หรือGo - ที่ซึ่งมีการเชื่อมโยงแบบไบนารีทิศทางไปยังระบบปฏิบัติการ

แต่เมื่อใช้Java - มีเลเยอร์เสมือนระหว่างระบบปฏิบัติการและภาษาอยู่แล้วทำให้การดำเนินงานสอดคล้องกันโดยไม่คำนึงถึงระบบปฏิบัติการพื้นฐาน

ในกรณีนี้ประโยชน์ของการรัน Docker สำหรับนักพัฒนาในท้องถิ่นเพื่อทำซ้ำสภาพแวดล้อมการผลิตจะถูกทำให้ไร้ผล (เทียบกับ Ruby, PHP หรือ Go)

ฉันเปิดให้มีการอภิปรายเกี่ยวกับเรื่องนี้และกระตือรือร้นที่จะได้ยินมุมมองที่ไม่เห็นด้วย (มีหลักฐาน)

ประโยชน์ในการพัฒนาของการใช้ Docker เป็นโมฆะเมื่อใช้ Java เมื่อเปรียบเทียบกับภาษาอื่น ๆ ใกล้กับระบบปฏิบัติการ Unix หรือไม่?


34
ทำไมคุณคิดว่า ruby ​​และ php เป็นเลขฐานสอง? Ruby และ php นั้นมีเทคนิคมากกว่า virtual Java ใน Java คุณต้องคอมไพล์ก่อนจากนั้นจึงรันโปรแกรมในเครื่องเสมือน ใน Ruby และ php คุณส่งซอร์สโค้ดและเครื่องเสมือนอ่านซอร์สโดยตรง
slebetman

12
"แต่เมื่อใช้ Java - มีเลเยอร์เสมือนระหว่างระบบปฏิบัติการและภาษาอยู่แล้วทำให้การดำเนินงานสอดคล้องกันโดยไม่คำนึงถึงระบบปฏิบัติการพื้นฐาน" LOL Java คิดค้น "เขียนครั้งเดียวทดสอบได้ทุกที่"
Andy

2
Java เป็นเป้าหมายเคลื่อนที่ มีการแนะนำคุณลักษณะบางครั้งที่ทำให้สิ่งต่าง ๆ เสียหาย (ความปลอดภัยในการรักษาความปลอดภัยไม่กี่ปีหลังเป็นตัวอย่างสำคัญ) หรือคุณพบข้อบกพร่องที่คุณต้องใช้รุ่นที่ระบุ การควบคุมสิ่งนี้ในนักเทียบท่าง่ายกว่าการใช้ระบบบรรจุภัณฑ์ดั้งเดิมของโฮสต์คอมพิวเตอร์
Thorbjørn Ravn Andersen

1
"การทำให้การดำเนินงานสอดคล้องกันโดยไม่คำนึงถึงระบบปฏิบัติการพื้นฐาน" โปรดทราบว่าการทำให้ภาษารันไทม์ทำงานอย่างสม่ำเสมอนั้นไม่ได้คัดค้านความจริงที่ว่าคุณอาจยังมีการพึ่งพาจากภายนอกอยู่บ้าง อาจเป็นเรื่องง่ายเหมือนการใช้เส้นทางไฟล์เฉพาะสำหรับบันทึกของคุณ
jpmc26

คำตอบ:


86

ไม่ใช่เลย.

ลองนึกภาพคุณกำลังเรียกใช้ Java รุ่น 1.8.0 บนทั้งเครื่องพัฒนาและเซิร์ฟเวอร์ของคุณ โดยวิธีการที่คุณทำงานพร้อมกันในสองโครงการทั้งสองใช้ Java

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

ตอนนี้อย่างน้อยหนึ่งโครงการคุณกำลังใช้ Java เวอร์ชันอื่น

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

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


20
สิ่งนี้เกิดขึ้นตลอดเวลาใน บริษัท ขนาดใหญ่ มันไม่ใช่แค่เรื่องทางทฤษฎี
enderland

5
คุณจะทำอย่างไรเมื่อคุณค้นพบข้อบกพร่องใน Docker?
โอเว่น

นอกจากนี้ Java 9 จะทำลายสิ่งต่างๆ จะมีความพยายามค่อนข้างจำเป็น
Thorbjørn Ravn Andersen

8
@Owen สิ่งเดียวกับที่คุณทำเมื่อคุณพบข้อผิดพลาดใน Java หรือใน {Linux, Windows} หรือใน CPU
Kroltan

1
@Trilarion: ใช่ แต่ส่วนใหญ่อยู่ในรูปแบบของโพสต์บล็อกโดยนักพัฒนา บริษัท ดังกล่าวกล่าวว่าลิงก์ "เรียนรู้เพิ่มเติม" บนdocker.com/customersจะให้ตัวอย่างของ บริษัท ขนาดใหญ่ที่ใช้นักเทียบท่าเพื่อแก้ปัญหาดังกล่าว ที่กล่าวว่าโดยปกติแล้ว บริษัท ดังกล่าวจะยอมรับว่าพวกเขาต้องการการจับคู่ที่สมบูรณ์แบบระหว่างการผลิตและการพัฒนาและประสบความสำเร็จกับ VMs ต่อมาพวกเขารู้ว่า "เฮ้ Docker แก้ปัญหาเดียวกับ VMs ยกเว้นว่าจะทำงานได้เร็วขึ้นและสามารถใช้เพื่อให้การปรับใช้สอดคล้องกัน"
Brian

35

คุณไม่ค่อยปรับใช้ "Java App" แอปพลิเคชัน java ของคุณมีโปรแกรมสนับสนุนที่แตกต่างกันมากมาย เราใช้ Apache HTTPD, Apache Tomcat, ActiveMQ สำหรับการส่งข้อความ, FTP Deamon, MySQL และบริการที่กำหนดเองจำนวนหนึ่งเพื่อรวมเข้ากับโปรแกรมที่ไม่สามารถทำงานได้โดยตรงกับ Java

สิ่งนี้ไม่แม้แต่จะเข้าสู่การพัฒนาซอฟต์แวร์ที่สอดคล้องกับมัน - eclipse, ant, adobe flex, groovy, firefox และ subversion (ฉันข้ามไปบ้าง)

ใช้เวลาระหว่างวันและหนึ่งสัปดาห์ในการตั้งค่าเวิร์กสเตชันใหม่ - เราได้พูดถึงการย้ายไปที่ Docker เพื่อทำให้ปัญหานี้ง่ายขึ้น มันจะน่าอัศจรรย์ถ้าเราสามารถเปิดตัวเวิร์กสเตชันใหม่ได้อย่างน่าเชื่อถือในสองสามชั่วโมง

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

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


ทำไมไม่สร้างภาพ
Dmitry Kudriavtsev

เราหวังว่าจะ เราเป็นทีมเล็ก ๆ ที่พยายามเพิ่มคุณสมบัติให้กับระบบที่สำคัญซึ่งใช้งานค่อนข้างหนักและไม่สามารถควบคุมเซิร์ฟเวอร์ได้เพียงพอที่จะสั่งการปรับใช้ของพวกเขา อาจใช้กับ dev แต่เราค่อนข้าง จำกัด อยู่ที่ 32mb ram - ฉันคิดว่าการวิ่งจากภาพนักเทียบท่าจะมีค่าใช้จ่ายบ้าง แต่แผนการของเราคือการเคลื่อนที่ในทิศทางนั้น
Bill K

ฉันหมายถึงเวิร์คสเตชั่น
Dmitry Kudriavtsev

เวลาและหน่วยความจำ - เราต้องปล่อยชิ้นส่วนออกเพื่อให้ทำงานในเวิร์กสเตชัน 32gb ของเรา (เซิร์ฟเวอร์ 64GB ใช้งานได้ดี) เราได้ทำการทดลองเล็กน้อยและอาจจะลองอีกครั้งในครั้งต่อไปที่เราจำเป็นต้องสร้างเวิร์กสเตชัน dev ใหม่
Bill K

8

คำถามนี้จะเกี่ยวข้องกับ golang ซึ่งคุณสามารถแยกไบนารีที่เชื่อมโยงแบบสแตติกและรันที่ใดที่หนึ่งได้ตรงข้ามกับ Python หรือ C ++ ที่คุณมักจะมีไลบรารี่ที่เชื่อมโยงกันจำนวนมาก การพัฒนาสภาพแวดล้อม.

มีสองจุดที่จะตอบคำถามที่นี่:

หนึ่ง: จะต้องมีวิธีที่ดีกว่าและมี: คุณสามารถสร้างตู้เทียบท่าขนาดเล็ก (และมีประสิทธิภาพมากขึ้น) โดยใช้เพียงสภาพแวดล้อมการติดตั้งซึ่งนำไปสู่ข้อดีที่คล้ายกันเช่นในกรณีของ Golang-with-environment กับ Golang-just - ภาชนะบรรจุไบนารี ในกรณีของ Java คุณสามารถสร้าง fat jar หรือแอพที่ติดตั้งได้ซึ่งมี jars ไลบรารีทั้งหมดและเชลล์สคริปต์ ในกรณีของ Python คุณสามารถใช้ auditwheel เพื่อสร้างวงล้อที่มีในตัวซึ่งเป็นอิสระจากสภาพแวดล้อมการสร้าง (และคุณสามารถใช้ C ++ พร้อมลิงก์แบบคงที่เพื่อให้ได้ผลเหมือนกัน)

ที่สอง: สิ่งที่คุณต้องการนักเทียบท่าสำหรับ ใน Java land คุณสามารถแยกส่วนต่าง ๆ ได้มากมายโดยใช้ตัวโหลดคลาส แต่ประเด็นหลักคือสิ่งที่อยู่รอบ ๆ แอ็พพลิเคชัน Java ไม่มีแอปพลิเคชัน Java ที่ทำงานด้วยตัวเอง - หากไม่ได้ทำงานใน docker มักจะต้องได้รับการดูแลโดย supervisord หรือ systemd หรือไลค์ ป้อน Kubernetes, Marathon, หรือ cloud Docker ซึ่งใช้ container abstraction เพื่อทำเวอร์ชวลไลเซชันไม่ใช่โฮสต์เอง แต่จริงๆแล้วจำลองเสมือนเครือข่ายทั้งหมดเพื่อให้คุณสามารถปรับใช้คอนเทนเนอร์และรันบนโฮสต์แบบสุ่ม

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


5

นี่เป็นคำถามที่ดีจริงๆ แต่หลังจากทำงานกับ Docker ฉันจะหันไปรอบ ๆ :

ประโยชน์ของ JVM ถูกทำให้เป็นเท็จโดยการจัดตู้คอนเทนเนอร์ (เช่น Docker) หรือไม่?

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

ฉันเพิ่งสร้างแอปพลิเคชั่นต้นแบบด้วย Java และ Docker ซึ่งดูเหตุการณ์ GC เป็นหลักและเมื่อส่วนเก่าของ heap มีค่าถึงขีดแบ่งเปอร์เซ็นต์มันจะปิดตัวเองลง นักเทียบท่า (โหมดจับกลุ่ม) จะหมุนขึ้นมาใหม่ โดยพื้นฐานแล้วมันไม่จำเป็นสำหรับรอบการทำงานหลักใน JVM และให้นักเทียบท่าจัดการกับมัน มันไม่ทำงานเช่นเดียวกับที่ฉันคาดหวัง (ลูกค้าเห็นผลกระทบของการปิดเครื่อง) แต่มันทำงานได้ดีพอที่จะทำการสาธิตสดให้กับฝูงชน

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


"... แต่มีอย่างน้อยหนึ่งทางเลือกที่ทำงานได้ซึ่งเป็นสิ่งที่ดีสำหรับทุกคน" ดังนั้นมันอาจเป็นทางเลือกอื่นที่ทำงานได้นี้หรือไม่?
Trilarion

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