覚書

EdgerRouter v1.9.7にするとTCP Dup ACKが発生して、ネットワークが不安定になる

Edge Router ER-8 を使っているのですが 最新のファームウェア v1.9.7(hotfix-2)を使うと外部からアクセスするのに 40秒近くかかるようになったので共有として。 EdgeRouter ER-8を買ってセットアップしてみた   症状 EdgeRouter v1.9.7, v1.9.7-hotfix1, v1.9.7-hotfix2 いずれのファームウェアにアップデートをすると ネットワークが不安定になるようになった。 TTFBが35秒程かかり、ロードが終わるのに40秒かかる現象になってしまった。 ※TTFB – Time to First Byte クライアントがHTTPリクエストを送信してからサーバーが返してクライアントが最初の1byteを取得するまでの時間 EdgeRouter <-> ロードバランサー <-> Webサーバー 上記構成で、ロードバランサーでパケットキャプチャをしてみた。   TCP Dup ACK が発生したのち、TCP Retransmission が頻発してます。   TCP Dup ACK とは パケットロス等で、受信者が想定しているシーケンス番号より、大きな値のシーケンス番号が送信者から送られてくることがあります。 すると、受信者は自分が想定しているシーケンス番号をACK番号にセットしたACKを直ちに送信者に送ります。これがDupACKです。 http://troushoo.blog.fc2.com/blog-entry-111.html 今回の場合はサーバーが効率目的で一方的にパケットいくつかを送った結果、パケットロス等が原因で届かなかったためか、クライアントはACK=1を期待してパケットを投げます。 しかし投げたパケットも届かなかったためか、もう1度ACK=1を期待してパケットを投げる。 これが重複したACK = DUP(licate) Ack(nowledgement)です。   TCP Retransmission とは Seq#が進んでおらず、TCP Fast Retransmission, TCP Out-Of-Order, TCP Spurious Retransmission の いずれにも該当しないパケット http://milestone-of-se.nesuke.com/knowhow/wireshark-tcp-error/ 今回の場合は、TCP Dup ACKを受け取ったサーバーが 再送のためTCP Retransmissionなパケットをクライアントに送ります。 しかし再送しまくってる(Seq=1)のにも関わらず、クライアントから返送がないため 9回も同じパケットをサーバーからクライアントに送信してます。(最後の9回目だけサイズが小さい) No.144 で初めてクライアントから サーバーが送った Seq=1 + LEN=1452 を受け取ったよパケットが届きました。 その他のTCP Retransmissionなパケットも、No.147, 149で届いてることが確認できました。     EdgeRouter v1.9.1.1 では ああ…綺麗だ。 直接的には原因は分からない(v1.9.1.1 と v1.9.7の差分が多すぎて辛い)。 時間があるときに見ていきたいと思います。 もし記事にミス等がありましたらコメントしてくださると助かります。

Systemdで動かすNode.jsでnewrelic agentを使う

また Systemd の話です。 Node.jsのプログラムをsystemdで動かすと意図しない動作をどうにかする GolangのGinをSystemdで動かすのにハマった 今回はバックエンドに newrelic を導入しようとしたところ、 うまく動作しなかったため解決策を載せておきます。   原因 Systemd のせいです。 newrelic のモジュールはアプリケーションフォルダに、ログファイルを吐き出すんですが モジュールがこれを見つけることができない(cgroupsのせいで /newrelic-log.txt を見る)ため   解決 newrelicのサイトに行くとnewrelic.jsを配置しないといけないわけですが [crayon-5b2a6ee48eebd445719895/] こんな感じになってると思います。 モジュールを見ていくと分かったんですけど これ以外にも設定できる項目がたくさんあります。 今回はログをきちんと見つけられるように絶対パスで指定します。 [crayon-5b2a6ee48eec9210415398/]  

AnsibleでコピーするときはSynchronizeモジュール使ったほうが幸せになれる

