https://blogs.oracle.com/developers/microservices-from-dev-to-deploy%2c-part-2%3a-nodeexpress-and-fn-serverless
前回のエントリで、Lydiaという創業者が運営するTechCorpという架空の会社を紹介しました。彼女はインターネット・ホームページのすばらしき日々を取り戻そうとしています。
Microservices From Dev To Deploy, Part 1: Getting Started With HelidonLydiaの会社のグローバルチームはすばらしい開発者で構成されており、彼らは彼女のビジョンをマイクロサービス・アーキテクチャで実装しています。すでに我々はLondonのChrisのチームと東京のMichikoのチームの情報を知っています。これらのチームは天気および名言のサービスをHelidonというOracleが作ったマイクロサービス・フレームワークで構築しました。
https://blogs.oracle.com/developers/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon
https://orablogs-jp.blogspot.com/2018/10/microservices-from-dev-to-deploy-part-1.html
HelidonChrisのチームはHelidon SEをGroovyから利用し、MichikoのチームはHelidon MPとJavaを選択しています。このエントリでは、MurielleとそのBangaloreのチームがNode.jsとExpressを使って株価サービスを作成し、DominicとそのMelbourneのチームがJavaとFn Project(サーバーレス・テクノロジー)を使ってランダムに猫の画像を出すサービスの構築といううらやましい作業をしているところを見ていきます。
https://helidon.io/
Fn ProjectHelidonを使えば関数型スタイルとMicroprofileスタイルのサービスの両方を簡単に実装できます。 しかし、個人的に5年前に考えていたことではありますが、NodeJSの人気は無視できません。Stack Overflowの最近の調査によると、プログラミング、スクリプト、マークアップ言語の中で最も人気のある技術としてJavaScriptを選択した回答者は69%を超えており、かつ、回答者の49%以上が「フレームワーク」カテゴリの最上位にNodeを位置づけています。
https://fnproject.io/
Stack OverFlow Developer Surveys - Most Popular Technologiesこれは、人々がフロントエンドでJavaScriptを使用するのは当然として、ますますバックエンドでJavaScriptを活用しようとしているということです。そのため、Murielleのチームは、ExpressとNodeを使用して株価サービスを構築することにしました。
https://insights.stackoverflow.com/survey/2018#technology
このサービスを作成するためのExpressについて深掘りはしませんが、株価の取得方法を簡単に見てみましょう。
(非同期呼び出しで)fetchを使っています。このメソッドは株価APIを呼び出し、URLパラメータを使って受け取ったティッカーシンボルを渡して、株価をJSON文字列としてAPI呼び出し元に返します。ローカルでサービスを実行したときの様子は以下の通りです。var express = require('express'); var router = express.Router(); var config = require('config'); var fetch = require("node-fetch"); /* GET stock quote */ /* jshint ignore:start */ router.get('/quote/:symbol', async (req, res, next) => { const symbol = req.param('symbol'); const url = `${config.get("api.baseUrl")}/?function=GLOBAL_QUOTE&symbol=${symbol}&apikey=${config.get("api.apiKey")}`; try { const response = await fetch(url); const json = await response.json(); res.send(json); } catch (error) { res.send(JSON.stringify(error)); } }); /* jshint ignore:end */ module.exports = router;
Murielleのチームは、将来的にサービスを拡張して履歴データ、暗号通貨のルックアップなど、ビジネスが必要とするものすべてを提供できますが、現時点では、受け取ったティッカーシンボルに基づいて現在の株価を返します。チームは今後のデプロイのためにDockerfileとKubernetesの設定ファイルを作成しています。
MelbourneのDominicのチームは、サーバーレス・テクノロジーをこれまでよく使ってきています。彼らは優先機能、つまりランダムな猫の画像を提供する機能を任されており、サーバーレス(テクノロジー)を使ってこの機能を提供すべきで、Fnを使ってサービスの構築に着手しようと考えています。
マイクロサービスアーキテクチャではサーバレスを考慮する必要はありませんが、サーバーレスを使えば、柔軟性に富み、スケーラブル、集中性、迅速なデプロイが可能という、マイクロサービス・アプローチの目標を達成できるでしょう。DominicのチームはサーバーレスとFnに関して調査を完了し、作業準備が整ったので、開発者はローカルFnサーバーをインストールし、Javaのクイックスタートに従ってfunctionのテンプレートを作成しました。
Serverless with Fn Projectプロジェクトの準備完了後、Dominicのチームはfunc.yamlファイルを修正して、プロジェクトの設定、特にapiBaseUrlとapiKeyを設定しました。
https://developer.oracle.com/opensource/serverless-with-fn-project
Install Fn
https://fnproject.io/tutorials/install/
Introduction
https://fnproject.io/tutorials/JavaFDKIntroduction/
schema_version: 20180708 name: cat-svc version: 0.0.47 runtime: java build_image: fnproject/fn-java-fdk-build:jdk9-1.0.70 run_image: fnproject/fn-java-fdk:jdk9-1.0.70 cmd: codes.recursive.cat.CatFunction::handleRequest format: http config: apiBaseUrl: https://api.thecatapi.com/v1 apiKey: [redacted] triggers: - name: cat type: http source: /random
CatFunction
クラスは基本的なもので難しくはありません。@FnConfiguration
で注釈を付けられたsetUp()
メソッドは、YAMLファイルの設定情報を含むfunctionコンテキストにアクセスし、関数の変数を初期化します。handleRequest()
メソッドはUnirestというクライアントライブラリを使用してHTTP呼び出しを行い、すばらしい猫の画像へのリンクを含むJSONを返します。functionのテストのため、ローカルのFnサーバーにデプロイして…public class CatFunction { private String apiBaseUrl; private String apiKey; @FnConfiguration public void setUp(RuntimeContext ctx) { apiBaseUrl = ctx.getConfigurationByKey("apiBaseUrl").orElse(""); apiKey = ctx.getConfigurationByKey("apiKey").orElse(""); } public OutputEvent handleRequest(String input) throws UnirestException { String url = apiBaseUrl + "/images/search?format=json"; HttpResponse<JsonNode> response = Unirest .get(url) .header("Content-Type", "application/json") .header("x-api-key", apiKey) .asJson(); OutputEvent out = OutputEvent.fromBytes( response.getBody().toString().getBytes(), OutputEvent.Status.Success, "application/json" ); return out; } }
動作確認すると…fn deploy --app cat-svc –local
以下のような結果が返ってきます。curl -i \ -H "Content-Type: application/json" \ http://localhost:8080/t/cat-svc/random
うまく動作しました。Dominicのチームは昼食前に猫のサービスを作成し、残りの時間はランダムに表示される猫の画像を見て過ごしました。HTTP/1.1 200 OK Content-Length: 112 Content-Type: application/json Fn_call_id: 01CRGBAH56NG8G00RZJ0000001 Xxx-Fxlb-Wait: 502.0941ms Date: Fri, 28 Sep 2018 15:04:05 GMT[{"id":"ci","categories":[],"url":"https://24.media.tumblr.com/tumblr_lz8xmo6xYV1r0mbi6o1_500.jpg","breeds":[]}]
さまざまなテクノロジーを使い、4チーム全てが任されたサービスの実装が完了しました。フロントエンドからサードパーティAPIを直接呼び出すのではなく、バックエンドにこのような簡単なサービスを実装する必要性を自問していらっしゃるかもしれません。理由はいくつかありますが、一部を見ていきましょう。
サーバーベースのバックエンド経由でこの機能を実装する理由の1つとして、サードパーティのAPIが信頼性が低かったり、レート制限があったりする可能性があります。独自のバックエンドを介してAPIをプロキシすることで、チームはキャッシュや独自に設計したレート制限を活用できるます。サードパーティAPIへのリクエストや、制限付きで管理できたり管理不可のサービスの潜在的なダウンタイムやレート制限の回避をする必要はなくなります。
第二に、チームはデータをクライアントに送信する前に制御できる、という点です。条件やビジネスニーズにより、他のサードパーティまたはユーザーデータでデータを補うことがAPI内で可能であれば、クライアント到達前にデータの追加、変更によってクライアントのCPU、メモリ、帯域幅の要件を削減できます。
最後に、ブラウザによるCORSの制約は、サーバーからAPIを呼び出すことで回避できます(CORS制約の結果ブラウザからのHTTP呼び出しをブロックを経験している場合には、このメリットは理解いただけると思います)。
TechCorp はこれでプロジェクトの最初のマイクロサービス開発のスプリントを完了しました。次回のエントリでは、4個のサービスをローカルのKubernetesクラスタにデプロイする方法と、Angularで作成するフロントエンドを深く見ていきます。
0 件のコメント:
コメントを投稿