Apache Kafka – zjištění údajů o konzumentovi

Při asynchroním posílání zpráv je občas důležité vědět, kolik zpráv bylo přijato, kolik zpráv ještě čeká na zpracování atd. Pokud navážu na předchozí příspěvek, kde jsme si vytvořili test-topic a poslali do něj několik zpráv, můžeme k tomuto účelu použít script bin/kafka-consumer-groups.sh. Ten nám zobrazí údaje pro určitou consumer group. Konzumentská skupina (consumer group) sdružuje konzumenty (consumers).

Konzumenta, který patří do určité skupiny vytvoříte pomocí volby --group

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test-topic --group test-group --from-beginning

Pokud pošlete do tématu (topic) několik zpráv a zavoláte skript, uvidíte základní údaje. Bylo posláno pět zpráv a všechny byly zkonzumovány.

Číst dálApache Kafka – zjištění údajů o konzumentovi

Základy Apache Kafky

Apache Kafka se používá pro asynchronní posílání zpráv. V tomto příspěvku ukáži instalaci na Linux a základní práci – vytvoření téma (topic) a posílání a přijímání zpráv.

Stáhněte si Kafku a rozbalte stažený soubor (tar -xzf kafka_verze.tgz). Přesuňte se do rozbaleného adresáře. Všechny důležité skripty naleznete v adresáři bin.

Kafka používá ZooKeeper. To je služba, která udržuje informace o konfiguraci v distribuovaném prostředí. Nejdříve je tedy potřeba spustit ZooKeeper server.

bin/zookeeper-server-start.sh config/zookeeper.properties

Číst dálZáklady Apache Kafky

Funkce groupBy v Kotlinu

Kotliní standardní klihovna nabízí funkce pro groupování elementů kolekcí. Základní groupBy() funkce přijímá lambdu a vrací mapu. V této mapě je každý klíč (key) výsledkem lambda funkce a hodnota (value) je seznam elementů z kolekce podle daného klíče.

    val names = listOf("Petr", "Jan", "Marie", "Matouš", "Petra", "Soňa", "Patricie")

    println(names.groupBy { it.first() })
    println(names.groupBy(keySelector = { it.first() }))
    // {P=[Petr, Petra, Patricie], J=[Jan], M=[Marie, Matouš], S=[Soňa]}

    println(names.groupBy { it.length })
    println(names.groupBy(keySelector = { it.length }))
    // {4=[Petr, Soňa], 3=[Jan], 5=[Marie, Petra], 6=[Matouš], 8=[Patricie]}

    println(names.groupBy(keySelector = { it.length }, valueTransform = { it.toUpperCase() }))
    // {4=[PETR, SOŇA], 3=[JAN], 5=[MARIE, PETRA], 6=[MATOUŠ], 8=[PATRICIE]}

    println(names.groupBy(keySelector = { it.substring(0, 2) }, valueTransform = { if (it.length == 4) it.toUpperCase() else it.toLowerCase() }))
    // {Pe=[PETR, petra], Ja=[jan], Ma=[marie, matouš], So=[SOŇA], Pa=[patricie]}

Číst dálFunkce groupBy v Kotlinu

Redis health check

Většinou není problém s připojením k redis databázi. Ani když používáte docker image a contejner s redisem zastavíte. Po jeho spuštění se aplikace zase korektně připojí do redis databáze. Měl jsem ale problém v případě kubernetu, kdy po znovu nasazení a spuštění docker kontejneru s redisem se aplikace nemohla sama připojit. Řešením bylo udělat health actuator a v případě, že je down, aplikaci restartovat. Jako klienta používám redisson.

import org.redisson.api.RedissonClient
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.actuate.health.Health
import org.springframework.boot.actuate.health.ReactiveHealthIndicator
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono

@Component
class RedisHealthChecker : ReactiveHealthIndicator {
    private val log = LoggerFactory.getLogger(RedisHealthChecker::class.java)

    @Autowired
    lateinit var redissonClient: RedissonClient

    override fun health(): Mono {
        return try {
            val bucket = redissonClient.getBucket("healthBucket")
            bucket.set("Ok")
            Mono.just(Health.Builder().up().build())
        } catch (e: Exception) {
            log.error("Error in redis connection", e)
            Mono.just(Health.Builder().down().build())
        }
    }
}

Užitečné příkazy psql

Připojení k databázi
psql -d databáze -U uživatel (připojí se do postgres databáze pod uživatelem)
psql -U uživatel -h url -p port (připojí se do postgres databáze, která je na url a portu pod uživatelem)

Pokud jste připojeni
\l (zobrazí seznam databází)
\c databáze (přepne se do databáze)
\c databáze uživatel (přepne se do databáze pod uživatelem)
\d (zobrazí seznam všech tabulek a sekvencí v dané databázi)
\dt (zobrazí seznam všech tabulek v dané databázi)
\ds (zobrazí seznam všech sekvencí v dané databázi)
\dn (zobrazí seznam schémat v dané databázi)
\df (zobrazí seznam funkcí v dané databázi)
\dv (zobrazí seznam views v dané databázi)
\du (zobrazí seznam uživatelů v dané databázi)
\d tabulka (zobrazí informace o dané tabulce)
\d sekvence (zobrazí informace o dané sekvenci)
\e (umožní vám zvolit editor pro psaní příkazu)

Nápověda
\? (zobrazí seznam psql příkazů)

Číst dálUžitečné příkazy psql

Weblux swagger pomocí springfox

Swagger je nástroj (knihovna), který umožňuje dokumentovat REST endpointy vaší aplikace. Dobré je to například pro vývoj, kdy konzument (např. vývojář frontendu) ví, jaké jsou aktuálně k dispozici endpointy, jaké mají vstupy a jaké objekty vrací. Jak zprovoznit swagger v projektu, který používá WebFlux a Spring Boot ukáži v tomto příspěvku.

Pokud máte projekt a používáte pro restové služby framework WebFlux a Spring Boot, je zprovoznění Swaggeru jednoduché. Stačí přidat následující závislosti (používám Gradle a Kotlin):

implementation("io.springfox:springfox-swagger2:3.0.0-SNAPSHOT")
implementation("io.springfox:springfox-swagger-ui:3.0.0-SNAPSHOT")
implementation("io.springfox:springfox-spring-webflux:3.0.0-SNAPSHOT")

a vytvořit konfigurační třídu pro Swagger:

Číst dálWeblux swagger pomocí springfox

Kotlin let není if

Konstrukce ?.let {} ?: run {} se sice používá jakoby místo if - else, ale není s ní zaměnitelná. Pokud máte nullable objekt, použitím ?.let {} zpracujete případ, kdy je not null a ?: run {} v případě, že je null. Dalo by se říct, klasické if – else. Níže je ukázka. Vytvoříme outer a inner mapu, inicializujeme jí a pak máme dva bloky. První s if – else a druhý s ?.let a ?: run. V blocích jde o to, že nejdříve se zkusí vytáhnout hodnota pro klíč z outer mapy a pokud je hodnota nalezena, totéž proběhne pro inner mapu.

Číst dálKotlin let není if

Změna velikosti swap v Ubuntu

Od Ubuntu verze 17.04 byla swap partition nahrazena swap souborem. To znamená, že velikost swap lze jednoduše měnit. Swap je místo na disku, které může operační systém použít jako další RAM (pokud nemá dostatek RAM, uloží si data na swap). To zda máte (a jak velký) swap nastaven zjistíte příkazem swapon. Pokud je výstup příkazu prázdný, swap nemáte zapnutý.

sudo swapon
NAME TYPE SIZE USED PRIO
/swapfile file 4G 512K -2

Swap vypnete příkazem swapoff.

sudo swapoff -a

Číst dálZměna velikosti swap v Ubuntu

Redis databáze

Redis databáze (jedna instance Redisu) by se měly používat pro oddělení různých klíčů patřících stejné aplikaci a nikoliv pro různé klíče různých aplikací.

Počet databází v Redisu je uveden v konfiguračním souboru /etc/redis/redis.conf.

# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT  where
# dbid is a number between 0 and 'databases'-1
databases 16

V redis-cli tento údaj můžete získat příkazem

127.0.0.1:6378> config get databases
1) "databases"
2) "16"

Číst dálRedis databáze

Získání klíčů Redis databáze

Pro získání klíčů v rámci Redisu při použítí redis-cli existuje příkaz KEYS pattern. Pokud chcete všechny klíče použijete KEYS *, pokud pouze klíče začínající na ‚my‘ použijete KEYS my*. Typ hodnoty klíče zjistíte příkazem TYPE nazev-klice.

Dokumentace nedoporučuje používat KEYS v produkční databázi nebo u velkých databází, neboť KEYS vrací všechny klíče a to může mít vliv na výkonnost. Místo KEYS se doporučuje použití SCAN. Scan vrací na každý dotaz jen omezené množství záznamů a požaduje cursor (ukazatel). V rámci odpovědi vrací nalezené klíče a další ukazatel. Dokud není vrácený ukazatel rovný 0, stále existují klíče, které ještě nebyly vráceny. Výchozí nastavení pro scan vrací 10 záznamů. To možné změnit volbou COUNT.

Číst dálZískání klíčů Redis databáze