ทั้งหมดอยู่ในกระบวนการที่ง่าย ทำซ้ำได้ และบำรุงรักษาได้

เกี่ยวกับบทความนี้

การใช้งานมาตรฐานของ Netflix Conductor ได้รับการกำหนดค่าให้ใช้ Elasticsearch 6 บทความนี้ครอบคลุมถึงการเปลี่ยนแปลงที่จำเป็นในการใช้ Elasticsearch 7 และ PostgreSQL รวมถึงการจัดเตรียมสคริปต์ต่างๆ เพื่อสร้างและเรียกใช้ Conductor โดยอัตโนมัติ ทั้งภายในเครื่องและในสถาปัตยกรรมระบบคลาวด์ .

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

ฉันใช้โค้ดที่ให้มาทั้งหมดบนเครื่อง Windows 10 จาก Git Bash ซึ่งมาพร้อมกับ Git สำหรับ Windows สถาปัตยกรรมคลาวด์ของเราทำงานบน CentOS

ตัวนำ Netflix คืออะไร?

Netflix Conductor คือกลไกจัดการเวิร์กโฟลว์ที่ Netflix สร้างขึ้นเพื่อ “ประสานโฟลว์กระบวนการตามไมโครเซอร์วิส” (ที่มา: “เอกสารประกอบของ Netflix Conductor”) รายการฟีเจอร์ทั้งหมดของ Netflix Conductor อยู่ที่ "ที่นี่" แต่ฟีเจอร์หลักบางประการได้แก่:

  • เวิร์กโฟลว์และคำจำกัดความของงานถูกนำมาใช้ในรูปแบบ JSON ช่วยให้สามารถกำหนดเวอร์ชันและรองรับเครื่องมือแบบกำหนดเองเพื่อสร้างและจัดการเวิร์กโฟลว์และงานต่างๆ ได้อย่างง่ายดาย
  • งานและผู้ปฏิบัติงาน เช่น โครงสร้างที่ประกอบขึ้นเป็นเวิร์กโฟลว์และไมโครเซอร์วิสที่โฮสต์งานเหล่านั้น ตามลำดับ ไม่เชื่อเรื่องภาษาโดยสมบูรณ์ ซึ่งช่วยให้การนำไปปฏิบัติเสร็จสิ้นในภาษาที่เหมาะสมที่สุดสำหรับงาน มีไลบรารีสำหรับ Java, Python, .NET (ปลั๊กไร้ยางอาย: อันนี้ได้รับการพัฒนาโดยฉัน) และอื่น ๆ
  • สถาปัตยกรรมฐานข้อมูลเป็นแบบเสียบได้ ซึ่งหมายความว่าเราสามารถเลือกฐานข้อมูลที่เราต้องการใช้สำหรับตัวนำได้ Conductor มาพร้อมกับปลั๊กอินสำเร็จรูปมากมาย ซึ่งรองรับ (รวมถึงปลั๊กอินอื่นๆ) Dynomite (โดย Netflix), MySQL และ PostgreSQL
  • Netflix Conductor มาพร้อมกับ UI (ตัวเลือก) ซึ่งช่วยให้เข้าใจและควบคุมขั้นตอนการทำงาน เช่น (เริ่มต้นใหม่) หยุดชั่วคราว หรือหยุด
  • โครงการทั้งหมดเป็นโอเพ่นซอร์สและกำลังได้รับการพัฒนาและสนับสนุนอย่างแข็งขัน

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

ในโปรเจ็กต์ปัจจุบันของฉัน เราใช้ Netflix Conductor และ PostgreSQL เพื่อรันกระบวนการ ETL ที่กำหนดเวลาไว้ สร้างรายงาน ดาวน์โหลดและอัปโหลดไฟล์ และสำหรับการตรวจสอบและแจ้งเตือน นอกจากนี้เรายังได้ตรวจสอบการใช้ Conductor เพื่อจัดเตรียมบัญชีผู้ใช้และโครงสร้างพื้นฐานอื่นๆ โดยอัตโนมัติ

การกำหนดค่าตัวนำ Netflix สำหรับ Elasticsearch 7

