1
/
5

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

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

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

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

Mattermost Private Cloud Messaging

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

今日はそのお話です。

概要

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


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

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

設計

概念図

最初は、「動けばいい」の信念のもと、上記図のBotシステムをそのまま1コンテナにしただけの設計でした。マイクロサービスを目指すにあたり、そのコンテナ内容を機能ごとに分割し、以下のような設計で実装しています。*2


作成したコンテナは以下の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

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

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


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

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


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

今後の拡張

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

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

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

*1:https://docs.mattermost.com/developer/webhooks-incoming.html

*2:https://www.wantedly.com/companies/wantedly/post_articles/32977

*3:https://qiita.com/kawasima/items/356d54e253c54d730fb0

*4:https://www.oreilly.co.jp/books/9784873117607/

株式会社ラクス's job postings
1 Likes
1 Likes

Weekly ranking

Show other rankings
Like Syuhei Sakae's Story
Let Syuhei Sakae's company know you're interested in their content