Microsoftは先頃Azure .NET SDKの新バージョンをリリースした。NuGetパッケージのシリーズとして提供される。.NETアプリケーションからAzureサービスにアクセスする、一貫性のある馴染みやすいインターフェースを提供するように設計されている。
Azure SDKチームのソフトウェアアーキテクトとして、さまざまな言語と数多くのAzureサービス用のSDKの設計に携わるJeffery Richter氏に話を聞いた。
InfoQ: Azureサービス用の新たな.NET SDKのローンチを決めた理由について聞かせてください。
Jeffery Pichter: これにはたくさんの理由があります。まず最初に、すべてのAzureサービスチームが、自分たちのSDKに責任を持っている、ということがあります。これは同時に、それぞれのSDKがまったく異なっているため、ユーザはそれぞれをスクラッチから学習しなければならない、ということにもなります。つまり一貫性がないのです。私たちはAzureプラットフォームを、ユーザに喜んで使って頂けるような、総合的なプラットフォームにしたいと思っています。新しいAzureサービスを簡単に導入できて、生産性を上げられるようなものにしたいのです。
第2に、新しいSDKは、キャンセルやリトライ、ロギングといったクラウド/分散システムの機能を取り入れたものにしたいと思っていました。
第3に、SDKをサスティナブルなアーキテクチャにしたいと思ったのです。新しい機能や変更を、既存のユーザを損なうことなく迅速に行えるようにしたいと考えました。HTTPパイプラインは、この多くを可能にしてくれました。実際にユーザは、このパイプラインを自身で拡張したり、独自の機能を加えたりできるのです!従来のSDKでは、ユーザから機能拡張の要求を頂いても、技術的な負債が原因となって、互換性を失わずに取り入れることのできない場合がありました。
第4に、これら共通のコンセプトをすべてのSDK言語に取り入れたかったのです。現在、この中には、.NET、.Java、TypeScript、Python、C、C++、Go、Android、iOSが含まれています。そして最後に、ユーザが自身の問題を簡単に診断できるようなデザインにしたいと思いました。分散システムでは、ネットワーク接続、認証、タイムアウトなど、さまざまな問題が発生します。新しいSDKは、要求ID生成、ロギング、分散トレース、エラー処理およびメッセージなど、ユーザを支援するメカニズムを強く意識したものになっています。
InfoQ: "Inside the Azure SDK Architecture"というブログ記事で、HTTPパイプラインにカスタムポリシを追加する可能性について言及されていますが、カスタムポリシが利用可能なシナリオとしては、どのようなものが考えられるのでしょうか?
Richter: そうですね、SDKクライアントライブラリはそれぞれ、ひとつないし複数のXxxClientクラスを定義します。それぞれのクラスは、Azureサービスと通信する方法を知っています。XxxClinetのインスタンスを生成する時には、サービスのエンドポイント、認証情報、一連のオプション(リトライやロギングなど)を指定します。ここで指定されたオプションが、XxxClientオブジェクトが所有するHTTPパイプラインを生成するために使用されるのです。HTTP要求と応答はすべて、このパイプラインを通じて行われます。このパイプラインは、すべてのXxxClientメソッドに一貫した動作を適用するためのものなのですが、
ユーザが独自にポリシクラスを作成して、インスタンスをこのパイプラインに挿入できるようにもなっています。例えば、クライアント側でキャッシュ処理を実装することが考えられます。生成されるHTTP要求を監視して、ローカルストレージをチェックし、要求されたデータが存在するならば、Azureサービスと通信せずにそのデータを単に返すようなポリシを挿入することができます。データが存在しなければ、Azureサービスをコールして応答を取得し、(以降の要求のために)ローカルにキャッシュした上で返します。
もうひとつの考えられるポリシは、サーキットブレーカパターンの実装です。これは現在のSDKにはなく、将来的に追加したいと考えているものなのですが、必要ならばユーザ自身で簡単に実装することができます。アプリケーションをテストする目的で、モックや障害挿入をサポートする独自のポリシを開発することも可能でしょう。
InfoQ: 新しいSDKのパフォーマンスについての話がありましたが、以前のバージョンと比較して、新バージョンのベンチマークのようなものはあるのでしょうか?
Richter: そうですね、オペレーションのパフォーマンスについては、サービスの処理やネットワークのレイテンシによる部分が大半を占めています。それに比べると、クライアント側の処理は極めて小さいのですが、新たなSDKアーキテクチャでは、XxxClientオブジェクトを共有可能にすることで、以前のSDKよりもメモリ使用量が少なくなっています。これによってガベージコレクションの頻度が下がり、パフォーマンスが向上しています。
さらにXxxClientオブジェクトはスレッドセーフで、ロックが取得されるのは認証情報のパスワードあるいはトークンが更新させる時のみになっています。このため、ひとつのXxxClientオブジェクトを複数のスレッドで並列的に、ブロックすることなく使用することが可能です。これもパフォーマンス向上に寄与しています。パフォーマンスがどれだけ改善するかは、アプリケーションや、アプリケーションがXxxClientオブジェクトを使用する方法によります。
InfoQ: ブログ記事では、開発者の生産性の向上を目的としたパターンの形式化への言及がありますが、どのようなものなのか、いくつか例をあげて説明して頂けますか?
Richter: パターンを形式化することで、すべてのAzure SDKが同じように動作するようになります。これによって、ひとつをマスタすれば、習得した知識を別のものに活用できるようになり、新たに使用するAzureサービスに集中することが可能になります。形式化されたパターンの例をいくつか紹介しましょう。
- XxxClientクラスを使って、Azureサービスとの通信を行う。
- エンドポイント、認証情報、オプションを使ってXxxClientを生成する。
- XxxClientの各メソッドにより、ひとつ(場合によっては複数)のオペレーションをAzureサービス上で起動する。
- それぞれのメソッドの操作はHTTPパイプラインを通じて送信され、リトライ、ログなど、一貫した動作が付与される。
- 各メソッドはキャンセルが可能である — サービスの応答遅延によるクライアントアプリのハングアップを回避する上で、これは非常に重要である。
なお、すべての言語を対象としたAzure SDKのガイドラインが公開されています。こちらで確認してください。
InfoQ: 旧バージョンから新しいSDKに移行するためには、どのようなステップがあるのでしょうか?簡単に移行できるのでしょうか、あるいは互換性はないのでしょうか?
Richter: 残念ながら、新しいSDKは以前のものとコンパチブルではありません。大幅な変更を実施する以外に、私たちが望んだものをすべて実現する方法がなかったのです。ですが、旧SDKを引き続き使用しながら、新しいSDKも使用することは可能なので、新たなコードは新しいSDKを対象に書くようにして、以前のコードは新しいSDKを使うように徐々に修正していって、最終的に古いSDKの技術的負債を取り除くようにするとよいでしょう。
繰り返しますが、新しいSDKは継続可能なアーキテクチャであることに重きを置いているので、今後数十年にわたって使い続けることができます。ですから、予測し得る将来においては、再び互換性を失うようなことはないと考えています。新しいSDKを大いに信頼して頂きたいと思います。
インタビュー回答者について
Jeffrey Richter氏はAzure SDKチームのソフトウェアアーキテクトで、さまざまな言語と多数のAzureサービスを対象ちおしたSDKの設計を支援している。また、Azure HTTP/REST API Review BoardのメンバとしてAzureサービスチームのHTTP APIをレビューし、正確性、一貫性、共通パターン、バージョン管理、持続可能性、冪等性などの検討も行っている。Azure Breaking Change Review Boardにも参加しており、サービスに非互換的変更を実施したいというAzureサービスチームと話し合いをしている。