以下の内容はhttps://tech.guitarrapc.com/entry/2019/04/03/113434より取得しました。


AzureFunctions におけるStorageTableBindingの選択

Azureには、Storage Tableという機能があり単純なテーブル形式でデータが管理できます。 C# のコード的にはTableEntityを継承してデータを表現し、メソッドを組み立ててCRUDを実現できます。

さて、このStorage TableをWebJobs並びにその実装の1つであるAzure Functionsで使うときについて考えてみましょう。

概要

Bindingには複数の課題があり、特にStorage TableやDBのバインディングはパラメーターが多く、問題が起きやすい。

  • Bindingは属性 + エントリーポイントのエラーのためStackTraceを取れないケースが多い
  • 加えてBindingのリフレクション多用による難しさ
  • StorageTableとDBは特にパラメーターが多くBinding問題に当たりやすい
  • NuGetバージョンのRegression耐性の乏しさ

このため、Storage TableやDBに関してはBindingはやめてFunction内でクライアントを自前で作って安定させるほうが良いことも多いです。

他のHttpTriggerやQueueなどはシンプルでトラブルが起こりにくく、自前で定型的に実装することになる機能がサポートされるので使ったほうが楽なBindingと感じます。

Binding にまつわる実装とデバッグの距離

自前コードからの呼び出し口があれば、デバッガを仕掛ける口があり距離としては近づきます。 しかし、Bindingは初期化時に起こるためデバッガとの距離が遠いという、作り上の潜在的な課題があります。

どこまで簡単にデバッグできるかはかなり重要な選択基準になるので順に見てみましょう。

属性 + エントリーポイント

Bindingは属性 + エントリーポイントのエラーのためデバッガを仕掛ける口がFunctionに開いていません。そのため、シンボルをVSで捕まえられるかが容易なデバッグの鍵となりますが、残念ながら多くの場合機能しないことが多いです。

例えば、Microsoft.Azure.WebJobs.Extensions.Storageが3.0.1のときはシンボルも取れずデバッガはおろかStackTraceも取れません。

Microsoft.Azure.WebJobs.Extensions.Storage が 3.0.1 でTableAttributeBinding でトラブル時は厳しい状況になる

→ Microsoft.Azure.WebJobs.Extensions.Storage 3.0.1から3.0.5に上げることでデバッガがソース内部まで行くように改善されます。(Bindingで落ちることに変わりはない)

この状況は、Bindingのパラメーターを間違えれば容易に再現できるので、エラーから状況を把握することを試してみてください。

リフレクションの多用とRegressionの多さ

WebJobsのBindingはリフレクションを多用しており、些細なミスで機能しないことが起こりえます。NuGetライブラリバージョンに依存したBinding失敗でバージョンを上げると同一コードで動かないといったRegressionが過去に何度も起こっており、また現在も起こりえます。

例えば、AzureFunctionsで利用するプロジェクトが複数あったときに、Microsoft.Azure.WebJobs.Extensions.Storageの下限バージョンとWindowsAzure.Storageバージョンでミスマッチを起こしているとBindingエラーが起こるようになります。(BindingRedirectではなく、です..... )

この問題は、気づけるなら大したことはありませんが、エントリーポイントのBindingでのエラーのため、自分のパラメーターミスが原因だった時と同じエラーでもあるため気づくのはこんなんです。

結果として、Bindingでのトラブルは解消するのが難しいです。

NuGetバージョンに起因した問題の再現方法

2つプロジェクトを用意し、片方はAzure funcitonsのプロジェクトでMicrosoft.Azure.WebJobs.Extensions.Storageを入れておきます。(例では3.0.1) もう片方は、WindowsAzure.StorageをNuGetで入れます。(何も考えずにいれると9.3.3が入ります)

AzureFunctionsでTableBindingをかけて実行すると、即落ちてTableAttributeBindingProvider.csがないためデバッグでその先のコードへたどり着けません。

TableAttributeBindingProvider..cs がないために落ちた箇所がわかりにくい状況

おもむろにNuGet Package Managerを見ます。最新バージョンのMicrosoft.Azure.WebJobs.Extensions.Storage (例は3.0.5) が出ているのでアップグレードします。

Microsoft.Azure.WebJobs.Extensions.Storage を最新版に上げる

コードの変更なく、先程のBinding時のエラーがリフレクションでとってきたtableAttributeのRowKeyがnullであるためにコケはじめます。

ライブラリ側のコードで落ちる箇所が表示されるようになる

AzureFunctionsプロジェクトのMicrosoft.Azure.WebJobs.Extensions.Storage 3.0.5の依存しているWindowsAzure.Storage のバージョンが >= 9.3.1となっています。

Microsoft.Azure.WebJobs.Extensions.Storageの依存するWindowsAzure.Storageバージョンの確認

依存プロジェクトのWindowsAzure.Storageを9.3.3にしていました。

依存プロジェクトのWindowsAzure.Storageに引きずられてアプリの利用バージョンが変わる

そこで依存プロジェクトのWindowsAzure.Storageを 9.3.1に変更します。

Microsoft.Azure.WebJobs.Extensions.Storage 3.0.5が依存するWindowsAzure.Storageの最小バージョン9.3.1にダウングレードして揃える

AzureFunctionsプロジェクトのMicrosoft.Azure.WebJobs.Extensions.Storage 3.0.5が依存しているWindowsAzure.Storage も9.3.1を見るように変わったことがわかります。

Microsoft.Azure.WebJobs.Extensions.Storage が参照するWindowsAzure.Storageが切り替わったことを確認

コードを何も変更してないけど正常に動くことが確認できます。

問題の回避方法

今、このBinding問題が起こっている方は、多くの場合、バージョン選択により問題が回避できます。(パラメーターが正しい場合ですが)

Microsoft.Azure.WebJobs.Extensions.Storageの利用しているWindowsAzure.Storage下限バージョンに合わせる

現在Storageに対するNuGetライブラリは、WindowsAzure.StorageからMicrosoft.Azure.Storage.Xxxxへの移行途中にあります。特にStorage Tableは影響度が高くしばらくは9.3.1、正しくはMicrosoft.Azure.WebJobs.Extensions.Storageの依存しているバージョンに従いましょう。

依存ライブラリに注意する

NuGetバージョン問題は、依存ライブラリになっている場合は個別ライブラリのバージョンに引っ張られる、というNuGet Packageの特性により「自分の気づかない内にバージョンが変わっていた」という状況が起こりやすいようです。

特に、プロジェクト参照していると依存プロジェクトのWindowsAzure.Storageバージョンに引きずられてバージョンが狂ってより死ぬ。という。

Bindingをやめる

そもそもBindingをやめるのが、デバッガビリティ、ライブラリのバージョンに起因したRegressionから簡単に逃げる選択肢になりえます。

自力でFunction内部にてクライアント(CloudTableClientなど) を生成することで、安定した利用ができるでしょう。特にパラメーターの多さから問題が起きやすいTableBindingとDB BindingはBindingを行わないのは選択肢となりえます。残念ですが。

複数の方が同じ結論でクライアントを自分で生成されているようです。

Q&A

Table Storage のBindingは空テーブルとか作ってくれて楽なんだけど

Bindingで行われる存在しないTable作成などはTerraformなどの静的な構成管理で担保もできるので、アプリケーションだけでなく全体像でハンドルもありですしコードで担保してもいいでしょう。

Microsoft.Azure.Storage.Xxxx やWindowsAzure.Storage 9.4.xを使い始めるタイミング

Microsoft.Azure.WebJobs.Extensions.Storageに依存しましょう。なお、Storage Tableは9.4.0からWindowsAzure.Storageから除外されてCosmosDBライブラリに移行します。Microsoft.Azure.WebJobs.Extensions.Storageのバージョンが9.4.xを使うまですぐに移行せずに少し様子を見たほうが良さそうです。

https://tech.guitarrapc.com/entry/2019/01/24/041510

BindingでMSIどうなってるの?

Storage BindingはMSIによる認証にも対応していないなど、クラウド側の更新への追随がまだ未整備という側面もあります。




以上の内容はhttps://tech.guitarrapc.com/entry/2019/04/03/113434より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14