» Go:使用Kafka构建事件驱动微服务 » 5. 部署 » 5.2 Docker Compose

Docker Compose

Docker Compose 是一个用于定义和运行多容器的 Docker 工具。它允许你使用 YAML 文件配置应用程序的服务、网络和卷,然后使用单个命令启动所有运行所需的容器,包括应用程序的依赖中间件和服务。

注意

安装 Docker Compose 最方便最推荐的方式是安装 Docker 桌面版。Docker 桌面版包含了 Docker 引擎,Docker CLI 和 Docker Compose。
按需安装 Compose:https://docs.docker.com/compose/install/

添加 compose/docker-compose.yml:

services:
  lr-event-books-web:
    build:
      context: ../
      dockerfile: service/web/Dockerfile
    ports:
      - 8080:8080
    volumes:
      - ./config-web.yml:/home/.server/config.yml
    depends_on:
      mysql:
        condition: service_healthy
      kafka:
        condition: service_healthy
  lr-event-books-trend:
    build:
      context: ../
      dockerfile: service/trend/Dockerfile
    ports:
      - 8081:8081
    volumes:
      - ./config-trend.yml:/home/.server/config.yml
    depends_on:
      redis:
        condition: service_started
      kafka:
        condition: service_healthy
  lr-event-books-rec:
    build:
      context: ../
      dockerfile: service/recommendation/Dockerfile
    ports:
      - 8082:8082
    volumes:
      - ./config-rec.yml:/home/.server/config.yml
    depends_on:
      mongo:
        condition: service_started
      kafka:
        condition: service_healthy
  redis:
    image: docker.io/bitnami/redis:7.0
    environment:
      - REDIS_PASSWORD=${REDIS_PASSWORD}
    ports:
      - 6379:6379
  mysql:
    image: docker.io/bitnami/mysql:5.7.43
    environment:
      - MYSQL_DATABASE=lr_book
      - MYSQL_USER=test_user
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    ports:
      - 3306:3306
    healthcheck:
      test:
        [
          "CMD",
          "mysqladmin",
          "ping",
          "-h",
          "localhost",
          "-u",
          "root",
          "-p$MYSQL_ROOT_PASSWORD",
        ]
      timeout: 20s
      retries: 10
    volumes:
      - ~/lr-mysql-data:/bitnami/mysql/data
  mongo:
    image: bitnami/mongodb:latest
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    ports:
      - 27017:27017
    volumes:
      - ~/lr-mongodb-data:/bitnami/mongodb
  kafka:
    image: bitnami/kafka:latest
    environment:
      - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
      - KAFKA_CFG_NODE_ID=0
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
    ports:
      - 9092:9092
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "kafka-topics.sh --list --bootstrap-server localhost:9092",
        ]
      interval: 10s
      timeout: 10s
      retries: 3

在 Docker Compose 中为 MySQL 和 Kafka 找到合适的 healthcheck test健康检查测试)很不容易。

添加 compose/config-web.yml:

app:
  port: 8080
  page_size: 5
  templates_pattern: "templates/*.html"
db:
  dsn: "test_user:test_pass@tcp(mysql:3306)/lr_event_book?charset=utf8mb4&parseTime=True&loc=Local"
mq:
  brokers:
    - kafka:9092
  topic: "lr-book-searches"
remote:
  trend_url: "http://lr-event-books-trend:8081/trends"
  rec_url: "http://lr-event-books-rec:8082/recommendations?uid="

你需要专供给 Docker Compose 的配置文件版本。因为在该环境里 host,路径,URL 等都变得不一样了。

添加 compose/config-trend.yml:

app:
  port: 8081
cache:
  address: redis:6379
  password: test_pass
  db: 0
mq:
  brokers:
    - kafka:9092
  topic: "lr-book-searches"
  group_id: "trend-svr"

添加 compose/config-rec.yml:

app:
  port: 8080
  page_size: 5
  templates_pattern: "templates/*.html"
db:
  dsn: "test_user:test_pass@tcp(mysql:3306)/lr_event_book?charset=utf8mb4&parseTime=True&loc=Local"
mq:
  brokers:
    - kafka:9092
  topic: "lr-book-searches"
remote:
  trend_url: "http://lr-event-books-trend:8081/trends"
  rec_url: "http://lr-event-books-rec:8082/recommendations?uid="

添加 compose/.env:

REDIS_PASSWORD=test_pass
MYSQL_PASSWORD=test_pass
MYSQL_ROOT_PASSWORD=test_root_pass

警醒: .env 文件应该被 .gitignore 设置成忽略。

