プログラマには固いコードを書いて欲しい。
「サーバが激重で繋がりにくいし、DBの接続エラーが出てる」と4つぐらい向こうの島の人たちが相談に来たので調べたりした一日だった。
とりあえず、apacheのMaxClientsが1024だったのに、mysqlのmax_connectionsがデフォルト(100)だったので、1024まで引き上げたが、すぐ食いつぶされる。
おかしいなと思って、processlistをみたらsleepのプロセスが山のようにあった。
Connectionまわりのpgmがおかしいんじゃないかと思って、PGに言っても「スクリプトが終了したらコネクション開放するでしょ?」とのことで取り合ってもらえない。「明示的に開放してくれよ。それが鉄則じゃないのか?少なくとも俺はそうして来た」なんて思いつつ解析を続けてみた。
ふとTCP側を見てみようと思って、lsofでhttpdのTCP周りを見てみたら、CLOSE_WAITのステータスのまま止まってるプロセスが多数。しかも全部auかDocomoからのアクセス。「おいおいなんだよ。これ」とか思って見ているとどうも、こいつらがmysqlのコネクションを食いつぶしてるみたいだったので、上司経由でPGに明示的にコネクション閉じる処理を入れてもらった。
そうすると、mysql側は問題なく処理されるようになってきた。
ちょっと「ほら見たことか」とか思った。
が、httpdのプロセスはCLOSE_WAITで止まりっぱなし。計測したところ、大体10分ぐらいはそのまま。
頭に来て、ApacheのTimeoutを150秒に下げたら結構スムーズに行くようになった。(でもESTABLISHや、CLOSE_WAITが通常より長い。)
帰り間際に調べてたら、どうもApacheかPHP辺りのDoS脆弱性っぽい感じの記述を見つけた。ApacheやPHPのバージョンみてもちょっと古いようだったし。明日しっかり調べてみようと思う。
PGには固くプログラミングしてもらわないと、原因の切り分けにも時間がかかるし、基本的にリソース消費はなるべく最小限に留めるというのが鉄則だと思うので、その辺はしっかりして欲しいものだ。特に、DB周りは、コネクションもトランザクションも最小限にするっていうのは基本中の基本でしょう。
そういう話をしていたら、「そういうこともあるので、今度のメールシステムをお願いしたいんですよね。みんなの手本になるような。」ということを上司から言われた。久々の開発だ!つーか、運用面倒見ながら開発はちょっとしんどいような気がする。パフォーマンスもセキュリティも俺がやらないと誰がやるって感じで。
それに、PHPはそんなに本腰を入れて使った事がないので時間がかかりそうな予感。定石とかわかんないよ。暇を見つけてメジャーなフレームワークのコードでも読んでみようかな。