7月 132016
 

Varnish4.1.3がリリースされました。
バグフィックスが主でアップデートを強く進めますが、他にも結構使える新機能が増えています。

ダウンロードはこちら
changes

新機能・変更

varnishncsaにバックエンドに問い合わせにいったものだけを表示するオプションが追加されました(-b)
今までは幾つか絞込の指定をしないと取れなかったのですが-bだけで済むので便利です
また同時にクライアントで絞り込んで表示するオプション(-c)も追加されています。(デフォルト動作)
ちなみに-b -cを同時に指定することも出来ます。

VSMを開放する際にどれだけ待機するかのパラメータが追加されました(vsm_free_cooldown)
今までは60秒でハードコードされていました。デフォルト値も60秒です。
通常の使い方ではいじることはないと思いますが、かなり激しいログの書き込みをするとかの環境だといじる機会はあるかもしれないです。

varnishlogの出力でバックエンドのトランザクションが開始する際にBackendStartが入るようになりました
クライアントのReqStartと対になるものです。

varnishncsaの-Fで指定できるものが増えました
3つ増えました。
 Varnish:side
 先ほど紹介した-b -cオプションに伴って増えたものです。
 バックエンドで絞込をしている場合はbを、クライアントからの表示の場合はcを出力します。
 -b -cを両方指定している場合に使うとどちらのログなのかがわかって良いと思います。
 Varnish:vxid
 vxidを出力します
 VSL:tag VSL:tag[field]
 指定したタグ(TimeStampなど)を出力します。
 基本vsl-queryと同じ指定ですがヘッダ指定は出来ません(VSL:ReqHeader:User-Agentみたいなのは出来ない)
 これできるといいなーと思うのでp-r書こうかな・・
 ちなみに複数引っかかる場合は最初のを出力します。
 例えばVSL:TimeStampを指定した場合は毎回Startのタイムスタンプが表示されます

TCP Fast Openをサポートしました
デフォルトはoffです(tcp_fastopen)

varnishtestに新しい同期用の命令を追加しました(barriers)
semaより使いやすいです

varnishstatで12桁以上の数値を出力する場合は丸めるようにしました#1855
CURRENTの表示でK/M/G/Tのように単位がつけられないカウンタは” %12ju”だったのですが12桁を超える場合は1000で割って” %9ju…”という表示になります。
コードを見た限りではxml/jsonで出力するときには影響しないのでそこまで気にすることはないかなと思います。

バグ修正

今回はかなりバグ修正が多いので幾つかピックアップして紹介します。
特にESI周りの修正が多いのでESIを使っている場合はアップデートすると良いと思います。

varnishncsaで-Lオプションが受け付けられないようになってたのを修正しました#1994

たまにAgeとAccept-Rangesヘッダが複数レスポンスされることがあるのを修正しました#1955

同名のVCLでvarnishをstop->startを繰り返すとその後segfaultを繰り返す事があったのを修正しました。#1933
dlopenのリファレンスカウンタが信用ならなかったみたいです。
vcl名は変わらないのですが、コンパイルしたvgc.soのパスに現在時刻(ナノ秒)が付与されるようになりました。
バッドアイデアとメッセージにあるので割と苦悩した感じがあります。

vcl_init/finiでstd.log/std.syslogを利用するとクラッシュするのを修正しました#1924

VSMのサイズが小さくてオーバーラン検出に問題が合ったのを修正しました#1873
varnishncsa等でオーバーランした際にもクラッシュしなくなりますが
オーバーランしたらvsmサイズを増やしたほうが良いでしょう。
それでも困るようであれば今回追加されたcooldownの調整も考えると良いかも

-Cオプション利用時にテンポラリで使用したディレクトリを消していなかったのを消すようにしました#1869

POSTリクエストをpipeで繋いだ場合に1分待たされることがあるのを修正しました#1806
4.1からはPOSTリクエストのデフォルトの動作がpassになっているので通常の場合は問題ないのですが
以前からの設定を使いまわしてる人などは割りとハマるかもしれないです。

バックエンドの接続数を示すカウンタを復活させました#1725
バックエンド周りのコード修正した際に意図せず消えたカウンタを復活させました。
確かに消えてました・・気づかなかった・・

次は5.0.0かなー
楽しみですね


3月 072016
 

Varnish4.1.2がリリースされました。
バグフィックスが主ですが、一部新機能があります。

ダウンロードはこちら
changes

また2016-03-09 12:00 CET(日本時間 同日20時)からリポジトリの場所が変更になります。
これは去年アナウンスされていたVarnish Cache project autumn cleaningの一環になります。
また、まだドキュメント側は更新されていませんがバグ報告についてもgithubに移行するはずです。

機能追加/改善

REAL型同士で算術演算子を使えるようになりました
4.1.1まではREAL型同士は+以外は使えなかったのですが新たに-*/がサポートされるようになりました。(1.1 – 0.9とかが出来るように)

absoluteURIでhttpsからはじまる場合でもHostをパース出来るようになりました
言葉にするより表のほうがわかりやすいと思いましたので動作パタンを表にしました。

  http://example.com/foo https://example.com/foo
Version req.http.host req.url req.http.host req.url
~4.1.1 example.com /foo https://example.com/foo
4.1.2~(with feature +https_scheme) example.com /foo example.com /foo

PROXYプロトコルに4.1で対応したしといった感じかと思います。
なお、標準ではoffになっているのでfeature +https_schemeを指定する必要があります。

VMODでACLが扱えるようになりました
vmodtool.pyを改善して4.0/4.1でソースツリーを共有出来るようにしました
おもにVMOD作成者向け

vmodtool.pyを改善して1つのディレクトリから複数のvmodを作成コンパイル出来るようにしました
varnish-modulesというのが少し前に公開された(Varnish謹製のVMOD集)のですが、これのための対応といった感じです

バグ修正(一部抜粋)

