เมื่อใดที่ไม่ควรใช้นักแสดงใน akka / erlang


58

ฉันทำงานกับ akka มา 7-8 เดือนแล้วทุกวัน เมื่อฉันเริ่มฉันจะทำงานกับแอพพลิเคชั่นและสังเกตว่านักแสดงจะถูกใช้โดยทั่วไปทุกครั้งที่อยู่ในระบบของนักแสดงเพื่อสื่อสารระหว่างวัตถุส่วนใหญ่ ดังนั้นฉันจึงทำแบบเดียวกัน - หมุนนักแสดงคนอื่นให้กับ x / y / z

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

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

ดังนั้นคำถามของฉันคือ - มีเวลาไม่ดีที่จะใช้นักแสดงหรือไม่? ฉันอยากรู้ว่า erlang มีลักษณะอย่างไรและจะต้องการข้อมูลเชิงลึกของผู้อื่นอย่างแท้จริง หรือถ้ามีหลักการบางอย่างที่นักแสดงใช้


งานประเภทใดที่เปิดโอกาสให้ทำงานกับ Akka ทุกวันเป็นเวลาหลายเดือน?
Den

3
คนดี :) หรือเปลี่ยนแปลงตัวเอง
JasonG

ฉันต้องการที่จะรู้เฉพาะสิ่งที่การค้าไม่ชอบอยู่ระหว่าง ไอเอ็นจีนักแสดงและเพียงแค่ใช้ธรรมดาask Future
Max Heiber

2
ฉันจบลงด้วยการเขียนหนังสือเกี่ยวกับ Akka สองสามปีต่อมาและฉันคิดว่าคุณสามารถสรุปได้เช่นนี้: ถ้าคุณมีบางรัฐ - เช่นเคาน์เตอร์ - การอ่านและการเขียนหลายหัวข้อจาก / ถึงค่านั้นจะจบลงด้วยกัน ไม่มีการประสานและล็อค หากคุณใส่สถานะนั้นไว้ในตัวนักแสดงคุณก็สามารถมั่นใจได้ว่ามันจะเข้าถึงได้อย่างปลอดภัยและคุณจะไม่ทิ้งการเขียนหรือการอ่านค้าง นักแสดงใน erlang และ akka ยังสันนิษฐานว่ารัฐอาจไม่ดีนักและนักแสดงสามารถโยนข้อผิดพลาดได้ดังนั้นคุณจึงมีลักษณะของระบบการบำบัดด้วยตนเอง ฟิวเจอร์สนั้นง่ายกว่าถ้าคุณไม่จำเป็นต้องกลายพันธุ์
JasonG

หลายปีต่อมาผมเป็น Erlang / โปรแกรมเมอร์ยาอายุวัฒนะและผมให้กลับมาที่นี้มีข้อมูลเชิงลึกใหม่ :) Elixir แตกต่างกันมากเนื่องจากมีวัตถุที่ไม่เป็นทางเลือกให้กระบวนการเพื่อให้กระบวนการที่ถูกสร้างขึ้นเสมอเมื่อคุณต้องการรัฐ มันเกิดขึ้นพร้อมกัน นี่คือฮิวริสติกที่ดีที่สุดยัง
JasonG

คำตอบ:


23

