Los híbridos ganan o los holívares son caros

La motivación para escribir este artículo fue el hecho de que hay un aumento en la aparición de materiales de marketing sobre Apache Kafka en habr.com. Y también el hecho de que los artículos den la impresión de que están escritos por personas que están un poco lejos del uso real es, por supuesto, solo una impresión, pero por alguna razón, la mayoría de los artículos contienen necesariamente una comparación de Apache Kafka con RabbitMQ, y no a favor de este último. Lo más interesante es que al leer estos artículos, los gerentes sin experiencia técnica comienzan a gastar dinero en investigación interna para que los principales desarrolladores y directores técnicos elijan una de las soluciones. Como soy muy codicioso / hogareño, y también como partidario de la tesis "La verdad NO nace en una disputa", le sugiero que se familiarice con un enfoque diferente, casi sin comparar diferentes corredores.







No hay comparación en ninguna parte



En general, de la manera correcta, debería haber hecho un artículo en un formato Kafka+RabbitMQ+Nats+ActiveMQ+Mosquito+etc



, pero me parece que para ustedes, queridos lectores, será exagerado, aunque generalmente todos los servicios anteriores (y no solo) están presentes en mis soluciones arquitectónicas. Y todavía no estoy hablando de esto sobre AzureServiceBus / AmazonServiceBus, que también participan en "híbridos" en programas de proyectos grandes. Por lo tanto, por ahora, detengámonos en el paquete Kafka + RabbitMQ, y luego comprenderá por qué: por analogía, puede conectar cualquier servicio con su protocolo. Porque:







comparando Apache Kafka y RabbitMQ, está comparando 2 (dos) marcas, o más bien 2 empresas comerciales: Confluent y vmWare, y una pequeña Apache Software Foundation (pero esta no es una empresa)

es decir, formalmente, al comparar, debemos comparar los modelos de negocio de las empresas que son los principales impulsores del desarrollo de nuestros sujetos experimentales de hoy. Dado que Habr todavía no es un portal para la investigación económica, para empezar, debemos recordar no las marcas, sino las descripciones que están detrás de estas marcas (la forma en que nuestros participantes actuales se llaman a sí mismos).







  • RabbitMQ es un agente de mensajes extensible y multiprotocolo
  • Apache Kafka es una plataforma de transmisión de eventos distribuida
  • Plataforma Confluent : una plataforma de transmisión de eventos con la capacidad de crear canales de datos de alto rendimiento para análisis e integración en escenarios comerciales


Confluent — Apache Kafka Confluent Apache Kafka. SchemeRegistry



, RestProxy



, kSQL



, , Kafka-Connect



.







— , RabbitMQ "", Kafka - ( ).







— , .







  • RabbitMQ — . ( Erlang)
  • Kafka — ( Scala/Java)








  • RabbitMQ . , .
  • Kafka , .


,



: , , - , , —



,



->



->









— . 14 , , "" ( ), .







  • ODBC
  • AMQP
  • MSMQ
  • XMPP
  • IP over Avian Carriers


