<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Emil Koutanov</title>
    <description>The latest articles on Forem by Emil Koutanov (@ekoutanov).</description>
    <link>https://forem.com/ekoutanov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F252201%2F6d49225e-1d72-47c1-8dd0-8106be0b8d6b.jpeg</url>
      <title>Forem: Emil Koutanov</title>
      <link>https://forem.com/ekoutanov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ekoutanov"/>
    <language>en</language>
    <item>
      <title>Deleted</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Thu, 11 Feb 2021 07:20:12 +0000</pubDate>
      <link>https://forem.com/ekoutanov/an-introduction-to-event-driven-architecture-3k08</link>
      <guid>https://forem.com/ekoutanov/an-introduction-to-event-driven-architecture-3k08</guid>
      <description>&lt;p&gt;Deleted&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>eventdriven</category>
      <category>eventsourcing</category>
      <category>cqrs</category>
    </item>
    <item>
      <title>An Introduction to Microservices</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Thu, 11 Feb 2021 07:16:45 +0000</pubDate>
      <link>https://forem.com/ekoutanov/an-introduction-to-microservices-4h2f</link>
      <guid>https://forem.com/ekoutanov/an-introduction-to-microservices-4h2f</guid>
      <description>&lt;h1&gt;
  
  
  A Brief History
&lt;/h1&gt;

&lt;p&gt;The term &lt;strong&gt;microservices&lt;/strong&gt; was first coined by Dr. Peter Rodgers in 2005 and was initially known as “micro web services”. The main driver behind “micro web services” at the time was to break up single large “monolithic” designs into multiple independent components/processes, thereby making the codebase more granular and manageable.&lt;/p&gt;

&lt;p&gt;Modular, distributed applications date for back several decades. And in this regard, microservices are not a new concept. However, what popularised microservices was the principles governing how they were designed and the way they were consumed. While conventional distributed systems of that era relied on proprietary communications protocols, microservices took advantage of open standards such as HTTP, REST, XML and JSON.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Simple Definition
&lt;/h1&gt;

&lt;p&gt;A microservice is a small, loosely coupled, distributed service. It is part of a broader microservices architecture, comprising a set of loosely coupled microservices that operate together to solve a common goal. A collection of microservices can be regarded as a system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/microservicegeeks/an-introduction-to-microservices-a3a7e2297ee0"&gt;Read the rest of the article on Medium.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>softwaredevelopment</category>
      <category>eventdriven</category>
      <category>java</category>
    </item>
    <item>
      <title>Combining strict order with massive parallelism using Kafka</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Mon, 25 Jan 2021 19:36:21 +0000</pubDate>
      <link>https://forem.com/ekoutanov/combining-strict-order-with-massive-parallelism-using-kafka-2o27</link>
      <guid>https://forem.com/ekoutanov/combining-strict-order-with-massive-parallelism-using-kafka-2o27</guid>
      <description>&lt;p&gt;&lt;em&gt;Getting the best of both worlds&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Having been involved in several large-scale Kafka projects for different clients across a broad range of industries, I have heard my fair share of questions on Apache Kafka — ranging from the fundamental to the esoteric. One question that never seems to go out of fashion is: &lt;em&gt;How can you maintain strict order, yet still process records in parallel?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And it's a fair question. Strict order assumes linearizability, the very notion of which seems to contradict with the objectives of parallelism.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--beUljeM9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgflip.com/3k02ub.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--beUljeM9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgflip.com/3k02ub.jpg" alt="One does not simply process ordered records in parallel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Partial and total order
&lt;/h1&gt;

&lt;p&gt;We will start by exploring the notion of &lt;em&gt;order&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;As expected of an event-streaming platform, Kafka &lt;strong&gt;preserves the order of published records, providing those records occupy the same partition&lt;/strong&gt;. In order to understand what this means in practice, one needs to explore the architecture of Kafka topics, and the underlying sharding mechanism — partitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codeburst.io/combining-strict-order-with-massive-parallelism-using-kafka-83dc1ec9be03"&gt;Read the rest of the article on Medium&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>apachekafka</category>
      <category>microservices</category>
      <category>java</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>Contrasting NATS with Apache Kafka</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Sun, 06 Sep 2020 20:44:03 +0000</pubDate>
      <link>https://forem.com/ekoutanov/contrasting-nats-with-apache-kafka-5edp</link>
      <guid>https://forem.com/ekoutanov/contrasting-nats-with-apache-kafka-5edp</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Kafka is an &lt;em&gt;Event Streaming Platform&lt;/em&gt;, while NATS is a closer to a conventional &lt;em&gt;Message Queue&lt;/em&gt;. Kafka is optimised around the unique needs of emerging &lt;em&gt;Event-Driven Architectures&lt;/em&gt;, which enrich the traditional pub-sub model with strong ordering and persistence semantics. Conversely, NATS is highly optimised around pub-sub topologies, and is an excellent platform for decoupling systems where message order and reliable delivery is a non-issue.&lt;/p&gt;

