固まるSSLプロセス

基盤:どうも以前から、HTTPSのリバースプロキシのサーバプロセスが固まって溜まってしまう現象があります。時々手動で掃除しているのですが。

開発:何でしょうね?コネクションにSSLをかぶせてるプロセスだと思いますが。

基盤:ps xlf するとこんな感じ。

基盤:現在のプロセス番号は5000番台なので、それより大きいPIDのは一巡以上前のやつです。

開発:WCHANがfutexシステムコールということなので、何かの排他制御で固まってるようですね。ていうかLinuxってプロセス番号15ビットなわけ?

基盤:まあそれはカーネルのコンフィグ次第じゃないですかね。先日までdelegate.orgだったAzureのUbuntu18でのDeleGateのログを見ると130000を超えたあたりまで行ってます。130000 == 0x1FBD0 ですから、おそらく17ビット使ってると思います。

社長:私はfutexというようなシステムコールは知らないし、呼んだ覚えは無いのですが。

開発:ライブラリ関数から呼んでるんでしょうね。gdbで覗いてみましょうか。

基盤:gdb … 無いですね。sudo apt install gdb。OK。

開発:で、sudo gdb dg9.9.13+ -p 32232。OK。そして bt。

社長:bt 超ナツカシス。

開発: SSLフィルターのスレッドの終了待ちのようですね。ログは?

社長:固まってるプロセスに共通点は?アクセス先とか。

基盤:実行ファイルとかPDFです。大きめのバイナリですかね。

開発:いずれも disconnected はしてるから、クライアント側とは切断していて、一方リバースプロキシ先のサーバとのSSLの切断を待ってるという状態ですね。

社長:SSLかTLSのプロトコルが変わったとかかな?10年前には見なかった現象ですが。というか、ヘビーにHTTPSのリバースプロキシはやったことがなかったかも知れませんが。

開発:それって再現性ありますかね?同じアクセスで固まらない場合があるかという。

基盤:同じのにアクセスしてみます。再現しないですね。固まらない。

開発:しかしこれ、クライアント側が切断されるまでやたら時間がかかりましたね。

基盤:データ転送自体は0.5秒くらいで終わってますが、SSLが切断されるまでに10秒とかかかってるような?

開発:なんか、スレッドidがおかしなことになってますね。32ビットと64ビットの違いとか?

社長:これって単にサーバとKeep-Aliveしてるって話のような?それならHTTP的にタイム・アウトして切れるまでSSLも切れない。まずはそれを止めてみましょう。

基盤:どうやるんでしょう?

社長:さあ。マニュアルを読んで下さい。

基盤:Manual.shtmlで keep を探す… これですかね?

基盤:それでは HTTPCONF=bugs:no-keepalive を足して再起動。おや、ゾンビがポートを離さないのでリスタートできない。しかたが無い、親なしになった子プロセスをkill -9 で成仏させて、再起動。これ、再起動時にSIGTERMじゃなくてSIGKILLで終了させるってオプション無いんでしょうか?

社長:SIGTERMを聞いてくれなかったらSIGINTかSIGKILLするというオプションは作ったように思います。

基盤:とりあえず再起動できたので。ロード。おやログがスッキリしました。

開発:でもあいかわらずスレッド終了待ちがタイムアウトとかしてるのは気持ちわるいですね。

基盤:それより何より、バイナリがブラウザに表示されてしまうというコレ。

開発:Content-Type: application/octet-stream じゃいかんのですかね?

基盤:いえ、リバース先の nginx はContent-Typeを付けてくれてないようです。

開発:ああ、それで DeleGate が Guessed って出してたのか。これ、デフォルトのContent-Type て付けられるんでしたっけ?

社長:さあ。マニュアルには何と?

基盤:content-type で検索… 文字コード変換の場合と、CFIの場合にしか出てこないですね。

社長:まあ、CFIを噛ませれば良いって話ではありますが… まあ、ちょっと重くはなるでしょうね。

