เมื่อใดควรใช้ตัวแสดงแทนโซลูชันการส่งข้อความเช่น WebSphere MQ หรือ Tibco Rendezvous


106

ฉันได้อ่านคำถามและคำตอบแล้วว่าการตัดสินใจในการออกแบบใดที่จะเป็นประโยชน์ต่อนักแสดงของสกาล่าแทนที่จะเป็น JMS .

โดยปกติเราใช้โซลูชันการส่งข้อความที่มีมาหลายปีแล้ว: การใช้งาน JMS เช่น WebSphere MQ หรือ Apache ActiveMQ ใช้สำหรับการสื่อสารแบบจุดต่อจุดหรือ Tibco Rendevous สำหรับการส่งข้อความแบบหลายผู้รับ

มีความเสถียรพิสูจน์แล้วและมีความพร้อมใช้งานและประสิทธิภาพสูง อย่างไรก็ตามการกำหนดค่าและการตั้งค่าดูซับซ้อนกว่าใน Akka มาก

เมื่อใดและเหตุใดฉันจึงควรใช้ Akka ในบางกรณีที่ใช้ผลิตภัณฑ์ดังกล่าวข้างต้น - WebSphere MQ หรือ ActiveMQ - สำเร็จแล้ว เหตุใดฉันจึงควรพิจารณาใช้ Akka แทน WebSphere MQ หรือ Tibco RV ในโครงการในอนาคตของฉัน

และเมื่อใดที่ฉันควรหลีกเลี่ยง Akka? มีความพร้อมใช้งานและประสิทธิภาพสูงเช่นเดียวกับโซลูชันอื่น ๆ หรือไม่? หรือเป็นความคิดที่ดีที่จะเปรียบเทียบ Akka กับตัวกลางการส่งข้อความอื่น ๆ ?

อาจมีโซลูชันการส่งข้อความอื่นในสภาพแวดล้อม JVM ซึ่งฉันควรพิจารณานอกเหนือจาก JMS (Point-to-Point), TibcoRV (Multicast) และ Akka


2
stackoverflow.com/questions/4648280/scala-actors-vs-jms/…อาจมีประโยชน์
srnm

คำตอบ:


92

ก่อนปิดว่า "เก่า" ระบบข้อความ (MQ) เก่าในการดำเนินงาน แต่พวกเขาจะใหม่ในความคิดของวิศวกรรม: คิวถาวรการทำธุรกรรม Scala Actors และ Akka อาจเป็นการนำไปใช้งานที่ใหม่กว่า แต่สร้างขึ้นจากรูปแบบการทำงานพร้อมกันของนักแสดงรุ่นเก่า

ทั้งสองรุ่นนี้ แต่จบลงด้วยการที่คล้ายกันมากในทางปฏิบัติเพราะพวกเขาทั้งสองมีข้อความตามเหตุการณ์: ดูคำตอบของฉันRabbitMQ VS Akka

หากคุณจะเขียนโค้ดเฉพาะสำหรับ JVM Akka ก็น่าจะเป็นทางเลือกที่ดี ไม่งั้นฉันจะใช้ RabbitMQ

นอกจากนี้หากคุณเป็นนักพัฒนา Scala Akka ก็ควรเป็นเกมง่ายๆ อย่างไรก็ตามการผูก Java ของ Akka ไม่ใช่ Java-ish มากนักและต้องการการแคสต์เนื่องจากระบบประเภทของ Scala

นอกจากนี้ใน Java คนทั่วไปมักไม่สร้างวัตถุที่ไม่เปลี่ยนรูปซึ่งฉันแนะนำให้คุณทำเพื่อการส่งข้อความ ดังนั้นจึงง่ายมากใน Java ที่จะทำบางสิ่งโดยไม่ได้ตั้งใจโดยใช้ Akka ที่จะไม่ปรับขนาด (โดยใช้วัตถุที่เปลี่ยนแปลงได้สำหรับข้อความโดยอาศัยสถานะการเรียกกลับแบบแปลก ๆ ) ด้วย MQ นี่ไม่ใช่ปัญหาเพราะข้อความจะถูกทำให้เป็นอนุกรมด้วยความเร็วเสมอ กับ Akka พวกเขามักจะไม่

Akka ยังปรับขนาดได้ดีกว่ากับผู้บริโภคจำนวนมากมากกว่า MQ ส่วนใหญ่ เนื่องจากสำหรับไคลเอนต์ MQ (JMS, AMQP) ส่วนใหญ่ทุกการเชื่อมต่อคิวต้องใช้เธรด ... ดังนั้นคิวจำนวนมาก == เธรดที่รันอย่างถาวรจำนวนมาก นี่เป็นปัญหาของลูกค้าเป็นหลัก ฉันคิดว่า ActiveMQ Apollo มีผู้มอบหมายงานที่ไม่ปิดกั้นซึ่งอ้างว่าแก้ไขปัญหานั้นสำหรับ AMQP ไคลเอนต์ RabbitMQ มีช่องทางที่ช่วยให้คุณสามารถรวมผู้บริโภคหลายรายได้ แต่ยังคงมีปัญหากับผู้บริโภคจำนวนมากที่อาจทำให้เกิดการชะงักงันหรือการเชื่อมต่อหยุดชะงักดังนั้นโดยทั่วไปจึงมีการเพิ่มเธรดเพิ่มเติมเพื่อหลีกเลี่ยงปัญหานี้

