クラウドネイティブなプログラミング言語Ballerinaとは?
現在、モノリシックなソフトウェアから、コンテナを中心としたサービスが連携するマイクロサービスなシステムへの移行が進んでいる。クラウドネイティブと呼ばれるようなマイクロサービスのシステムでは、コンテナは入れ物でしかないし、Kubernetesはそれを協調させるためのスケジューラーとして、最終的に複数のコンテナが稼働することで突然のアクセスのピークへの対応や、エラー処理を全体として担保することが要点になる。Kubernetesが選ばれるのは、それらの変動に対して基本機能として対応できる部分が評価されているからだろう。しかし一部のシステムが稼働していない場合の処理、例えば一定時間のリトライを制御するサーキットブレーカーをどの部分で実装するのか? などに関しては、まだ各々が試しながら実装しているというのが2018年時点での現状ではないだろうか。
そんな中、クラウドネイティブなコンピューティグを推進するCNCFが、最新の言語としてBallerinaを紹介するWebinarを公開した。この記事ではそのBallerinaの概要について、Webinarを元にクラウドネイティブなインテグレーションに特化した開発言語の一端を紹介したい。
Ballerinaに関するWebinar:Intro to Ballerina: A Cloud Native Programming Language
Webinarの講師役は、オープンソースソフトウェアのインテグレーションやAPIマネージメントのソリューションを提供している企業、WSO2のCTO、Paul Fremantle氏だ。WSO2は、Ballerinaの開発をリードしている企業でもある。
Fremantle氏はまず「過去60年間に渡ってソフトウェアは進化してきた」と語ったのち、現在は徐々にモノリシックなシステムから複数のコンポーネントが稼働するシステムに移行しており、最終的にはマイクロサービス、そしてサーバーレスに移行するだろうと予測した。
そしてその進化の過程で、全てのソフトウェアがエンドポイントを持ち、他のソフトウェアから呼び出すことができるようになっていると解説。ここでは、APIからデバイスまでを含んでエンドポイント化していると説明。
そのエンドポイントを連携、統合するためのクラウドネイティブなソフトウェアが必要になってきていると説明。特にサーキットブレーカーやロードバランシング、エラーハンドリングなど、複数のプロセスが連動するような場合に必須となる機能を実装できることが必要だと解説した。
しかし、従来のインテグレーションに特化したESB(Enterprise Service Bus)やBPM(Business Process Management)、EAI(Enterprise Application Integration)などのソフトウェアでは、現代のモダンなソフトウェア開発にマッチしていない。そこで、JavaやJavaScriptなどの言語と、SpringやNode.jsなどのフレームワークを組み合わせて実装することになるが、その両者の間に大きな隙間、ギャップがあり、どちらの方法もインテグレーションと非同期で並列的な機能要件を同時に満足させることはできなかった。そしてそれを埋めるのが、Ballerinaという言語だという。
「compiled, type safe, concurrent programming language」であるというのが、Ballerinaの簡潔な説明だ。ここからはデモを交えて、Ballerinaの特徴を紹介する流れになった。
まずFremantle氏は、Visual Studio CodeでHello Worldを書くというデモを紹介した。新しい言語を紹介する際には定番のデモだ。しかし他の言語と少し異なる点は、Ballerinaの動作環境はネットワークで繋がっていることが大前提になっているということだろう。そこでこのデモでも、アプリケーションが実行され、そのエンドポイントをcurlコマンドで叩くと結果が返るというものになる。
上半分のエディター部分でdemo.balというソースファイルを作成し、左下のターミナルのエリアで以下のコマンドを実行し、ソースをコンパイルしてdemo.balxという実行形式ファイルを作る。
$ ballerina build demo.bal
その後、右下のエリアでcurlコマンドを実行する。「http://localhost:9090/hello/hi」にアクセスした結果、「hello CNCF!」という文字列が返ってきたことがわかる。
続いて、返す文字列をソースコードにハードコードするのではなく、パラメータとして文字列を渡してPOSTする方式に修正してみる。ここでは重要なのは、Ballerinaはネットワークを前提としているため、SQL Injectionのような攻撃をあらかじめ想定しているという点だろう。そのため、単にパラメータを結合して表示させるような操作を行おうとすると、警告が出力される。
res.setPayload("hello " + untaint body+"!\n");
次に示すスクリーンショットにあるように、「tainted(汚染)」されていることが前提になり、明示的に「untaint」という記述をする必要がある。このような特徴は、性善説でソフトウェアを書いてはいけないという部分の現れだろう。
次は、パラメータの文字列を使ってTwitterに投稿するというデモだ。そのためにWSO2が公開しているTwitter連携のためのパッケージを利用する。Ballerinaは公開されたパッケージレジストリを持っているために、そこからballerina pullコマンドで必要なパッケージをダウンロードすることも可能だ。
機能としては、Twitterに投稿するのと同時にレスポンスとしてJSONを返すように修正する。
この右下のターミナルに、レスポンスとしてJSONが返されているのがわかる。
また実際のFremantle氏のTwitterにも「#Ballerinalang」というハッシュタグ付きのツイートが投稿されていることがわかる。
この簡単なデモをシーケンスダイアグラムで表示すると、以下のような感じになる。最初に紹介したHello Worldは、呼び出し元であるCallerが、Helloというオブジェクトのhiというエンドポイントに対して文字列を返すという簡単なシーケンスであることがわかる。
一方Twitter連携のシーケンスは、以下のようになる。
ここで機能の一つとして、シーケンスダイアグラムを表示する機能を紹介した。これはVisual Studio Codeが書かれたソースコードを認識して、どのように呼び出されているのかをダイアグラムとして表示することができるというものだ。これはVisual Studio Codeのプラグインの機能だが、ネットワークを前提とするBallerinaならではの機能だろう。
例えばif文を挿入すれば、プログラマーにはお馴染みのひし形で分岐が表示される。
またクラウドネイティブということでコンテナやKubernetesにも対応しており、パッケージをロードするだけでKubernetes用の必要ファイルの生成なども自動化されるという。
そして冒頭のサーキットブレーカーの実装例として、外部のWebサービスから文字列を検索し、それをパラメータとしてTwitterに引き渡すことで、複数のサービスをネットワーク経由で連携させるソースコードが紹介された。ここでは外部サービスが連携されるだけではなく、外部サービスに異常が起きた時にサーキットブレーカーが発動するように、サーキットブレーカーを実装するというデモにもなっていた。
リトライまでの時間や、何秒おきにリトライするのかなどの設定を、ソースコードとして記述できる。
他にもトレーシングとして、JaegerやZipkinとの連携ができていることを紹介。
またCodefreshと連携することで、GCP上のGitに修正したコードをPushしてCI/CDを走らせ、テストから本番環境への実装も自動化されていることをデモンストレーションした。
今回のデモで使われたコンポーネントは次の通りだ。
今回のデモと全く同じものではないが、シンプルなバージョンがGitHubに公開されているようだ。以下のリンクを参照されたい。
Ballerina Playground - Hello Service
他にも多くの機能があり、言語としてだけではなくパッケージマネージャーやテストツールなども開発が進んでいるようだ。
Ballerinaは言語仕様レベルから、非同期でネットワークを強く意識して開発されていることがわかる。最後に質問として出されたGoとの違いについては、「Goを否定するつもりはないが、Goよりもわかりやすいのではないか」というコメントをしていたのが印象的だった。
サーキットブレーカーなどのクラウドネイティブな機能を実装するのは、どのレベルが良いのか? これに関しては様々な選択肢がこれからも出てくるのではないだろうか。ユーザーにとってみれば難しい問題だが、まずはBallerinaを試してみることをお勧めしたい。「Fail Fast, Fail Often」はそれが正しいかどうかはさておき、クラウドネイティブな企業のマントラなのだから。
参考:Ballerinaの公式サイト:https://ballerina.io/