Web API 鯖を建ててみた - Falcon -

やんちゃんbot開発してる最中、シグナルの受け渡しにSLACKというSNSサービスを使おうかと考えていました。10名ほどのテスターさんとのテストをやっててアクセスエラーによる遅延が想定以上の時間で発生しました。

どうやらSLACKの規約で1分に60回超えると厳しいよ、みたいなので規制されてるぽい。仕方ないのでSLACK使うのをあきらめて、別の道を探しました。

GoogleのBloggerAPI: 便利そうなんだけど、なんかごちゃごちゃしててわかりにくい。

WEBAPIサーバー: Falconというのが軽くて早いというのでサンプルコードをコピペして動かしてみたら、本当に簡単だった。getが走ったらDB読み込みしてくるサンプルがあったので、テキストファイル読み込みに改変して、ラズパイ互換機で動かしてみました。

自宅内LANで、3台の端末から0.5秒おきアクセスを約8時間実施、15万アクセス超えで問題なく動いてたので、これは使えそうと判断しました。

このnote記事で公開してるのは、参考にしたWEBサイトとファイルから読み込んでくる鯖側のサンプルコードと、クライアント側で動かすサンプルコードの2種類です。

公式サイトはこちら。

参考サイトはこちら。

DBアクセスの参考サイト。

サーバ側のコード。httpd = simple_server.make_server("192.168.1.8", 8000, app)のところのIPアドレスは皆さんの環境に合わせて変えて下さい。外部からHTTPアクセスがあった時に毎回entrySign.txtファイルを読み込んで、アクセスしてきた相手に返しています。

# -*- coding: utf-8 -*-
# test_FalconServer.py
import falcon
import json

class FileResource:

    def on_get(self, req, resp):
        f = open('entrySign.txt', 'r')
        jf = json.load(f)
        resp.body = json.dumps(jf, ensure_ascii=False)


app = falcon.API()
app.add_route('/fileRead', FileResource())

if __name__ == "__main__":
    from wsgiref import simple_server

    httpd = simple_server.make_server("192.168.1.8", 8000, app)
    httpd.serve_forever()

サーバー側の動かし方

python test_FalconServer.py


受け渡すファイルの中身、JSON形式で保存しています。

{"symbol":"XBTUSD" ,"timestamp":"2018-10-08T09:32:41.682358Z" }


クライアント側のコード、runSec = 0.5 のところでループ時間を決めています。url = 'http://192.168.1.8:8000/fileRead' のところで、サーバーのIPアドレス、ポート番号、パスを指定しています。サーバー側設定では8000番のポートをhttpアクセス用であらかじめ開けています。VPSなどではあらかじめ開いてるとは限らないので注意が必要です。

import requests
import json
import time
# クライアントがわのコード test_FalconClient.py

# 無限に繰り返し..
runSec = 0.5
cnt = 0
while(runSec > 0):
    url = 'http://192.168.1.8:8000/fileRead'
    response = requests.get(url)
    json_data = response.json()
    print(str(len(json_data)))
    cnt += 1
    print("Loop count=" + str(cnt))
    time.sleep(runSec)

クライアント側の動かし方

python test_FalconClient.py

以下、2018年10月22日追記、VPSでの稼働設定の記録

webArenaで難航したのでさくらでやってみたらすんなりいった。さくらで作ったiptables定義をアリーナに移植してみたら、やはりすんなりいった。但しアリーナはコンパネからのセキュリティグループ設定もしている。

悪かったのは iptables定義だった。定義サンプルはこちら。

# うまくいったiptables定義 2018/10/22
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
#
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8000 -j ACCEPT
# -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
#
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

以下、定義を反映させるコマンド類。

[ centOS6 ]
ルール定義の編集と反映
vi /etc/sysconfig/iptables
service iptables restart

サービスの稼働状況確認と稼働ON
chkconfig iptables --list
chkconfig iptables on

[ ubuntu ]
ルール定義の編集と反映
sudo vi /etc/iptables/iptables.rules
cat /etc/iptables/iptables.rules
sudo iptables-restore < /etc/iptables/iptables.rules

[ 共通 ]
nmapでポートが開いてるか確認する
falcon起動中はopenになってれば正常

nmap -p 8000 鯖のIPアドレス
見たいポート番号がまだあるときはカンマ区切りで続ける
例. nmap -p 8000,80,22 鯖のIPアドレス

実行結果例
PORT      STATE    SERVICE
22/tcp    filtered ssh
8000/tcp  open     http-alt

webArenaはさくらに比べて、つまづきが多い、centOSのせいなのか、VPSのせいなのかは不明。さくらのほうが体感速度も速いので、時間を節約したい人には、さくらVPSをお勧めします。falconは接続先が増えるにしたがってリソースを喰っていくので接続ユーザー数に応じてメモリ調整等が必要になるやもしれません。

追記、10月25日

tcpコネクション数の上限変更

1コネクションあたり350byte食うそうなのでVPSの空きメモリを元に計算する。アリーナはメモリ1GB、freeコマンドで見て650MB遊んでるので下記設定で100M割り振っても問題ない。さくらで使うときは半分以下にする。

【 centOS6 】
現状値確認
sysctl -a|grep nf_conntrack_max

定義ファイルを変更
vim /etc/sysctl.conf
以下を追加
# /proc/sys/net/nf_conntrack_max , ip conntrack
net.nf_conntrack_max = 327520

以下で反映
sysctl -p

反映を確認する
sysctl -a|grep nf_conntrack_max

1端末から2秒おきのアクセスで netstat|wc でみて70から77行程度、関係ない行を無視して、約70コネクションで推移している。同時アクセス参加者が100名と仮定して最大コネクション想定値は8000弱なので上記の設定は多すぎるが大は小を兼ねるので大きめに割り振った。


チップはこちらからお願いします