ตามที่กล่าวไว้ในบทนำ การใช้งานมาตรฐานของ Netflix Conductor ได้รับการกำหนดค่าให้ใช้ Elasticsearch 6 มีการรองรับ Elasticsearch 7 ในตัว แต่จำเป็นต้องทำการเปลี่ยนแปลงหลายอย่างเพื่อเปิดใช้งาน มี เอกสารประกอบ บน GitHub เพื่อทำการเปลี่ยนแปลงเหล่านี้ แต่ดูเหมือนจะไม่เสร็จสมบูรณ์ทั้งหมด ฉันต้องการการเปลี่ยนแปลงที่ฉันอธิบายด้านล่างเพื่อสร้างและรันกับ Elasticsearch 7

ในขณะที่เขียน Elasticsearch 7.17.1 เป็นเวอร์ชันล่าสุดของ Elasticsearch 7

ต่อไปนี้เป็นข้อมูลสรุปโดยย่อของการเปลี่ยนแปลงที่จำเป็น (การอ้างอิงไฟล์ทั้งหมดสัมพันธ์กับโฟลเดอร์รูท):

  • build.gradle — เปลี่ยน ext['elasticsearch.version'] = revElasticSearch6
    เป็น ext['elasticsearch.version'] = revElasticSearch7
  • settings.gradle — ลบบรรทัด include 'es6-persistence'
  • server/build.gradle — เปลี่ยน implementation project(':conductor-es6-persistence')
    เป็น implementation project(':conductor-es7-persistence')
  • server/src/main/resources/application.properties — เปลี่ยน conductor.elasticsearch.version=6
    เป็น conductor.elasticsearch.version=7
  • docker/docker-compose.yaml — เปลี่ยน image: elasticsearch:6.8.15
    เป็น image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
  • test-harness/build.gradle — เปลี่ยน testImplementation project(‘:conductor-es6-persistence’)
    เป็น testImplementation project(‘:conductor-es7-persistence’)
  • /testharness/src/test/java/com/netflix/conductor/test/integration/AbstractEndToEndTest.java — เปลี่ยน conductor.elasticsearch.version=6
    เป็น conductor.elasticsearch.version=7

เปลี่ยน DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch-oss").withTag("6.8.12"));
เป็น DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch").withTag("7.17.1"));

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

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

ในบิลด์ ฉัน clone ที่เก็บ Conductor จากนั้นใช้ไฟล์ patch หลายไฟล์เพื่อทำการเปลี่ยนแปลงที่ฉันต้องการ แม้ว่าขั้นตอนเหล่านี้จะเพิ่มเวลาในการสร้างเล็กน้อย แต่ฉันรู้สึกว่านี่เป็นการประนีประนอมที่ดีระหว่างความเร็วและการรักษาพื้นที่เก็บข้อมูลของฉันเองให้สะอาดและบำรุงรักษาได้

นี่คือวิธีการทำงาน:

  1. โคลน repo ของ Conductor ภายในไดเร็กทอรีโปรเจ็กต์ของคุณ
  2. ทำการเปลี่ยนแปลงข้างต้น
  3. ในโฟลเดอร์ Conductor ให้รัน git diff > v3.5.1-update-to-es7.patch เพื่อสร้างไฟล์ patch v3.5.1 มีไว้เพื่อความสะดวก เพื่อระบุว่าแพตช์นี้ใช้ได้กับเวอร์ชันนั้นเท่านั้น
  4. คัดลอกไฟล์ patch ไปยังไดเร็กทอรีราก เพื่อให้คุณสามารถลบ Conductor repo ได้อย่างปลอดภัย และใช้การเปลี่ยนแปลงทุกครั้งที่คุณโคลน repo อีกครั้ง

คุณต้องลบไฟล์ dependencies.lock ใด ๆ ออกก่อนที่จะสร้าง มันง่ายเหมือนการวิ่ง rm -f **/dependencies.lock

หากต้องการลบไฟล์ lock โดยอัตโนมัติและนำแพตช์ไปใช้ ฉันได้สร้างสคริปต์ 01.get-conductor.sh แล้ว:

คุณจะเห็นได้ว่าฉันกำลังใช้แพตช์เพิ่มอีกสองสามอันจริงๆ สิ่งเหล่านี้ไม่จำเป็นต้องรันกับ Elasticsearch 7

