10月 282018
 

6.1.0が出たときにすぐ記事を書かなかったのは、リリース後に一部デグレ(varnishhist表示)がIRCで話題になって6.1.1をリリースする?
みたいな話がでていたので実際に6.1.0を動かしながらはまりポイントがないかを探しながら6.1.1のリリースをまってました。
思ったより期間があいたので、先に書いとけばよかったなと反省しています。すいません。
また、すでにPRが用意されていることからさほど時期を開けずにLTS(多分)である6.0.2もリリースされると思われます。

6.0.0/6.0.1から6.1.1の変更は新機能もあるのですが、それ以上にバグ修正が多いので基本的にバージョンアップをおすすめします(6.0.2でもいいですが)

特に以下の機能を使っている場合は関連するバグ修正がいくつかあるのでバージョンアップを強くお勧めします。
・HTTP/2 (6.1.1/6.0.2のみの重要な修正があるので6.1.0/6.0.1を利用している場合もバージョンアップ必要)
・proxy protocol
・UDS
・pipe

ダウンロードはこちらから

6.1.xと6.0.xの違い

6.1.xはいくつかの新機能やコア部分の変更はありますが、バージョンアップに苦労するような変更はほぼありません。
例えばVCLについては削除された変数などがないため、6.0で動いていたものをそのまま動かすことができます。
ただしvmodについてはdirector APIの変更があったため、一部については再コンパイルだけでは動作させることができません。(要対応)

では、今回はどのような大きな変更があったかというと
backendをフェッチしてstorageに格納する際に呼ばれるVFPと呼ばれるスタックをVCLから入れ替えなどの操作ができることになったことです。
今までもVFPスタックに処理を追加することはできたのですが(Varnishでテストコードを書こう!~実践編~+Bodyを読もう!)、デフォルトの順番を動かすことや差し替えを行う事が難しかったのです。
例えば今回の変更で、デフォルトのgzip処理をZopfliに変更するようなこともできるといえば可能です。(他にもESI処理の置き換えも)
ちなみにVarnishにはクライアントにレスポンスする直前に呼ばれるVDPスタックもあるのですが、ここの同様な操作は6.1.xでは実装されていません。
しかしtrunkではVDP関連のコミットがあるのでおそらく次期バージョン(2019/03)では来ると思います。

VarnishのLTS

Varnishは古いバージョンのサポートを早々に打ち切ります。
しかし一部のバージョンについては長くサポートされています。
例えば4.1.xは5.xがサポートが打ち切られているのにも関わらずサポートされ続けています。
Releases & Downloads

