サヌバヌなしのマむクロサヌビスクラりドバヌゞョン

芪愛なる読者の皆さん、こんにちは



最も気を぀けおください、私たちはマむクロサヌビスに関する革新的な本に取り組んでいたすが、同時に、このトピックに぀いおむンタヌネットで曞いたものを読むこずを忘れないでください。 したがっお、著者のTim Wagnerがマむクロサヌビスアヌキテクチャに関する圌の芋解を共有しおいるAmazonブログの興味深い蚘事を通過するこずはできたせんでした。



倚くのJava、JavaScript、スキヌマ、掚論、および倧量のテキスト



LinuxCon / ContainerCon 2015カンファレンスで、 「 サヌバヌのないマむクロサヌビス 」ずいうデモレポヌトを発衚したした。 その䞭で、画像凊理甚のマむクロサヌビスの䜜成に぀いお説明し、いく぀かの地域に展開し、このマむクロサヌビスをマシンむンタヌフェむスずしお䜿甚するモバむルアプリケヌションを䜜成し、Amazon API GatewayずWebサむトを䜿甚しおHTTPSベヌスのAPIを远加し、構築党䜓を実行したしたナニットおよび負荷テスト-すべおサヌバヌなし。



この蚘事では、前述のレポヌトを完党に埩元し、いく぀かの堎所で、建築の繊现さを掘り䞋げおいたす。 远加の図はスラむドの遞択にありたす。 このアヌキテクチャのもう1぀の䟋は、gistリポゞトリ内のSquirrelBin実行可胜ファむルです。



サヌバヌレスアヌキテクチャ



「サヌバヌレス」ずいう甚語は、明瀺的なアヌキテクチャが䞍芁であるこずを意味したす。぀たり、サヌバヌなしで、サヌバヌに展開せずに、プログラムをむンストヌルせずに実行できたす。 マネヌゞドクラりドサヌビスずラップトップでのみ動䜜したす。 以䞋の図は、䞻芁なコンポヌネントずその接続を瀺しおいたす。マシンむンタヌフェむスずしおのラムダ関数ず、それに盎接接続するモバむルアプリケヌション、およびAmazon S3にある静的サむトにHTTP゚ンドポむントを提䟛するAmazon API Gateway。







AWS Lambdaを䜿甚したモバむルおよびWebアプリケヌション甚のサヌバヌレスアヌキテクチャ



それでは始めたしょう



ステヌゞ1画像凊理甚のサヌビスを䜜成したす



プロセス党䜓を簡玠化するために、Lambdaテクノロゞヌnodejsに組み蟌たれおいるImageMagickラむブラリを䜿甚したす。 ただし、これは必須ではありたせん-独自のラむブラリが必芁な堎合は、 JavaScriptたたはネむティブラむブラリをロヌドしたり、 Pythonを実行したり、コマンドラむンの実行可胜ファむルにコヌドをラップしたりできたす 。 次の䟋はnodejsに実装されおいたすが、 Java 、 Clojure 、 Scala、たたはAWS Lambdaの別のjvm蚀語を䜿甚しおこのようなサヌビスを䜜成するこずもできたす。



以䞋のコヌドは、ImageMagickの䞀皮の「ハロヌワヌルド」ず芋なすこずができたす-コマンドの基本構造このコマンドはスむッチオペレヌタヌに粟通し、バラの埋め蟌み画像を抜出しお返すこずができたす。 結果のコヌディングずは別に、他のすべおをJSONで曞くこずもできたす。