&lt;p&gt;I’ll preface this post by pointing out that there is another product — &lt;strong&gt;NATS Streaming&lt;/strong&gt; — which is a different beast and is closer to Kafka. You may want to take a detour to NATS Streaming if you after an alternative event streaming platform; otherwise, read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Subscriptions
&lt;/h1&gt;

&lt;p&gt;At its core, &lt;strong&gt;NATS is about publishing and listening for messages&lt;/strong&gt;. These depend heavily on subjects which scope messages into streams or topics. Consumers subscribe to topics either verbatim (matching the topic name precisely), or using wildcards. Below is an illustration of publisher-subject-consumer relationship in NATS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itnext.io/contrasting-nats-with-apache-kafka-1d3bdb9aa767"&gt;Read the rest of the article on Medium.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apachekafka</category>
      <category>nats</category>
      <category>microservices</category>
      <category>eventstreaming</category>
    </item>
    <item>
      <title>Apache Kafka in a Nutshell</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Sat, 25 Apr 2020 06:15:05 +0000</pubDate>
      <link>https://forem.com/ekoutanov/apache-kafka-in-a-nutshell-3knn</link>
      <guid>https://forem.com/ekoutanov/apache-kafka-in-a-nutshell-3knn</guid>
      <description>&lt;p&gt;So, you’ve heard of this Kafka thing that’s popping up all over the shop. From green-sprout startups to greedy multi-nationals, in all sorts of weird and wonderful contexts. It appears that someone has figured out a Swiss Army knife piece of über-tech that works for microservices, event-streaming, CQRS, and just about anything else that makes the headlines.&lt;/p&gt;

&lt;p&gt;As someone who’s been working with Apache Kafka since 2015, helping several clients build complex event-driven and microservices-style applications, I’ve heard my fair share of questions. First, it was I who was doing most of the asking. Then I found myself on the receiving end. At the time of writing, I’m trending among the &lt;a href="https://www.quora.com/topic/Apache-Kafka/writers"&gt;top-ten writers on Quora&lt;/a&gt; — a feat I owe mostly to the mistakes I’ve made along the way, which have made me a little more aware. With the shameless chest-beating out of the way, I thought I’d put together an FAQ-style post that breaks Kafka down, focusing on the aspects that matter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/apache-kafka-in-a-nutshell-5782b01d9ffb"&gt;Read the rest of the article on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apachekafka</category>
      <category>eventsourcing</category>
      <category>eventstreaming</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Why is Kafka so Fast</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Thu, 06 Feb 2020 22:04:35 +0000</pubDate>
      <link>https://forem.com/ekoutanov/why-is-kafka-so-fast-1m12</link>
      <guid>https://forem.com/ekoutanov/why-is-kafka-so-fast-1m12</guid>
      <description>&lt;p&gt;The last few years have brought about immense changes in the software architecture landscape. The notion of a single monolithic application, or even several coarse-grained services sharing a common data store has been all but erased from the hearts and minds of software practitioners world-wide. Autonomous microservices, event-driven architecture, and CQRS are the dominant tools in the construction of contemporary business-centric applications. To top it off, the proliferation of device connectivity — IoT, mobile, wearables — are creating an upward pressure on the number of events a system must handle in near-real-time.&lt;/p&gt;




&lt;p&gt;Let's start by acknowledging that the term 'fast' is multi-faceted, complex, and highly ambiguous. Latency, throughput, jitter, are metrics that shape and influence one's interpretation of the term. It is also inherently contextual: the industry and application domains in themselves set the norms and expectations around performance. Whether or not something is fast depends largely on one's frame of reference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache Kafka is optimised for throughput&lt;/strong&gt; at the expense of latency and jitter, while preserving other desirable qualities, such as durability, strict record order, and at-least-once delivery semantics. When someone says 'Kafka is fast', and assuming they are at least mildly competent, you can assume they are referring to Kafka's ability to &lt;em&gt;safely&lt;/em&gt; accumulate and distribute a very high number of records in a short amount of time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/why-kafka-is-so-fast-bde0d987cd03"&gt;Read the rest of the article on Medium.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>bigdata</category>
      <category>eventsourcing</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Getting Started with Istio</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Mon, 20 Jan 2020 07:56:52 +0000</pubDate>
      <link>https://forem.com/ekoutanov/getting-started-with-istio-423j</link>
      <guid>https://forem.com/ekoutanov/getting-started-with-istio-423j</guid>
      <description>&lt;p&gt;The last few years have brought about immense changes in the software architecture landscape. A major shift that we have all witnessed is the breakdown of large monolithic and coarse-grained applications into fine-grained deployment units called &lt;em&gt;microservices&lt;/em&gt;, communicating predominantly by way of synchronous REST and gRPC interfaces, as well as asynchronous events and message passing. The benefits of this architecture are numerous, but the drawbacks are equally evident. Aspects of software development that used to be straightforward in the 'old world', such as debugging, profiling and performance management, are now an order of magnitude more complex. Also, a microservices architecture brings its own unique challenges. Services are more fluid and elastic, and tracking of their instances, their versions and dependencies is a Herculean challenge that balloons in complexity as the service landscape evolves. To top this off, services will fail in isolation, further exacerbated by unreliable networks. Given a large enough system, parts of it may be suffering a minor outage at any given point in time, potentially impacting a subset of users, quite often without the operator's awareness. With so many 'moving parts', how does one stay on top of these challenges and ensure the system is running smoothly without impacting the customer and driving the developers out of their wits?&lt;/p&gt;