นี่เป็นคำถามที่ฉันสนใจและฉันได้ทำการวิจัยเกี่ยวกับ สำหรับมุมมองอื่น ๆ ให้ดูโพสต์บล็อกนี้โดย Noel Walshหรือคำถามนี้ใน Stack Overflow ฉันมีความคิดเห็นที่ฉันต้องการนำเสนอ:

  • ฉันคิดว่า Akka เพราะมันใช้งานได้กับข้อความ บ่อยครั้งสำหรับการเห็นพ้องฉันจะเถียงว่านี่ไม่ใช่สิ่งที่คุณต้องการ ดึงปลอดภัยกว่ามาก ตัวอย่างเช่นรูปแบบหนึ่งที่พบบ่อยสำหรับระบบการกระจายที่จะมีชุดของคนงานประมวลผลข้อมูลในคิว เห็นได้ชัดว่านี้เป็นไปได้ใน Akkaแต่มันไม่จำเป็นต้องดูเหมือนจะเป็นคนวิธีแรกลอง Akka ยังมีกล่องจดหมายที่ทนทานแต่ก็ขึ้นอยู่กับวิธีการใช้งานของคุณอีกด้วย - คิวที่ใช้ร่วมกันครั้งเดียวนั้นมีความยืดหยุ่นมากกว่าการต่อคิวงานสำหรับการปรับสมดุล / การมอบหมายงานอีกครั้ง
  • เป็นเรื่องง่ายที่จะนึกถึงการแทนที่ชั้นเรียนของคุณด้วยนักแสดง ในความเป็นจริงบางคนดูเหมือนจะสนับสนุนโดยบอกว่านักแสดงควรทำสิ่งเดียวเท่านั้น ข้อสรุปเชิงตรรกะนี้เพิ่มความซับซ้อนของรหัสตามที่เจสันอธิบายเพราะถ้าทุกคลาสเป็นนักแสดงนั่นเป็นข้อความพิเศษจำนวนมากและรับ / ส่งบล็อค นอกจากนี้ยังทำให้มันยากที่จะเข้าใจและทดสอบโค้ดเพราะคุณจะสูญเสียความเป็นทางการของอินเตอร์เฟซ - และผมไม่เชื่อว่าการแสดงความคิดเห็นเป็นวิธีแก้ปัญหานี้ นอกจากนี้แม้จะมีประสิทธิภาพตามตำนานของ Akkaฉันสงสัยว่าการเพิ่มจำนวนนักแสดงไม่ได้เป็นความคิดที่ดี - เมื่อเราใช้ Java thread เรารู้ว่ามันมีค่าและประหยัดตามนั้น
  • มันเกี่ยวข้องกับประเด็นก่อนหน้านี้ แต่สิ่งที่น่ารำคาญอีกประการคือการสูญเสียข้อมูลประเภทที่ Noel และ Pino เน้นสำหรับพวกเราหลายคนนั่นคือสาเหตุที่เราใช้ Scala มากกว่าภาษาอื่นเช่น Python มีวิธีการบางอย่างรอบนี้มี แต่พวกเขามีทั้งที่ไม่ได้มาตรฐาน , ไม่แนะนำหรือการทดลอง
  • ในที่สุดการเห็นพ้องด้วยกันแม้ว่าคุณจะมีความคิดว่า "ปล่อยให้มันพัง"มันก็ยาก รูปแบบการเขียนโปรแกรมทางเลือกสามารถช่วย แต่พวกเขาไม่ได้ทำให้ปัญหาหายไป - พวกเขาเปลี่ยนพวกเขา - ที่ว่าทำไมมันเป็นเรื่องที่ดีที่จะคิดเกี่ยวกับพวกเขาอย่างเป็นทางการ นอกจากนี้ยังเป็นสาเหตุที่นักพัฒนา Joe Average เข้าถึงเครื่องมือที่สร้างขึ้นอย่างพร้อมเช่น RabbitMQ, Storm, Hadoop, Spark, Kafka หรือฐานข้อมูล NoSQL Akka มีเครื่องมือและส่วนประกอบที่สร้างไว้ล่วงหน้าแล้วซึ่งเท่ห์ แต่ก็ให้ความรู้สึกในระดับต่ำดังนั้นองค์ประกอบทั่วไปที่สร้างขึ้นพร้อมของระบบกระจายจะช่วยนักพัฒนาและสร้างระบบที่ถูกต้อง

เช่นเดียวกับเจสันฉันกระตือรือร้นที่จะได้ยินความเห็นของผู้อื่นที่นี่ ฉันจะแก้ไขปัญหาบางอย่างข้างต้นและใช้ Akka ได้ดีขึ้นได้อย่างไร


1
ฉันพบโพสต์นี้เกี่ยวกับการทดสอบใน Akka spot-on timgilbert.wordpress.com/2013/07/07/…
Mark Butler