การกล่าวว่าการรีบูตของ Akkaนั้นค่อนข้างใหม่และอาจยังไม่ได้ให้การรับประกันข้อความที่เชื่อถือได้ทั้งหมดและ QoS ที่คิวข้อความแบบเดิมมีให้ (แต่มีการเปลี่ยนแปลงทุกวัน) โดยทั่วไปแล้วยังเป็นแบบเพียร์ทูเพียร์ แต่ฉันคิดว่ารองรับเซิร์ฟเวอร์ทูเพียร์ซึ่งโดยทั่วไปแล้วระบบ MQ ส่วนใหญ่ทำ (เช่นจุดเดียวของความล้มเหลว) แต่มีระบบ MQ ที่เป็นแบบเพียร์ทูเพียร์ (RabbitMQ เป็นเซิร์ฟเวอร์ - เพื่อเพื่อน).

ในที่สุด RabbitMQ และ Akka ก็เป็นคู่ที่ดีจริงๆ คุณสามารถใช้ Akka เป็นกระดาษห่อหุ้มไปยัง RabbitMQ ได้โดยเฉพาะเนื่องจาก RabbitMQ ไม่ได้ช่วยคุณในการจัดการปริมาณการใช้ข้อความและกำหนดเส้นทางข้อความในเครื่อง (ใน JVM เดียว)

เมื่อใดควรเลือก Akka

  • มีผู้บริโภคจำนวนมาก (คิดเป็นล้าน)
  • ต้องการเวลาแฝงต่ำ
  • เปิดไปที่โมเดลการทำงานพร้อมกันของนักแสดง

ตัวอย่างระบบ: ระบบสนทนาแบบเรียลไทม์แบบโต้ตอบ

เมื่อใดควรเลือก MQ

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

ระบบตัวอย่าง: ระบบประมวลผลชุดธุรกรรมตามกำหนดการ

แก้ไขตามความคิดเห็นที่เกี่ยวข้อง

ฉันตั้งสมมติฐานว่า OP เกี่ยวข้องกับการประมวลผลแบบกระจายซึ่งทั้งAkkaและ Message Queues สามารถจัดการได้ นั่นคือผมถือว่าเขาพูดเกี่ยวกับการกระจาย Akka ใช้ Akka สำหรับการทำงานพร้อมกันในท้องถิ่นเป็นแอปเปิ้ลสีส้มเปรียบเทียบที่จะคิวข้อความมากที่สุด ฉันพูดมากที่สุดเพราะคุณสามารถใช้โมเดลคิวข้อความในเครื่องเป็นแบบจำลองพร้อมกัน (เช่นหัวข้อคิวการแลกเปลี่ยน) ซึ่งทั้งไลบรารีReactorและsimple-reactทำ

การเลือกโมเดล / ไลบรารีพร้อมกันที่เหมาะสมเป็นสิ่งสำคัญมากสำหรับแอปพลิเคชันที่มีเวลาแฝงต่ำ โซลูชันการประมวลผลแบบกระจายเช่นคิวข้อความมักไม่เหมาะเนื่องจากการกำหนดเส้นทางมักจะทำผ่านสายซึ่งช้ากว่าภายในแอปพลิเคชันอย่างเห็นได้ชัดดังนั้น Akka จึงเป็นตัวเลือกที่ดีกว่า อย่างไรก็ตามฉันเชื่อว่าเทคโนโลยี MQ ที่เป็นกรรมสิทธิ์บางอย่างช่วยให้สามารถกำหนดเส้นทางในพื้นที่ได้ ดังที่ฉันได้กล่าวไว้ก่อนหน้านี้ไคลเอนต์ MQ ส่วนใหญ่ค่อนข้างโง่เกี่ยวกับเธรดและไม่ต้องพึ่งพา IO ที่ไม่ปิดกั้นและมีเธรดต่อการเชื่อมต่อ / คิว / ช่อง ... ไอโอที่ไม่บล็อกแดกดันนั้นไม่ได้มีเวลาแฝงต่ำเสมอไป แต่โดยทั่วไปแล้วทรัพยากรมากกว่า มีประสิทธิภาพ

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


3
ฉันคิดว่าคำตอบสำหรับคำถามที่ผิดต้องไม่ถูก คุณไม่สามารถเปรียบเทียบคิวข้อความและรูปแบบการทำงานพร้อมกันได้ พวกเขาสร้างขึ้นเพื่อแก้ปัญหางานที่แตกต่างกันโดยสิ้นเชิงและมีคำว่า "ข้อความ" เหมือนกัน
Igor S.