&lt;p&gt;With the increased adoption of microservices, the industry has been steadily coming up with patterns and best-practices that have made the entire experience more palatable. &lt;em&gt;Resiliency Patterns&lt;/em&gt;, &lt;em&gt;Service Discovery&lt;/em&gt;, &lt;em&gt;Container Orchestration&lt;/em&gt;, &lt;em&gt;Canary Releases&lt;/em&gt;, &lt;em&gt;Observability Patterns&lt;/em&gt;, &lt;em&gt;BFF&lt;/em&gt;, &lt;em&gt;API Gateway&lt;/em&gt;... These are some of the concepts that practitioners will employ to build more robust and sustainable distributed systems. But these concepts are just that — abstract notions and patterns — they require &lt;em&gt;someone&lt;/em&gt; to implement them &lt;em&gt;somewhere&lt;/em&gt; in the system. More often than not, that 'someone' is &lt;em&gt;you&lt;/em&gt; and 'somewhere' is &lt;em&gt;everywhere&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/getting-started-with-istio-524628c025"&gt;Read the rest of the article on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>servicemesh</category>
      <category>istio</category>
    </item>
    <item>
      <title>Logging on the cheap</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Tue, 10 Dec 2019 01:26:55 +0000</pubDate>
      <link>https://forem.com/ekoutanov/logging-on-the-cheap-1km5</link>
      <guid>https://forem.com/ekoutanov/logging-on-the-cheap-1km5</guid>
      <description>&lt;p&gt;&lt;em&gt;To log or not to log?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Writing new code is a relatively small part of application development. A much larger part of a software engineer's life involves supporting and maintaining existing systems. First and foremost, this requires the right level of insight — understanding what exactly the system is doing, particularly when this isn't quite what you (and your customers) were expecting. Logging, tracing, remote debugging, and application performance monitoring are essential in attaining the level of observability required to comfortably operate and support a modern application suite.&lt;/p&gt;

&lt;p&gt;When building conventional applications, the question of whether an action should be logged or not is rarely a subject of rigorous debate. (By 'conventional', we mean most e-commerce applications with fairly routine non-functional requirements concerning throughput, latency, availability, and so forth.) Occasionally, we come across a class of applications that breaks that mould. Sometimes particular modules of an otherwise conventional system might be subject to very stringent constraints around their performance. An application might perform an expensive calculation in a tight loop, or it may be required to respond (on average) within a tight time frame. Invasive instrumentation of these applications changes their timing behaviour — even simple log calls carry an overhead that might cardinally impact the customer experience. In these sorts of scenarios, the question posed at the beginning of the article — &lt;em&gt;To log or not to log?&lt;/em&gt; — becomes a real point of debate. Do you sacrifice break-neck performance for observability, or is performance the coveted money-maker that dwarfs every other concern?&lt;/p&gt;




&lt;h1&gt;
  
  
  Introducing Zerolog?
&lt;/h1&gt;

&lt;p&gt;This article is going to explore &lt;a href="https://github.com/obsidiandynamics/zerolog"&gt;Zerolog&lt;/a&gt; (abbreviated to Zlg) — an ultra-low-overhead logging façade for performance-sensitive Java applications. The objectives of Zlg are twofold —&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ultra-low overhead for suppressed logging.&lt;/strong&gt; In other words, the cost of calling a log method when logging for that level has been disabled is negligible. Furthermore, it is possible to invoke Zlg in such a way as to reduce these costs to absolute zero.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uncompromised code coverage.&lt;/strong&gt; Suppression of logging should not impact statement and branch coverage metrics. A log entry is a statement like any other — if it's worth writing, it's worth testing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://itnext.io/logging-on-the-cheap-568674fa6387"&gt;Read the rest of the article on Medium.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>slf4j</category>
      <category>logging</category>
      <category>log4j</category>
    </item>
    <item>
      <title>Official Kafdrop Docker Image</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Mon, 11 Nov 2019 21:50:57 +0000</pubDate>
      <link>https://forem.com/ekoutanov/official-kafdrop-docker-image-4i43</link>
      <guid>https://forem.com/ekoutanov/official-kafdrop-docker-image-4i43</guid>
      <description>&lt;p&gt;In case you were wondering, &lt;a href="https://github.com/obsidiandynamics/kafdrop"&gt;Kafdrop&lt;/a&gt; has an &lt;a href="https://hub.docker.com/r/obsidiandynamics/kafdrop"&gt;official Docker image&lt;/a&gt;. Which is great; it means you don't have to clone the repo, mess around with Maven builds or even install the JVM. &lt;/p&gt;

