無印吉澤

ソフトウェア開発、運用管理(俗にいう DevOps)、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Admiral Stats のサービス提供終了に向けた作業予定

f:id:muziyoshiz:20170128164643p:plain

お知らせ(繰り返し)

先日お伝えした通り、2019年9月末をもって Admiral Stats のサービス提供は終了します。

Admiral Stats 上のプレイデータはすべて閲覧できなくなるため、必要な方は今月中(つまり明日まで!)にエクスポート機能を使って CSV ファイルのダウンロードをお願いします。

今後の作業予定

といいつつ、サービス提供終了に向けた準備がなかなか進んでいないため、10月になってもまだしばらく Admiral Stats は動いていると思います……。

ただ、10月1日以降は、準備ができた段階で追加のお知らせなど無しにサービスを停止していきますので、予めご了承ください。

今後は、次のように作業を進めていき、遅くとも10月以内には完了させるつもりです。

  • Admiral Stats の終了をお知らせするページを作成(おそらく GitHub Pages で作成)
  • admiral-stats.com で表示されるページを、現在の Admiral Stats から上記のページに変更
  • Admiral Stats 関係のサーバをすべて停止
  • Mackerel 上でサーバを退役
  • Admiral Stats の Twitter アプリ設定を削除
  • GitHub 上のソースコードの README に、サービス提供終了の旨を追記
  • Travis CI でのビルド設定を削除
  • Admiral Stats をせっかく3年近く運用してきたので、そのまとめ記事を何か書く(やってみてよかったこととか、かかった費用の内訳とか)

Admiral Stats のエクスポート機能提供のお知らせ(2019年9月末まで使えます)

f:id:muziyoshiz:20170128164643p:plain

先日お伝えした通り、Admiral Stats のサービス提供は9月末をもって終了します。 その際にお約束していたエクスポート機能の開発が完了しました。

2019年9月末にサービスを終了するため、エクスポートしたい方はそれまでにお試しください。

muziyoshiz.hatenablog.com

エクスポート機能の使い方

ログイン後に、メニューから「エクスポート」をクリックしてください。次のようなページが表示されます。このページのリンクをクリックすると、CSV ファイルのダウンロードが始まります。

f:id:muziyoshiz:20190831161449p:plain

ファイル形式の解説

基本的に、MySQL のテーブルに保存されている値をそのまま出力しています。ただし、ログイン中のユーザの情報だけをエクスポートしているので、admiral_id カラムは出力していません。

提督情報 - 基本情報 (admiral_statuses.csv)

カラム名 内容
exported_at SEGA の「提督情報」からエクスポートされた日時
fuel 燃料
ammo 弾薬
steel 鋼材
bauxite ボーキサイト
bucket 修復バケツ
level 艦隊司令部Level
room_item_coin 家具コイン
result_point 戦果
rank 暫定順位
title_id 階級を表す数値
strategy_point 戦略ポイント
kou_medal 甲種勲章の数
title_id の値 意味
0 新米少佐
1 中堅少佐
2 少佐
3 新米中佐
4 中佐
5 大佐
6 少将
7 中将
8 大将
9 元帥
10 集計中

提督情報 - イベントの進捗 (event_progress_statuses.csv)

カラム名 内容
exported_at SEGA の「提督情報」からエクスポートされた日時
event_no イベント No. (例:第壱回なら 1)
level 難易度(HEI, OTU, KOU)
period 作戦(前段作戦: 0, 後段作戦: 1, Extra Operation (EO): 2)
opened 難易度が解放済みかどうか
current_loop_counts 現在の周回数(1〜)
cleared_loop_counts 最終ステージまで攻略済みの周回数(0〜)
cleared_stage_no 現在の周回で攻略済みのステージ番号(0 〜)
current_military_gauge_left 攻略中のステージの海域ゲージの現在値(0〜)

提督情報 - 輸送イベントの進捗 (cop_event_progress_statuses.csv)

カラム名 内容
exported_at SEGA の「提督情報」からエクスポートされた日時
event_no イベント No. (例:第壱回なら 1)
numerator TPゲージの残量
denominator TPゲージの最大数
achievement_number 現在の周回数(1周目=クリア周回数0の場合は1)
area_achievement_claim "全提督協力作戦 達成報酬獲得権利" の権利獲得済かどうか
limited_frame_num 限定フレームの所持数

艦娘情報 (ship_statuses.csv)

カラム名 内容
exported_at SEGA の「提督情報」からエクスポートされた日時
book_no 艦娘図鑑の図鑑 No.
remodel_level 解像度合いを表す数値
level レベル
star_num 星の数
exp_percent 経験値の獲得割合(%)
blueprint_total_num 改装設計図の枚数
married ケッコンカッコカリ済みかどうか
remodel_level の値 意味
0 未改造
1
2 改二, 千歳/千代田 甲
3 千歳/千代田 航
4 千歳/千代田 航改
5 千歳/千代田 航改二

Admiral Stats のサービス提供終了のお知らせ

f:id:muziyoshiz:20170128164643p:plain

大切なお知らせ