ณ จุดนี้คุณสามารถสร้างตัวนำได้ ฉันสร้าง 02.build-conductor-server.sh เพื่อจุดประสงค์นี้:

ในส่วน “การรวบรวมทั้งหมดเข้าด้วยกัน” ฉันจะจัดเตรียมสคริปต์เพิ่มเติมหลายรายการเพื่อทำให้การโคลน แพตช์ และสร้างกระบวนการเพิ่มเติมเป็นแบบอัตโนมัติ รวมถึงวิธีใช้ตัวแปรสภาพแวดล้อมเพื่อกำหนดค่า Elasticsearch

การกำหนดค่าตัวนำ Netflix สำหรับ PostgreSQL

การเรียกใช้ Conductor กับ PostgreSQL มีอธิบายไว้ใน "ไฟล์ README" เช่นกัน การรัน docker-compose -f docker-compose.yaml -f docker-compose-postgres.yaml upจะเริ่มต้นอินสแตนซ์คอนเทนเนอร์เพิ่มเติมสำหรับ PostgreSQL และกำหนดค่า Conductor เพื่อใช้งาน

แต่ในกรณีของเรา เราต้องการทำงานกับการติดตั้ง PostgreSQL ที่มีอยู่ นอกจากนั้น เราไม่ต้องการให้สร้างอ็อบเจ็กต์ฐานข้อมูล Conductor ใน public schema เช่นเดียวกับค่าเริ่มต้น

เพื่อให้บรรลุเป้าหมายนี้ เราจำเป็นต้องเปลี่ยนไฟล์ config-postgres.properties ข้อมูลนี้อยู่ในโฟลเดอร์ conductor/docker/server/config แต่เนื่องจากเราได้รับ Conductor repo ในแต่ละบิลด์ เราจึงไม่สามารถเปลี่ยนแปลงได้จากที่นั่น

ดังนั้นฉันจึงสร้างโฟลเดอร์ docker ในรูทโปรเจ็กต์ของฉันซึ่งจะมีการปรับแต่งทั้งหมดสำหรับไฟล์ในโฟลเดอร์ conductor/docker ในการสร้าง ฉันเพียงแค่คัดลอกเนื้อหาของโฟลเดอร์นี้

ตอนนี้สคริปต์ 02.build-conductor-server.sh กลายเป็น:

ไฟล์ config-postgres.properties ในเครื่องของเราเป็นเพียงสำเนาของต้นฉบับ โดยมีการแก้ไขส่วนของ PostgreSQL ดังต่อไปนี้:

ด้วยการเพิ่ม currentSchema ลงใน URL แหล่งข้อมูล เราตรวจสอบให้แน่ใจว่าออบเจ็กต์ฐานข้อมูล Conductor ถูกสร้างขึ้นในสคีมาที่ระบุ คุณสมบัติ applicationName ช่วยเราในการดีบักเซสชันฐานข้อมูลหากจำเป็น

ยกเว้นว่ามันใช้งานไม่ได้ เมื่อเรารัน Conductor โดยใช้การเปลี่ยนแปลงเหล่านี้ คุณสมบัติ currentSchema จะถูกละเว้น และทุกอย่างจะถูกสร้างขึ้นใน public schema ไม่เจ๋ง. ฉันยื่นข้อบกพร่องต่อ PR ที่เป็นต้นเหตุ

ฉันจะสละเวลาคุณหลายชั่วโมงในการค้นหาสาเหตุและนำเสนอ "วิธีแก้ปัญหา" รวมถึงราคาอากาศด้วยเพราะมันให้ความรู้สึกเหมือนเป็นการแฮ็กมากกว่า แต่มันได้ผล

ในไฟล์ postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java นั้น Flyway (ซึ่งจัดการการย้ายฐานข้อมูล) ได้รับการกำหนดค่าด้วยบรรทัด .schemas("public") ซึ่งทำให้ละเว้นความพยายามในการเปลี่ยนแปลงสคีมาเริ่มต้น การลบบรรทัดนี้จะช่วยแก้ปัญหาได้

ฉันสร้าง v3.5.1-fix-currentSchema-override.patch สำหรับสิ่งนี้และรวมไว้ในสคริปต์ 01.get-conductor.sh

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