&lt;p&gt;Docker images are updated automatically with each release build of Kafdrop, courtesy of the public Travis build pipeline. The &lt;code&gt;latest&lt;/code&gt; tag on DockerHub always points to the most recent stable build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;To run Kafdrop, run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:9000 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_BROKERCONNECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host:port,host:port &lt;span class="se"&gt;\&lt;/span&gt;
    obsidiandynamics/kafdrop:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;host:port,host:port&lt;/code&gt; with the bootstrap list of Kafka host/port pairs. Once the container boots up, navigate to &lt;a href="http://localhost:9000"&gt;localhost:9000&lt;/a&gt; in your browser. You should see the Kafdrop landing screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FJC8MMTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1760/0%2ALGCqvYOmcxb8pEm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FJC8MMTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1760/0%2ALGCqvYOmcxb8pEm5.png" alt="Kafdrop – Kafka Web UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hey there!&lt;/strong&gt; We hope you really like Kafdrop! Please take a moment to &lt;a href="https://github.com/obsidiandynamics/kafdrop/stargazers"&gt;⭐&lt;/a&gt; the repo or &lt;a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fobsidiandynamics%2Fkafdrop&amp;amp;text=Get%20Kafdrop%20%E2%80%94%20a%20web-based%20UI%20for%20viewing%20%23ApacheKafka%20topics%20and%20browsing%20consumers%20"&gt;Tweet&lt;/a&gt; about it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;The Kafdrop Docker image is configured by simply passing in environment variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;KAFKA_BROKERCONNECT&lt;/code&gt;: Bootstrap list of Kafka host/port pairs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JVM_OPTS&lt;/code&gt;: JVM options.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JMX_PORT&lt;/code&gt;: Port to use for JMX. No default; if unspecified, JMX will not be exposed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HOST&lt;/code&gt;: The hostname to report for the RMI registry (used for JMX). Default: &lt;code&gt;localhost&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SERVER_PORT&lt;/code&gt;: The web server port to listen on. Default: &lt;code&gt;9000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SERVER_SERVLET_CONTEXTPATH&lt;/code&gt;: The context path to serve requests on (must end with a &lt;code&gt;/&lt;/code&gt;). Default: &lt;code&gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;KAFKA_PROPERTIES&lt;/code&gt;: Additional properties to configure the broker connection (base-64 encoded).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;KAFKA_TRUSTSTORE&lt;/code&gt;: Certificate for broker authentication (base-64 encoded). Required for TLS/SSL.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;KAFKA_KEYSTORE&lt;/code&gt;: Private key for mutual TLS authentication (base-64 encoded).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Connecting to a secure cluster
&lt;/h3&gt;

&lt;p&gt;Need to connect to a secure Kafka cluster? No problem; Kafdrop supports TLS (SSL) and SASL connections for &lt;a href="http://kafka.apache.org/090/documentation.html#security"&gt;encryption and authentication&lt;/a&gt;. This can be configured by providing a combination of the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Truststore&lt;/strong&gt;: specifying the certificate for authenticating brokers, if TLS is enabled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keystore&lt;/strong&gt;: specifying the private key to authenticate the client to the broker, if mutual TLS authentication is required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Properties file&lt;/strong&gt;: specifying the necessary configuration, including key/truststore passwords, cipher suites, enabled TLS protocol versions, username/password pairs, etc. When supplying the truststore and/or keystore files, the &lt;code&gt;ssl.truststore.location&lt;/code&gt; and &lt;code&gt;ssl.keystore.location&lt;/code&gt; properties will be assigned automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These files are supplied in base-64-encoded form via environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:9000 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_BROKERCONNECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host:port,host:port &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_PROPERTIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.properties | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_TRUSTSTORE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.truststore.jks | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;  &lt;span class="c"&gt;# optional&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_KEYSTORE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.keystore.jks | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;      &lt;span class="c"&gt;# optional&lt;/span&gt;
    obsidiandynamics/kafdrop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Kafdrop in Kubernetes
&lt;/h3&gt;

&lt;p&gt;You can also launch Kafdrop in Kubernetes with the aid of Helm chart.&lt;/p&gt;