2016年9月から約3年に渡って、https://www.admiral-stats.com/ にて提供していた Admiral Stats のサービス提供を終了します。

今後の予定としては、8月末を目標に、プレイデータの一部に限定したエクスポート機能を実装するつもりです。その後、1ヶ月の猶予をもって、9月末にサービス提供を終了します。

いままで Admiral Stats をご愛顧いただきありがとうございました。

ユーザーの方にしていただく必要があること

特にありません。9月末までは従来どおりに Admiral Stats 上でプレイデータを閲覧できます。最新のデータ形式への対応はしない予定です。

退会手続きなどは必要ありません。個人を特定可能なデータは、9月末のサービス終了後にすべて破棄します。

サービス提供後も admiral-stats.com のドメインは保持し、https://www.admiral-stats.com/ へのアクセスは GitHub の Admiral Stats ページにリダイレクトする予定です。

エクスポート機能について

元々、プライバシーポリシーのページには「エクスポート機能の提供予定はありません」と記載していました。

しかし、3年近くプレイデータを溜めていただいている方もいますので、最低限のプレイデータは CSV 形式でエクスポートできるようにしたいと考えています(夏休みにできる範囲でがんばって実装します)。

いま検討中なのは以下の範囲です。

  • 提督情報
    • 艦隊司令部レベル・経験値、資源、資源以外の消耗品、戦果、暫定順位
  • イベントの進捗、輸送イベントの進捗
    • 周回数のみ
  • 艦娘情報
    • レベル・経験値(艦娘別)のみ

その他の情報は、ほとんどは SEGA 公式のサイトで確認できるため、対象外とさせてください。

その他

Admiral Stats のソースコードは GitHub で公開したままにします。削除の予定はありません。MIT License に従って手元で利用いただいたり、ソースコードをフォークしていただくのは自由です。

最後に:サービス提供終了に関する事情とかいろいろ

以下、個人的な話なので読まなくても OK です。

2016年4月に艦これアーケードのサービスが開始し、このゲームにハマったのが Admiral Stats 開発のきっかけでした。しかし、個人的な心境の変化であったり、使える時間の変化があって、去年11月のAL/MI作戦を最後に、艦これアーケードを全くプレイしていない状態でした。

艦これアーケード自体はいまでも面白いゲームだと思うし、ゲームが嫌になる何かがあったとかでは無いです。ただ、最近何度か公式サイトで大きなプレイデータ形式の変更があり、ゲームをプレイしていない状態で、変更に追従するモチベーションが無くなってしまっていました。

そのため、まともに動かない(このままだといずれそうなる)サービスを放置するよりは、きちんと期限を決めてサービス提供を終了しようと思った次第です。

最後に改めて、いままで Admiral Stats をご愛顧いただきありがとうございました。また、周辺ツールの提供、Web サイトでの紹介など、ご協力頂いた皆様も誠にありがとうございました。

nginx.conf の location の優先順位を正しく理解する

f:id:muziyoshiz:20171026000347p:plain

最近、Nginx の location 設定の優先順位を誤解していて軽くつまづきました。このへん時々よくわからなくなるので、自分のためにまとめておきます。

情報源

公式の説明は、マニュアルの Module ngx_http_core_module ページ内の "location" の項にあります。

nginx.org

location の修飾子(modifier)

location を定義する際に使える修飾子は、以下の5種類です。

修飾子 判定方法
= 完全一致
なし 前方一致
^~ 前方一致
~* 正規表現(case-insensitive)
~ 正規表現(case-sensitive)

前方一致が2種類ありますが、これは「^~ は省略可能」という意味ではありません

location の優先順位

location の優先順位を考える上でややこしい点は、書かれた順に評価される設定と、最長一致で評価される設定が混在していることです。特に、優先順位をややこしくしているのが ^~ の存在です。

Nginx は、あるリクエスト URI に対する configuration を決めるために、以下の手順で location を選択します。

  1. 完全一致の location を判定し、マッチしたらその location を選んで終了
  2. 前方一致の location を判定し、最も長い文字列がマッチしたものを記録する(最も長い文字列がマッチした location が ^~ 修飾子を使っていた場合に限り、その location を選んで終了)
  3. 正規表現の location を、設定ファイルに書かれた順で判定し、最初にマッチしたものが見つかった時点で終了
  4. 3 でマッチするものが見つからなかった場合は、2 で見つかった location を選んで終了

ポイントは、^~ にマッチしたらその場で判定が終わるわけではない、ということです。^~ なしの前方一致のほうが最も長い文字列(longest matching prefix)の場合は、手順3の正規表現の判定に進んでしまう、という点に注意が必要です。

もしも ^~ 修飾子を全く使わなければ、以下のように簡単に優先順位を説明できます。

  1. 完全一致
  2. ~* または ~ 修飾子で定義された正規表現のうち、設定ファイルに書かれた順で最も最初にマッチしたもの
  3. 修飾子なしで定義された前方一致のうち、最も長い文字列がマッチしたもの

結局 location はどういう順に書いたらいいか?