背景 Ansibleでターゲットホストに何かをコピーするとき copyモジュールを使ってる人はとても多いと思います。 しかし恐ろしいぐらい遅いため、ansible copy slow何かで調べると 色々対策が書かれている記事があると思います。 まあそれを試しても劇的な改善はなく、結果として意味のないものです。   Synchronizeモジュールを使う Ansible – synchronize Copyモジュールと同等のことをやってみます。 1. ターゲットホストにファイルを配置する [crayon-5b2a6ee48f0ed199409596/]   2. パーミッションを変更する [crayon-5b2a6ee48f0fb267884023/] Synchronizeモジュールにもownerやgroupオプションはあるんですが これは Ansible 実行マシンに存在するユーザー、グループで且つ、 ターゲットホストにも存在しないといけないという制約があるので、 別タスクでパーミッション等を変更する必要があります。   比較 全部で350行ぐらいある Playbook の中のcopyモジュール版と Synchronizeモジュール版で比べた結果です。 Copy real 4m25.575s Synchronize real 2m12.755s 圧倒的

GolangのGinをSystemdで動かすのにハマった

背景 デプロイ先のサーバーでビルドしたものを 以下のようなUnitファイルを作ったら起動できなかった話 [crayon-5b2a6ee48f194948490517/]   systemctl -l status hoge とやってもエラーが分からず /var/log/messagesを見るとpanic: html/template: pattern matches no files: templates/*が出力されてました。 賢い人ならこんなミスをしないと思うけど…;;   解決 [crayon-5b2a6ee48f199650046853/] WorkingDirectoryを追加して実行パスを適切に設定してあげれば 起動できるようになりました。 Golang…難しい。

Slackにネイティブアプリのエンジニアに優しいBOTを作ってみた

皆さんSlack使ってますよね。 今じゃIT企業以外にもSlackが導入されてて日本への浸透も広がってきたと思います。   背景 今は趣味で色々やってるんですが、開発したAPIを叩くiOSエンジニアに 「最近のアクセスログが欲しい」 「エラーログ見せて欲しい」 等、色々と言われます。 ネイティブアプリのエンジニアはそもそもサーバーにログインする習慣がないので SSHのアクセス権限等を付与してあげてもインフラに関する知識や、覚えることが増えるので 直接聞いてきます。 これを解決するためにSlackのBOTがやるようにすればお互い楽なんじゃね?と思い、 作ってみた結果良かったのでチラ裏程度にご紹介です。   Buri Bot できることは ・APIサーバーのアクセスログを返す ・APIサーバーのエラーログを返す ・DBのテーブルを全て空にする ・DBのテーブル レコードを返す と言った、必要最低限のものを実装しました。   アクセスログを見る とりあえず最新の3件だけ   エラーログを見る エラーログはとりあえずの最新の1件だけ   テーブルを全部空にする APIを叩きすぎてぐちゃぐちゃになったテーブルをリセットするには とても便利。   テーブルの中身を見る GetRecord <テーブル名> <環境(stg|dev)> where <カラム> <値>みたいな感じで見る。 レコード数が多いとどうなるか分からない(文字制限が分からない)のでとりあえずwnereで規制しました。   結果 文字化けしててよく分からないけど便利だってことは分かりました。

MySQLのデータベースをインポートする際に存在するテーブルのレコードを削除せずにALTER文を作成、実行するスクリプトを作った

先月末に数学のテストを終えました。 C単位は降ってきてほしいと切に願います。 あと、中間発表を控えてます。   背景 ステージング環境のDBをプロダクション環境のDBへインポートする際に レコードを消すわけには行かず ・プロダクションにないテーブルは作成 ・すでに存在するテーブルはステージングとプロダクションの差異のALTER文を作成して実行 ということを実現したいと思っていたところ ・Workbench ・Schemea Sync ・手動 のどれかが解決方法らしい。 Workbenchを使うとうまく行かず、Schema Syncは導入が面倒、手動も面倒ということで シェルスクリプトで作ってみた。   schemaSync – シェルスクリプト https://gist.github.com/rluisr/ace0513d0251d6ceb2a093cf23b6dafb できること ・宛先DBにないテーブルを作成 ・宛先DBに既にあるテーブルはソース元と差異を取得してALTER文を作成、実行 ・AUTO_INCREMENTの値は不変 できないこと ・SSL ・テーブルオプション(文字コード等)の変更はされない 必要なコマンド ・mysql ・mysqldump ・mysqldiff   前準備 ソースのテーブル構造   宛先のテーブル構図 modifyがありません。   宛先テーブルにはレコードを追加しておきます。   ソースには追加でテーブルを1つ作り、計2つ   宛先DBのテーブルはそのまま1つ   実行する [crayon-5b2a6ee48f25a348732270/] 最後にALTER文1つずつに確認画面がでるので 確認しながら実行できまできます。   宛先DBにソースのテーブルが作成される。   どちらにも存在したusersテーブルはレコードが削除されることなく ソースで追加したmodifyカラムが追加されました。 割りと実現したいことはできたかも。 他のエラー文を残したまま、WARNING文(パスワードをコマンドに書くな)無視はいつかやろうと思う。 本番環境で使ってみようと思います。 あ、これを使って生じた如何なる問題も僕は責任を持ちません。

Node.jsのプログラムをsystemdで動かすと意図しない動作をどうにかする

背景 Node.jsで書かれたプログラムをsystemdで動かすと 実行ディレクトリが変わってソースによっては意図しない動作をします。 例 コード [crayon-5b2a6ee48f39c968084582/] 例 systemd Unitファイル [crayon-5b2a6ee48f3a2668220541/] 例 結果 [crayon-5b2a6ee48f3a5008667968/] requireで読み込んだプログラムはキャッシュされるため 逐一、使用する場面でキャッシュを削除し再度読み込むようなプログラムです。 systemd で動かすと結果の通り、キャッシュを削除していても Unix タイムスタンプが変更されずにいます。   原因 ソースコード fs.writeFileSync('/tmp/blog-test.log', path.resolve('date.js')); node test.js /root/blog-test/date.js systemd /date.js path.resolve('date.js')は相対パスから絶対パスを取得する部分ですが これがうまく動いていません。 systemd は cgroups を使って管理されるため プログラムの実行パスが / となり、delete require.cache が動きませんでした。     解決方法 サーバー上では systemd で起動しています。 各エンジニアのローカル環境でも正常に動いてほしいので サーバー上に環境変数を用意して雑に対応しました。 [crayon-5b2a6ee48f3a7526191852/]     思ったこと 「○○エンジニアは、○○だけに精通していれば良い」という人に反対です

Vultr.com $5 VPS と AWS EC2 t2.micro どっちがオススメか

初めて精神安定剤みたいのを買いました。 今後外出するときは使用してみたいと思います。   背景 会社のHPなどサービスを提供する際に停止してもそこまでクリティカルでないものを 如何に安く運用するかと考えたときにVPSかEC2かで悩んだので色んな観点からまとめようと思った次第です。   EC2以外の選択肢 EC2は思ったほど性能が良くない(と耳にしたことがある)ので クリティカルじゃないものなら敢えてEC2じゃなくて他社のVPSで良いのではと思う 国内のVPSだと さくらインターネット GMO カゴヤ ConoHa 国外だと Vultr.com cloudatcost AlphaRacks とか色々あります。 この中でもVultr.comは安くて安定性も良かったので 今回は Vultr.com $5/m のVPSとEC t2.microを比べてみます。 スペックはどちらも 1Core / 1G です。 月額$2.5で東京リージョンがある激安SSD VPSを契約してWordPressを移行した「Vultr」   スペック EC2 t2.micro Vultr  $5 CPU Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz Virtual CPU MEM 1G 1G SSD 8GB (gp2 – EBS) 25GB OS CentOS 7.3.1611 CentOS 7.3.1611 参考 ap-northeast-1a 東京リージョン どちらも CPU/MEM は 1Core/1G です   UnixBench t2.micro – 1回目 [crayon-5b2a6ee48f5ce502950007/]   t2.micro – 2回目 [crayon-5b2a6ee48f5d8737678846/]   Vultr $5 – 1回目 [crayon-5b2a6ee48f5dc923957809/]   Vultr $5 – 2回目 [crayon-5b2a6ee48f5e4716070152/]   結果 – UnixBench EC2 t2.micro Vultr $5 1回目 1586.7 1303.6 2回目 871.6 1333.7 1回目は t2.micro が優勢だったけどこれはT2インスタンス特有のバーストです。 クレジット残高が無くなったので2回目は本来の性能(言い方が難しい)になってます UnixBenchって何だかんだCPU寄りの結果だと思ってる(個人的に)ので fioもやってみたいと思います。     fio $ fio -filename=/tmp/test2g -direct=1 -rw=…