การกำหนดค่าการเก็บถาวรเวิร์กโฟลว์

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

เพียงเพิ่ม conductor.workflow-status-listener.type=archive ลงในไฟล์ config-postgres.properties

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

วางมันทั้งหมดเข้าด้วยกัน

เพื่อให้การทำงานข้างต้นทำงานได้ภายในเครื่องและในสภาพแวดล้อมคลาวด์ของเรา เราต้องการใช้ตัวแปรสภาพแวดล้อมเพื่อกำหนดค่า Elasticsearch และ PostgreSQL ในการดำเนินการนี้ เราจะไปที่ไฟล์ startup.sh ในโฟลเดอร์ conductor/docker/server/bin เราคัดลอกไฟล์นี้ไปยังโฟลเดอร์ docker ในเครื่องของเรา เพื่อให้เราสามารถทำการเปลี่ยนแปลงบางอย่างได้

เราเพิ่มบรรทัดต่อไปนี้หลังบล็อก if..fi:

จำตัวยึดตำแหน่ง ## ที่คุณเห็นก่อนหน้านี้หรือไม่ เราใช้เครื่องมือ sed เพื่อแทนที่ด้วยค่าที่กำหนดค่าไว้ในตัวแปรสภาพแวดล้อมที่ตรงกัน

หากต้องการทำงานภายในเครื่อง เราจะเพิ่มตัวแปรสภาพแวดล้อมและค่าของตัวแปรเหล่านั้นลงในไฟล์ docker-compose.yaml และ docker-compose-postgres.yaml ซึ่งเราได้คัดลอกไปยังโฟลเดอร์ docker ในเครื่องของเรา ตามตัวอย่าง ดูไฟล์ docker-compose-postgres.yaml:

เราใช้ค่าเวทย์มนตร์ host.docker.internal เพื่อชี้ไปยังอินสแตนซ์ PostgreSQL ในเครื่องของเรา เนื่องจาก localhost จะไม่ทำงานจากภายในคอนเทนเนอร์ Docker

สคริปต์ 02.build-conductor-server.sh ก็คัดลอก startup.sh เช่นกัน

สุดท้ายก็เหลือสคริปต์อีกเพียงไม่กี่ตัวเท่านั้น

03.build-conductor-ui.sh ดูแลการสร้างอิมเมจ UI ของตัวนำ:

เราสามารถรัน Conductor โดยใช้ 04.run-local.sh ซึ่งจริงๆ แล้วไม่ได้ทำอะไรมากไปกว่าการเรียก docker compose up:

หรือเราสามารถเรียกใช้ 04.run-local-postgres.sh เพื่อทำงานกับฐานข้อมูล PostgreSQL ของเรา:

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

สรุปแล้ว

การเรียกใช้ Netflix Conductor ด้วย Elasticsearch 7 และ PostgreSQL ต้องใช้เวลาสักหน่อย แต่ด้วยการใช้พลังของ git diff และการเขียนสคริปต์แบบทุบตี เราจะทำให้กระบวนการนี้ง่ายดาย ทำซ้ำได้ และใช้งานได้ทั้งในบริบทภายในเครื่องและบนระบบคลาวด์

ซอร์สโค้ดข้างต้นทั้งหมดมีให้ใช้งาน บน GitHub

ฉันหวังว่าบทความนี้จะช่วยคุณในการเริ่มต้นใช้งาน Netflix Conductor โดยใช้ Elasticsearch 7 และ PostgreSQL

ขอให้มีความสุขในการเขียนโค้ด!

ข้อมูลโค้ดทั้งหมดในบทความนี้สร้างขึ้นโดยใช้ gistbuilder ซึ่งเป็นโปรแกรมเล็กๆ น้อยๆ ที่ดีที่ฉันเขียนเพื่อจุดประสงค์นั้น

หากคุณพบว่าบทความนี้มีประโยชน์ คุณอาจสนใจวิธีที่เราจัดกำหนดการเวิร์กโฟลว์ในโครงการของเรา โชคดีสำหรับคุณ ฉันเขียนบทความเกี่ยวกับเรื่องนั้นด้วย: