AWSで実現するPhoton Loadbalancer(Master)の冗長化

俺です。Photon人気ですね(俺調べ)

ちょっと最近[Excel方眼紙er](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC)以来のWindowsに再入信してまして、
[Photon Server](https://www.photonengine.com/en/OnPremise)を弄くってるのですが、
Photon Loadbalancerの冗長化ってできないんじゃないかなあと思ってたら

Route53 DNS Failoverで実現できるんじゃねとアドバイス頂いたので、試してみました。

Photon GameServerはコンフィグファイルにPhoton Loadbalancer(Master)のIP(内部IPなり)やDNS名を指定しなければいけませんが、
EC2のPublic DNS名を指定するとVPC内からは内部IPでPhoton Loadbalancer(Master)に接続され、
インターネット(クライアント)からはEIPまたはPublic IPでPhoton Loadbalancer(Master)に接続されるので最高というやつです。

# Route53 setting

## Hosted Zones

|endpoint name|record type|value|routing policy|failover record type|health check associate|
|:----:|:---------:|:------:|:------:|:----:|:-----:|
|photon-lb.oredayooreda.oreda.be|CNAME|ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com|Failover|Primary|photon lb healthcheck|
|photon-lb.oredayooreda.oreda.be|CNAME|ec2-YY-YY-YY-YY.ap-northeast-1.compute.amazonaws.com|Failover|Secondary| なし |

## Health Checks

health check先のホストにはPhoton Loadbalancer(Master)用EC2のPublic DNS名を指定します。
ヘルスチェックタイムアウトは最小10秒にすることができます。

|health check name|what to monitor|Specify endpoint by|Protocol|Domain name|Port|Request interval|Failure threshold|
|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|
|photon lb healthcheck|endpoint|Domain name|tcp|ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com|4530|standard(30sec)|1|


# EC2まわり

### EC2

|EC2|host|Public DNS名|EIP|Private IP|
|:---:|:---:|:---:|:---:|:---:|
|master|Windows 2012R2|ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com|52.52.52.52|172.16.0.10|
|master(standby)|Windows 2012R2|ec2-YY-YY-YY-YY.ap-northeast-1.compute.amazonaws.com|52.52.52.53|172.19.248|

### Photon

v4を利用。GMOさんが提供してくれてますよ！ライセンスは買いましょう。

## Photon Loadbalancer(Master)

- Active/Standbyとくにやることなし
- Loadbalancer(Master)として接続受付するようにセットアップして、Photonサービスを起動しておけばOK

## Photon GameServer

### Photon.LoadBalancing.dll.config

- %PHOTON_HOME%\deploy\Loadbalancing\GameServer\bin\Photon.LoadBalancing.dll.config

145行目辺りのMaster Server用エンドポイントに、DNS Failoverを設定してあるDNSレコード名を指定し、Photonサービスを起動します。
Loadbalancer(Master)とGameServerのEC2が同一VPCで稼働していれば、内部IPで接続されます。最高

```
      <!-- Set to the IP Address of the Photon instance where your Master application is running. -->
      <!-- Get Master EC2 Private IP -->
      <setting name="MasterIPAddress" serializeAs="String">
        <value>photon-lb.oredayooreda.oreda.be</value>
      </setting>
```

# Route53 DNS Failoverを実行する

## Failover発動前

### DNS名とIPのチェック

- インターネット越しのクライアントから名前解決を実行
 
```
orenomac$ dig photon-lb.oredayooreda.oreda.be +short
ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com.
52.52.52.52
```

- VPC内部のEC2から名前解決を実行

```
C:\Users\Administrator>nslookup photon-lb.oredayooreda.oreda.be.
サーバー:  ip-172-16-0-2.ap-northeast-1.compute.internal
Address:  172.16.0.2

権限のない回答:
名前:    ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com.
Address:  172.16.19.10
Aliases:  photon-lb.oredayooreda.oreda.be
```

## DNS Failover発動

Loadbalancer(Master) Active系のPhoton ServiceなりEC2そのものを停止して、
Route53 Health Checkをfailさせます。

### インターネット越しの名前解決

```
orenomac$ dig photon-lb.oredayooreda.oreda.be
ec2-YY-YY-YY-YY.ap-northeast-1.compute.amazonaws.com.
52.52.52.53
```

### VPC内のEC2による名前解決

こちらもMaster(Standby)のPrivateIPに変わっています

```
C:\Users\Administrator>nslookup photon-lb.oredayooreda.oreda.be.
サーバー:  ip-172-16-0-2.ap-northeast-1.compute.internal
Address:  172.16.0.2

権限のない回答:
名前:    ec2-YY-YY-YY-YY.ap-northeast-1.compute.amazonaws.com
Address:  172.16.19.248
Aliases:  photon-lb.oredayooreda.oreda.be
```

### Photon Serverのログ

見事にGameServerがStandby側のPhoton Loadbalancer(Master)へ再接続されてます。
HAProxyと違ってエンドポイントにDNS名称を指定しても、IPアドレスをキャッシュせずに
新しいIPで再接続してくれるので、何もしなくて良さそうです。

![Photon_Master死亡時の挙動.png](https://qiita-image-store.s3.amazonaws.com/0/42755/5dc58d29-ba08-6735-0b70-02a6c68c8b41.png)

# フェイルバック

今のところ安全にオンラインで戻す方法は見つけられてません。

DNS Failoverが発動した後、停止したMaster(Active)を正常な状態に戻して、DNSレコードが元の状態に戻っても、
GameServerは再接続しません。フェイルオーバーした方にのみ接続されているのをPhotonのログから確認しました。

とすると、DNSレコードが元に戻ると、Photon Loadbalancer(Master)に接続されているGameServerは存在しないため、
クライアントがGameServerに接続できなくなるので、よろしくないですね。

GameServerが復旧したLoadBalancerへ再接続させるには以下の手段を用いることになります
どちらもクライアントは一時的にゲームへ接続できなくなりますが、(1)であればPhoton GameServerが再接続されるの間、
新規受付が行われないだけになるはずなので、影響は小さそうです。

(1) GameServerが接続中のFailover先であるPhoton Loadbalancer(Master)を停止する
(2) GameServerを再起動する



# Next step

とりあえずPhoton Loadbalancerの冗長化はできるようになりましたが、
ゲームサービスの提供を継続できるかは、クライアント・アプリケーションの挙動を見ながらの判断が必要かなとおもいますー。
ほんとにうまくいくのかなーと。

=> ちょっと試した結果. マッチメイキングをPhoton側ではなく、別途REST APIを立てて運用する仕組みであればこの手法はうまくいくかなと

↓な感じの機能をつかわなければOK

https://doc.photonengine.com/en/realtime/current/reference/matchmaking-and-lobby


# special thanks

この実装案のヒントというか答えというか議論できた [y13i](http://qiita.com/y13i) & [SatoHiroyuki](http://qiita.com/SatoHiroyuki) thanks 

完