变化内容,.gitignore:

@@ -21,3 +21,4 @@
 go.work
 
 bin/
+.env

运行所有服务:

cd compose
docker compose up

你将看到如下内容:

[+] Running 7/7
 ✔ Container compose-redis-1                 Created                                                                                                                                                                                    0.0s 
 ✔ Container compose-kafka-1                 Recreated                                                                                                                                                                                  0.1s 
 ✔ Container compose-mysql-1                 Recreated                                                                                                                                                                                  0.1s 
 ✔ Container compose-mongo-1                 Recreated                                                                                                                                                                                  0.1s 
 ✔ Container compose-lr-event-books-rec-1    Created                                                                                                                                                                                    0.1s 
 ✔ Container compose-lr-event-books-trend-1  Created                                                                                                                                                                                    0.1s 
 ✔ Container compose-lr-event-books-web-1    Created                                                                                                                                                                                    0.1s 
Attaching to kafka-1, lr-event-books-rec-1, lr-event-books-trend-1, lr-event-books-web-1, mongo-1, mysql-1, redis-1
kafka-1          | kafka 07:58:07.37 INFO  ==> 
kafka-1          | kafka 07:58:07.37 INFO  ==> Welcome to the Bitnami kafka container
...

redis-1          | redis 13:24:52.38 
redis-1          | redis 13:24:52.39 Welcome to the Bitnami redis container
...

mongo-1          | mongodb 13:24:52.60 INFO  ==> 
mongo-1          | mongodb 13:24:52.60 INFO  ==> Welcome to the Bitnami mongodb container
mongo-1          | mongodb 13:24:52.61 INFO  ==> ** Starting MongoDB setup **
...
mysql-1          | mysql 13:24:52.61 
mysql-1          | mysql 13:24:52.62 Welcome to the Bitnami mysql container
mysql-1          | mysql 13:24:52.63 INFO  ==> ** Starting MySQL setup **
...

你不再需要手动安装那些数据库。它们都被 docker compose 搞定了。
不过,你还是需要在你的 mysql docker 容器里确保 lr_event_book 库的存在。

CREATE DATABASE lr_event_book CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

放入测试图书,如果没有的话。

curl -X POST -H "Content-Type: application/json" -d '{"title": "To Kill a Mockingbird", "author": "Harper Lee", "published_at": "1960-07-11", "description": "A novel set in the American South during the 1930s, dealing with themes of racial injustice and moral growth."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "1984", "author": "George Orwell", "published_at": "1949-06-08", "description": "A dystopian novel depicting a totalitarian regime, surveillance, and propaganda."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Pride and Prejudice", "author": "Jane Austen", "published_at": "1813-01-28", "description": "A classic novel exploring the themes of love, reputation, and social class in Georgian England."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Catcher in the Rye", "author": "J.D. Salinger", "published_at": "1951-07-16", "description": "A novel narrated by a disaffected teenager, exploring themes of alienation and identity."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Lord of the Rings", "author": "J.R.R. Tolkien", "published_at": "1954-07-29", "description": "A high fantasy epic following the quest to destroy the One Ring and defeat the Dark Lord Sauron."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Moby-Dick", "author": "Herman Melville", "published_at": "1851-10-18", "description": "A novel exploring themes of obsession, revenge, and the nature of good and evil."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Hobbit", "author": "J.R.R. Tolkien", "published_at": "1937-09-21", "description": "A fantasy novel set in Middle-earth, following the adventure of Bilbo Baggins and the quest for treasure."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Adventures of Huckleberry Finn", "author": "Mark Twain", "published_at": "1884-12-10", "description": "A novel depicting the journey of a young boy and an escaped slave along the Mississippi River."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "War and Peace", "author": "Leo Tolstoy", "published_at": "1869-01-01", "description": "A novel depicting the Napoleonic era in Russia, exploring themes of love, war, and historical determinism."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Alice’s Adventures in Wonderland", "author": "Lewis Carroll", "published_at": "1865-11-26", "description": "A children’s novel featuring a young girl named Alice who falls into a fantastical world populated by peculiar creatures."}' http://localhost:8080/api/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Odyssey", "author": "Homer", "published_at": "8th Century BC", "description": "An ancient Greek epic poem attributed to Homer, detailing the journey of Odysseus after the Trojan War."}' http://localhost:8080/api/books

现在,如果你访问页面 http://localhost:8080/ ,你将看到 3 个微服务提供的所有功能。

用关键词”love“,”peace“和”Odyssey“等进行搜索,然后刷新页面,查看结果。

你的事件驱动微服务成功啦! 📢

上页下页