特に明言されているわけではないのですが(MLとかIRCでなんどかそのような発言は見かけましたが)
VarnishSoftware(VS)がリリースしているVarnishCachePlusのベースとしているバージョンはLTSとしてサポートされるようです。
(用はスポンサーがついてる Please backport #2077 to 5.1.x
現在のところPlusは6.0.1r2と4.1.10r5がリリースされていますので6.0.xと4.1.xはLTSです。
とはいえ6.0ベースのPlusが出たので、さすがに4.1.xは収束していくのではと考えています。
もし、現在4.1.xを使っている方は6.0.xまで上げるのも検討してもよいかと思います。

6.1.1と6.0.2の位置づけについて

今回のリリースで6.0.2だけに追加されている機能があります。(もちろんVFPスタック操作については6.1限定です)
理由を聞いたところ6.1.1はbugfixリリースで新機能を入れることで新しいバグが入り込むのを避けたいということでした。

動作変更について

HostヘッダなしのHTTP/1.1のリクエストを400で返すように変更(#2631)
そもそもHTTP/1.1はHostヘッダが必須なので特に気にすることはないでしょう。
builtin.vclでの実装なので、どうしても困ることがあるのであれば処理を上書きすればよいかと思います。(望ましくないですが)
For HTTP/1.1 requests, Host is mandatory

パラメータの追加

max_vcl/max_vcl_handling
varnishの設定を適用する際にreloadをしていると以前のvclが残ります。
当然これらはディスク容量を圧迫しますし、また一部の操作(vcl.listなど)は当然遅くなります。
max_vclはvcl数の閾値でデフォルトは100です。で、閾値を超えた場合の動作を定義するのがmax_vcl_handlingです。
0は警告も何もしない、1でwarning表示(デフォルト)、2でVCLの追加を拒否します。
デフォルトの状態で使い続けても特にVCLの追加ができなくなることもないので(warnはでる)
warnが出たらvcl.discardしていくのもよいかと思います。

backend_local_error_holddown/backend_remote_error_holddown
バックエンドに接続を行う際に、自身もしくは接続先のリソース不足などで接続失敗することがあります。
この場合で即時再試行しても結局リソース不足で再度失敗することが多いので、少し待ってみるのも効果的です。
このパラメータはその秒数を指定するものです。
backend_local_error_holddownはEADDRNOTAVAIL・EACCESS・EPERMが起きた際に待機する秒数で
backend_remote_error_holddownはECONNREFUSED・ENETUNREACHが起きた際に待機する秒数です。
どちらもデフォルトでよいかなと思います。
また、これらのエラーが起きた際は後述するカウンタが上がりますので、その際はチューニングや構成見直しを行うと良いでしょう。

thread_pool_watchdog
h2の場合依存関係や制御情報をやり取りするだけのストリームがあるのですが、Varnishの場合はそれもスレッドを割り当てます。
ですので、スレッド不足で実際のリクエストに対してスレッド割り当てができない場合、そこでリクエストの処理を待ってしまいデッドロックする可能性があります。
これらのデッドロックを検知した場合に子プロセスを再起動するのですが、その設定時間がこれです。
基本的にデフォルト値で問題ないでしょう。
もし、これ起因でrestartが走るようであれば、スレッド関連の設定を見直すのがよいでしょう(thread_pool_maxなど)
また、h2起因で追加されたパラメータですが、別にh2以外でもデッドロックが起きた場合は発動します。

VCL変更

削除されたいくつかの変数が復活
req.ttl・req.ttl・req.graceが復活しています。

すでにimportしたvmodを再度importしようとしてもエラーにならないように変更
地味にうれしい変更です。
例えばvmod_stdはよく使われているvmodなのですが、複数のvclをincludeしている際にimport std;を複数のvclに記載してエラーになることがあります。(きちんとdefine.vclみたいなものにまとめておけばいいのですが)
この変更でエラーにならずに2回目以降のimportは無視されるようになります。

vcl_init中のreturn failでメッセージを入れられるようになりました
vcl_initで何かしらのエラーが起きて終了させたいときに使えるreturn(fail)ですが
なんのエラーで落ちたかとメッセージで出す方法がありませんでした。
今回return(fail(“foo”))といった指定が可能になったことで失敗した理由を通知することが可能です。


//vcl
sub vcl_init{
  return(fail("foo"));
}

//output
VCL "boot" Failed initialization
Message:
        foo

このような形で出力されます。

beresp.filtersの追加
後述します

新機能について

vmod_stdにfnmatchを追加


BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname=1, BOOL noescape=0, BOOL period=0)

shellでパスを指定するような(ex:/var/log/*)形で指定することが可能です。
pathname/noescape/periodはそれぞれfnmatchのflagsの該当するものと同じ意味です。
FNMATCH

サンプルにもありますが、


if (std.fnmatch("/foo/*", req.url)) { ... }

といった感じでurlマッチに使えると思います。
これの便利なところとしては、VCL中で使う正規表現と違いpre-compileが必要無いのでマッチパタンを変数にするといったことも可能です。

VFPスタックの呼び出し順をVCLから変更可能に(6.1.x)

先ほども述べた通り現状ですぐに役に立つものではありません。
VFPを提供するVMODが増えてくれば有用でしょう。
とりあえず現状どのようなものが適用されているかを確認するのであれば


varnishlog -graw -i filters

で見ることができます。

また、レスポンスヘッダにどのようなフィルタが使われているかをだすには


sub vcl_backend_response {
  set beresp.http.x-filters = beresp.filters;
}

このようにすればヘッダに出力されます。

また設定するには


sub vcl_backend_response {
  set beresp.filters = "esi" // gzipじゃない時のberesp.do_esi = true;と同等;
}

とすればよいでしょう。
とはいえ、理解せずに弄るといろいろ崩れたりしますので注意しましょう。(多分VMODで指定されると思うのでその通り使えばOKかと)
かなり上級者向けの設定です。

varnishadm(varnish-cli)でのjson出力(6.0.2/6.1.0)

json出力がサポートするようになりました。


# sudo varnishadm backend.list -j

[ 2, ["backend.list", "-j"], 1540196843.165,
  {
    "reload_20181022_074741_10060.***": {
      "type": "backend",
      "admin_health": "probe",
      "probe_message": "5/5 good",
      "last_change": 1540194463.057
    },

...

    "reload_20181022_074741_10060.***": {
      "type": "hash",
      "admin_health": "probe",
      "probe_message": "healthy",
      "last_change": 1540194463.054
    }
  }
]

6.1.1では一部、6.0.2は大部分のコマンドで出力をサポートしています。
varnishadmの結果をスクリプトで処理する際には非常に便利だと思います。

6.1.0/6.0.2の両方で対応しているもの
– ping
– backend.list
– help

6.0.2のみで対応しているもの
– status
– vcl.list
– param.show
– ban.list
– storage.list
– panic.show

statの強化
varnishstatで表示されるstatがかなり追加されています。
こちらも一部は6.0.2のみ対応の項目があります

6.1.0/6.0.2の両方で対応しているもの
– MAIN.sess_fail_econnaborted
– MAIN.sess_fail_eintr
– MAIN.sess_fail_emfile
– MAIN.sess_fail_ebadf
– MAIN.sess_fail_enomem
– MAIN.sess_fail_other
– [backend名].unhealthy
– [backend名].busy
– [backend名].fail
– [backend名].fail_eacces
– [backend名].fail_eaddrnotavail
– [backend名].fail_econnrefused
– [backend名].fail_enetunreach
– [backend名].fail_etimedout
– [backend名].fail_other
– [backend名].helddown

以下6.0.2のみ対応
– wrk.client_resp_500
– wrk.ws_backend_overflow
– wrk.ws_client_overflow
– wrk.ws_thread_overflow
– wrk.ws_session_overflow

例えばfail_eaddrnotavail(EADDRNOTAVAIL)であればエフェメラルポートの確保に失敗してるんだろうということで設定の見直しなどができると思います。
また、overflowのカウンタも便利です。
これらはそれぞれ起動パラメータのworkspace_clientなどと一致するので、カウンタが上がっていたらチューニングを行うと良いでしょう。

その他変更について

director周りにAPIが変更されているため一部vmodは対応が必要
通常のVMODであれば再コンパイルだけで動くと思いますが、director周りを触るvmodの場合は対応が必須です。
アップデートする前に対応しているか確認すると良いでしょう。

バグ修正について

6.0.2/6.1.1は大量のバグ修正が含まれます。
また、毎回言ってるのですがHTTP/2で重要なバグフィックスが2件あります(他にもあるんですが特に重要・・・)

HTTP/2利用時にスレッドリークが起こるの修正(#2623)

閉じられたストリーム宛てにPRIORITYフレームが届くとプロトコルエラーとして扱っていたのを修正(#2775)

http/2のexperimentalはまだ外れてないのですが、さすがにもう強烈なバグは出尽くしたんじゃないかなとか・・・考えてます。

そのほか

公式パッケージでUbuntu18.04(bionic)向けのパッケージが追加
varnishtestでhaproxyを扱うことが可能に
おそらくvarnishtestは将来的にプロジェクトが分離され汎用的になるでしょう(Divorcing varnishtest from varnish-cache)
既にレポジトリもあります
VTest