"องค์ประกอบที่ถ่ายทอดทางพันธุกรรม" ยังคงมีประโยชน์สำหรับการฉีดแบบพึ่งพา เช่นผ่านการพึ่งพาเป็นอุปกรณ์ประกอบฉาก (ใช้พารามิเตอร์คอนสตรัคเตอร์) ปัญหาก็คือการกำกับดูแล - นักแสดงที่สร้างขึ้นจะได้รับการดูแลที่อื่นนอกเหนือจากนักแสดง เราเตอร์สามารถใช้เพื่อห่อกลยุทธ์การกำกับดูแลรอบนักแสดงที่สร้างขึ้นในระดับสูงสุด แต่ศักดิ์สิทธิ์ตอนนี้ค่อนข้างซับซ้อน! ฉันเดาว่าเค้กน่าจะเป็นทางออกที่ดีกว่า - มีลักษณะกับการสร้างนักแสดงสำหรับนักแสดงที่ให้บริการดีบีตัวอย่างเช่น จากนั้นเพียงใช้คุณลักษณะการทดสอบ mock / stub db ในบริบทข้อความ
JasonG

1
ใช่แน่นอน - การกำกับดูแลไม่สามารถทำงานได้ดีกับการฉีดที่ต้องพึ่งพา นอกจากนี้ฉันยังมีกรณีที่ฉันจำเป็นต้องฉีดโรงงานมากกว่าชั้นเรียนมิฉะนั้นจะมีปัญหาการปิดที่แปลกประหลาด - ฉันเดาว่าเนื่องจากการดูแลกระทู้ของ Akka
Mark Butler

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

ฉันเพิ่งเริ่มต้นหลักสูตรนี้: coursera.org/course/posaถึงแม้ว่าจะมุ่งเน้นไปที่การเขียนโปรแกรม Android เป็นหลัก แต่ก็มีภาพรวมที่ดีเกี่ยวกับการทำงานพร้อมกันใน Java ดังนั้นสิ่งหนึ่งที่ฉันสงสัยเกี่ยวกับคือ "ไม่ใช่ Akka เพียงแค่รูปแบบแฟนซีของลูปของเหตุการณ์พร้อมกับเสียงระฆังและนกหวีด (เพราะคุณสามารถใส่ลูปของเหตุการณ์ในเธรดอื่น)"
Mark Butler

21

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

  1. รูปแบบการทำงานพร้อมกัน
  2. ที่หลีกเลี่ยงการเข้าถึงพร้อมกันไปยังสถานะที่ไม่แน่นอน
  3. ใช้กลไกการสื่อสารแบบอะซิงโครนัสเพื่อจัดเตรียมการทำงานพร้อมกัน

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

  • คุณไม่อนุญาตให้มีการทำงานพร้อมกันหรือ
  • คุณไม่อนุญาตให้ใช้สถานะที่ไม่แน่นอน
  • คุณต้องพึ่งพากลไกการสื่อสารแบบซิงโครนัส

จากนั้นตัวแบบนางแบบจะไม่ให้ประโยชน์มากนัก

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


ขอบคุณ - ฉันคิดว่าคุณต้องประเมินสองสิ่งแล้ว - รัฐที่ไม่แน่นอนและเห็นพ้องด้วย? ไม่มีปัญหาในการแก้ไขหากคลาสนั้นไร้สัญชาติหรือไม่ทำงานพร้อมกัน อีกหนึ่งข้อพิจารณา - ฉันคิดว่าการยอมรับข้อบกพร่องเป็นอีกประเด็น เช่นถ้าคุณมีไคลเอนต์ Redis ที่เปลี่ยนไม่ได้ แต่มันอาจล้มเหลวในขณะที่ทำงาน - นั่นจะไม่ใช่กรณีการใช้งานที่ดีหรือไม่? การรีสตาร์ทนักแสดงคนนั้นอาจจำเป็นไหม ในขณะที่ - แม้ว่าชั้นเรียนอาจจะไม่เปลี่ยนรูปแบบล้วนๆ - เป็นไปได้มากที่จะมีสถานะที่เสียหายนอกตัวนักแสดงที่ไม่เปลี่ยนรูปซึ่งอาจทำให้มันล้มเหลว
JasonG

