Yakstは、海外の役立つブログ記事などを人力で翻訳して公開するプロジェクトです。
約9年前投稿 修正あり

マイクロサービス時代のHAProxy

マイクロサービスのアーキテクチャでシステムを開発すると、サービス間の通信を効率的に管理する方法が必要になる。この問題を解決するためにHAProxyを使う一例を提示する。

原文
HAproxy in the era of Microservices (English)
翻訳依頼者
D98ee74ffe0fafbdc83b23907dda3665
翻訳者
D98ee74ffe0fafbdc83b23907dda3665 doublemarket
翻訳レビュアー
B5aa4f809000b9147289650532e83932 taka-h F14f7aec988d2bd9a998b805b6ba4c9d kwatch
原著者への翻訳報告
未報告


「マイクロサービス」は、この10年でもっとも興味深いアーキテクチャーのスタイルを表す言葉として、使い散らされている最新のアーキテクチャーバズワードでしょう。

マイクロサービスとは?

Martin Fowlerの定義によれば以下のようになります。

要するにマイクロサービスというアーキテクチャーのスタイルは、それぞれが独自のプロセスで動きHTTPリソースAPIなどの軽量なメカニズムでコミュニケーションを取り合う小さなサービスの形をとったひとつのアプリケーションを開発していくというアプローチです。これらのサービスは、ビジネス上の機能を中心に作られ、完全に自動化されたデプロイの仕組みによって、別々にデプロイできます。これらのサービスを集中的に管理する仕組みがあり、それは異なるプログラミング言語で書かれていたり、異なるデータストレージ技術を使っていたりする場合もあります。

さらにシンプルに言えば、マイクロサービスは、コンテキスト境界(bounded context)の中で協力し合い、HTTPのような軽量な通信手段でコミュニケーションし合う小さな自律的に動くサービスあるいは独立したプロセスであると考えられます。

マイクロと言ってもどの程度の小ささなのか?それは何でもそうですが状況によります。マイクロサービスはひとつのアクターからなるべきだと主張する人もいます。Jon Eaves氏のように、最大でも2週間で完了できるものにすべきという人もいます。私は、大まかなルールとしては小さなチーム(または開発者1人)で容易にメンテナンスできるぐらいに小さいもので、何かひとつのことをやるのに焦点を当てており、それをうまく処理できるべきだと思っています。

こういったアーキテクチャーの利点はたくさんあります。例えば、新しい技術に素早く取り掛かりやすく、チームを成長させやすくなります。ある問題に対してそれを解決するのに適した技術を採用しやすいということです(例として、Neo4jをストレージにしてScalaで書くことも、CassandraをバックエンドにしてGoで書くこともできます)。また、複数のマシンを使ったサービス群に分散しているので、システム全体が停止してしまうリスクを限定することができます。比較的小さなサーバ上でスケールさせやすいので、コストを劇的におさえられます。

しかし一方で、このアプローチは別の部分には複雑さをもたらしもします。そのひとつがルーティングです。

統一されたルーティング

統一されたルーティング

複数のコンテキスト境界に分かれた比較的複雑なドメインを考えると、それらは2つ以上のマイクロサービスから成り立っていて、それぞれが特定のドメインの処理を行うことになります。これらをスケールさせていくと、その数はどんどん大きくなります。

こういったサービス群を使っている時、それらを全部追跡していたくはないでしょう。さらに進むと、もしこれらのサービスと通信する必要のあるモバイルアプリケーションを書いたとして、各マイクロサービスへのたくさんのアドレスを全てメンテナンスしなくてはなりませんが、そんなことしたくありません。コンテキスト境界ごとに1つのベースURL(http://account.mystuff.com/api のようなもの)を割り当てるようプログラムでき、ヘッダーを基にどのマイクロサービスを呼び出すか何らかの形で分かればましになるでしょう。

そこで、HAProxyの出番です。

マイクロサービスにHAProxyを使う

その名前が示すように、HAProxyはTCPとHTTPの両方が使える高可用性のプロキシサーバーであり、ロードバランサーです。詳しい情報はドキュメントにあります。

多くの機能がありますが、どのバックエンドにリクエストを送るか決めるのに使われるアクセスリスト(ACL)のコンセンプトが重要です。ヘッダーとURL、さらに他のものについてもACLが使われます。

ひとつのコンタクトポイントを持つようにしたいモバイルアプリケーションの例に戻ると、開発者が送信できるリクエストには、HAProxyがどのエンドポイントにルーティングするかを判断するためのヘッダー(例えば"x-microservice-app-id")を含めることができます。注 : このコンタクトポイントは、SPOF(単一障害点)になるのを防ぐために、ロードバランサーを指す複数のIPアドレスを持つAレコードに紐づけられている必要があります。

これを実現するための例は以下の通りです。

## Mesosphere Marathonのservicerouter.pyにおけるhaproxyの設定がベース

global
  daemon
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice
  maxconn 4096
  tune.ssl.default-dh-param 2048

defaults
  log               global
  retries           3
  maxconn           2000
  timeout connect   5s
  timeout client    50s
  timeout server    50s

listen stats
  bind 127.0.0.1:9090
  balance
  mode http
  stats enable
  stats auth admin:admin

frontend microservice_http_in
  bind *:80
  mode http

frontend microservice_http_appid_in
  bind *:81
  mode http
  acl app__accountCreationService hdr(x-microservice-app-id) -i /accountCreationService
  acl app__profileEditingService hdr(x-microservice-app-id) -i /profileEditingService
  use_backend accountCreationService_10000 if app__accountCreationService
  use_backend profileEditingService_20000 if app__profileEditingService

frontend microservice_https_in
  bind *:443 ssl crt /etc/ssl/yourCertificate
  mode http

frontend accountCreationService_10000
  bind *:10000
  mode http
  use_backend accountCreationService_10000

frontend profileEditingService_20000
  bind *:20000
  mode http
  use_backend profileEditingService_20000

backend profileEditingService_20000
  balance roundrobin
  mode http
  option forwardfor
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }
  server 151_256_250_152_35900 151.256.250.152:35900
  # 追加のサーバがあればここに

backend accountCreationService_10000
  balance roundrobin
  mode http
  option forwardfor
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }
  server 101_206_200_192_31900 101.206.200.192:31900
  # 追加のサーバがあればここに

ヘッダー名がクライアント側で管理しなければならないものになります。何らかの命名規則を決めて使えば、ヘッダーの値は算出可能になるので、大量になる可能性のあるヘッダー名をクライアントが管理する必要性をなくすことができます。

このアプローチに従うと、HAProxyの設定をデプロイと合わせて同期する機能が必要になるでしょう。そういったことを行う色々なツールがあります。例えば、Marathonは上の例と同じようなHAProxyの設定を生成するユーティリティですし、KongはAPIゲートウェイです。

次の記事
LIKE句のSQLインジェクション
前の記事
オブジェクト指向プログラミングとは? : スティーブ・ジョブズの答え

Feed small 記事フィード

新着記事Twitterアカウント