開発:ソースを見てみますか。grep Guessed src/*.c。ああ、http.cですね。どれ…

開発:これって、推定した結果を反映させる気満々だったようですが。

社長:ちょっと、クライアントに返しているヘッダをログに出してもらえますか?

基盤:こういう様子です。Content-Type 返してませんね。小さなCOPYRIGHTファイルにアクセスしてコレですから、サイズとかバイナリがとかでは無く、単にオリジンサーバが返してなかったらそうなるということのようです。

社長:ぐう。あー、お腹がすきましたね。飲みに行きましょうか。

開発:いや、ここは逃げずにもうひと踏ん張り。

基盤:バイナリのタイムスタンプからしてソースはこれかな。一応コピーしてと… しまった!自分自身にtar cf | xf してファイルが壊れました。

開発:まあ、隣のサーバにコピーがありますし。

基盤:あ、いや。一応tarしてアーカイブしてありました。

開発:で http.c を見る。Guess した Content-Type は何に使われているのか… ああ、内部的な判定に使われてるだけで出力されてないですね。じゃこれをクライアントに向けて出しちゃうと…

開発:めでたし。

基盤:ブラウザもちゃんと認識してくれますね。

社長:めでたし。お昼に行きましょう。

* * *

社長:あー食った飲んだで1,500円。予は満足じゃ。

開発:さたぽんのおばちゃん、店がすいてる時にビール頼むと一品サービスしてくれますね。あれはふつうの飲み屋なら、400円くらいの価値はあります。

社長:いやそれで、途中で出ていった中年男性が「また来ます」って言ったら見送りに出たおばちゃんが「あい、またきます」って返事してて、幼児の言語学習過程を見るようでした。

開発:あの男性はおばちゃんを女性として認識している感じがしましたね。

基盤:おばちゃんは実は女性だった!

社長:一般的にはそうでしょう。

開発:バグズ・ライフのてんとう虫が子供におばちゃんて呼ばれてましたね(笑)

経理:昨日のカードの使用履歴を見ますと、アマゾンVM20台一ヶ月分が一瞬で消費されてますが。

社長:いや昨日は久しぶりにボウリングの試合に出ましてね。ヒゲがちょっとウケましたw。コロナで試合が無くなってから2ヶ月?何も運動してなかったもんで、火星人みたいな状態なわけですよ。それで15ポンドの鉛のように重いボールを持ったり投げたりするのって、最初は恐怖感がありましたね。スピードが16km/h出なかったりとか。だけど本番になったら出端から裏ターキーだったり。まさにビギナーズラックw。ていうかあのまま変えずに投げてたらスコア的には良かったのかも知れないけど、恥ずかしいから表に入れたくなってしまうわけです。すごく凸凹したけどこんな状態で200も出るもんだなと関心しました。チームも好調で、全体の2位で今季を終えました。だけど3ゲーム目にもう体力というか握力の限界みたいになってしまい。今日もまだ手首あたりにだるさが残っています。昔は30ゲームくらい平気で投げたものですが…

社長:まあそれで無事に試合を乗り切ったごほうびに、ボウリング場の向かいの台湾料理の店で祝杯を挙げたわけです。あの店では致死量まで飲み食いしても5,000円を超える心配はありません。でそこから代行なんですが「7kmで2,500円です」て告げられた時。以前はなんとも思わなかったのですが、アマゾンVM5台ぶんかぁと思ったら、ずっしりと来ましたね。

基盤:まあそれを言えばタバコひと箱でVM1ヶ月動くわけですからね。

開発:基本、気晴らしに一番お金がかかると。

社長:それでかえりがけにゥエルシァでタバコなんかを買ったのですが、支払いは非接触でできますとカードのメールにあったので、試したんですが、ダメでした。たぶんコンビニでの話なのかな。

経理:そうするともうナナコも不要になりますね。

開発:さらばななこ、そしておにぎり銀行。

社長:それで4月からずっと不愉快なのですが、レジ袋は有料になりますがどれになさいますか?と聞かれるわけです。買った分がちょうど入る袋に決まってるし、どのサイズが適切なのか、そっちで判断してくれよと思うわけです。で「ちょうど良いサイズのをw」って答えるんですが、それもるもう飽きたというかうんざりです。

社長:ああそれで、カップ麺の棚を眺めたところ、100円以下、150円前後、200円超という3クラスがあることに気づきました。凄麺は200円、カップラーメンが150円、辛ラーメンとかが100円、そういう棲み分けのようです。

開発:そういえばトイレのLED電球が海王星状態になってしましました。

開発:ボイジャーになった気分です。

社長:それ、買ってくるの忘れました。お出かけ前にポチポチっとして袋に入れといてくれたら良いのに。まああそこがそういう気の利いたサービスできるとは思えないですが。

基盤:というか、都会ならアマゾンで宅配してくれるのでは。

開発:いや、それをやったら足腰退化してまじ火星人になっちゃうでしょう。

* * *

— 2020-0630 SatoxITS

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です