Swiftでアクセスカウンターを作ってみる

2018/04/16

サイトに欠かせないものといえばコレ

今回何年かぶりに新規にサイトを立ち上げてみた。 ある程度形にしてみたものの、何かが足りない気がする。 そうだ。アクセスカウンターだ。

昔はCGI置いてたり忍者ツールズ使ってたりしてたけど、 最近は何故か情報が少ない。Qiitaにも記事がない。 このままじゃキリ番報告すら出来ない。

…前置きはこれくらいにして、簡単なアクセスカウンタを作ってみます。 データベースとの接続も含めた、ちょっとしたサーバアプリケーションの実装をしてみました。

Swift + Vapor

記事を書く前にPythonで一度実装してみたのですが、 折角なのでSwift実装に置き換えてみました。

サーバサイドSwiftにもいろいろ実装があるようですが、 中でもメジャーそうな Vapor を使っています。 テンプレートエンジンの他、MySQLなど各種データベースに接続するためのProviderも用意されているようです。 割とガチなサーバサイド実装が出来る、のかもしれない。

開発環境

  • 開発環境
    • macOS High Sierra 10.13.2
    • Xcode 9.2

作ってみる

Swiftなので開発はXcode。 型推論効いたり、補完が賢かったり、ブレークポイント置けたりと、 サーバサイド書くのにしては随分リッチな環境みたいです。

こんな感じで実装してみました。

https://github.com/bibmeke/NSOCounter

main.swiftに収まってて、大して解説する必要のない程度にシンプルです。

ポイントとしてはヘッダーの X-Real-IP を見て、24時間以内の同一接続元は加味しないようにしています。 X-Real-IP はNginxがヘッダーに載せるよう後々設定します。

カウンタの値などのデータは同じインスタンス内で動作させるRedisに置くことにしました。 RedisサーバにはRedisProviderを使ってアクセスしにいきます。 Package.swift に追加し、適当に Config/ の中身書けば使えるようになります。

実行環境

  • 実行環境
    • Debian 9.3 stretch
    • Swift 4.0.3

実行環境セットアップ

まずはSwift入れないと始まらないです。

https://swift.org/

swift.orgでLinux用バイナリを見てみると、Ubuntuの情報しかない。 最近はUbuntu使えってことか。そうですか。そうですか。 まあ結論Debianでも動くので問題無いです。

まず前準備としていくつかパッケージを入れます。 大して情報がないのでトライ&エラーでいくつかapt-getしました。

% sudo apt-get install clang curl libssl1.0-dev libicu-dev libpython2.7

そしてSwiftのインストール。

% wget https://swift.org/builds/swift-4.0.3-release/ubuntu1610/swift-4.0.3-RELEASE/swift-4.0.3-RELEASE-ubuntu16.10.tar.gz
% tar -xzf swift-4.0.3-RELEASE-ubuntu16.10.tar.gz

展開して出来たディレクトリは適当な場所に移動して、PATHを通しておきます。

% sudo mv swift-4.0.3-RELEASE-ubuntu16.10/ /opt/swift
% echo "export PATH=/opt/swift/usr/bin:$PATH" >> ~/.zshrc

これでSwiftの実行環境が整いました。

% swift --version
Swift version 4.0.3 (swift-4.0.3-RELEASE)
Target: x86_64-unknown-linux-gnu

動かしてみる

あとはサーバ上でソース持ってきてビルドして実行します。

% git clone https://github.com/bibmeke/NSOCounter.git
% swift build -c release
% ./.build/x86_64-unknown-linux/release/NSOCounter

無事動けば8080ポートでLISTENが始まります。

あ、Redisは別途動かしておいて下さい。

設定

今回アクセスカウンタはWebサーバ上で動かしているため、 フロントのNginxにproxy_passを設定します。

location /count {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header Connection "";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

あとは適当にdaemon化させておくと良いでしょう。 今回は他の用途でも使っているsupervisorを使いました。

まとめ

ギョームに向いているかどうかの判断はもう少し枯れてからになるだろうと思うものの、 サーバサイドでもSwiftは徐々に力を付けてきている感じがします。 やはりサーバサイドもモダンな言語で書ける強みは大きいですね。 今のRubyやPythonのようなポジションにSwiftが来ることを期待してます。

Post Directory