この記事を書いた動機は、habr.comでApacheKafkaに関するマーケティング資料の出現が増加しているという事実でした。また、記事が実際の使用から少し遠い人々によって書かれているという印象を与えるという事実は、もちろん印象にすぎませんが、何らかの理由で、ほとんどの記事には必然的にApache KafkaとRabbitMQの比較が含まれており、後者を支持していません。最も興味深いのは、そのような記事を読むと、技術的なバックグラウンドを持たないマネージャーが内部調査にお金を費やし始め、主要な開発者と技術ディレクターがソリューションの1つを選択することです。私は非常に貪欲で家庭的であり、「真実は論争の中で生まれない」という論文の支持者でもあるので、別のアプローチに慣れることをお勧めします-ほとんど異なるブローカーを比較することはありません。
どこにも比較なし
一般的に、正しい方法で、私はフォーマットKafka+RabbitMQ+Nats+ActiveMQ+Mosquito+etc
で記事を作成する必要がありましたが、通常、上記のすべてのサービス(およびそれだけではない)が私のアーキテクチャソリューションに存在しているにもかかわらず、読者の皆様にとってはやり過ぎだと思います。また、AzureServiceBus / AmazonServiceBusについてはまだ話していません。これらは、大規模なプロジェクトプログラムの「ハイブリッド」にも参加しています。したがって、ここでは、Kafka + RabbitMQバンドルについて詳しく見ていきましょう。そうすれば、その理由を理解できます。類推すると、任意のサービスをそのプロトコルに接続できます。理由:
Apache KafkaとRabbitMQを比較すると、2つのブランド、つまり2つの商用企業(ConfluentとvmWare、および小さなApache Software Foundation)を比較します(ただし、これは企業ではありません)
つまり、正式に比較する場合、今日の実験対象の開発の主な推進力である企業のビジネスモデルを比較する必要があります。Habrはまだ経済研究ポータルではないので、最初に、ブランドではなく、これらのブランドの背後にある説明(現在の参加者が自分自身を呼ぶ方法)を覚えておく必要があります。
- RabbitMQは、マルチプロトコルで拡張可能なメッセージブローカーです。
- Apache Kafkaは、分散イベントストリーミングプラットフォームです
- Confluentプラットフォーム-分析とビジネスシナリオへの統合のための高性能データパイプラインを作成する機能を備えたイベントストリーミングプラットフォーム
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 — .
最後にCunfluent Inc
、開発プラットフォームとしてのKafka-Connect
JDKエコシステムの選択はまったく同じように奇妙に見えることに注意したいと思います。競合他社が同じことをしても驚かないでしょうが、GoLangではNodeJS(のようなものKafka-Beats-Hub
)

私は巧妙なプロジェクトDocker2GraphVizを使用してGraphViz形式で美しい写真を作成します-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