afnf.net

帯域制限でNo buffer space availableを解決した

Linux squid VPS 2014/05/25 21:58

経緯

apache httpdでフォワードプロキシを運用していたのですが、稀に"No buffer space available"というエラーが出て、ネットワーク全体が死んでしまう問題が起きていました。発生すると、SSHログインすら不可能になります。

ServersMan@VPSのコンパネからOSを再起動すれば解消するのですが、さすがにまずいので調査しました。

構成とか

  • ServersMan@VPS
  • CentOS 6.5
  • apache httpd 2.2系
  • SSHポートフォワーディングでプロキシにアクセス

切り分け

問題の発生を確認したのは、プロキシ経由で大きなファイルをダウンロードしている場合だけでした。また、ダウンロード速度が速い場合に発生しやすいようでした。

さらにOS再起動で解消することから、VPSアカウントに対する制限が発動したわけではなさそうです。

クライアントは、WindowsとLinuxの両方で発生しました。サーバ側の問題であることは間違いなさそうです。

仮定

エラー内容と原因の切り分けから、ダウンロード速度とアップロード速度のギャップによる問題を疑いました。対向サーバからのダウンロードが速すぎるため、プロキシクライアントへのデータ転送が追いつかず、送信バッファが足りなくなるというストーリーです。

この仮定が正しければ、ダウンロード側の帯域制限で解消できるはずです。

類似の情報が多くないのは、SSHポートフォワーディングも一因になっているからだと考えました。トンネルによる暗号化と認証は必須なので、切り分けはやりませんでした。

mod_bwのインストール

httpdにmod_bwというモジュールがあるのですが、意図するような帯域制限ができませんでした。フォワードプロキシでは動作しないのかもしれません。

squidのインストール

httpd2.4系に乗り換えるのもあれなので、squid (3.1.10)を使うことにしました。

設定はこんな感じ。シンプルでいいですね。

# /etc/squid/squid.conf
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl CONNECT method CONNECT

http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny to_localhost

http_access allow localhost
http_access deny all

http_port 127.0.0.1:99999

visible_hostname unkown
forwarded_for off
request_header_access X-FORWARDED-FOR deny all
request_header_access Via deny all
request_header_access Cache-Control deny all

hierarchy_stoplist cgi-bin ?

cache_mem 32 MB
cache_dir ufs /var/spool/squid 128 16 256

coredump_dir /var/spool/squid

shutdown_lifetime 1 seconds

delay_pools 1
delay_class 1 1
delay_access 1 allow all
delay_parameters 1 500000/500000 #500KB/s = 4.0Mbps

外部公開の必要がないので、http_portで127.0.0.1を指定しています。念のため、allow localhostとdeny allも設定。

プロキシの使用を悟られたくないので、forwarded_forrequest_header_accessなども設定しました。

メモリを節約するため、cache_mem 32 MBを明記。

shutdown_lifetime 1 secondsを明記しないと、再起動に30秒かかります。ちょいハマり。

最下部の4行が帯域制限です。500KB/sとしました。

検証

帯域制限付きのsquidに移行してからは、"No buffer space available"は一度も発生していません。仮定は当たっていたようです。

まとめ

餅は餅屋。

書いていて気付いたんですが、帯域制限無しのsquidでエラーが再現するかどうか確認するべきでした。もしかするとhttpdのせいかもね(おい

Linux squid VPS 2014/05/25 21:58
comments (0)

blog-java2 engine (build:2017-09-13 21:46 JST)