RAKUS Developers Blog

株式会社ラクスのエンジニアブログ

戦闘力53万風のマイクロサービス

f:id:Y-Kanoh:20180111033033j:plain

こんにちは!エンジニアのY-Kanohです。

弊社のエンジニアは、業務終了前にその日の稼働報告を社内システムに入力することになっています。 しかしながら、この入力を忘れるメンバー(主に私)が多く、チームのリーダーに指摘されてから、数日前の仕事状況を思い出して記入することが度々ありました...。(すみません。)

そこで、チームで導入されているチャットツール、「MatterMost」に稼働報告を忘れている人へ通知をするようにしてみました。

Mattermost Private Cloud Messaging

しかし、ただ作るだけではすぐ終わってしまったので、かねてから興味があったDockerを使ってマイクロサービスとして作り直しています。

今日はそのお話です。

概要

大雑把に言えば、作成したBotシステムは下図のようなイメージです。

f:id:Y-Kanoh:20180111024417p:plain

プログラムは毎朝始業直前に動かすようセットします。 稼働状況は社内のDBに登録されているので、まず社内DBを参照し、昨日の入力を忘れているメンバーを見つけ、チャットに通知します。

MatterMostには外部連携機能があり、外部システムからの投稿が可能です。*1

設計

概念図

最初は、「動けばいい」の信念のもと、上記図のBotシステムをそのまま1コンテナにしただけの設計でした。

マイクロサービスを目指すにあたり、そのコンテナ内容を機能ごとに分割し、以下のような設計で実装しています。*2

f:id:Y-Kanoh:20180111024243p:plain

作成したコンテナは以下の7つです。

  1. 管理用BFFコンテナ
  2. Bot用BFFコンテナ
  3. API Gatewayコンテナ
  4. API Gateway情報DBコンテナ
  5. 社内DBアクセス用コンテナ
  6. チーム情報DBアクセス用コンテナ
  7. チーム情報DBコンテナ

※社内DBには稼働情報、チームDBにはチームメンバー情報やチームが使用しているチャット情報が格納されています。

これらのコンテナ群は、大きくBFFAPI Gatewayバックエンドの三種類に分けることができます。

BFF

BFFとは、Backends for Frontendsの略で、つまりフロントエンドのためのバックエンドです。*3 *4

BFFは、クライアントの種類ごとに、クライアントとバックエンドの間で、データ加工や画面作成などの処理を行います。

BFFを使用することで、バックエンドから受け取ったデータを、各BFFが対象とするデバイスやユーザ向けに適した形に加工して表示させることができます。

API Gateway

機能を各コンテナに分けるうえで、一つ問題がありました。

コンテナ同士はやり取りする相手のコンテナ接続情報を知っておく必要があります。そのため、やり取りするコンテナを増やすたびに、接続先情報をそれぞれ定義する必要があるため、 コンテナ依存関係の定義が複雑になってしまいます。

そこで、今回はバックエンドのコンテナは、互いに通信せず、必ずAPI Gatewayを介してやり取りするようにしました。 これにより、以下のメリットが見込まれます。

  • APIを一元管理
  • コンテナ間の依存関係を簡略化
  • 共通処理を行う場合ここで実行可能
  • BFFからのサービス呼び出しを簡略化

バックエンドのAPIは、必ずAPI Gatewayを介して呼び出されます。Gatewayに来たリクエストは、Gatewayで適切なコンテナへルーティングされるため、Dockerコンテナで面倒なコンテナ同士の依存関係を定義する必要はなくなります。

また、今回は特に実装していませんが、バックエンドへの認証機能や、ログの収集なども、ここで一括して行うことができます。

今回、API Gatewayには、OSSとして開発が進められているKongを使用します。

Kong - Open-Source API Management and Microservice Management

バックエンド

BFF、API Gatewayの導入により、バックエンドはその他の機能とかなり疎結合になります。

フロント側に適したデータ形式に加工する必要が少ないため、設計の制約が減ります。

そこで、バックエンドのAPIは、RESTの原則に基づいた実装にしました。

docker-compose.yml

docker-compose.ymlは以下の通りです。

前述したAPI Gatewayにより、各コンテナはkongコンテナをlinkさせるだけでバックエンドのAPIが使用できます。

version: '2'
#==============================================================================
# Volumeの定義
#==============================================================================
volumes:
  team_vol:
    driver: 'local'
  kong_vol:
    driver: 'local'

#==============================================================================
# servicesの定義
#==============================================================================
services:
  #############################################################################
  ## API Gateway
  #############################################################################
  # API GatewayのDB
  kong-database:
    image: postgres:9.4
    environment:
      - POSTGRES_USER=kong
      - POSTGRES_DB=kong
    volumes:
            - kong_vol:/var/lib/postgresql/data

  # API Gatewayの初期設定を行うコンテナ
  kong-migration:
    image: kong
    depends_on:
      - kong-database
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
    command: kong migrations up

  # API Gatewayコンテナ
  kong:
    image: kong:latest
    depends_on:
      - kong-database
      - kong-migration
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
      - KONG_PG_DATABASE=kong
    ports:
     - "8000:8000"
     - "8443:8443"
     - "8001:8001"
     - "8444:8444"

  #############################################################################
  ## 社内DBアクセス機能
  #############################################################################
  qcp_watcher:
    links:
      - kong
    build:
      context: "./BEService/QcpWatcher"
      dockerfile: "Dockerfile"
    ports:
      - 49513:80
    extra_hosts:
      - qcp:192.168.99.100  #社内DBのホストを指定

  #############################################################################
  ## Team情報管理機能
  #############################################################################
  # Team情報管理DB
  team_db:
    build: "./BEService/Team/DB"
    ports:
      - 54321:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres
    volumes:
            - team_vol:/var/lib/postgresql/data

  # TeamDBアクセスコンテナ
  team:
    links:
      - kong
      - team_db
    build: "./BEService/Team"
    ports:
      - 49514:80


  #############################################################################
  ## Bot用コンテナ(MatterMost連携コンテナ)
  #############################################################################
  mm_bff:
    links:
      - kong
    build: "./FEService/MmBff"
    ports:
      - 49515:80

  #############################################################################
  ## 管理者用コンテナ
  #############################################################################
  admin_bff:
    links:
      - kong
    build: "./FEService/AdminBff"
    ports:
      - 49516:80

実際に作成したBot

毎朝こんな感じに通知してくれるようになりました。

f:id:Y-Kanoh:20180111025537p:plain

より通知を目立たせるために、戦闘力が53万の方にご協力いただいています

f:id:Y-Kanoh:20180108181755p:plain

この方にはbotをマイクロサービスにする前から協力いただいています。最初はアイコン画像だけでしたが、メンバーからの要望により、口調もあの方になりました。

最初は黄色いネズミのアイコンだったのですが、こちらのほうが断然反応していただけました。

f:id:Y-Kanoh:20180108181351p:plain

全員稼働報告が入力できていた場合は、ちゃんと褒めて(?)いただけます。ありがたや。

今後の拡張

Botを機能ごとに分割することで、追加機能の実装もやりやすくなりました。

また、コンテナによって機能ごとにプログラムが隔離されているため、興味がある技術を試しに使ってみることもできます。

そのため、今後は業務に役立ちそうなものを 趣味 自己学習として、拡張できればと思います。

Copyright © RAKUS Co., Ltd. All rights reserved.