個人的には読みやすさを考えて、評価される順(自分が評価してほしいと期待する順)に書いておくのがよいと思います。また、^~ ありの前方一致は混乱を招くため、^/ から始まる正規表現として書いてしまったほうがよいのではないか、と思います。

  1. 完全一致の location を書く
  2. 優先したい前方一致の location を、^/ から始まる正規表現の location として書く(^~ は使わない)
  3. 正規表現の location を、優先したいものから順に書く
  4. 修飾子なしの前方一致の location を、長いものから順に書く

Nginx のマニュアルに書かれた location の例を微修正して、上のルールに従って書き直したものがこちらです。

# ルートへの完全一致
location = / {
    [ configuration A ]
}

# /images/ 以下の画像
location ~ ^/images/ {
    [ configuration D ]
}

# /images/ 以外に置かれた画像
location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

# /documents/ 以下のページ
location /documents/ {
    [ configuration C ]
}

# その他すべてのページ
location / {
    [ configuration B ]
}

まとめ

おそらくですが、適当な順序で location を書いてしまってもなんとなくそれなりに動くように、こういう仕様になっているのではないか、と思います。とはいえ、このへんを正確に理解しておかないと、他の人が書いた nginx.conf をいじるときにつまづきやすいので気をつけましょう。

参考ページ

location に関する説明を色々探してみて、このブログの記載が一番わかりやすくて参考になりました。

paulownia.hatenablog.com

おまけ:location の説明の日本語訳

以下、マニュアルの該当箇所の日本語訳です。古いバージョンの Nginx について書かれた記載や、特殊なケース(macOS など)について書かれたケースは割愛しました。

Sets configuration depending on a request URI.

location はリクエスト URI に応じて configuration を設定する。

The matching is performed against a normalized URI, after decoding the text encoded in the “%XX” form, resolving references to relative path components “.” and “..”, and possible compression of two or more adjacent slashes into a single slash.

マッチングは正規化された URI に対して実施される。正規化とは、"%XX" 形式でエンコードされたテキストのデコード、相対パスを表すコンポーネント "." および ".." への参照の解決、そして2つ以上の隣接したスラッシュの1個のスラッシュへの圧縮である。

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

location は prefix string または正規表現で定義できる。 正規表現は "~*" 修飾子(case-insensitive なマッチング)、または "~" 修飾子(case-sensitive なマッチング)で指定される。 与えられたマッチする location を探すために、nginx は最初に prex strings (prefix locations) を使って定義された location をチェックする。 そのチェックの間に、最も長い prefix とマッチした location が選ばれて記録される。 その次に正規表現が、設定ファイルの中で登場した位置の順にチェックされる。 正規表現の検索は、最初にマッチした段階で終了して、その location に書かれた configuration が使われる。 もし、そのリクエスト URL にマッチする正規表現が見つからなかった場合は、その前の段階で記録された prefix location の configuration が使われる。

location blocks can be nested, with some exceptions mentioned below.

location ブロックはネスト可能である。ただし、以下に示すいくつかの例外がある。

Regular expressions can contain captures (0.7.40) that can later be used in other directives.

正規表現は captures を含むことができる(0.7.40)。これは後の directives で使うことができる。

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

もし、longest matching prefix location が "^~" 修飾子を持っていたら、正規表現はチェックされない。

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

また、"=" 修飾子 を使うと、URI と location の完全一致を定義できる。 もし、完全一致が見つかったら、location の検索は終了する。例えば、もし "/" へのリクエストが頻繁に起こるなら、location = / を定義することでそれらのリクエストの処理を高速化できる。検索は最初の比較で完了するからである。そのような location が、ネストされた location を持つことは明らかにできない。

Let’s illustrate the above by an example:

上記のことを、例を使って説明しよう。

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

The “/” request will match configuration A, the “/index.html” request will match configuration B, the “/documents/document.html” request will match configuration C, the “/images/1.gif” request will match configuration D, and the “/documents/1.jpg” request will match configuration E.

/ へのリクエストは configuration A にマッチする。"/index.html" へのリクエストは B にマッチし、"/documents/document.html" は C にマッチする。"images/1.gif" は D にマッチし、"/documents/1.jpg" は E にマッチする。

The “@” prefix defines a named location. Such a location is not used for a regular request processing, but instead used for request redirection. They cannot be nested, and cannot contain nested locations.

"@" 前置詞は名前付きの location を定義する。そのような location は正規表現の処理には使われないが、リクエストのリダイレクトのために使われる。"@" 付きの location はネストできないし、ネストされた location を含むこともできない。

If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, or grpc_pass, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of the URI and location could be defined like this:

もし、location が、/ で終了する prefix string によって定義された場合、リクエストは proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, または grpc_pass のうちの1つによって処理されて、その特別な処理が実行される。 この文字列に一致する URI を持つリクエスト、しかし末尾に / が付かない URI の場合は、その URI に対する恒久的なリダイレクトが、/ 付きの URI に対して返される。 もし、その動作が望ましくない場合、URI と location の完全一致を以下のように定義すればよい。

location /user/ {
    proxy_pass http://user.example.com;
}

location = /user {
    proxy_pass http://login.example.com;
}