ฉันเดาว่านักแสดงที่รับผิดชอบการสื่อสารกับ Redis จะได้รับการยกเว้นและรีสตาร์ทแม้ว่า
JasonG

@ JasonG ในใจของฉัน "การยอมรับความผิด" ไม่ใช่ลักษณะของโมเดลนักแสดงโดยทั่วไป - เป็นสิ่งที่มาพร้อมกับการใช้โมเดลนักแสดงใน Erlang (และอาจจะ Akka?) ฉันไม่สามารถพูดกับ redis ได้ แต่ฉันต้องยอมรับว่า "ไคลเอนต์ที่ไม่เปลี่ยนรูปแบบ" ฟังดูแปลกสำหรับฉัน ... ถ้าส่วนประกอบซอฟต์แวร์ล้มเหลวฉันไม่เห็นว่ามันจะไม่เปลี่ยนรูปได้อย่างไร
Aidan Cully

การยอมรับข้อบกพร่องและการควบคุมดูแลอยู่ใน akka และคล้ายกับ erlang มาก ฉันเข้าใจสิ่งที่คุณกำลังพูดเกี่ยวกับลูกค้าที่ไม่เปลี่ยนรูป แต่ไม่ได้หมายความว่าสถานะรหัสไม่เปลี่ยนแปลงทุกที่ หากฉันเริ่มต้นการเชื่อมต่อเมื่อเริ่มต้นอาจเป็นไปได้ว่ารหัสลูกค้าสามารถเปลี่ยนไม่ได้ด้วยกลยุทธ์การเริ่มต้นใหม่ที่ใช้กับความผิดพลาดใด ๆ เพียงแค่เริ่มต้นใหม่นักแสดงเมื่อพบปัญหา
JasonG

12

สัญชาตญาณของคุณถูกต้อง IMHO การใช้นักแสดงทุกที่เปรียบเหมือนการใช้ค้อนสุภาษิต

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


ขอบคุณมาก ฉันสนใจจริงๆที่จะเห็นสิ่งที่เกิดขึ้นในการสนทนานี้
JasonG

0

ในการสั่งซื้อการส่งข้อความเข้า / ส่งออก:

เมื่อเร็ว ๆ นี้ฉันได้พบกับแอปพลิเคชั่นที่ใช้ akka ซึ่งโมเดลของนักแสดงทำให้เกิดปัญหาการเกิดขึ้นพร้อมกันจริง ๆ

ปัญหาคือข้อความที่เข้ามาเคลื่อนไหวใน 'ช่องทาง' ที่แตกต่างกัน (ผ่านเส้นทางนักแสดงที่แตกต่างกัน) แต่รหัสสันนิษฐานว่าข้อความจะมาถึงที่ปลายทางสุดท้ายตามลำดับเดียวกับที่พวกเขามาถึง ตราบใดที่ข้อมูลมาถึงด้วยช่วงเวลาที่กว้างพอสมควรสิ่งนี้จะใช้ได้เพราะจะมีข้อความที่ขัดแย้งกันเพียงครั้งเดียวไปยังปลายทาง เมื่อช่วงเวลาลดลงพวกเขาก็เริ่มออกคำสั่งและทำให้เกิดพฤติกรรมแปลก ๆ

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


นี่คือพื้นฐานและเกี่ยวข้องอย่างกว้างขวาง คุณสามารถรับประกันการสั่งซื้อระหว่างนักแสดงสองคนเท่านั้น doc.akka.io/docs/akka/current/scala/general/ ...... คุณไม่สามารถรับประกันการจัดส่งคำสั่งซื้อในระบบใด ๆ ที่คุณแฟน / ออก andreasohlund.net/2012/01/01/18/dont-assume-message-ordering
JasonG

-1

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

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

ฐานข้อมูลเช่น mnesia อาจถือได้ว่าเป็นการจัดเก็บข้อมูลภายนอกจากกระบวนการสืบค้น


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

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