Gleyzer両氏によって共同開発されました。2019で、同言語の発表を行いました。InfoQはPurdy氏に言語と、氏らが解決を目指した問題について聞きました。設計/アーキテクチャアジャイルマニュフェスト:ソフトウェアアーキテクトの視点ソフトウェアアーキテクトの役割と責任はアジャイルソフトウェア開発のためのマニフェストの価値と矛盾していると見えますが、優れたアーキテクトはアジャイル開発チームをサポートするテクニックを見つけています。Streamingは、ストリーミングデータのためのSQLライクなインターフェースを提供します。Streamsによって、Redisがストリーミングデータを複数のプロデューサとコンシューマの間で消費、保持、配信することができるようになります。ソフトウェア開発のマニフェストたゆまず息もつかずに市場に突進することで、会社を静かに消滅の崖っぷちへと追い込みます。それは設計してコードを書く方法を再考する時です。簡単さへの投資は、速さへの投資です。簡単さは知的財産の主鉱脈でもあります。競争上の優位性は、一度失ったら、もう一度手に入れることはほとんど不可能です。Buytaerts氏が過去10年間にわたって、企業がDevOps採用のハイプサイクルをくぐり抜け、変革に対する誤解を解消する過程を支援してきた経験について語ります。Vert.xツールキットを使ったモダンでレスポンシブ、かつレジリエントな、メッセージ駆動の継続的インテグレーション(CI)システムによる設計と開発の世界にお誘いします。System(JPMS)を活用して、明確に定義されたインターフェース経由で通信する疎結合モジュールを複数使用したアプリケーションの構築を行います。JPMSは、大規模な既存コードベースへの対処に加えて、新たなアプリケーション開発においても、Javaアーキテクトと開発者が自信を持ってモジュールを使用できることを意図しています。既存のJavaライブラリをモジュールシステムで使用するのは、必ずしも容易ではありません。そこで今回は、Javaモジュールシステムを使った開発で遭遇するさまざまな課題と、システムを稼働させる上での回避策について説明したいと思います。Product)を定義することにしましょう。ここではDockerネイティブなシステムとしての構築を目指します。APIとして提供することが求められています。リポジトリに対するCRUDのサポート。リポジトリとは、バージョン管理下のプロジェクトを表します。接続の詳細をGitリポジトリあるいはPerforceデポに対して指定します。“パイプライン・アズ・コード”思想のサポート。パイプラインは、アーティファクトとしてのコードを作成するワークフローを定義します。パイプラインの定義にはJavaScriptを使用します。スクリプトファイルはコードベースとともに、ソースコードリポジトリに格納することが可能です。パイプラインの起動と停止を行なうAPIの提供。指定されたパイプラインのインスタンスがビルドを構成します。MVPの定義が完了すれば、システムの構築に取り掛かることができます。最初のステップはプロジェクトスケルトンの作成です。この目的には、IntelliJのマルチモジュールgradleプロジェクトテンプレートが便利です。9を使用するので、最新かつ最高バージョンのgradle(執筆時点では4.4.1)を使用できるというメリットがあります。9を指定する必要があります。プロジェクトのメインである“build.gradle”ファイルは、次のような内容になっているはずです。ほとんどのシステムと同じように、このシステムでもエンティティオブジェクトをホストする共通コアライブラリ、ユーティリティクラス、共有定数やクエリパーザを持つことにします。9モジュールとして定義しましょう。9モジュールは、インターフェースやクラス、リソースを集めた自己記述型のコレクションです。開発者がモジュールの公開部分と他のモジュールへの依存関係を定義するために、JPMSの新たな構成体として“module-info.java”が追加されました。このファイルを使用してモジュールの名称を定義し、他のモジュールへの依存関係、およびこのアプリケーション内で他のモジュールによって使用されるパッケージを指定します。以下のコードは、module-infoファイルを使ってコアモジュールを記述する方法を示しています。定義部分を詳しく見ていきましょう。すべての“module-info.java”ファイルは、キーワード“module”に続くモジュール名から始まります。モジュール名の定義は、パッケージ名の命名規則としては一般的な、逆ドメイン名記述法で行います。それに続くコードブロック内には2つの新しいキーワード、“exports”と“requires”があります。“exports”キーワードは、このモジュールが公開するパブリックパッケージ、つまりこのモジュールの公開APIの宣言に使用されます。“requires”キーワードはモジュールの依存性の宣言に使用します。9モジュールはどうやって作成するのか、という疑問が生じることと思います。この目的のために導入されたのが、自動モジュールといういう概念です。非モジュールjarは、そのjarファイルの名称をベースとした名前のモジュールjarに、その名のとおり自動的に変換されます。自動付与される名称は、“jarファイル名の拡張子を削除し、ドットをハイフンに置き換えた上で、バージョン番号があれば削除する”、というアルゴリズムで導出されます。非モジュールである“vert-core-3.5.0.jar”ライブラリは、“vertx.core”という名前の依存対象として指定されます。後述のNettyのネイティブトランスポートライブラリに依存する場合のように、この方法で推論された自動モジュールが常に機能するとは限りません。データベースコールやユーザ認証、エンジンの実行、CIシステム内のさまざまなシステムプラグインとの通信などの処理を行なうモジュールも、コアモジュールと同じように定義する必要があります。モジュールJavaアプリケーションの基本概念をいくつか紹介しましたので、ここで一歩戻ってvert.xの説明をしましょう。vert.xは、呼び出しスレッドをブロックしない非ブロックAPIを提供するツールキットです。この非ブロック性のおかげで、vert.xアプリケーションは、少数のスレッドプールを使って多数の並列処理を行なうことができます。これを実現しているのがマルチリアクタ(multi-reactor)パターンです。JavaScriptに精通した開発者であれば、登録されたハンドラに到達したイベントを配信する、単一のスレッドイベントループを思い浮かべることができるでしょう。マルチリアクタパターンはこれに準じたアプローチですが、単一スレッドが本質的に持つ制限を克服するために、vert.xでは、サーバで利用可能なコア数に基づいた複数のイベントループを使用します。vert.xはまた、“アクタ(actor)”が受信したメッセージに応答することで、メッセージを使った相互通信を行うという、疎結合のアクタモデルに基づいた独善的(opinionated)並列処理モデルを備えています。vert.xのアクタは“バーティクル(verticle)”と呼ばれて、通常はイベントバスを介して送信されるJSONメッセージを使って他のバーティクルと通信します。vert.xがデプロイするインスタンス数をバーティクル毎に指定することもできます。イベントバスは、HazelcastやZookeeperなどのさまざまなクラスタマネージャをプラグアンドプレイで使用して、クラスタを構成できるように設計されています。各バーティクル、あるいはvert.xインスタンス上で動作するバーティクルの組み合わせは、マイクロサービスであると見なすことができます。manifesto)に完全に沿ったものになります。そのことを念頭において、今回のCIシステムの全体的な流れを見てみましょう。上に示すように、多数のバーティクルがvert.xイベントバスを介して相互通信を行います。この図において、プラグインもバーティクルである点に注意してください。VERTICLE)を経由します。APIエンドポイントはCLIおよびGUIクライアントによって使用され、リポジトリへの接続の詳細を指示するとともに、パイプラインの生成とその実行を行います。以下のコードは、vert.xでのAPIとルートの定義方法に関する考え方を示す部分を抜粋したものです。APIの定義にvert.xのWebライブラリを使用して、すべてのルートを“/api/v1/”ベースのパスの下にマウントします。vert.xはその他にも、リアクティブなアプリケーションを短時間で開発するために、数多くのライブラリや機能を提供しています。3仕様準拠のアプリケーションAPIを設計すれば、リクエストの検証とセキュリティの検証をライブラリに自動処理させることが可能になります。vert.xのOAuthライブラリを使用すれば、GoogleやFacebook、あるいは独自のカスタムプロバイダなどのOAuthプロバイダを使って、アプリケーションとAPIを保護することができます。VERTICLE)は、パイプラインインスタンスの実行や構築を調整する役割を持っています。APIがクライアントによって呼び出されると、サーババーティクルがエンジンバーティクルにメッセージを送ります。パイプライン実行を開始するこのメッセージを受信することにより、エンジンが新しいフローオブジェクトをインスタンス化するのです。フローオブジェクトは、パイプラインインスタンスの進行を追跡するために使用される、シンプルなステートマシンです。任意の時点において、フローオブジェクトは、セットアップ・実行・ティアダウンのいずれかの状態を持つことができます。着信したメッセージに基づいて、新たな状態に移行することも可能です。それぞれ状態においてフローオブジェクトはイベントを発行し、メッセージとしてイベントバス上に送信します。登録されたプラグインがこれらのメッセージを処理して、処理結果を非同期に、イベントバスを介して返信します。パイプラインを起動するメッセージハンドラを登録し、フローオブジェクトを生成して、プラグインからの着信メッセージを処理する方法を示すコードの抜粋を以下に示します。エンジンバーティクルは、プラグインとバーティクルの配置やデプロイも行います。9で変更されたJavaのサービスローダのメカニズムを使って、サーバ起動時にプラグインの配置とデプロイを行うことにします。サービスのロードについて理解するには、サービスとサービスプロバイダについて説明しなければなりません。サービスは、よく知られているインターフェースないしクラス(通常は抽象クラス)です。サービスの具象クラスがサービスプロバイダです。ServiceLoaderクラスは、特定のサービスを実装したサービスプロバイダをロードするための機構です。モジュールが特定のサービスを使用していることを宣言するには、このServiceLoaderクラスを使用します。ServiceLoaderを使うことで、ランタイム環境にデプロイされたサービスプロバイダを特定してロードすることが可能になります。サーバモジュールはPluginインターフェースを使うことを宣言し、ワークスペース(WORKSPACE)モジュールは、対応する“module-info.java”ファイルに記述されたPluginコントラクトを実装した2つのサービスを提供することを宣言します。これによって、サーバモジュールが起動すると、ServiceLoaderが呼び出されて2つのプラグインを受信し、それらがバーティクルとしてデプロイされます。プラグインの仕事はたくさんあります。最初に、パイプラインフローの対象イベントを処理するメッセージハンドラを登録します。ワークスペースプラグインは、gitからのコード同期を担当します。パイプラインスクリプトを見つけ出し、パイプラインを実行する方法について記述したコードを実行する役割を持っています。RUNNER)プラグインによってDockerコンテナ内で実行されます。vert.xはJavaの組込みJavaScriptエンジンであるNashhornを利用しているので、JavaScriptを実行できます。vert.xがJavaScriptやKotlin、Groovyなどの言語をサポートする多言語ツールキットであることに注目してください。以下はパイプラインスクリプトの一部です。スクリプトランナプラグインは、受信したメッセージに基づいてDockerイメージをダウンロードし、コンテナを生成して、その中でshellコマンドを実行します。Dockerエンジンと対話する必要があります。APIは、TCPソケット上の従来のHTTPではなく、Unixドメインソケット上のHTTPで公開されるのが一般的です。vert.xの活躍する場がここにあります。Dockerエンジンとの通信でブロッキングコードを使用している既製のjarを使う代わりに、vert.xの非同期クライアントを使った通信が可能になります。vert.xは、Nettyが提供するネイティブなトランスポートライブラリが存在することを確認すると、そちらのトランスポートを使用します。“build.grade”ファイルと“module-info.jar”ファイルの両方に“netty-transport-native-kqueue”のようなネイティブトランスポートへの依存性を加えることで、この機能が有効になります。vert.xがunixドメインソケット上でのhttpwをサポートしていない点には注意してください。この問題は近々、うまくいけば次期リリースで対処される予定です。当面はvert.xコアライブラリに簡単なコード修正を施して再構築することで、この問題を回避できます。Dcokerエンジンと通信するプラグインは次のようなものになります。“netty-transport-native-kqueue-4.1.15.Final-osx-x86_64.jar”のような非モジュールjarを依存関係として加えると、自動的にモジュール名が生成されるのですが、jarファイルにJavaの予約語である“native”が含まれているため。コンパイル時にエラーとなります。Nettyの開発者は次期リリースでこの問題に対処するとしていますが、jarのマニフェストファイルに“Automatic-Module-Name”エントリを加えれば、この問題を回避することができます。それにはまず、jarをフォルダに展開して、その中にcdします。io.netty.transport.kqueue”を追加します。それが終われば、次のコマンドを実行してjarファイルを生成します。次のコマンドを実行することによって、マニフェストファイルで指定されている自動生成されたモジュール名がjavaによって認識されていることを確認できます。自動生成されたモジュール名がJavaの予約語と干渉するその他の非モジュールjarについても、同じようなコマンドを使って修正する必要があります。これまでの作業で、CIシステムの構築して実行する準備ができました。アプリケーションの実行には次のコマンドを使用します。JPMSをサポートするため、“javac”や“java”といった既存のコマンドツールにも新しいオプションが追加されています。これらのオプションは、以前のクラスパスに代えて、モジュールパスとモジュールjarを使用するように、javaのコンパイラやランタイムに指示するものです。指定されたフォルダからjavaモジュールを検索するように、javaに指示するために使用します。アプリケーションを起動するモジュールとmainクラスを指定するためのものです。9を使用したDockerネイティブなCIシステムを構築しました。具体的なコードをGitHubで参照して、vert.xとモジュールがコンパクトで独立性の高いモジュールJavaアプリケーションの構築にいかに適しているか、詳しく確認して頂ければと思います。Tatiraju氏はOracleのプリンシパルエンジニアとして、Eコマースプラットフォーム、検索エンジン、バックエンドシステム、Webおよびモジュールプログラミングの分野で10年近い経験を持っています。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見るあなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。登録するとさまざまなことができます。アカウント登録をしてInfoQをお楽しみください。あなたの意見をお聞かせください。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見る様々なイノベーターとアーリーアダプターがお送りするテクノロジーの概要を見る。自分がまだ知らないことに気づいていないと知るあなたが興味のあるトピックスをいつでも最新な情報に。あなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。よい世界へ私たちが暮らす世界を大切に思い、よりよいものにしたいと考えています。人のためのソフトウェア開発を加速し私たちのミッションを実現することで、この思いを成し遂げようとしています。私たちは利益の1%をさまざまな慈善団体に寄付しています。会社として、また従業員として、そうしたことの価値を強く信じているからです。with.プライバシーBTあなたのプロファイルは最新ですか?プロフィールを確認してアップデートしてください。アドレス*Eメールを変更すると確認のメールが配信されます。会社名:現在の会社名をご入力ください。Other組織規模:現在の組織規模をご入力ください。2,501+国:現在の国を設定してください。Zimbabwe都道府県:現在の都道府県に設定してください。次の都道府県にアップデートする:ニュースレターを購読しますか?インダストリーメールを購読しますか?本Eメールに登録すると、以前より関心のあったトピックの関連情報をお送りする場合がございます。詳細はこちらのプライバシーポリシーをご覧ください。newsletter?新しいメールアドレスに確認用のメールを送信します。このポップアップ画面は自動的に閉じられます。