La motivation pour écrire cet article était le fait qu'il y a une augmentation de l'apparence des documents marketing concernant Apache Kafka sur habr.com. Et aussi le fait que les articles donnent l'impression qu'ils sont écrits par des personnes un peu éloignées de l'utilisation réelle n'est bien sûr qu'une impression, mais pour une raison quelconque, la plupart des articles contiennent forcément une comparaison d'Apache Kafka avec RabbitMQ, et non en faveur de ce dernier. Ce qui est le plus intéressant, c'est qu'en lisant de tels articles, les gestionnaires sans expérience technique commencent à dépenser de l'argent pour la recherche interne afin que les principaux développeurs et CTO choisissent l'une des solutions. Comme je suis très gourmand / simple, et aussi depuis que je suis partisan de la thèse "La vérité n'est PAS née dans un conflit", je vous suggère de vous familiariser avec une approche différente - presque sans comparer différents courtiers.
Aucune comparaison nulle part
En général, de la bonne manière, j'aurais dû faire un article dans un format Kafka+RabbitMQ+Nats+ActiveMQ+Mosquito+etc
, mais il me semble que pour vous, chers lecteurs, ce sera exagéré, bien que généralement tous les services ci-dessus (et pas seulement) soient présents dans mes solutions architecturales. Et je ne parle pas encore de cela sur AzureServiceBus / AmazonServiceBus - qui participent également aux «hybrides» dans les grands programmes de projets. Par conséquent, pour l'instant, attardons-nous sur le bundle Kafka + RabbitMQ, et ensuite vous comprendrez pourquoi: par analogie, vous pouvez connecter n'importe quel service avec son protocole. Car:
en comparant Apache Kafka et RabbitMQ vous comparez 2 (deux) marques, ou plutôt 2 sociétés commerciales - Confluent et vmWare, et un peu Apache Software Foundation (mais ce n'est pas une entreprise)
c'est-à-dire, formellement, lorsqu'on compare, il faut comparer les modèles économiques des entreprises qui sont les principaux moteurs du développement de nos sujets d'expérimentation d'aujourd'hui. Étant donné qu'Habr n'est toujours pas un portail de recherche économique, pour commencer, nous ne devons pas nous souvenir des marques, mais des descriptions qui se cachent derrière ces marques (la façon dont nos participants actuels s'appellent).
- RabbitMQ est un courtier de messages multi-protocoles et extensible
- Apache Kafka est une plateforme de diffusion d'événements distribuée
- Confluent Platform - une plateforme de streaming d'événements avec la possibilité de créer des pipelines de données hautes performances pour l'analyse et l'intégration dans des scénarios d'entreprise
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 — .
Eh bien, pour terminer, je voudrais noter que le choix de l' écosystème JDK en Cunfluent Inc
tant que plate-forme de développement Kafka-Connect
semble tout de même étrange. Je ne serais pas surpris que leurs concurrents fassent de même, mais sur GoLang, NodeJS (quelque chose comme Kafka-Beats-Hub
)
Je fais de belles images au format GraphViz en utilisant le projet intelligent Docker2GraphViz - aide à maintenir à jour le plan et la documentation technique au format 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