2
ใช่และไม่ใช่ Akka รองรับการส่งข้อความแบบกระจายและคุณสามารถสร้างรูปแบบการทำงานพร้อมกันจากกระบวนทัศน์คิวข้อความได้อย่างง่ายดาย (เครื่องปฏิกรณ์ของ Google Spring) ความแตกต่างเพียงอย่างเดียวในตอนนี้คือ RabbitMQ มีข้อความที่ทนทาน .. เดี๋ยวก่อน Akka สนับสนุนตอนนี้ด้วย เขาอาจพูดว่า "นักแสดง" ในชื่อเรื่อง แต่ชี้ให้เห็นอย่างชัดเจนว่า Akka มีการทับซ้อนกันมากกับระบบที่ใช้ข้อความจำนวนมาก (ทั้งแบบพร้อมกันและแบบกระจาย)
Adam Gent

4
BTW @IgorS. รูปแบบการทำงานพร้อมกันโดยทั่วไปที่ใช้กับคิวข้อความเรียกว่า SEDA (สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์แบบจัดฉาก) นอกจากการใช้คิวหัวข้อและการแลกเปลี่ยนแล้วยังเป็นรูปแบบการทำงานพร้อมกันในตัวมันเอง (ซึ่งเกิดขึ้นกับโมเดลแบบกระจายเช่นกัน .. เช่นเดียวกับโมเดลนักแสดง) ฉันยังดูถูกจริงๆเมื่อมีคนพูดว่า "คำถามผิด" .. นอกจากคำถามที่ไม่เหมาะสมแล้วคำถามจะผิดเมื่อไหร่? เป็นคนขี้ขลาดและเป็นผู้นำที่จะพูดอะไรแบบนั้น
Adam Gent

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

1
หนึ่งใน Akka Java API - ตอนนี้สะอาดมากโดยเฉพาะกับ JDK 8 lambdas ฉันสงสัยว่ามันจะดีขึ้นถ้า / เมื่อพวกเขาแนะนำวัตถุที่มีค่าด้วย JDK 10
Rob Crawford

4

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

https://github.com/zcox/akka-zeromq-java


6
ZeroMQ ไม่ใช่ระบบส่งข้อความ ค่อนข้างเป็นซ็อกเก็ตที่ปรับปรุงใหม่ ระบบส่งข้อความแบบเต็มรูปแบบมีความซับซ้อนกว่า ZeroMQ มาก โครงการที่ลิงก์ของคุณดูเหมือนจะเป็นเพียงกระดาษห่อหุ้มบาง ๆ รอบ ๆ ZeroMQ กับ Akka
Vladimir Matveev

1

Akka-Camel น่าจะเป็นตัวอย่างที่ดีกว่า ZeroMQ - ZeroMQ คือการสื่อสาร tcp โดยตรงไปยัง tcp (ด้วยเหตุนี้จึงเป็นศูนย์ - ไม่มีคิวข้อความ)

ด้วย AkkaCamel คุณสามารถแยกคิวออกไปและผลิต / บริโภคข้อความโดยตรงจากนักแสดงโดยไม่ต้องใช้รหัสใด ๆ เพื่อจัดการกับข้อความคิวข้อความที่ผลัก / ดึง

คุณสามารถละทิ้ง akka-zeromq และใช้ Akka ได้โดยตรงกับการควบคุมระยะไกล ฉันคิดว่า akka-zeromq กำลังถูกลบออกจากไลบรารีหลัก แต่เราสร้างไลบรารี zeromq ที่ดีสำหรับ akka ที่เรียกว่า scala-zeromq ( https://github.com/mDialog/scala-zeromq )

Akka มีสองกรณีการใช้งานหลักที่สำคัญ:

1) สถานะไม่แน่นอน

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

2) การกระจาย

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

นี่คือตัวอย่างการใช้ Akka กับ ActiveMQ กับ Akka-Camel (โดยใช้ Java8)

import akka.actor.Props;
import akka.camel.Camel;
import akka.camel.CamelExtension;
import akka.testkit.TestActorRef;
import akka.testkit.TestProbe;
import org.junit.Ignore;
import org.junit.Test;
import akka.camel.javaapi.UntypedProducerActor;
import akka.camel.javaapi.UntypedConsumerActor;
import static com.rogers.totes.TotesTestFixtures.*;
import org.apache.activemq.camel.component.*;

public class MessagingTest {
    @Test @Ignore
    public void itShouldStoreAMessage() throws Exception{
        String amqUrl = "nio://localhost:61616";
        Camel camel = (Camel) CamelExtension.apply(system);
        camel.context().addComponent("activemq", ActiveMQComponent.activeMQComponent(amqUrl));

        TestProbe probe = TestProbe.apply(system);
        TestActorRef producer = TestActorRef.create(system, Props.create((Producer.class)));
        TestActorRef consumer = TestActorRef.create(system, Props.create((Consumer.class)));
        producer.tell("Produce", probe.ref());

        Thread.sleep(1000);
    }
}

class Producer extends UntypedProducerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }
}

class Consumer extends UntypedConsumerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("GOT A MESSAGE!" + message);

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