var im = require("imagemagick"); var fs = require("fs"); exports.handler = function(event, context) { if (event.operation) console.log("Operation " + event.operation + " requested"); switch (event.operation) { case 'ping': context.succeed('pong'); return; case 'getSample': event.customArgs = ["rose:", "/tmp/rose.png"]; im.convert(event.customArgs, function(err, output) { if (err) context.fail(err); else { var resultImgBase64 = new Buffer(fs.readFileSync("/tmp/rose.png")).toString('base64'); try {fs.unlinkSync("/tmp/rose.png");} catch (e) {} // discard context.succeed(resultImgBase64); } }); break; //     default: var error = new Error('Unrecognized operation "' + event.operation + '"'); context.fail(error); return; } };
      
      







たず、サヌビスが機胜するこずを確認したしょう。 これを行うには、次のJSONをAWS Lambdaコン゜ヌルのテストりィンドりに送信したす。



 { "operation": "ping" }
      
      







必須の「ポン」応答を受信する必芁がありたす。 次に、実際にImageMagick呌び出しに進み、そのようなJSONを送信したす。



 { "operation": "getSample" }
      
      







このク゚リは、base64で゚ンコヌドされたPNG PNGむメヌゞの文字列衚珟を取埗したす“” iVBORw0KGg ... Jggg ==”。 これらが単なるランダム文字ではないこずを確認するには、それらを切り取り、Base64を画像に倉換する䟿利なデコヌダヌcodebeautify.org/base64-to-image-converterなどに二重匕甚笊なしで貌り付けたす。 バラの矎しい画像を取埗する必芁がありたす。







サンプル画像赀いバラ



次に、画像凊理サヌビスを远加しお、nodejsラッパヌの残りの䜿甚を準備したす。 さたざたな操䜜を提䟛したす。







ここのコヌドのほずんどは非垞に簡単です。 このコヌドは、nodejsに実装されたImageMagickプロシヌゞャをラップし、それらの䞀郚はJSONを受け入れたすこの堎合、Lambdaによっお送信されたむベントはクリアされ、リダむレクトされたすが、文字列の配列ずしお枡されるコマンドラむン匕数いわゆる「カスタム」を受け入れたす。 ImageMagickを以前に䜿甚したこずがない堎合、この機胜の1぀の偎面は明らかではないかもしれたせん。぀たり、コマンドラむンのラッパヌずしお機胜し、ファむル名にセマンティクスがありたす。 競合する2぀のニヌズがありたす。第1に、クラむアントはセマンティクスたずえば、JPEGに察するPNGなどの出力画像圢匏を転送する必芁があり、第2に、サヌビスの䜜成者はディスク䞊の䞀時ストレヌゞを保存する堎所を決定する必芁があるため、詳现の挏掩を蚱可したせん実装。 これらの䞡方の問題を同時に解決するために、JSONスキヌムで2぀の匕数「inputExtension」ず「outputExtension」を定矩し、クラむアント郚分ファむル拡匵子ずサヌバヌ郚分ディレクトリ名およびベヌス名を組み合わせお、ファむルの実際の堎所を䜜成したす。 完成したコヌドは、次の画像凊理図面で確認できたすそしお䜿甚できたす。



ここで実行できるテストは倚数ありたすが以䞋で実行したす、操䜜性を簡単にテストするために、ロヌズの同じ画像を再床抜出し、ネガティブフィルタヌを䜿甚しお返したす色反転を実行したす。 Lambdaコン゜ヌルで同様のJSONファむルを䜿甚できたす。base64Imageフィヌルドの内容を画像に䞀臎する文字に眮き換えるだけですこのシヌケンスは非垞に長くなりたす。

 { "operation": "convert", "customArgs": [ "-negate" ], "outputExtension": "png", "base64Image": "...fill this in with the rose sample image, base64-encoded..." }
      
      







画像にデコヌドされた出力は、真の怍物の掗緎、青いバラです







青いバラ元の画像から赀いバラでネガ



サヌビスの機胜に関しおはそれだけです。 原則ずしお、ここから匕甚を開始し、「1回皌働」から「24時間皌働のモニタリングずプロダクションのロギングを備えたスケヌラブルで信頌性の高いサヌビス」に切り替えたす。 しかし、これがLambdaの矎しさです。私たちの画像凊理コヌドはすでに完党に展開されたマむクロサヌビスであり、実甚化の準備が敎っおいたす。 それを呌び出すこずができるモバむルアプリケヌションを远加するには...



ステヌゞ2モバむルクラむアントを䜜成する



アプリケヌションを凊理するためにマむクロサヌビスに連絡する方法はいく぀かありたすが、サンプルクラむアントを瀺すために、Android甚の小さなアプリケヌションを䜜成したす。 以䞋は、ContainerConレポヌトで䜿甚されるクラむアントコヌドです。 ここでは、画像ずフィルタヌを取埗できる単玔なAndroidアプリケヌションを䜜成したす。その埌、フィルタヌが「倉換」操䜜で画像に適甚され、最終的に䜕が埗られるかがわかりたす。 フィルタリングは、AWS Lambdaで動䜜する画像凊理マむクロサヌビスで行われたす。



このアプリケヌションの機胜を明確にするために、AWS Lambdaアむコンを䟋にずりたす。







AWS Lambdaアむコンを衚瀺するAndroid゚ミュレヌタヌ



「ネガティブ」フィルタヌを遞択しお、アむコンの色を反転したす。







画像倉換に「ネガ」フィルタヌを遞択したす



...そしお、ここに結果がありたすLambdaモニカヌの青いバヌゞョン元はオレンゞでした







「吊定」フィルタヌをAWS Lambdaアむコンに適甚した結果



さらに、珟代のシアトルのパノラマにビンテヌゞの倖芳を䞎えるこずができたす。 シアトルの写真を撮り、セピアトヌンのフィルタヌを適甚したす。







セピア調のシアトルのパノラマ。



コヌドに枡したす。 ここでは、Androidのプログラミングの基本を説明する぀もりはありたせんが、アプリケヌションのLambda固有の芁玠に泚意しおください。 独自のアプリケヌションを䜜成しおいる堎合は、AWS Mobile SDKアヌカむブを有効にしお、以䞋のコヌドサンプルを実行する必芁がありたす。 抂念的には、コヌドは4぀の郚分で構成されおいたす。



  1. POJOデヌタスキヌマ
  2. リモヌトサヌビスの定矩操䜜
  3. 初期化
  4. サヌビスコヌル




すべおの郚品を順番に怜蚎しおください。



デヌタスキヌムは、クラむアントずサヌバヌ間で転送する必芁があるすべおのオブゞェクトを定矩したす。 「ラムダ䞻矩」はありたせん。 すべおのオブゞェクトは、特別なラむブラリやフレヌムワヌクのない通垞のPOJOPlain Old Java Objectです。 基になるむベントを定矩し、それを展開しお操䜜の構造を反映したす。 䞊蚘の画像凊理サヌビスを定矩およびテストするずきに䜿甚したJSONの「javification」があるず想定できたす。 Javaサヌバヌも䜜成する堎合は、通垞、これらのファむルを共通むベント構造の定矩の䞀郚ずしお共有したす。 この䟋では、これらのPOJOはサヌバヌ偎のJSONに倉換されたす。



LambdaEvent.java



 package com.amazon.lambda.androidimageprocessor.lambda; public class LambdaEvent { private String operation; public String getOperation() {return operation;} public void setOperation(String operation) {this.operation = operation;} public LambdaEvent(String operation) {setOperation(operation);} }
      
      







ImageConvertRequest.java



 package com.amazon.lambda.androidimageprocessor.lambda; import java.util.List; public class ImageConvertRequest extends LambdaEvent { private String base64Image; private String inputExtension; private String outputExtension; private List customArgs; public ImageConvertRequest() {super("convert");} public String getBase64Image() {return base64Image;} public void setBase64Image(String base64Image) {this.base64Image = base64Image;} public String getInputExtension() {return inputExtension;} public void setInputExtension(String inputExtension) {this.inputExtension = inputExtension;} public String getOutputExtension() {return outputExtension;} public void setOutputExtension(String outputExtension) {this.outputExtension = outputExtension;} public List getCustomArgs() {return customArgs;} public void setCustomArgs(List customArgs) {this.customArgs = customArgs;} }
      
      







これたでのずころ、すべおは比范的単玔です。 デヌタモデルができたので、いく぀かのJavaアノテヌションを䜿甚しおサヌバヌ゚ンドポむントを定矩したす。 ここでは、「ping」ず「倉換」ずいう2぀の操䜜を提䟛しおいたす。 他の操䜜を远加しおコヌドを拡匵するこずは難しくありたせんが、これは以䞋で説明するデモアプリケヌションには必芁ありたせん。



ILambdaInvoker.java



 package com.amazon.lambda.androidimageprocessor.lambda; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunction; import java.util.Map; public interface ILambdaInvoker { @LambdaFunction(functionName = "ImageProcessor") String ping(Map event); @LambdaFunction(functionName = "ImageProcessor") String convert(ImageConvertRequest request); }
      
      







これで、アプリケヌションの䞻芁郚分に進む準備ができたした。 ここでは、䞻にAndroidのステンシルコヌドず、クラむアントリ゜ヌスを簡単に管理するためのコヌドが衚瀺されたすが、Lambdaに関連するいく぀かのフラグメントに個別に泚目したす。



これは「init」セクションです。 ここでは、Lambda APIを呌び出す認蚌プロバむダヌが䜜成され、Lambda-invokerが䜜成されたす。これにより、䞊蚘で定矩された゚ンドポむントを呌び出し、POJOオブゞェクトをデヌタモデルに転送できたす。



  //   CognitoCachingCredentialsProvider CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider( this.getApplicationContext(), "us-east-1:<YOUR COGNITO IDENITY POOL GOES HERE>", Regions.US_EAST_1); //  LambdaInvokerFactory,       Lambda. LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(), Regions.US_EAST_1, cognitoProvider); //  - Lambda         Json. lambda = factory.build(ILambdaInvoker.class);
      
      







非垞に興味深いもう1぀のコヌドは、リモヌトプロシヌゞャコヌル自䜓です。



  try { return lambda.convert(params[0]); } catch (LambdaFunctionException e) { Log.e("Tag", "Failed to convert image"); return null; }
      
      







実際、すべおの魔法匕数のシリアル化ず結果の逆シリアル化は暗黙的に進行し、ここでいく぀かの゚ラヌ凊理を実行するだけなので、それほど興味深いものではありたせん。

完党な゜ヌスファむルを次に瀺したす。



MainActivity.java



 package com.amazon.lambda.androidimageprocessor; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.Spinner; import android.widget.Toast; import com.amazon.lambda.androidimageprocessor.lambda.ILambdaInvoker; import com.amazon.lambda.androidimageprocessor.lambda.ImageConvertRequest; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunctionException; import com.amazonaws.mobileconnectors.lambdainvoker.LambdaInvokerFactory; import com.amazonaws.regions.Regions; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; public class MainActivity extends Activity { private ILambdaInvoker lambda; private ImageView selectedImage; private String selectedImageBase64; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //   CognitoCachingCredentialsProvider CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider( this.getApplicationContext(), "us-east-1:2a40105a-b330-43cf-8d4e-b647d492e76e", Regions.US_EAST_1); //  LambdaInvokerFactory,       Lambda. LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(), Regions.US_EAST_1, cognitoProvider); //  - Lambda         Json. lambda = factory.build(ILambdaInvoker.class); //  lambda-,  ,    pingLambda(); } //  lambda- @SuppressWarnings("unchecked") private void pingLambda() { Map event = new HashMap(); event.put("operation", "ping"); //  Lambda-    . // ,       . new AsyncTask<Map, Void, String>() { @Override protected String doInBackground(Map... params) { //   "ping".   ,    //  LambdaFunctionException. try { return lambda.ping(params[0]); } catch (LambdaFunctionException lfe) { Log.e("Tag", "Failed to invoke ping", lfe); return null; } } @Override protected void onPostExecute(String result) { if (result == null) { return; } //    Toast.makeText(MainActivity.this, "Made contact with AWS lambda", Toast.LENGTH_LONG).show(); } }.execute(event); } //     "process image" public void processImage(View view) { //     if (selectedImageBase64 == null) { Toast.makeText(this, "Please tap one of the images above", Toast.LENGTH_LONG).show(); return; } //    String filter = ((Spinner) findViewById(R.id.filter_picker)).getSelectedItem().toString(); //    ImageConvertRequest request = new ImageConvertRequest(); request.setBase64Image(selectedImageBase64); request.setInputExtension("png"); request.setOutputExtension("png"); //     List customArgs = new ArrayList(); request.setCustomArgs(customArgs); switch (filter) { case "Sepia": customArgs.add("-sepia-tone"); customArgs.add("65%"); break; case "Black/White": customArgs.add("-colorspace"); customArgs.add("Gray"); break; case "Negate": customArgs.add("-negate"); break; case "Darken": customArgs.add("-fill"); customArgs.add("black"); customArgs.add("-colorize"); customArgs.add("50%"); break; case "Lighten": customArgs.add("-fill"); customArgs.add("white"); customArgs.add("-colorize"); customArgs.add("50%"); break; default: return; } // async-  lambda- new AsyncTask() { @Override protected String doInBackground(ImageConvertRequest... params) { try { return lambda.convert(params[0]); } catch (LambdaFunctionException e) { Log.e("Tag", "Failed to convert image"); return null; } } @Override protected void onPostExecute(String result) { //    ,    if (result == null || Objects.equals(result, "")) { hideLoadingDialog(); Toast.makeText(MainActivity.this, "Processing failed", Toast.LENGTH_LONG).show(); return; } //      base64         byte[] imageData = Base64.decode(result, Base64.DEFAULT); selectedImage.setImageBitmap(BitmapFactory.decodeByteArray(imageData, 0, imageData.length)); hideLoadingDialog(); } }.execute(request); showLoadingDialog(); } /*      */ public void selectLambdaImage(View view) { selectImage(R.drawable.lambda); selectedImage = (ImageView) findViewById(R.id.static_lambda); Toast.makeText(this, "Selected image 'lambda'", Toast.LENGTH_LONG).show(); } public void selectSeattleImage(View view) { selectImage(R.drawable.seattle); selectedImage = (ImageView) findViewById(R.id.static_seattle); Toast.makeText(this, "Selected image 'seattle'", Toast.LENGTH_LONG).show(); } public void selectSquirrelImage(View view) { selectImage(R.drawable.squirrel); selectedImage = (ImageView) findViewById(R.id.static_squirrel); Toast.makeText(this, "Selected image 'squirrel'", Toast.LENGTH_LONG).show(); } public void selectLinuxImage(View view) { selectImage(R.drawable.linux); selectedImage = (ImageView) findViewById(R.id.static_linux); Toast.makeText(this, "Selected image 'linux'", Toast.LENGTH_LONG).show(); } //   'id'  ,   base64 private void selectImage(int id) { Bitmap bmp = BitmapFactory.decodeResource(getResources(), id); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); selectedImageBase64 = Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT); } //       public void reset(View view) { ((ImageView) findViewById(R.id.static_lambda)).setImageDrawable(getResources().getDrawable(R.drawable.lambda, getTheme())); ((ImageView) findViewById(R.id.static_seattle)).setImageDrawable(getResources().getDrawable(R.drawable.seattle, getTheme())); ((ImageView) findViewById(R.id.static_squirrel)).setImageDrawable(getResources().getDrawable(R.drawable.squirrel, getTheme())); ((ImageView) findViewById(R.id.static_linux)).setImageDrawable(getResources().getDrawable(R.drawable.linux, getTheme())); Toast.makeText(this, "Please choose from one of these images", Toast.LENGTH_LONG).show(); } private void showLoadingDialog() { progressDialog = ProgressDialog.show(this, "Please wait...", "Processing image", true, false); } private void hideLoadingDialog() { progressDialog.dismiss(); } }
      
      







これがモバむルアプリケヌション党䜓です。 これは、デヌタモデルJavaクラス、制埡モデルいく぀かのメ゜ッド、すべおの皮類を初期化する3぀のコマンド、およびtry / catchブロックで囲たれたリモヌト呌び出しで構成されおいたす...簡単です。



いく぀かの地域での展開



これたでのずころ、このコヌドが機胜する堎所に特に焊点を合わせおいたせん。 Lambdaはコヌドをリヌゞョン内にデプロむする責任がありたすが、䜿甚する他のリヌゞョンを決定する必芁がありたす。 最初のデモでは、米囜東郚で機胜する関数を䜜成したした。たずえば、これはバヌゞニア州のデヌタセンタヌに適甚されたす。 グロヌバルサヌビスを提䟛しおいるこずを䞊蚘で曞きたした。したがっお、これらの地域からのモバむルアプリケヌションが最小限の遅延でサヌビスに接続できるように、ペヌロッパアむルランドおよび倪平掋地域東京にカバレッゞを拡倧したしょう。







2぀の远加リヌゞョンにLambda関数をデプロむするためのサヌバヌレスメカニズム



サヌバヌレスWebアプリケヌションパヌト1API゚ンドポむント



これで、モバむルアプリケヌションず、そのマシンむンタヌフェむスずしお機胜するグロヌバルに展開された画像凊理サヌビスができたした。 デバむスではなくブラりザで䜜業するこずを奜む同志のために、サヌバヌレスWebアプリケヌションの䜜成に移りたしょう。 これは2段階で行いたす。 たず、画像凊理サヌビスのAPI゚ンドポむントを䜜成したす。 次に、次のセクションで、Amazon S3を䜿甚しおサむト自䜓を远加したす。



AWS Lambdaを䜿甚するず、コヌドをサヌビスに簡単に倉換できたす。これは、Webサヌビスクラむアントむンタヌフェむスがここで既に「組み蟌たれおいる」ためです。 ただし、これにはクラむアント前のセクションで䜜成したモバむルクラむアントなどがAWSから提䟛された認蚌情報でリク゚ストに眲名する必芁がありたす。 このタスクは、Androidアプリケヌションで䜿甚されるAmazon Cognito認蚌クラむアントによっお解決されたすが、りェブサむトを通じお画像凊理サヌビスを共有したい堎合はどうでしょうか



これを行うには、別のサヌバヌであるAmazon API Gatewayを䜿甚したす 。 このサヌビスを䜿甚するず、むンフラストラクチャを必芁ずせずにAPIを定矩できたす。APIはAWSによっお完党に管理されたす。 APIゲヌトりェむを䜿甚しお、画像凊理サヌビスで䜿甚されるURLを䜜成したす。これにより、Webナヌザヌがその機胜のサブセットにアクセスできたす。 Amazon API Gatewayは、さたざたなAPIぞのアクセスを制埡するさたざたな方法を提䟛したすAPI呌び出しはAWS認蚌情報で眲名するか、OAuthトヌクンを䜿甚しおトヌクンヘッダヌを怜蚌にリダむレクトするだけで、APIキヌを䜿甚できたすセキュリティで保護されたアクセスが必芁な堎合はお勧めしたせんたたはAPIを完党に䜜成したすここに瀺すように、䞀般公開されおいたす。



ゲヌトりェむAPIは、倚様なアクセスモデルに加えお、この蚘事の範囲を超えた倚くの機胜も提䟛したす。 それらの䞀郚は組み蟌みDDOS攻撃に察する保護などで、その他はキャッシュなどにより、人気のあるむメヌゞを繰り返し抜出する際の遅延ずコストをさらに削枛できたす。 API Gatewayでは、クラむアントずマむクロサヌビス間の間接レベルを実装するこずにより、バヌゞョン管理ずプラむマリデヌタの配眮ステヌゞングに別々の手順を䜿甚しお、それらを独立しお開発するこずもできたす。 それたでの間、䞻な問題の解決に焊点を圓おたす。画像凊理サヌビスをAPIずしお提䟛するこずです。



それでは、APIを䜜成したしょう。 AWSコン゜ヌルで、[API Gateway]をクリックし、[新しいAPI]を遞択しお、APIに名前を付けるか、説明を远加したす。 「ImageAPI」ずいう名前を遞択したした。







次に、新しいAPIのリ゜ヌスを䜜成し「ImageProcessingService」ず呌びたす、その䞭にPOSTメ゜ッドを䜜成したす。 統合のタむプずしお「Lambda関数」を遞択し、画像凊理のサヌビスずしお䜿甚するLambda関数の名前を入力したす。 「メ゜ッド芁求」構成で、蚱可タむプを「なし」に蚭定したす぀たり、パブリック゚ンドポむントになりたす。 以䞊です。







統合をテストするには、「テスト」ボタンをクリックしたす。







次に、テストペむロヌド{「操䜜」「ping」}を指定したす。 APIをLambda関数に正垞に関連付けたこずを瀺す、予想される「ポン」の結果を取埗する必芁がありたす。



泚以䞋では、より完党なより深いテストを行いたすが、通垞、pingなどの単玔な操䜜に関連付けられたトップレベルリ゜ヌスずしおGETメ゜ッドをAPIに远加するず䟿利です。 これにより、どのブラりザヌからでも、APIがLambda関数に正しく接続されおいるこずをすばやく確認できたす。 デモアプリケヌションおよび䞀般的にでは、これは必須ではありたせんが、この手法を奜む可胜性は十分にありたす。



次に来るもの静的S3コンテンツに぀いおは、CORSをアクティブにする必芁もありたす。 簡単ですが、いく぀かのステップで行われたす。 API Gatewayチヌムはこのプロセスを匕き続き簡玠化するため、ここでの指瀺をすぐに繰り返さないようにするためにたもなく期限切れになる可胜性がありたす、 ドキュメントを参照したす。



[このAPIをデプロむ]ボタンをクリックしたす。 これで、サむトを䜜成する準備がすべお敎いたした



-, 2: Amazon S3



: Javascript- S3, :



 var ENDPOINT = 'https://fuexvelc41.execute-api.us-east-1.amazonaws.com/prod/ImageProcessingService'; angular.module('app', ['ui.bootstrap']) .controller('MainController', ['$scope', '$http', function($scope, $http) { $scope.loading = false; $scope.image = { width: 100 }; $scope.ready = function() { $scope.loading = false; }; $scope.submit = function() { var fileCtrl = document.getElementById('image-file'); if (fileCtrl.files && fileCtrl.files[0]) { $scope.loading = true; var fr = new FileReader(); fr.onload = function(e) { $scope.image.base64Image = e.target.result.slice(e.target.result.indexOf(',') + 1); $scope.$apply(); document.getElementById('original-image').src = e.target.result; //   ! $http.post(ENDPOINT, angular.extend($scope.image, { operation: 'resize', outputExtension: fileCtrl.value.split('.').pop() })) .then(function(response) { document.getElementById('processed-image').src = "data:image/png;base64," + response.data; }) .catch(console.log) .finally($scope.ready); }; fr.readAsDataURL(fileCtrl.files[0]); } }; }]);
      
      







HTML- ( ) :



 <!DOCTYPE html> <html lang="en"> <head> <title>Image Processing Service</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Open+Sans:400,700"> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body ng-app="app" ng-controller="MainController"> <div class="container"> <h1>Image Processing Service</h1> <div class="row"> <div class="col-md-4"> <form ng-submit="submit()"> <div class="form-group"> <label for="image-file">Image</label> <input id="image-file" type="file"> </div> <div class="form-group"> <label for="image-width">Width</label> <input id="image-width" class="form-control" type="number" ng-model="image.width" min="1" max="4096"> </div> <button type="submit" class="btn btn-primary"> <span class="glyphicon glyphicon-refresh" ng-if="loading"></span> Submit </button> </form> </div> <div class="col-md-8"> <accordion close-others="false"> <accordion-group heading="Original Image" is-open="true"> <img id="original-image" class="img-responsive"> </accordion-group> <accordion-group heading="Processed Image" is-open="true"> <img id="processed-image" class="img-responsive"> </accordion-group> </accordion> </div> </div> </div> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap-tpls.min.js"></script> <script type="text/javascript" src="main.js"></script> </body> </html>
      
      







, CSS:



 body { font-family: 'Open Sans', sans-serif; padding-bottom: 15px; } a { cursor: pointer; } /** LOADER **/ .glyphicon-refresh { -animation: spin .7s infinite linear; -webkit-animation: spin .7s infinite linear; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @-webkit-keyframes spin { from { -webkit-transform: rotate(0deg); } to { -webkit-transform: rotate(360deg); } }
      
      








 S3:







URL S3 , ., “http://image-processing-service.s3-website-us-east-1.amazonaws.com/”. URL — :











API Gateway Lambda- , URL. . , , !

, API. : « HTTPS-» Lambda, POST , API Gateway:



 { "options": { "host": "fuexvelc41.execute-api.us-east-1.amazonaws.com", "path": "/prod/ImageProcessingService", "method": "POST" }, "data": { "operation": "getSample" } }
      
      







. : Lambda- Amazon DynamoDB. Lambda, « »:



 { "operation": "unit", "function": "HTTPSInvoker", "resultsTable": "unit-test-results", "testId": "LinuxConDemo", "event": { "options": { "host": "fuexvelc41.execute-api.us-east-1.amazonaws.com", "path": "/prod/ImageProcessingService", "method": "POST" }, "data": { "operation": "getSample" } } }
      
      







, , . Lambda, « »:



 { "operation": "load", "iterations": 100, "function": "TestHarness", "event": { "operation": "unit", "function": "HTTPSInvoker", "resultsTable": "unit-test-results", "testId": "LinuxConLoadTestDemo", "event": { "options": { "host": "fuexvelc41.execute-api.us-east-1.amazonaws.com", "path": "/prod/ImageProcessingService", "method": "POST" }, "data": { "operation": "getSample" } } } }
      
      







:











, , .. -, API Gateway HTTP, . , - DynamoDB, .



たずめ



, , . «» , , , - : , , API, . !



All Articles