(python, C#, java) 1 — One-S-Connectors



(https://code.google.com/archive/p/one-c-connectors/source/default/source). ( 1 1 " 1-" — ).

( 2006 ) , / -. . ODBC Kafka/NATs/ModBus.







— ( )



, — 1-, .









Kombu — , Apache Kafka https://github.com/celery/kombu/issues/301 - " ", Python https://github.com/confluentinc/confluent-kafka-python

— , : Java, GoLang, RUST, etc. NATs ActiveMQ JMS — : Java ,









? , , " " — RabbitMQ ( /deps



) RabbitMQ, Confluent Apache Kafka .







PostgreSQL — CREATE EXTENSION hypopg



, Pivotal/vmWare

— " " — 84Codes



https://github.com/84codes. — 84Codes , / CloudAMQP CloudKarafka.







, , 2 :







  • vmWare , RabbitMQ — . , GitHub.
  • Confuent Enterprise Enterprise-Kafka-Connect, GUI .


- https://github.com/jcustenborder/kafka-connect-rabbitmq, , Java Maven Archetype https://github.com/jcustenborder/kafka-connect-archtype — , Confluent , Kafka .

Kafka



, Java, Enterprise . RabbitMQ



, (Erlang ), 84Codes



. Erlang — , OpenStack.









. , , ITILv4, 3







  • ProtocolLock VendorLock — , , - — : .
  • , — .
  • 3



    TDD, BDD, CICD, ScallableAgile DevOps (DocOps, DevSecOps)



    — . TimeToMarket.


, , Docker-Compose. — () — , . — Kafka+RabbitMQ 84Codes



( — https://www.84codes.com/).









, . , , , Apache Kafka exactly-ones



. — , ->



Kafka ( Topic



) — Offsets



.







exactly-ones

exactly-ones — " 1", Exactly once — , .







. :







  • Zookeper
  • KafkaBroker
  • RabbitMQ
  • KafkaConnect








  • Python AMQP 0.9
  • # AMQP 1.0
  • C# Kafka


: Apache Kafka — ( ) Java, , librdkafka — C++ - ,. Kafka , " ": , https://github.com/edenhill/librdkafka/pulse/monthly, wmWare https://github.com/rabbitmq

:







RabbitMQ-Kafka-Sinc-Connector



— Confluent Github.









2 — - -.







RabbitMQ Kafka









docker-compose -f dockers/infra.yml up -d
      
      





, , , Kafka-UI RabbitMQ-Sinc, Kafka RabbitMQ







    image: provectuslabs/kafka-ui:latest
    ports:
      - 8080:8080
    depends_on:
      - kafka-broker
      - zookeeper
    environment:
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: broker:29092
      KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper:2181
      KAFKA_CLUSTERS_0_JMXPORT: 9101

      
      





Java







    <parent>
        <groupId>com.github.jcustenborder.kafka.connect</groupId>
        <artifactId>kafka-connect-parent</artifactId>
        <version>1.0.0</version>
    </parent>
      
      





pom.xml — , https://github.com/jcustenborder/kafka-connect-parent, Java-Kafka-Adapter







c RMQ Java — https://www.rabbitmq.com/java-client.html







            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>${rabbitmq.version}</version>
      
      





— , , :







  • java — -1-build-connect-jar.bat



  • 00-build-connect-image.sh











  • 01-start-infra.sh





— Docker PWD Windows Linux — . — sh













RabbitMQ :







:







  • 9092 — Kafka
  • 8080 — Apache Kafka UI
  • 5672 — AMQP 0.9 AMQP 1.0
  • 15672 — RabbitMQ
  • 28082curl





RabbitMQ Docker:







  • enabled-rmq-plugins





[
    rabbitmq_management, 
    rabbitmq_amqp1_0, 
    rabbitmq_mqtt, 
    rabbitmq_federation, 
    rabbitmq_federation_management,
    rabbitmq_shovel,
    rabbitmq_shovel_management,
    rabbitmq_prometheus
].
      
      





  • , — rmq_definitions.json





     "bindings":[
        {
           "source":"orders-send",
           "vhost":"/",
           "destination":"orders-amqp-10-consumer",
           "destination_type":"queue",
           "routing_key":"",
           "arguments":{

      
      













docker-compose -f dockers/infra.yml restart protocol-connect-sync

docker-compose -f applications.yml build
docker-compose -f applications.yml up
      
      

















:







  • -



    2


        producer = conn.Producer(serializer='json')
        producer.publish({'client': '', 'count': 10, 'good': ''},
                      exchange=order_exchange,
                      declare=[kafka_queue, amqp10_queue])
        time.sleep(2)
      
      





RUN python -m pip install \
    kombu \
    librabbitmq
      
      





AMQP 0.9 — librabbitmq https://github.com/alanxz/rabbitmq-c







  • AMQP 1.0 — , . .


            Attach recvAttach = new Attach()
            {
                Source = new Source()
                {
                    Address = "orders-amqp-10-consumer",
                    Durable = 1,
                },
      
      






            ReceiverLink receiver = 
                new ReceiverLink(session,"netcore_amqp_10_consumer", recvAttach, null);

            Console.WriteLine("Receiver connected to broker.");

            while (true) {
                Message message = receiver.Receive();
                if (message == null)
                {
                    Console.WriteLine("Client exiting.");
                    break;
                }
                Console.WriteLine("Received " 
                  + System.Text.Encoding.UTF8.GetString((byte[])message.Body)
      
      











  <ItemGroup>
    <PackageReference Include="AMQPNetLite.Core" Version="2.4.1" />
  </ItemGroup>

      
      





https://github.com/Azure/amqpnetlite Microsoft . AMQP 1.0 https://docs.microsoft.com/ru-ru/azure/service-bus-messaging/service-bus-amqp-overview













  • Kafka — . Exactly once.


                AutoOffsetReset = AutoOffsetReset.Earliest
      
      





                c.Subscribe("orders-from-amqp");
      
      





                    while (true)
                    {
                        try
                        {
                            var cr = c.Consume(cts.Token);
      
      





:







  • 5








  • 3








  • Kafka-Ui








  • RabbitMQ








Java ?



— , , Kafka-Connect-Base







[submodule "dockers/rabbitmq-kafka-sink"]
    path = dockers/rabbitmq-kafka-sink
    url = https://github.com/aliczin/kafka-connect-rabbitmq

      
      





, Kafka-Connect — .







:









public class RabbitMQSourceTask extends SourceTask {
      
      







        this.channel.basicConsume(queue, this.consumer);
        log.info("Setting channel.basicQos({}, {});", this.config.prefetchCount, this.config.prefetchGlobal);
        this.channel.basicQos(this.config.prefetchCount, this.config.prefetchGlobal);
      
      





  • .


  @Override
  public List<SourceRecord> poll() throws InterruptedException {
    List<SourceRecord> batch = new ArrayList<>(4096);

    while (!this.records.drain(batch)) {
      
      





AMQP 0.9 . Java . J2EE.







  private static final Logger log = LoggerFactory.getLogger(MessageConverter.class);
  static final String FIELD_ENVELOPE_DELIVERYTAG = "deliveryTag";
  static final String FIELD_ENVELOPE_ISREDELIVER = "isRedeliver";
  static final String FIELD_ENVELOPE_EXCHANGE = "exchange";
  static final String FIELD_ENVELOPE_ROUTINGKEY = "routingKey";

  static final Schema SCHEMA_ENVELOPE = SchemaBuilder.struct()
      .name("com.github.jcustenborder.kafka.connect.rabbitmq.Envelope")
      .doc("Encapsulates a group of parameters used for AMQP's Basic methods. See " +
          "`Envelope <https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Envelope.html>`_")
      .field(FIELD_ENVELOPE_DELIVERYTAG, SchemaBuilder.int64().doc("The delivery tag included in this parameter envelope. See `Envelope.getDeliveryTag() <https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Envelope.html#getDeliveryTag-->`_").build())
      .field(FIELD_ENVELOPE_ISREDELIVER, SchemaBuilder.bool().doc("The redelivery flag included in this parameter envelope. See `Envelope.isRedeliver() <https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Envelope.html#isRedeliver-->`_").build())
      .field(FIELD_ENVELOPE_EXCHANGE, SchemaBuilder.string().optional().doc("The name of the exchange included in this parameter envelope. See `Envelope.getExchange() <https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Envelope.html#getExchange-->`_"))
      .field(FIELD_ENVELOPE_ROUTINGKEY, SchemaBuilder.string().optional().doc("The routing key included in this parameter envelope. See `Envelope.getRoutingKey() <https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Envelope.html#getRoutingKey-->`_").build())
      .build();
      
      





… , — . .









Github.







https://github.com/aliczin/hybrid-eventing. Creative Commons Attribution 4.0 International.







— DevOps . , — , .







" " () —







orderEventsApp->Amqp09: send order
Amqp09->Amqp10: fanout\n copy event
Amqp09->KafkaQ: fanout\n copy event
KafkaQ->KafkaConnect: consume\n on message
KafkaConnect->KafkaConnect: transform\n message
KafkaConnect->Kafka: publish to topic
      
      

















Amqp10->orderEventSubApp: subcribe\n for event
orderJournalApp->Kafka: read kafka journal
      
      





















  • Apache Kafka Java , librdkafka — KafkaAPI



    . Java .







  • , RabbitMQ/Kafka/Nats/ActiveMQ — -.







  • Docker, .

















:







  • Mosquito — SCADA ModBus/OPC-UA. — " " — https://github.com/mainflux/mainflux







  • ActiveMQ — Java , Erlang, — RabbitMQ AMQP 1.0 -> ActiveMQ



    RabbitMQ, JMS.







  • NATsOpenFaaS



    , " " Amazon Lambda



    . — : https://github.com/nats-io/nats-kafka — OpenFaaS 1- — 2.5 https://youtu.be/8sF-oGGVa9M









(/ — : ) /, - , , . " "







:  
          Produser/Consumer
        
           
              

: vmWare   Stream  RabbitMQ 
     vmWare     
         
         
            RabbitMQ
              

:   1-   ActiveMQ    1
          1   
            Kafka API
        ActivemeMQ2Kafka
              1

etc
      
      





, — — : https://github.com/fclairamb/ftpserver/pull/34 — FTP , S3.







— : : .







  • . DevOps k8s, OpenShift, etc — , - .
  • — PRODUCTION-READY .




( ) , - :







HTTP, AMQP 0.9, AMQP 1.0, Apache Kafka 23, MQTT, WebSockets, <SOAP>

. 1 — . Google 1+RabbitMQ 1+Kafka 1+OpenFaas



— RabbitMQ Kafka " 1" . 1 — , . Java/C#/Python/C++/Rust/etc.







https://shd101wyy.github.io/markdown-preview-enhanced Visual Studio Code — .







Bueno, como punto final, me gustaría señalar que la elección del ecosistema JDK Cunfluent Inc



como plataforma de desarrollo Kafka-Connect



parece igualmente extraña. No me sorprendería que sus competidores hicieran lo mismo, pero en GoLang, NodeJS (algo así como Kafka-Beats-Hub



)













Hago imágenes bonitas en formato GraphViz utilizando el inteligente proyecto Docker2GraphViz: ayuda a mantener actualizados el esquema y la documentación técnica en formato Markdown







set CURPATH=%~dp0
set DOCKER_DIR=%CURPATH%\dockers

docker run --rm -it --name dcv -v %DOCKER_DIR%\:/input pmsipilot/docker-compose-viz render -m image --force --output-file=infra-topology.png infra.yml
docker run --rm -it --name dcv -v %CURPATH%\:/input pmsipilot/docker-compose-viz render -m image --force --output-file=apps-topology.png applications.yml

copy /b/v/y dockers\infra-topology.png content\assets\infra-topology.png
copy /b/v/y apps-topology.png content\assets\apps-topology.png
      
      






All Articles