&lt;p&gt;Clone the repository (if necessary):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/obsidiandynamics/kafdrop &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;kafdrop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Install (or upgrade) the chart. Replace &lt;code&gt;3.x.x&lt;/code&gt; with the &lt;a href="https://github.com/obsidiandynamics/kafdrop/releases"&gt;latest stable release&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade &lt;span class="nt"&gt;-i&lt;/span&gt; kafdrop chart &lt;span class="nt"&gt;--set&lt;/span&gt; image.tag&lt;span class="o"&gt;=&lt;/span&gt;3.x.x &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; kafka.brokerConnect&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;host:port,host:port&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; kafka.properties&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.properties | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; kafka.truststore&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.truststore.jks | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; kafka.keystore&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;kafka.keystore.jks | &lt;span class="nb"&gt;base64&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A list of settable values can be found in &lt;a href="https://github.com/obsidiandynamics/kafdrop/blob/master/chart/values.yaml"&gt;values.yaml&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;I'm one of the maintainers of &lt;a href="https://github.com/obsidiandynamics/kafdrop"&gt;Kafdrop&lt;/a&gt; and a bit of a Kafka enthusiast. I'm also an avid crusader for microservices and event-driven architecture. If you're interested in these topics, or just have a question to ask, &lt;a href="https://twitter.com/i/user/562466177"&gt;grab me on Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kafka</category>
      <category>kafdrop</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Kafka Gotchas – The Must-Know</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Mon, 04 Nov 2019 03:51:02 +0000</pubDate>
      <link>https://forem.com/ekoutanov/kafka-gotchas-good-but-far-from-perfect-2jcj</link>
      <guid>https://forem.com/ekoutanov/kafka-gotchas-good-but-far-from-perfect-2jcj</guid>
      <description>&lt;p&gt;I've assisted several large clients in building a microservices-style architecture using Kafka as a messaging backbone, having a reasonably good understanding of its abilities and the use cases that really bring them out. But I'm not a Kafka apologist by any stretch; any technology that has gone through such a rapid adoption curve is bound to polarise its audience and rub certain developers up a wrong way, and Kafka is no exception. Like anything else, you need to invest a significant amount of time in getting across Kafka and event streaming in general, before you become fully proficient and can harness its might. And be prepared to face one or two frustrations, to put it mildly, along the way.&lt;/p&gt;

&lt;p&gt;I've compiled a list of shortcomings that may cause developer frustration, or catch out unsuspecting first-timers. In no particular order:&lt;/p&gt;

&lt;h1&gt;
  
  
  Too many tunable knobs
&lt;/h1&gt;

&lt;p&gt;The number of &lt;a href="https://kafka.apache.org/documentation/#configuration"&gt;configuration parameters&lt;/a&gt; in Kafka can be overwhelming, not just for newcomers but also seasoned pros. Possibly with the sole exception of the JVM, I cannot think of another technology that has this many configuration parameters. This isn't to say that the config options aren't necessary; but one does wonder how many of those parameters could instead be replaced by ergonomics, much like Java did with G1. So rather than specifying a plethora of individual thresholds and tolerances, let the operator set a performance target, and have the system derive an optimal set of values that best meet this target.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itnext.io/kafka-gotchas-24b51cc8d44e"&gt;Read the rest of the story on Medium.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>microservices</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>Introduction to Event Streaming with Kafka and Kafdrop</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Sun, 03 Nov 2019 08:12:10 +0000</pubDate>
      <link>https://forem.com/ekoutanov/introduction-to-event-streaming-with-kafka-and-kafdrop-38n1</link>
      <guid>https://forem.com/ekoutanov/introduction-to-event-streaming-with-kafka-and-kafdrop-38n1</guid>
      <description>&lt;p&gt;Event sourcing, eventual consistency, microservices, CQRS... These are quickly becoming household names in mainstream application development. But do you know what makes them tick? What are the basic building blocks required to assemble complex, business-centric applications from fine-grained services without turning the lot into a big ball of mud?&lt;/p&gt;

&lt;p&gt;This article examines a fundamental building block — &lt;strong&gt;event streaming&lt;/strong&gt;. Leading the charge will be &lt;a href="https://kafka.apache.org"&gt;Apache Kafka&lt;/a&gt; — the &lt;em&gt;de facto&lt;/em&gt; standard in event streaming platforms, which we'll observe through &lt;a href="https://github.com/obsidiandynamics/kafdrop"&gt;Kafdrop&lt;/a&gt; — a feature-packed web UI.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Brief Intro
&lt;/h1&gt;

&lt;p&gt;Event streaming platforms reside in the broader class of Message-oriented Middleware (MoM) and are similar to traditional message queues and topics, but offer stronger temporal guarantees and typically order-of-magnitude performance gains due to &lt;strong&gt;log-structured immutability&lt;/strong&gt;. In simple terms, write operations are mostly limited to sequential appends, which make them fast. &lt;em&gt;Really fast.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/introduction-to-event-streaming-with-kafka-and-kafdrop-22afdb4b380a"&gt;Read the rest of the article on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>eventstreaming</category>
      <category>microservices</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>Kafdrop - An Open-Source Kafka Web UI</title>
      <dc:creator>Emil Koutanov</dc:creator>
      <pubDate>Tue, 22 Oct 2019 10:10:22 +0000</pubDate>
      <link>https://forem.com/ekoutanov/kafdrop-an-open-source-kafka-web-ui-mbn</link>
      <guid>https://forem.com/ekoutanov/kafdrop-an-open-source-kafka-web-ui-mbn</guid>
      <description>&lt;p&gt;As a messaging platform, Kafka needs no introduction. Since its inception, it has virtually rewritten the book on event streaming and has catalysed the adoption of the now household design patterns — microservices, event-sourcing and CQRS.&lt;/p&gt;

