A motivação para escrever este artigo foi o fato de que há um aumento no aparecimento de materiais de marketing sobre o Apache Kafka no habr.com. E também o fato de os artigos darem a impressão de serem escritos por pessoas que estão um pouco longe do uso real, é claro, é apenas uma impressão, mas por alguma razão, a maioria dos artigos necessariamente contém uma comparação de Apache Kafka com RabbitMQ, e não a favor deste último. O mais interessante é que, ao ler esses artigos, gerentes sem formação técnica começam a gastar dinheiro em pesquisa interna para que os principais desenvolvedores e CTOs escolham uma das soluções. Por ser muito ganancioso / caseiro, e também por ser partidário da tese "A verdade NÃO nasce em disputa", sugiro que você se familiarize com outra abordagem - quase sem comparar corretores diferentes.
Sem comparação em qualquer lugar
Em geral, da maneira correta, deveria ter feito um artigo em formato Kafka+RabbitMQ+Nats+ActiveMQ+Mosquito+etc
, mas me parece que para vocês caros leitores será um exagero, embora geralmente todos os serviços acima (e não apenas) estejam presentes em minhas soluções arquitetônicas. E não estou falando sobre isso ainda sobre AzureServiceBus / AmazonServiceBus - que também participam de "híbridos" em programas de grandes projetos. Portanto, por enquanto, vamos nos deter no pacote Kafka + RabbitMQ e então você vai entender o porquê: por analogia, você pode conectar qualquer serviço com seu protocolo. Porque:
comparando Apache Kafka e RabbitMQ você está comparando 2 (duas) marcas, ou melhor, 2 empresas comerciais - Confluent e vmWare, e um pouco de Apache Software Foundation (mas esta não é uma empresa)
isto é, formalmente, ao comparar, devemos comparar os modelos de negócios das empresas que são os principais motores do desenvolvimento dos nossos sujeitos experimentais de hoje. Uma vez que o Habr ainda não é um portal de pesquisa econômica, para começar devemos nos lembrar não das marcas, mas das descrições que estão por trás dessas marcas (como nossos atuais participantes se autodenominam).
- RabbitMQ é um corretor de mensagens extensível e multi-protocolo
- Apache Kafka é uma plataforma de streaming de eventos distribuída
- Confluent Platform - uma plataforma de streaming de eventos com a capacidade de criar pipelines de dados de alto desempenho para análises e integração em cenários de negócios
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 ( Python) — https://docs.celeryproject.org/projects/kombu/en/stable/introduction.html#transport-comparison
- CAP .NetCore — https://github.com/dotnetcore/CAP
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 ,
- https://github.com/rabbitmq/rabbitmq-server/tree/master/deps/
- https://docs.confluent.io/current/connect/kafka-connect-rabbitmq/index.html
- https://github.com/84codes/kafka-connect-rabbitmq/blob/master/docker-compose.yml
? , , " " — 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 — " 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
- 28082 —
curl
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.
NATs —
OpenFaaS
, " "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 — .
Bem, como um ponto final, eu gostaria de observar que a escolha do ecossistema JDK Cunfluent Inc
como uma plataforma de desenvolvimento Kafka-Connect
parece a mesma estranha. Eu não ficaria surpreso se seus concorrentes fizessem o mesmo, mas em GoLang, NodeJS (algo como Kafka-Beats-Hub
)

Eu faço belas imagens no formato GraphViz usando o projeto inteligente Docker2GraphViz - ajuda a manter o esboço e a documentação técnica no formato Markdown atualizados
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