Content-LengthがないHTTP/1.0かつPOST/PUTした場合すぐ400を返すように変更(#1843)
今まではchunkedとして扱ってしまって結果としてtimeoutを待ってましたが400をすぐ返すように変更しました。

フェッチ時(VFP_Push)にworkspaceがオーバーフローした場合panicしていたのをFetchErrorに変更しました(#1739)
panicするほどのエラーではないということで変更です。

hit-for-pass利用時にbodyが空っぽになるケースがあったのを修正(#1858)
本来不要なIMSの評価を行っていたため結果としてbodyが空っぽになるケースがあったのでhit-for-pass時のIMSの評価を辞めました。

ESI利用時にメモリリークするケースがあったのを修正(#1860)
これはAddressSanitizer(ASAN)で検出したのです。(他にも#1852を検出しています)
ASANについては以下を見てみると面白いと思います
CAN WE RUN C CODE AND BE SAFE?

ban-listを回収(ban-lurker)してる際にpanicするケースがあるのを修正しました(#1863/#1864)


2月 032016
 

Varnish4.1.1がリリースされました。
ドキュメントの修正や、バグフィックスが主ですが幾つかの仕様変更があります。
4.1.0を利用している場合はアップデートをおすすめします。

ダウンロードはこちら
changes

機能追加

varnishncsaに-fオプションが追加されました
これは単純に-Fで指定するフォーマットをファイルから読み込みができるというだけです。
エスケープ等が面倒な時はよいかもしれないです。

仕様変更

varnishncsaはデーモンで動作する際に-wオプションが必須になりました
-wはファイルに出力するオプションで、通常デーモンで動作させる場合は指定しているものなので特に影響はないかと思います。

If-None-Match(INM)とIf-Modified-Since(IMS)リクエストが同時に来た場合IMSを無視します
この動作自体はRFC7232の3.3に記述されている通りです
(A recipient MUST ignore If-Modified-Since if the request contains an If-None-Match header field)

ステータスコードが1xx, 204, 304の場合はContent-Lengthヘッダをレスポンスしません
これらのステータスコードはbodyを含みませんので不要です。

VCLをネストしてincludeする際のカレントディレクトリをそれぞれのVCLのディレクトリに変更しました
いまいち一文で書くとわかりづらいのですが用はこういうことです。


/etc/varnish/default.vcl
/etc/varnish/common/base.vcl
/etc/varnish/common/acl/internal.vcl
/etc/varnish/common/acl/admin.vcl

例えばVCLをこのように配置していて相対パスでincludeする場合


~4.1.0
■/etc/varnish/default.vcl
vcl 4.0;
include "./common/base.vcl";

■/etc/varnish/common/base.vcl
vcl 4.0;
include "./common/acl/internal.vcl";
include "./common/acl/admin.vcl";

4.1.0までは基点となる/etc/varnish/を基準とした相対パスで書く必要がありましたが、
4.1.1からは


4.1.1~
■/etc/varnish/default.vcl
vcl 4.0;
include "./common/base.vcl";

■/etc/varnish/common/base.vcl
vcl 4.0;
include "./acl/internal.vcl";
include "./acl/admin.vcl";

このようにincludeが記述されたVCLのディレクトリを基準として読み込みます。
割と便利だと思います

hit-for-passもgrace動作するようになりました(#1818)

vcl_dir, vmod_dirにコロン区切りで複数のディレクトリを指定できます

varnishreplayが削除されました
少し前からコンパイルされないようになっていたのですがコード自体も削除されました。

バグ修正(一部抜粋)

大きなファイルを扱う際に遅くなっていたのを修正(#1798)

IPv6アドレスのパースに失敗するのを修正(#1801)

PROXYプロトコルを利用した際にvarnishlogが正しく表示されないケースがあったのを修正しました(#1804)
Proxyプロトコルのvxidが0になっていてその影響で-g request, sessionがうまく動きませんでした。

INMリクエストでETagを比較する際に弱い比較関数を使用するようにしました(#1816)
RFC7232に準拠した形です。

vsl-queryでフィールドをfloatsで評価しようとした場合に評価できないのを修正(#1845)
4.1.0からのデグレですが、具体的には”timestamp:resp[2] > 1.”のような絞り込みができなくなってました。


10月 122015
 

Varnish4.1.0がリリースされました。
多くの新機能・改善・バグフィックスとほんの少しのVCLの変更があります。
特にバグフィックスを求めるユーザにとっては朗報です。
今までチケット上は修正されたけど各ブランチにマージされていなかったものが全て今回4.1ブランチにマージされたのでそれを求めるユーザにとっても更新するのも良いと思います。
割と大規模な変更があるので安定性について気になっている方もいると思いますが、4.1.0-beta1を2週間強ほど知り合いのサイト(ESI含む)に入れて運用しましたが
踏んだバグは一つ(#1792)で修正済みで安定して動いています。
また、CPUの使用率も下がっているようです。
ダウンロードはこちら

VCLの変更について
本家のアップデートガイドでも書いてある通り4.0.xのVCLをそのまま使用することが出来ます。
但しdeprecated的なのが増えているのとvmod_stdで引数の追加があるので注意が必要です。

HTTP/0.9のサポートを終了しました
むしろしていたのかという気持ちに・・

PROXY Protocol(v1/v2)のサポート
PROXY Protocol(v1/v2)をサポートしています。
使用する場合は起動オプションで以下のように指定します。(,PROXYを追加)


-a [IP Address]:[Port],PROXY

これに伴いremote.ip/local.ipが追加されました(後述)
接続してくる上位PROXYサーバのIPを制限したい時(ACL)に便利です。
またVarnishではhitchというPROXY Protocolを喋るTLS/SSLProxyを作っており(この前バージョンが1.0.0になった)
これと組み合わせるのを想定していると考えています。

VCLの自動cold/warm機能
Varnishはvclをreloadをした場合でも古いvclを保持しておいて後で使用することが出来ました。
この状態ではオリジンにヘルスチェックが飛んでしまい、それを防ぐには古いvclを削除するには明示的にdiscradをする必要がありました。
しかし4.1では使用されなくなったVCLは一定時間経過後(vcl_cooldown)にcold状態になりヘルスチェックが止まります。

セキュリティの強化(jails)
4.0.3


root     30262  0.0  4.2 124540 84320 ?        SLs  Oct05   0:43 /usr/sbin/varnishd ...
nobody   30264  0.1  4.2 582932 85724 ?        Sl   Oct05  15:19  \_ /usr/sbin/varnishd ...

4.1.0


varnish   1278  0.2  0.2 124768  5376 ?        Ss   16:32   0:00 /usr/sbin/varnishd ...
varnish   1280  1.7  5.8 1639192 117276 ?      Sl   16:32   0:00  \_ /usr/sbin/varnishd ...

今まではマスタープロセスはroot権限で動いていたのですが4.1からはセキュリティの強化のためになるだけ別ユーザで動くようにしました。
デフォルトではvarnishを使います。
もし任意のユーザ名を指定したい場合は起動オプションで-jオプションで指定可能です。

VMODでアクセスできる範囲の大幅な強化
これはどちらかと言うとVMODを作る人向けなのですが
以下のことが可能になっています

  • レスポンスボディに対するフィルタ機能(VFP/VDP)
  • バックエンドの動的生成
  • カスタムバックエンドの作成

まだすべて試しきれていないのですがどれも非常に強力です。
これは機会があれば別記事で取り上げようと思います。

動作変更

stale-while-revalidate(RFC5861)に対応しました
graceの初期値に使う感じです。

VCL変更/アクションのリターン値

vcl_hit
return(fetch)はreturn(miss)に変更する必要があります。
ただし4.1.0時点では変更を促すログを出しますがfetchはmissと同じように動作します
恐らく次の大型バージョンアップ時で消されるのではないかと思います。

vcl_backend_error
return(abandon)が追加されました。

vcl_init
return(fail)が追加されました。
文字通りfailを返すとvclの初期化に失敗します。

VCL変更/変数

remote.ip / local.ip (IP READ)
先程も述べたとおりPROXY Protocolに対応したため、それに伴いclient.ip/server.ipにPROXYサーバから渡された値が入ってくるようになりました。
(※ここで言うPROXYサーバはhaxproxyだったりAWSのELB等のPROXY Protocolを喋る上位サーバです。)
そのためclient.ipがVarnishに接続してきたIPアドレスを示すのではなくPROXYサーバがに接続してきたIPアドレスが入ってくる可能性が出てきました。
言葉で説明するよりマトリックスで示したほうが分かりやすいので以下に示します。


Direct
[client(192.168.1.200)]
   ↓
[Varnish(192.168.1.100:6081)]

Proxy Protocol
[client(192.168.1.200)]
   ↓
[HAProxy(192.168.1.10:8080)]
   ↓
[Varnish(192.168.1.100:6086)]

Description Direct PROXY Protcol
remote.ip ローカル(Varnish)に接続してきたIPアドレス 192.168.1.200(Client) 192.168.1.10(HAProxy)
client.ip クライアントのIPアドレス 192.168.1.200(Client) 192.168.1.200(Client)
local.ip ローカル(Varnish)のIPアドレス 192.168.1.100:6081(Varnish) 192.168.1.100:6086(Varnish)
server.ip クライアントのコネクションを受けたIPアドレス 192.168.1.100:6081(Varnish) 192.168.1.10:8080(HAProxy)

req_top.* (READ)
トップリクエストのreq.*を参照します、書き込みは出来ません。
何に使えるかというとESIの時に親(top)のreq.urlを知りたいといった時です。
取得できるのはあくまでもリクエストに関わるものなので例えばreq_top.backend_hintみたいなものはありません。
使用できるのは以下です。
req_top.method
req_top.url
req_top.http.*
req_top.proto

beresp.was_304 (BOOL READ)
文字通りbackendから304(Not Modified)が返却され、既に取得しているオブジェクトのリフレッシュに成功した場合にtrueになります。

beresp.age / obj.age (DURATION READ)
オブジェクトが生成されてからの経過時間(Age)を返却します。

beresp.backend (BACKEND READ)
fetchに利用したバックエンドを返却します。
例えばバックエンド名を取得したい場合はberesp.backend.nameとします。

resp.is_streaming (BOOL READ)
ストリーミングされている場合にtrueになります。

パラメータの変更

変更されたもの
workspace_session
4.0.3: 384byte
4.1.0: 512byte

vsl_mask
4.0.3: -VCL_trace,-WorkThread,-Hash
4.1.0: -VCL_trace,-WorkThread,-Hash,-VfpAcct
※VfpAcctは4.1.0で追加されたログ項目

削除されたもの
group
group_cc
listen_address
user
pool_vbc
timeout_req
timeout_idleと統一

追加されたもの
vcl_cooldown
VCLがcold状態に遷移するまでの時間

vmod_std

real2integerが追加されました。
型変換関数でfallbackがなかったものにfallbackが追加されました(time2integer / time2real / real2time)

varnishstat

-wがなくなりました

varnishhist / log / ncsa / top

-tオプションが追加されました(VSMを開く際のタイムアウト設定)

その他

vmodを追加しました
追加したといってもデフォルトで入っているわけではなく別reposです
libvmod_saintmode
Varnish3.0系であったsaintmodeです

libvmod_xkey
セカンダリハッシュを作成します。主にパージに利用し高速に動作します。
恐らくですがVarnishPlusで提供されていたhash-ninjaと同等のものと考えています。

libvmod-rtstatus
varnishstatと同等のデータを出力します

リンク

https://www.varnish-cache.org/docs/trunk/whats-new/changes.html
https://github.com/varnish/Varnish-Cache/blob/4.1/doc/changes.rst


3月 302015
 

Varnish3.0.7がリリースされました。
Version3.0.xのサポート期限が4月までのため流石にもう追加リリースはないんじゃないかと考えています。

なお今回のリリースはバグフィックスと改善になります。
アップデートを強くおすすめします(特にラインセパレータの扱いに対する修正のため)

Changes
ダウンロード


BugFix

1690 – RHEL7/CentOS7環境においてinitスクリプトの問題でうまく動かない問題を修正しました

単一のCR(\r)をラインセパレータとして扱うのを辞めました
通常LFもしくはCRLFをラインセパレータとして使いますがCRも許容していました。
これによりHTTPを解釈する複数のMWでのヘッダの解釈違いを利用することでキャッシュポイズニング攻撃を行うことが可能です。
といっても割と限られた条件なのでめっちゃ緊急というわけでもないです。

クライアントから複数のContent-Lengthを送られてきた場合に400を返すようにしました

1627 – Content-Lengthがおかしいのを修正しました
HTTP/1.0なクライアントでgzip+streamingの場合にContent-Lengthがおかしくなっていたようです。

ban利用時にメモリリークしていたのを修正しました

改善

Hop-by-hop/Endo-to-endヘッダのチェックを強化しました

親-子プロセスにおいて通信の問題が起きた際のエラー検出・再起動プロセスを改善しました


2月 222015
 

Varnish4.0.3がリリースされました。
今回のリリースは公式で行ってる通り多くのfixがありますが重要なバグフィックスを含みます。
比較的遭遇しやすいRaceコンディションに起因するpanicが修正されています。
アップデート時の注意事項はありますが、基本的にアップデートをおすすめします。

Changes
ダウンロード

変更内容から幾つか抜粋して紹介します。


バグフィックス

1650 – 複数のXFFヘッダがあった場合は折りたたむように修正しました

1620 – スレッドプールに空きが無い場合にclientスレッドを使うのを辞めました
空きが無いためbackgroundスレッドを作成出来ない場合にclientスレッドを使っていたのを辞めました。
また、フェッチするためにスレッドがない場合にカウントアップするカウンタfetch_no_threadが追加されました。
これがもし増えるような状況であればスレッド周りのパラメータ調整を行うと良いでしょう。

1566 – VCL中の「?」をエスケープするようにしました

1660 – SynthではRangeリクエストを無視するようになりました。
Synthでレスポンスを返すパスでrangeリクエストを受け付けた場合にassertしていたためです。

1637 – VEP(ESI処理)のコールバックが失敗した際にpanicしていたのをフェッチ失敗(503)として扱うようにしました

1665 – リクエストのタイムアウト計算をドキュメントに合わせました
リクエストのタイムアウトを計算する際にアイドルタイムを基準に計算していましたが
リクエストの最初のバイトを受け取った時間を基準に変更しました。

1672 – バックエンドが意図しない304をレスポンスしてきた場合にpanicしたのを修正しました
バックエンドに対してINM/IMSリクエストをしていないのに304をレスポンスしてきた場合にpanicしたのを修正しました。

1539 – lookupしようとしたオブジェクトがちょうどオブジェクトを開放していくスレッドに変更された際にpanicしてたのを修正しました
感覚的にですが、割と踏む確率が高かったバグです。

1349 – varnishadm:backend.set_healthyのマッチを修正しました

1623 – varnishhist:-dオプション使用時にsegfaultするのを修正しました

1378 – varnishncsa:印字不可能な文字をエスケープして出力するようにしました

1462 – varnishncsa:URLなどリクエストに関わる値は最初のエントリを利用しステータスコードなどレスポンスに関わるものは最後の値を使うように変更しました
いまいちわかりづらいのでIMSリクエストを送った場合のログで例をあげます
■4.0.2/varnishncsa


192.168.1.31 - - [19/Feb/2015:01:47:49 +0900] "GET http://192.168.1.37:6081/x.html HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"

■4.0.3/varnishncsa


192.168.1.31 - - [19/Feb/2015:01:47:16 +0900] "GET http://192.168.1.37:6083/x.html HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"

■4.0.2/varnishlog -graw -c


         6 Begin          c sess 0 HTTP/1
         6 SessOpen       c 192.168.1.31 59552 :6081 192.168.1.37 6081 1424279850.057539 15
         6 Link           c req 7 rxreq
         7 Begin          c req 6 rxreq
         7 Timestamp      c Start: 1424279850.057624 0.000000 0.000000
         7 Timestamp      c Req: 1424279850.057624 0.000000 0.000000
         7 ReqStart       c 192.168.1.31 59552
         7 ReqMethod      c GET
         7 ReqURL         c /x.html
         7 ReqProtocol    c HTTP/1.1
         7 ReqHeader      c Host: 192.168.1.37:6081
         7 ReqHeader      c User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0
         7 ReqHeader      c Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
         7 ReqHeader      c Accept-Language: ja,en-us;q=0.7,en;q=0.3
         7 ReqHeader      c Accept-Encoding: gzip, deflate
         7 ReqHeader      c Connection: keep-alive
         7 ReqHeader      c If-Modified-Since: Wed, 18 Feb 2015 16:43:37 GMT
         7 ReqHeader      c If-None-Match: "280ea4-b-50f5f855c1b9e"
         7 ReqHeader      c Cache-Control: max-age=0
         7 ReqHeader      c X-Forwarded-For: 192.168.1.31
         7 VCL_call       c RECV
         7 VCL_return     c hash
         7 ReqUnset       c Accept-Encoding: gzip, deflate
         7 ReqHeader      c Accept-Encoding: gzip
         7 VCL_call       c HASH
         7 VCL_return     c lookup
         7 Debug          c "XXXX MISS"
         7 VCL_call       c MISS
         7 VCL_return     c fetch
         7 Link           c bereq 8 fetch
         7 Timestamp      c Fetch: 1424279850.058979 0.001355 0.001355
         7 RespProtocol   c HTTP/1.1
         7 RespStatus     c 200★←これが使われた
         7 RespReason     c OK
         7 RespHeader     c Date: Wed, 18 Feb 2015 17:17:30 GMT
         7 RespHeader     c Server: Apache/2.2.22 (Ubuntu)
         7 RespHeader     c Last-Modified: Wed, 18 Feb 2015 16:43:37 GMT
         7 RespHeader     c ETag: "280ea4-b-50f5f855c1b9e"
         7 RespHeader     c Vary: Accept-Encoding
         7 RespHeader     c Content-Encoding: gzip
         7 RespHeader     c Content-Type: text/html
         7 RespHeader     c X-Varnish: 7
         7 RespHeader     c Age: 0
         7 RespHeader     c Via: 1.1 varnish-v4
         7 VCL_call       c DELIVER
         7 VCL_return     c deliver
         7 Timestamp      c Process: 1424279850.059049 0.001425 0.000070
         7 RespProtocol   c HTTP/1.1
         7 RespStatus     c 304★←本当はこれを使ってほしい
         7 RespReason     c Not Modified
         7 RespReason     c Not Modified
         7 Debug          c "RES_MODE 0"
         7 RespHeader     c Connection: keep-alive
         7 Timestamp      c Resp: 1424279850.059136 0.001513 0.000087
         7 Debug          c "XXX REF 2"
         7 ReqAcct        c 423 0 423 315 0 315
         7 End            c

■4.0.3/varnishlog -graw -c


     32774 Begin          c sess 0 HTTP/1
     32774 SessOpen       c 192.168.1.31 59586 :6083 192.168.1.37 6083 1424279998.331551 15
     32774 Link           c req 32775 rxreq
     32775 Begin          c req 32774 rxreq
     32775 Timestamp      c Start: 1424279998.331637 0.000000 0.000000
     32775 Timestamp      c Req: 1424279998.331637 0.000000 0.000000
     32775 ReqStart       c 192.168.1.31 59586
     32775 ReqMethod      c GET
     32775 ReqURL         c /x.html
     32775 ReqProtocol    c HTTP/1.1
     32775 ReqHeader      c Host: 192.168.1.37:6083
     32775 ReqHeader      c User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0
     32775 ReqHeader      c Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
     32775 ReqHeader      c Accept-Language: ja,en-us;q=0.7,en;q=0.3
     32775 ReqHeader      c Accept-Encoding: gzip, deflate
     32775 ReqHeader      c Connection: keep-alive
     32775 ReqHeader      c If-Modified-Since: Wed, 18 Feb 2015 16:43:37 GMT
     32775 ReqHeader      c If-None-Match: "280ea4-b-50f5f855c1b9e"
     32775 ReqHeader      c Cache-Control: max-age=0
     32775 ReqHeader      c X-Forwarded-For: 192.168.1.31
     32775 VCL_call       c RECV
     32775 VCL_return     c hash
     32775 ReqUnset       c Accept-Encoding: gzip, deflate
     32775 ReqHeader      c Accept-Encoding: gzip
     32775 VCL_call       c HASH
     32775 VCL_return     c lookup
     32775 Debug          c "XXXX MISS"
     32775 VCL_call       c MISS
     32775 VCL_return     c fetch
     32775 Link           c bereq 32776 fetch
     32775 Timestamp      c Fetch: 1424279998.333049 0.001412 0.001412
     32775 RespProtocol   c HTTP/1.1
     32775 RespStatus     c 200
     32775 RespReason     c OK
     32775 RespHeader     c Date: Wed, 18 Feb 2015 17:19:58 GMT
     32775 RespHeader     c Server: Apache/2.2.22 (Ubuntu)
     32775 RespHeader     c Last-Modified: Wed, 18 Feb 2015 16:43:37 GMT
     32775 RespHeader     c ETag: "280ea4-b-50f5f855c1b9e"
     32775 RespHeader     c Vary: Accept-Encoding
     32775 RespHeader     c Content-Encoding: gzip
     32775 RespHeader     c Content-Length: 31
     32775 RespHeader     c Content-Type: text/html
     32775 RespHeader     c X-Varnish: 32775
     32775 RespHeader     c Age: 0
     32775 RespHeader     c Via: 1.1 varnish-v4
     32775 VCL_call       c DELIVER
     32775 VCL_return     c deliver
     32775 Timestamp      c Process: 1424279998.333124 0.001487 0.000075
     32775 RespProtocol   c HTTP/1.1
     32775 RespStatus     c 304★←これを使った(最後のエントリ)
     32775 RespReason     c Not Modified
     32775 RespReason     c Not Modified
     32775 RespUnset      c Content-Length: 31
     32775 Debug          c "RES_MODE 0"
     32775 RespHeader     c Connection: keep-alive
     32775 Timestamp      c Resp: 1424279998.333257 0.001620 0.000133
     32775 Debug          c "XXX REF 2"
     32775 ReqAcct        c 423 0 423 319 0 319
     32775 End            c


4.0.2の場合はステータス200でLength:0で帰ってきています。
これは最初に現れたRespStatusを利用したためです
期待しているのはdeliverする直前、つまり最後の値なわけで4.0.3では最後のRespStatusの304を出力するようになっています。

機能追加

vmod_std: VOID std.cache_req_body(BYTES)が追加されました
使い方については以前書いたこちらの記事を参照してください(Varnishでテストコードを書こう!~実践編~+Bodyを読もう!

vmod_std: TIME std.time(STRING,TIME)が追加されました


//VCL
std.log(""+now);
std.log(""+std.time("hogehoge",now));//無効な文字列を指定すると第二引数が使われる
std.log(""+std.time("Sun, 22 Feb 2015 00:0:00 GMT",now));

//結果
//-   VCL_Log        Sun, 22 Feb 2015 01:21:31 GMT
//-   VCL_Log        Sun, 22 Feb 2015 01:21:31 GMT
//-   VCL_Log        Sun, 22 Feb 2015 00:00:00 GMT

使用可能なフォーマットは


"Sun, 06 Nov 1994 08:49:37 GMT"
"Sunday, 06-Nov-94 08:49:37 GMT"
"Sun Nov  6 08:49:37 1994"
"1994-11-06T08:49:37"
"784111777.00"
"784111777"

です

VCL変更

bereq.uncacheableがread-onlyになりました

obj.uncacheableがvcl_hitではなくvcl_deliverで使えるようになりました

パラメータ変更

fetch_chunksizeが128KBから16KBに変更されました

アップデート時の注意

fileストレージを利用している場合で空き容量が指定サイズを上回っている場合に
「larger than file system」と出て起動に失敗します。(関係するコミット
Varnishのfileストレージを利用する場合にフラグメントを防ぐためにddで先にファイルを作っておく事を公式でも推奨していますが
既に確保しているサイズを考慮していないため、ddで事前確保しようとするとディスクサイズの50%以下しか使用できません。
一旦消してしまえば問題なく起動しますが注意が必要です。
また、この問題は当然ですが4.0.3にアップデートしたあとにrestartを行っても起きるので注意してください。(reloadは問題なしです)
あとでチケットきろうかなと思います。


10月 182014
 

Varnish4.0.2がリリースされました。
多くのバグフィックスと機能追加・改善・修正、ドキュメント改善などを含むためバージョンアップを強く薦めます。
ちなみにvarnishstatのヒットレート表示も復活しています。

Changes
ダウンロード

変更内容から幾つか抜粋して紹介します。


バグフィックス

ESIのメモリリークを修正

deliver時に競合状態陥る可能性があるバグを修正
チケット報告はされていないのできわめて稀なケースだとは思います。

再利用を行う変数の初期化不足で落ちるケースがあるのを修正しました(#1553)

purge時にworkspaceを使いきって落ちるのを修正しました(#1551)

varnishtopで正しくグループ化されないのを修正しました(#1591)

VMOD_ABIのバージョン要件が4.0.1で緩和されたはずなのにされていなかったのを修正しました(#1538)

varnishncsaでHTTPでない壊れたリクエストが来た場合に出力しないようにしました(#1584)

max-ageとageが存在する場合でTTL計算時にageが二重で効いていたのを修正しました(#1578)
例えばmax-ageが10でageが2だった場合、期待されるttlは8ですがageが二重で効いて6になってました。

director.hashでバックエンドを取得する際に存在しない変数を指定すると落ちるのを修正しました(#1568)
hashディレクターで取得する際にreq.http.cookieのようにリクエストによっては存在しないものを指定すると落ちましたがそれを修正。

vcl_backend_responseからretryするとbereqの変更内容が消えるのを修正しました(#1512)
この修正と一緒にbackendスレッドでロールバックを行うと落ちる問題も修正されました。

リクエストのbodyを読みきれなかった場合で落ちるケースが有るのを修正しました(#1562)

shm_reclenを増やすと落ちるケースが有るのを修正しました(#1547)

random/hashディレクターでsickなbackendにリクエストを投げるケースがあるのを修正しました(#1575)

varnishtest実行時にバッファ不足でassertが出るのを改善しました
varnishtestのログのバッファサイズは256KB持っているのですが
出力されるログが多すぎると以下の様なエラーがでるので512KBまで拡張しました。


パラメータ追加・変更

追加:group_cc
vclをコンパイルする際に利用するcc_commandを実行するグループを指定できます。

名前変更:vsl_reclen(旧名shm_reclen)
まだshm_reclenは残っていますがそのうち消えると思うので使っている場合は変えましょう。

値変更:workspace_client
最小値が3KBから9KBに増えました。


機能追加・改善・修正

vmod_std:querysortでのキー数制限(32)がなくなりました
workspaceを使うようになっていますのですごく大きなキーを変更する可能性がある場合は大きめにすると良いです。

vclにHTTP型が追加されました
reqやbereqなどをまるごとvmodに渡すようなことが出来るようになりました。

vmodにBYTES型が追加されました
もともとvclではあったBYTESですが、型変換無しでvmodに渡せるようになりました。

rollbackがstd.rollbackに移動しました
rollbackは非推奨になります。

vcl_deliverでsynthが使えるようになりました

varnishstatのhitrate表示が復活しました
よかった・・・

組み込みのエラーページがvalid HTML5になりました

server.(hostname|identity)がすべてのファンクションで使えるようになりました
4.0.1まではclientスレッドのファンクションでしか使えませんでした。

vmod_std:文字列検索をするstrstrが追加
使い方は通常のstrstrと同じです。
大文字小文字は区別されますので必要に応じてstd.tolowerを使うなどで揃えると良いです。


//STRING strstr([検索対象文字列], [検索文字列])

//req.url中に/admin/が含まれているかをチェック
if(std.strstr(req.url, "/admin/")){
  //found
  ...
}else{
  //notfound
  ...
}

varnishlog:-kオプションが復活
指定個数のトランザクションを表示したらexitするオプションです

varnishadm:vcl.showでincludeされているすべてが表示できる-vオプションが追加
varnishadmで現在loadされているvclのリストを出力するvcl.showというコマンドがあるのですが
一つ困ったところにinclude先が表示されないという問題がありました。
しかし今回サポートされた-vオプションでその名前でloadされているvclの全情報(builtin.vcl含む)が表示されるようになりました。


[root@cache01 ~]# varnishadm vcl.show -v boot

// VCL.SHOW 0 110 input
vcl 4.0;
import std;
import directors;
include "/etc/varnish/backend.vcl";
include "/etc/varnish/main.vcl";

// VCL.SHOW 1 5479 Builtin
...中略...

// VCL.SHOW 2 1180 /etc/varnish/backend.vcl
probe healthcheck {
...中略...

// VCL.SHOW 3 3179 /etc/varnish/main.vcl
sub vcl_synth{
...中略...

といった感じです。
コメントのVCL.SHOWは以下の情報を示します
// VCL.SHOW [srcbodyのインデックス番号] [文字列長] [srcname]
まずVCLはDSLで実行前にCのコードに変換されるのですが、その際にVCL_confという構造体に各種の情報が突っ込まれていてインデックス番号とsrcnameはそこの情報になります。


varnishd -d -f /etc/varnish/default.vcl -C
の出力から抜粋
const char *srcname[4] = {
        "input",
        "Builtin",
        "/etc/varnish/backend.vcl",
        "/etc/varnish/main.vcl",
};
const char *srcbody[4] = {
    /* "input"*/
        "vcl 4.0;\n"
        "import std;\n"
...
        "",
    /* "Builtin"*/
        "/*-\n"
        " * Copyright (c) 2006 Verdens Gang AS\n"
...
        "}\n"
        "",
    /* "/etc/varnish/backend.vcl"*/
        "probe healthcheck {\n"
...
        "",
    /* "/etc/varnish/main.vcl"*/
        "sub vcl_synth{\n"
...
        "",
};
...
const struct VCL_conf VCL_conf = {
        .magic = VCL_CONF_MAGIC,
        .init_vcl = VGC_Init,
        .fini_vcl = VGC_Fini,
        .ndirector = 9,
        .director = directors,
        .ref = VGC_ref,
        .nref = VGC_NREFS,
        .nsrc = 4,★VCLの個数
        .srcname = srcname,★名前(inputはルートのVCL、builtinはVarnishのデフォルトの動作を定義したもの、ファイルパスのものはincludeしたもの)
        .srcbody = srcbody,★VCLそのもの
        .recv_func = VGC_function_vcl_recv,
        .pipe_func = VGC_function_vcl_pipe,
        .pass_func = VGC_function_vcl_pass,
        .hash_func = VGC_function_vcl_hash,
        .purge_func = VGC_function_vcl_purge,
        .miss_func = VGC_function_vcl_miss,
        .hit_func = VGC_function_vcl_hit,
        .deliver_func = VGC_function_vcl_deliver,
        .synth_func = VGC_function_vcl_synth,
        .backend_fetch_func = VGC_function_vcl_backend_fetch,
        .backend_response_func = VGC_function_vcl_backend_response,
        .backend_error_func = VGC_function_vcl_backend_error,
        .init_func = VGC_function_vcl_init,
        .fini_func = VGC_function_vcl_fini,
};


直近のVDDによると次は4.1でが予定されていて速くて年内に出る可能性があります。


10月 182014
 

varnish3.0.6がリリースされました。
現在計画されている3.0.x系の最終リリースになります。

Changes
ダウンロード

今回のリリースはほぼドキュメント修正とバグフィックスですがpanic起こすバグ修正もありますのでバージョンアップをおすすめします。


バグフィックス

http_max_hdrが4の倍数でない場合にクラッシュして起動しないバグを修正しました(#1327)
親プロセスは起動しますが子プロセスがpanicを起こして上がってきません。

ESI利用時にReqEndのタイムスタンプがマイナスになるのを修正しました(#1297)
コードを見てる感じだと本来親リクエストでのみ初期化すべきタイムスタンプを
小リクエストを処理している際にも初期化してしまって演算時にマイナスになるようです。
動作上の実害はありませんが、詳しくログを眺めてる人にとっては気になるかもしれません。

特定条件でbanの回収が正常に出来ないケースを修正しました(#1470)
Busy状態のオブジェクトに対してban lurkerスレッドが動作しようとする場合は処理をスキップしますが
フラグの立て方がまずく、再実行時にマッチされないのを修正しました。

同梱されているjemallocがsegfaultを起こすのを修正しました(#1448)

バックエンド名のprefixがif/include/elseで始まる際にVCLのエラーになるのを修正しました(#1439)
地味に嬉しいです。

オリジンのレスポンスでgzipデータ終了後にごみデータが続くとスレッドがスピンするのを修正しました(#1086)

varnishtest実行時にバッファ不足でassertが出るのを改善しました
varnishtestのログのバッファサイズは256KB持っているのですが
出力されるログが多すぎると以下の様なエラーがでるので512KBまで拡張しました。


Assert error in vtc_log_emit(), vtc_log.c line 122:
  Condition(vtclog_left > l) not true.

ヘビーにvarnishtestを使う人(私とか)にとっては嬉しい変更です。


その他変更

varnishncsaの%Dが整数に切り捨てられます
4.0での変更と同様です。
マイクロ秒単位なので特に影響ないと思います。


6月 262014
 

Varnish4.0.1が公開されました。
ついでに公式サイトもデザインが新しくなって見やすくなりました。

バージョンアップ自体は主にBugfixで、4.0.0がリリースされて報告されていたバグが基本的に修正されています。
幾つか重要度の高いbugfixがあるので4.0.0を入れた人は適用するのをおすすめします。
(僕が報告してたスレッドが開放されないなどのバグも修正されてました)

また、今回も機能変更と追加がかなりされています。
動作に関わるところをについて抜粋して紹介します。

公式Changes
ダウンロード

機能変更

Persistent storageがdeprecatedになりました

ML見てたら不穏な動きが出てたのでどうなるかなーとおもってたんですがさっくり廃止予定になりました。
4.0.0になって多少使いやすくなったとおもったんですがパフォーマンスを維持しつつ整合性を確保するのがきつかったみたいです。
今後利用する際は-s deprecated_persistentと指定する必要があります。
また、やり取りでの想像ですが次のリリースで消すということはなさそうな気がします。
コード修正が必要になった段階で切り離すんじゃないかなと


vmod_std機能追加

クエリソート機能が追加されました(querysort)

vimeoのboltsortが取り込まれました。


sub vcl_recv{
  //in:/?a=1&c=3&b=2
  //  :/?b=2&c=3&a=1
  //out:/?a=1&b=2&c=3
  set req.url = std.querysort(req.url);
}

クエリをお手軽に正規化することが可能になりキャッシュ効率がよくなることが期待できます。
一つ注意事項があるとすればキー数は32に制限されていることです。
ただ、最新コード上はその制限が解除されており(というかリリース日当日に解除されてる)
次のリリースには取り込まれると思います。
32以上のキー数を扱う可能性がある場合はとりあえずこのComitを適用すればよいと思います

変換系のメソッドが追加されました

文字列->浮動小数(real)


//std.real([文字列], [パース失敗時のfallback値])
//out:
//-   VCL_Log        12.990
//-   VCL_Log        0.000
std.log(""+std.real("12.99",0.0));
std.log(""+std.real("hoge",0.0));


浮動小数->時間(real2time)


//std.real2time([浮動小数])
//out:
//-   VCL_Log        Wed, 25 Jun 2014 15:26:40 GMT
//-   VCL_Log        Wed, 25 Jun 2014 15:26:40 GMT
std.log(""+std.real2time(1403707478));
std.log(""+std.real2time(1403707478.999));

※若干例が悪いかも

時間->整数(time2integer)


//std.time2integer([時間])
//out:
//-   VCL_Log        1403707709
//-   VCL_Log        1403707769
std.log(""+std.time2integer(now));
std.log(""+std.time2integer(now + 1m));

時間->浮動小数(time2real)


//std.time2real([時間])
//out:
//-   VCL_Log        1403707750.479
//-   VCL_Log        1403707750.489
std.log(""+std.time2real(now));
std.log(""+std.time2real(now + 10ms));


VCL変更

日付の指定に年(y)を指定できるようになりました

365d = 1yです


その他変更

varnishncsaの%Dが整数に切り捨てられます

マイクロ秒単位なので特に影響ないと思います

varnishncsaで新しいフォーマットが追加されました

%I(全受信バイト数)と%O(全送信バイト数)が追加されました。
個人的に結構嬉しいです。

passがtransfer-encoding: chunkedに対応しました

今までreturn(pipe)じゃないとダメでした(builtin.vclでpipeしてた)


あとアップデートかけた時にVarnishのrestart走ります。(前まで無かったような気が・・・)
以下の組み合わせの場合は即死しますので注意してください
 ・persistentを利用している
 ・パッケージの自動アップデートが有効になっている
このケースの場合以下のコンボが成立します
 1) パッケージの自動アップデートがかかる
 2) 4.0.1でrestartがかかる
 3) persistentの名前を置き換える必要があるので起動しない
 4) ( ˘ω˘)

また、まだ告知はされていませんが3.0.6RC1が上がっているので近いうちに3系のアップデートも来るかもしれないです。
あと週末にでも別記事で4.1といった今後のリリーススケジュールについて書きます!


4月 112014
 

3.0.0の公開から約3年ぶりにメジャーバージョンが上がりました。(公式サイト)
今回も非常に多岐に渡る変更があるのですが、前回とはまた少し毛色が違います。
大きな変更点について見て行きましょう。

ストリームのフルサポート

3.0の時もストリームはサポートしていたのですが、4.0になってより強化されました。

初回コネクション 同時接続してきたコネクション
3.0 ストリームされる 初回コネクションが完了するまでロックされ、その後一気に転送
4.0 ストリームされる 既に初回コネクションでストリーム済みのデータを一気に転送してその後ストリーム

イマイチイメージが掴みづらいかもと思ったのでgifアニメを作ってみました。
やってる内容は、1秒ごとにaを出力するphpに対して開始時間を数秒ずらして3並列で取得していっています。
初回のアクセスが終わった後は何回かアクセスしてみてキャッシュされていることを確認しています。

window配置

初回のクライアント 3秒遅れのクライアント 5秒遅れのクライアント
apacheログ
varnishncsa

検証コード
■slow.php


<?php
header('Cache-Control: max-age=20');
ob_end_flush();
ob_start('mb_output_handler');
for($i=0;$i<10;$i++){
        echo "a\n";
        ob_flush();
        flush();
        sleep(1);
}

■vcl@3.0.5


sub vcl_fetch{
  set beresp.do_stream = true;
  set beresp.ttl   = 1w;
}

■vcl@4.0.0


sub vcl_backend_response{
  set beresp.do_stream = true;
  set beresp.ttl = 1w;
}

ストリームの様子のgif
3.0.5
varnish3-stream


4.0.0
varnish4-stream


3.0.5は最初のアクセス以外はブロックされていますが4.0.0はブロックされていない上に既に転送されているものは最初に一気に転送されているのがわかります。
比較的大きなコンテンツを配信する場合は非常に有用な機能といえます。

オブジェクトがexpireした際にgrace期間が残っている場合は、古いオブジェクトを返しつつバックグラウンドでオブジェクトを更新します

オブジェクトがexpireした時の動作も強化されました。

初回expire後のコネクション 同時接続してきたコネクション フェッチ終了後
3.0 fetchを行い新オブジェクトを転送する、fetchの間は通常どおり待機させられる 古いオブジェクトを転送 新オブジェクトを転送
4.0 バックグラウンドでfetchを行い、自コネクションは古いオブジェクトを転送 古いオブジェクトを転送 新オブジェクトを転送

今回もgifを撮ってみました。
取得に3秒かかるコードでTTLは10秒です。expire時の動きを見てみてください。

検証コード
■date.php


<?php
header('Cache-Control: max-age=20');
echo date("Y/m/d H:i:s")."\n";
sleep(3);

■vcl@3.0.5


sub vcl_fetch{
  set beresp.do_stream = true;
  set beresp.ttl   = 10s;
  set beresp.grace = 10m;
}

■vcl@4.0.0


sub vcl_backend_response{
  set beresp.do_stream = true;
  set beresp.ttl   = 10s;
  set beresp.grace = 10m;
}

grace動作
3.0.5
varnish3-bgfetch


4.0.0
varnish4-bgfetch


3.0ではexpire時にsleepが効いているのが分かります。
4.0ではそれがありません。

varnishlogをグルーピング出力したりqueryで絞り込むことが可能に

これは非常に大きな機能なので別記事で取り上げますが
簡単に言うとリクエストがどのESIにサブリクエストを使っているかなどがグルーピングできたり
携帯端末で1秒以上レスポンスにかかったログの抽出が出来たりします。

directorがvmodになりました

これも別記事で取り上げます。
独自のdirectorが作りやすくなったのと他にも利点があります。

vmodがrequest bodyを見ることが可能になりました

今までも超トリッキーな事をすれば見ることは可能だったのですが正式にサポートされました。
POSTリクエストの中身を見て何かしらの処理を行うようなvmodを作るのが簡単になります。

インラインCがデフォルト無効になりました

これは廃止されるというわけではなくセキュリティ対策としてデフォルト無効になっているだけです。
vcc_allow_inline_cというパラメータで復活可能です。

VCLが大幅に変わった

恒例行事です。別記事で書きます。
公式のアップグレード方法は以下です
Upgrading to Varnish 4

varnishapi周りが刷新

当然ですが3.0向けのvmodは移行が必要です。

バグ修正多数

今までバグ修正はされていたもののリリースには含まれていなかった様々なバグ修正が今回のタイミングで取り込まれています。
たとえば
syntheticでASCIIコード以外を出力しようとした場合に文字化けするバグ修正が取り込まれていたり
vclをdiscardしてもヘルスチェックが止まらないバグなどが直っています

varnishstatの表示改善

これは実際に触ってみたほうが早いですが、カウンタの説明が出るようになっています。

パラメータの変更

これも別途記事で書きます。

まとめ

他にも取り上げては居ませんがかなりの変更点があります。

さて、ここまでわざとぼかして書いていたのですが
今回の一番大きな変更はクライアントとバックエンドのスレッドを分離したことです。
これにより、ストリームやgrace時の動作改善などが可能となりました。
また現versionでは残念ながら実装されていませんが、パラレルフェッチESIも可能となるはずです。(予定には入っているようです)
また、これはコード上の話ですが3.0まではHTTPを処理する箇所がvarnishのコードと結構くっついていたのですが
4.0では分離されており拡張が容易な構造にリファクタリングされています。
これはHTTP2.0を見据えた変更です。
最初に2.1から3.0の変更とは毛色が違うといったのは、構造を大幅にリファクタリングしたということです。

また、検証をしている段階では比較的安定しており、最近趣味で手伝っているPVもそれなりに多いサイトに週末にでも投入して動作検証も行う予定です。
その結果も記事などにできればなぁと考えています。

あと今回もリリースパーティーやるみたいなので
誰かやらないかなとチラチラと・・・