&lt;p&gt;Being such a godsend, it &lt;em&gt;almost&lt;/em&gt; gets away with its notorious lack of tooling. You'd be hard-pressed to find a developer who hasn't at one time looked at the built-in CLI tools, cupped their face and uttered: &lt;em&gt;"Is this it? Are you kidding me?"&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Out There
&lt;/h1&gt;

&lt;p&gt;With the popularity of Kafka, it's no surprise that several commercial vendors have jumped on the opportunity to monetise Kafka's lack of tooling by offering their own. &lt;em&gt;Kafka Tool&lt;/em&gt;, &lt;em&gt;Landoop&lt;/em&gt; and &lt;em&gt;KaDeck&lt;/em&gt; are some examples, but they're all for personal use only unless you're willing to pay. (And it's not to say that you shouldn't, but that's rather beside the point.) Any non-trivial use in a commercial setting would be a violation of their licensing terms. It's one thing using them at home for tutorials or personal projects; when you're using a commercial tool without the appropriate license, you are putting your employer at risk of litigation and playing Russian Roulette with your career.&lt;/p&gt;

&lt;p&gt;But what about open source?&lt;/p&gt;

&lt;p&gt;When it comes to Kafka topic viewers and web UIs, the go-to &lt;em&gt;open-source&lt;/em&gt; tool is &lt;a href="https://github.com/obsidiandynamics/kafdrop" rel="noopener noreferrer"&gt;Kafdrop&lt;/a&gt;. With 900K Docker pulls at the time of writing, I don't believe there are many other Kafka tools that have enjoyed this level of adoption. Kafdrop lets you view topic contents, browse consumer groups, view consumer lag, topic configuration, broker stats, and one or two other things. All in all, it does an amazing job of filling the apparent gaps in the observability tooling of Kafka, solving problems that the community has been pointing out for too long.&lt;/p&gt;

&lt;p&gt;Kafdrop is an Apache 2.0 licensed project, like Apache Kafka itself. So it's won't cost you a penny. If you haven't used it yet, you probably ought to. So let's take a deeper look.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;The Kafdrop web UI project is hosted on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/obsidiandynamics" rel="noopener noreferrer"&gt;
        obsidiandynamics
      &lt;/a&gt; / &lt;a href="https://github.com/obsidiandynamics/kafdrop" rel="noopener noreferrer"&gt;
        kafdrop
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kafka Web UI
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/wiki/obsidiandynamics/kafdrop/images/kafdrop-logo.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiki%2Fobsidiandynamics%2Fkafdrop%2Fimages%2Fkafdrop-logo.png" width="90px" alt="logo"&gt;&lt;/a&gt; Kafdrop – Kafka Web UI   &lt;a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fobsidiandynamics%2Fkafdrop&amp;amp;text=Get%20Kafdrop%20%E2%80%94%20a%20web-based%20UI%20for%20viewing%20%23ApacheKafka%20topics%20and%20browsing%20consumers%20" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4f677ce944dfdeb7a8cd741560d35d006363ef6160adeb63ee3d8c73373b1f51/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f75726c2f687474702f736869656c64732e696f2e7376673f7374796c653d736f6369616c" alt="Tweet"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/obsidiandynamics/kafdrop/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eb89d254912231697038ef31a83e262f93b6206783b8c407f1e3dfe8cd9606fa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f70726963652d465245452d3030393866372e737667" alt="Price"&gt;&lt;/a&gt;
&lt;a href="https://github.com/obsidiandynamics/kafdrop/actions/workflows/master.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/obsidiandynamics/kafdrop/actions/workflows/master.yml/badge.svg" alt="Release with mvn"&gt;&lt;/a&gt;
&lt;a href="https://hub.docker.com/r/obsidiandynamics/kafdrop" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d226ca9dc86b3a8012cd320544fd9da1f883721a3b675ee5d62ac74f7c331fc8/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f70756c6c732f6f6273696469616e64796e616d6963732f6b616664726f702e737667" alt="Docker"&gt;&lt;/a&gt;
&lt;a href="https://lgtm.com/projects/g/obsidiandynamics/kafdrop/context:java" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/119d9a3de8db106720ac164820b91f9fd56e9ae3f5ed9a60d05e2cdad0e79aac/68747470733a2f2f696d672e736869656c64732e696f2f6c67746d2f67726164652f6a6176612f672f6f6273696469616e64796e616d6963732f6b616664726f702e7376673f6c6f676f3d6c67746d266c6f676f57696474683d3138" alt="Language grade: Java"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Kafdrop is a web UI for viewing Kafka topics and browsing consumer groups.&lt;/em&gt; The tool displays information such as brokers, topics, partitions, consumers, and lets you view messages.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/obsidiandynamics/kafdropdocs/images/overview.png?raw=true"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fobsidiandynamics%2Fkafdropdocs%2Fimages%2Foverview.png%3Fraw%3Dtrue" alt="Overview Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This project is a reboot of Kafdrop 2.x, dragged kicking and screaming into the world of Java 17+, Kafka 2.x, Helm and Kubernetes. It's a lightweight application that runs on Spring Boot and is dead-easy to configure, supporting SASL and TLS-secured brokers.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Features&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;View Kafka brokers&lt;/strong&gt; — topic and partition assignments, and controller status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View topics&lt;/strong&gt; — partition count, replication status, and custom configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse messages&lt;/strong&gt; — JSON, plain text, Avro and Protobuf encoding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View consumer groups&lt;/strong&gt; — per-partition parked offsets, combined and per-partition lag&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create new topics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;View ACLs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support for Azure Event Hubs&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Requirements&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Java 17 or newer&lt;/li&gt;
&lt;li&gt;Kafka (version 0.11.0 or newer) or Azure Event Hubs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Optional, additional integration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Schema Registry&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Getting Started&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;You…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/obsidiandynamics/kafdrop" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;There's a couple of options at your disposal. You could show a little bravery by &lt;a href="https://github.com/obsidiandynamics/kafdrop" rel="noopener noreferrer"&gt;cloning the repository&lt;/a&gt; and building from source. It's a Java (JDK 11) SpringBoot project, and you can build it with a single Maven command, providing you have the JDK installed. If you want to go down this path, the repo's &lt;code&gt;README.md&lt;/code&gt; file will guide you through the steps. For now, let's take the easy way — Docker. (I sure would.)&lt;/p&gt;

&lt;p&gt;Docker images are &lt;a href="https://hub.docker.com/r/obsidiandynamics/kafdrop" rel="noopener noreferrer"&gt;hosted on DockerHub&lt;/a&gt;. Images are tagged with the &lt;a href="https://github.com/obsidiandynamics/kafdrop/releases" rel="noopener noreferrer"&gt;Kafdrop release number&lt;/a&gt;. The &lt;code&gt;latest&lt;/code&gt; tag points to the latest stable release. &lt;/p&gt;

&lt;p&gt;To launch the container in the background, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:9000 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KAFKA_BROKERCONNECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;host:port,host:port&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    obsidiandynamics/kafdrop


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;KAFKA_BROKERCONNECT&lt;/code&gt; environment variable must be set to the bootstrap list of brokers.&lt;/p&gt;

&lt;p&gt;That's it. We should be up and running. Once it starts, you can launch the Kafka web UI by navigating to &lt;a href="http://localhost:9000" rel="noopener noreferrer"&gt;localhost:9000&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The above example assumes an authenticated connection over a plaintext TCP socket. If your cluster is configured to use authentication and/or transport-level encryption, consult the &lt;code&gt;README.md&lt;/code&gt; for connection options. It's actually surprisingly easy to configure Kafdrop for a SASL/SSL locked-down cluster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Navigating the Kafka Web UI
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Browsing the Cluster
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Cluster Overview&lt;/strong&gt; screen is the landing page of the web UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2312%2F1%2AVdMHg_A9svbBho790n06zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2312%2F1%2AVdMHg_A9svbBho790n06zg.png" alt="Cluster Overview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You get to see the overall layout of the cluster — the individual brokers that make it up, their addresses and some key broker stats — whether they are a controller and the number of partitions each broker owns. The latter is quite important — as your cluster size and the number of topics (and therefore partitions) grows, you generally want to see an approximately level distribution of partitions across the cluster.&lt;/p&gt;

&lt;p&gt;Next is the &lt;strong&gt;Topics List&lt;/strong&gt;, which in most cases is what you're really here for. Any reasonably-sized microservices-based ecosystem might have hundreds, if not thousands of topics. As you'd expect, the list is searchable. The stats displayed alongside each topic are fairly ho-hum. The one worth noting is the &lt;em&gt;under-replicated&lt;/em&gt; column. Essentially, it's telling us the number of partition replicas that have fallen behind the primary. Zero is a good figure. Anything else is indicative of either a broker or a network issue that requires immediate attention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Kafdrop is a discovery exploration tool; it is not a real-time monitoring tool. You should instrument your brokers and raise alerts when things go awry.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Listing Topics
&lt;/h2&gt;

&lt;p&gt;Click on a topic in the list to get to the &lt;strong&gt;Topic Overview&lt;/strong&gt; screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2Fdownload%2FIgU5L1o" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2Fdownload%2FIgU5L1o" alt="Topic Overview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screen is subdivided into four sections.&lt;/p&gt;

&lt;p&gt;On the top-left, there is a summary of the topic stats — a handy view, not dissimilar to what you would have seen in the cluster overview.&lt;/p&gt;

&lt;p&gt;On the top-right, you can view the custom configuration. In the example above, the topic runs a stock-standard config, so there's nothing to see. Had the configuration been overridden, you'd see a set of custom values like in the example below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2608%2F1%2A6WtxyvpqH-GovRROVtOqGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2608%2F1%2A6WtxyvpqH-GovRROVtOqGg.png" alt="Custom Topic Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The bottom-left section enumerates over the partitions. The partition indexes are links — clicking through will reveal the first 100 messages in the topic.&lt;/p&gt;

&lt;p&gt;There are several interesting parameters displayed in this section:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First offset&lt;/td&gt;
&lt;td&gt;Also known as the low-water mark, this is the offset of the first retained message, or the high-water mark if the partition is currently void of messages. The first offset is monotonically non-decreasing with respect to any write (and by implication, read) operation that may be performed on the partition, including publishing of messages and the routine purge and compaction operations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Last offset&lt;/td&gt;
&lt;td&gt;The offset that will be assigned to the next message. (This is also known as the high-water mark.) Akin to the first offset, the last offset is monotonically non-decreasing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;The quantity of retained messages within the partition.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leader Node&lt;/td&gt;
&lt;td&gt;The ID of the current leader node.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replica Nodes&lt;/td&gt;
&lt;td&gt;The broker IDs that have been assigned a replica of the partition. This set includes the leader node.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In-sync Replica Nodes&lt;/td&gt;
&lt;td&gt;A subset of the replica nodes that only includes in-sync nodes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline Replica Nodes&lt;/td&gt;
&lt;td&gt;A subset of the replica nodes that only includes offline brokers. Anything other than an empty set suggests an issue with the broker nodes or the network, and requires urgent attention.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preferred Leader&lt;/td&gt;
&lt;td&gt;A yes/no value, indicating whether the current leader is configured as the preferred leader.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Under-replicated&lt;/td&gt;
&lt;td&gt;A yes/no value, indicating that one or more replica nodes has fallen behind the primary. Under normal circumstances there should be no under-replicated partitions.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;consumers&lt;/strong&gt; section on the bottom-right lists the consumer group names as well as their aggregate lag (the sum of all individual partition lags).&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Consumer Groups
&lt;/h2&gt;

&lt;p&gt;Clicking on the consumer group on the Topic Overview gets you into the &lt;strong&gt;Consumer View&lt;/strong&gt;. This screen provides a comprehensive breakdown of a single consumer group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2244%2F1%2Av_yaBhKr44Js4phjwqHfCw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2244%2F1%2Av_yaBhKr44Js4phjwqHfCw.png" alt="Consumer View"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The view is sectioned by topic. For each topic, a separate table lists the underlying partitions. Against each partition, we see the committed offset, which we can compare against the first and last offsets to see how our consumer is tracking. Conveniently, Kafdrop displays the computed lag for each partition, which is aggregated at the footer of each topic table.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Some amount of lag is unavoidable. For every message published, there will invariably be a quantum of time between the point of publishing and the point of consumption. In Kafka, this period is usually in the order of tens or hundreds of milliseconds, depending on both the producer and consumer client options, network configuration, broker I/O capabilities, the size of the pagecache and a myriad of other factors. What you need to look out for is &lt;em&gt;growing lag&lt;/em&gt; — suggesting that the consumer is either unable to keep up or has stalled altogether. In the latter case, you'll also notice that the lag isn't being depleted even when the producer is idling. This is when you'll need to ALT-TAB away from Kafdrop into your favourite debugger.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Viewing Messages
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Message View&lt;/strong&gt; screen is the coveted topic viewer that has in all likelihood brought you here. You can get to the message view in one of two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click the &lt;strong&gt;View Messages&lt;/strong&gt; button in the Topic Overview screen.&lt;/li&gt;
&lt;li&gt;Click the individual partition link in the Topic Overview.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2272%2F1%2AEaTHQlFTaNghuODuHE7rdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2272%2F1%2AEaTHQlFTaNghuODuHE7rdw.png" alt="Message Viewer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's exactly what you'd expect — a chronologically-ordered list of messages (or &lt;em&gt;records&lt;/em&gt;, in Kafka parlance) for a chosen partition.&lt;/p&gt;

&lt;p&gt;Each entry conveniently displays the offset, the record key (if one is set), the timestamp of publication, and any headers that may have been appended by the producer.&lt;/p&gt;

&lt;p&gt;There's another little trick up Kafdrop's sleeve. If the message happens to be a valid JSON document, the topic viewer can nicely format it. Click on the green arrow on the left of the message to expand it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1726%2F1%2ACK1W-ulb_d81R8J0h2Aa_A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1726%2F1%2ACK1W-ulb_d81R8J0h2Aa_A.png" alt="JSON-formatted message view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;The more you use Kafka, the more you come to discover and appreciate its true potential — not just as a versatile event streaming platform, but as a general-purpose messaging middleware that lets you assemble complex business systems from asynchronous, loosely coupled services. &lt;/p&gt;

&lt;p&gt;You'll invariably experience the frustrations that are to be expected from a technology that has only recently entered the mainstream, by comparison with the more mature MQ brokers of yore. What's reassuring is that the Open Source community hasn't stood still, producing an evolving ecosystem, complete with the documentation and tooling necessary for us to get on with our jobs. The least we can do in return is raise a pull request once in a while or maybe answer a StackOverflow question or three.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Was this article useful to you? Take a moment to bookmark it, so others might spot it too. I'd love to hear your feedback, so don't hold back! If you are interested in Kafka or event streaming, or just have any questions, &lt;a href="https://twitter.com/i/user/562466177" rel="noopener noreferrer"&gt;follow me on Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>eventdriven</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
