AWS Lambda Beraksi. Bagian 2: mengenal alat pengembangan dan pengujian



Panduan ini adalah hasil dari pengalaman pribadi dalam mengembangkan dan menguji aplikasi Serverless, serta manuver antara kruk dan sepeda ketika mencoba mengujinya. Ketika saya pertama kali mulai mengembangkan aplikasi Serverless, saya harus memikirkan semuanya dengan tangan saya, tidak ada panduan yang jelas atau alat yang mudah untuk pengembangan dan pengujian lokal.

Sekarang situasinya berubah: alat mulai muncul, tetapi menemukan manual tentang penggunaannya tidak mudah. Pada artikel ini saya akan menunjukkan dengan contoh sederhana cara bekerja dengan fungsionalitas baru. Anda dapat dengan mudah menguasainya dan mengatasi masalah dan bug yang saya “beruntung” temui.

Anda akan belajar bagaimana mengembangkan menggunakan konsol browser AWS, SAM-CLI, dan IntelljIDEA. Saya juga akan berbicara tentang pengujian: integrasi, E2E, dan pengujian unit. Dan akhirnya, kita akan membahas berapa biaya solusi semacam itu (spoiler: Anda dapat menghemat banyak di dalamnya).

Artikel ini akan bermanfaat bagi mereka yang mulai mengembangkan aplikasi Serverless dan belum terbiasa dengan alat dan pendekatannya.


Apa yang akan dibahas


Halo semuanya! Nama saya Alexander Gruzdev, dan saya senang mempersembahkan bagian kedua artikel tentang penggunaan dan pengembangan solusi Serverless berdasarkan AWS Lambda. Dalam sekuelnya, kita akan berbicara tentang cara mengembangkan dan menguji solusi dari bagian pertama ( AWS Lambda Beraksi di Jawa 11. Kami mengunjungi Serverless dalam “Produksi” ).

Sejak publikasi artikel terakhir, aplikasi pengujian telah sedikit didesain ulang, tetapi makna utamanya tetap sama. Ini adalah bentuk HTML sepele "Hubungi Kami", yang mengirim data dari formulir ke API Gateway melalui permintaan HTTP, dan, pada gilirannya, proksi permintaan pemrosesan ke AWS Lambda. Selama pemrosesan, lambda menulis data ke tabel DynamoDB dan mengirim surat melalui AWS SES. Diagram komponen disajikan di bawah ini.

Diagram komponen


Kandungan


  1. Pengembangan Menggunakan Konsol Browser AWS
  2. Pengembangan menggunakan SAM-CLI
  3. Pengembangan menggunakan IntelljIDEA
  4. Jenis Pengujian
  5. Biaya Tanpa Server
  6. tautan yang bermanfaat



1. Pengembangan menggunakan konsol browser AWS



Konsol AWS


Konsol AWS menyediakan akses ke layanan AWS apa pun, baik itu server EC2 virtual Anda, pengaturan peran / akses kebijakan IAM atau AWS Lambda dengan semua parameter yang dapat diubah secara waktu nyata tanpa memindahkan kembali melalui sistem Pengiriman Berkelanjutan / Penerapan Berkelanjutan.

Ini sangat mempercepat proses pengembangan dan beberapa jenis pengujian. Ini juga membantu mengontrol secara visual parameter peluncuran dan operasi aplikasi Anda.

Konsol Gateway API


Konsol memungkinkan Anda untuk memantau keadaan aplikasi saat ini, mengelola lingkungan Anda dan memberikan versi baru. Saya akan menunjukkan bagaimana ini dapat digunakan untuk memverifikasi kesehatan lingkungan.

Mari kita lihat seperti apa bentuk konsol "ajaib" ini di tangkapan layar pada tab Sumber di aplikasi Contact Us: Screenshot menunjukkan bagaimana permintaan dari klien melalui API Gateway masuk ke lambda dan bagaimana respons kembali ke klien ketika sumber daya POST dipanggil / kontak.

Sumber daya gerbang



  • Permintaan metode - langkah pertama dalam memproses permintaan. Dalam kasus kami, ini tidak mengandung pengaturan apa pun, tetapi mungkin berisi, misalnya, pengaturan untuk otorisasi.
  • Permintaan integrasi berarti bahwa permintaan HTTP akan dikirim ke lambda dalam format khusus: itu berisi semua informasi yang dikirim oleh klien dan perincian tentang konteks yang dipanggil.
  • Respons integrasi mengatakan bahwa klien HTTP akan menerima respons langsung dari lambda. Karena itu, Anda sendiri yang bertanggung jawab atas pembentukan badan respons di lambda.


Nonaktifkan integrasi proxy
API Gateway , Use Lambda Proxy integration Integration Request. . , , .


Sampel permintaan integrasi
SAM init events, , Integration request. , AWS , . AWS Lambda.


Tekan tombol TEST untuk memverifikasi aplikasi berfungsi. Ini akan memberi Anda akses ke panggilan API HTTP Gateway.

Di tangkapan layar berikut, saya mengirim permintaan untuk menghangatkan lambda: Selain menanggapi permintaan, Gateway API juga menampilkan log terperinci. Dengan cara yang sama, Anda dapat membuat permintaan nyata dengan mengganti badan permintaan JSON dalam bentuk:
Permintaan uji gateway


{
    "subject": "Email subject",
    "question": "Your question…",
    "username": "Your name…",
    "phone": "Your phone…",
    "email": "Your email…"
} 


Jadi, Anda dapat menguji API secara manual tanpa formulir UI dan aplikasi Front-end, sehingga memisahkan pengembangan front-end dan back-end. Sebagai alternatif untuk konsol bawaan, Anda dapat menggunakan Postman atau klien HTTP lainnya.

Tukang pos sebagai alternatif
HTTP- Postman. . , API Gateway AWS , API. , , AWS .


Konsol Lambda


Untuk pengujian dan pengembangan, selain permintaan melalui API Gateway, Anda dapat menggunakan konsol browser AWS Lambda.

Layarnya dibagi menjadi beberapa blok:
  • Desainer menunjukkan pemicu dan lapisan yang ada. Dalam kasus kami, pemicunya adalah API Gateway. Jika kita mengkliknya, semua informasi yang diperlukan akan terbuka: URL, panggung, jalur sumber daya.
  • Alias (tersedia saat memilih alias lambda tertentu) memungkinkan Anda mengonfigurasi distribusi lalu lintas menurut versi lambda. Lebih lanjut tentang ini di paragraf berikutnya.
  • Function code — . zip- , . , Function code . Python/NodeJs.
  • Environment variables. , . , , . , . , , .
  • Tags — , , , , .
  • Execution role — ( ) , .
  • Basic settings — .
  • Network: - , VPC. — .
  • AWS X-Ray . AWS-.
  • Reserve concurrency , . .
    Provisioned concurrency
  • Provisioned concurrency — . , . , — . Free Tier .
  • Doa asinkron memungkinkan Anda mengonfigurasi penanganan permintaan asinkron khusus. Kami menunjukkan berapa banyak panggilan berulang yang harus dilakukan jika terjadi kesalahan, dan untuk berapa lama permintaan dapat bertahan dalam antrian. Secara opsional, Anda dapat menentukan antrian untuk memproses permintaan yang gagal.

  • Database proxy adalah fitur baru lain yang memungkinkan Anda untuk mengkonfigurasi akses ke database melalui proxy dalam bentuk API Gateway + Lambda.


Selanjutnya, mari kita lihat bagaimana mengembangkan dari konsol ini. Selain mengubah parameter, fungsi Konfigurasi Acara Tes dapat digunakan untuk membuat permintaan pengujian. Daftar yang agak luas tersedia, tetapi kami akan mengambil keuntungan dari apa yang telah saya lampirkan dalam proyek:
Hubungi kami permintaan
{
  "body": "{\"subject\": \"Question\",\"question\": \"How much does it cost\",\"username\": \"Alex\",\"phone\": \"+79999999999\",\"email\": \"alex@gmail.com\"}",
  "resource": "/{proxy+}",
  "path": "/path/to/resource",
  "httpMethod": "POST",
  "isBase64Encoded": false,
  "queryStringParameters": {
    "foo": "bar"
  },
  "pathParameters": {
    "proxy": "/path/to/resource"
  },
  "stageVariables": {
    "baz": "qux"
  },
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Cache-Control": "max-age=0",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "US",
    "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Custom User Agent String",
    "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
    "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "requestContext": {
    "accountId": "123456789012",
    "resourceId": "123456",
    "stage": "prod",
    "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "requestTime": "09/Apr/2015:12:34:56 +0000",
    "requestTimeEpoch": 1428582896000,
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "accessKey": null,
      "sourceIp": "127.0.0.1",
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "Custom User Agent String",
      "user": null
    },
    "path": "/prod/path/to/resource",
    "resourcePath": "/{proxy+}",
    "httpMethod": "POST",
    "apiId": "1234567890",
    "protocol": "HTTP/1.1"
  }
}


Setelah menambahkan permintaan, klik Uji dan lihat hasil lambda: Lambda mengembalikan JSON, yang berisi kode status dan badan respons. Nilai tubuh akan langsung ke klien yang disebut Gateway API. Selain itu, tangkapan layar memiliki karakteristik panggilan: waktu eksekusi, waktu eksekusi yang akan kami bayarkan, jumlah maksimum memori yang dikonsumsi oleh lambda. Dengan mengandalkan metrik ini, kami dapat mengonfigurasi jumlah memori optimal sehingga lambda cocok dengan persyaratan tingkat harga / respons Anda.
Sumber daya gerbang



Menggunakan Konsol AWS untuk Menguji Penerapan Canary


Sekarang mari kita menyentuh satu poin penting terkait dengan penyebaran versi baru lambda. Saya menetapkan parameter seperti itu ketika saya menulis templat SAM:
AutoPublishAlias: live
DeploymentPreference:
  Type: Canary10Percent10Minutes

Parameter pertama secara otomatis menambahkan alias langsung ke setiap versi baru dari lambda .
Sedikit tentang alias
, . , , API Gateway. 1, 2, 3 . LATEST, . 2 3 API Gateway (Stage AWS), Gateway-Lambda. API Gateway (ARN ), LATEST.

— ( ), , , ARN . , Stage API Gateway . , API Gateway: dev, qa prod .

, , . , . , live, . live- , , , , CloudWatch.


Untuk menguji penyebaran kenari, Anda dapat menggunakan konsol Gateway API dan konsol Lambda.

Pertama, Anda perlu mengubah kode lambda sehingga mengembalikan jawaban yang berbeda. Misalnya, dalam pemrosesan pemanasan, tentukan Versi 2 dan bukan Versi 1 dalam respons. Ini akan menjadi penanda kami.

Sekarang, dengan menggunakan fungsionalitas API dari Uji Gateway, kami dapat memastikan bahwa dalam sepuluh menit ketika mengirim permintaan WARM-UP, hanya 10% respons yang akan memiliki Versi 2 di badan respons. Setelah waktu ini, Versi 2 akan mengembalikan 100% permintaan.

Selain konsol Gateway API, kita dapat menggunakan konsol Lambda, di mana, setelah memilih alias yang diperlukan, kita melihat kebijakan distribusi lalu lintas yang dapat dikontrol.
Alias ​​lambda



2. Pengembangan lokal menggunakan SAM-CLI


Beberapa waktu lalu, salah satu kelemahan utama menggunakan lambda dianggap ketidaknyamanan dalam pengembangan dan pengujian pada mesin lokal. Sekarang situasinya telah banyak berubah: SAM-framework telah muncul, yang memungkinkan tidak hanya untuk mengumpulkan dan menyebarkan solusi, tetapi juga menyederhanakan pembangunan lokal.

Misalnya, Anda dapat memanggil lambda Anda langsung dari konsol:
sam local invoke -e ./events/warm_up_request.json ContactUsFunction

Perintah ini diluncurkan dari direktori dengan templat SAM dan mentransfer konten file JSON ke input lambda ContactUsFunction (ini adalah nama logis dalam templat).

Artinya, menggunakan perintah ini, SAM memunculkan gambar lambci / lambda: java11 di docker , dan menjalankan kode Anda di dalamnya. Untuk mengakses layanan jarak jauh, seperti SES, konfigurasi AWS Anda dengan kunci rahasia / akses digunakan, sehingga harus mutakhir. Poin penting lainnya: jika Anda tidak menambahkan header untuk mode pemanasan, layanan nyata AWS SES dan DynamoDB akan dipanggil.

Hubungi log di sini
F:\aws\projects\contact-us-sam-app>sam local invoke -e ./events/warm_up_request.json ContactUsFunction
Invoking com.gralll.sam.App::handleRequest (java11)
Fetching lambci/lambda:java11 Docker container image......
Mounting F:\aws\projects\contact-us-sam-app\.aws-sam\build\ContactUsFunction as /var/task:ro,delegated inside runtime container
?[32mSTART RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2 Version: $LATEST?[0m
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 INFO  App - Request was received
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 DEBUG App - {
  "body" : "{\"subject\": \"Question\",\"question\": \"How much does it cost\",\"username\": \"Alex\",\"phone\": \"+79999999999\",\"email\": \"alex@gmail.com\"}",
  "resource" : "/{proxy+}",
  "requestContext" : {
    "resourceId" : "123456",
    "apiId" : "1234567890",
    "resourcePath" : "/{proxy+}",
    "httpMethod" : "POST",
    "requestId" : "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "extendedRequestId" : null,
    "accountId" : "123456789012",
    "identity" : {
      "apiKey" : null,
      "apiKeyId" : null,
      "userArn" : null,
      "cognitoAuthenticationType" : null,
      "caller" : null,
      "userAgent" : "Custom User Agent String",
      "user" : null,
      "cognitoIdentityPoolId" : null,
      "cognitoIdentityId" : null,
      "cognitoAuthenticationProvider" : null,
      "sourceIp" : "127.0.0.1",
      "accountId" : null,
      "accessKey" : null
    },
    "authorizer" : null,
    "stage" : "prod",
    "path" : "/prod/path/to/resource",
    "protocol" : "HTTP/1.1",
    "requestTime" : "09/Apr/2015:12:34:56 +0000",
    "requestTimeEpoch" : 1428582896000,
    "elb" : null
  },
  "multiValueQueryStringParameters" : { },
  "multiValueHeaders" : {
    "X-WARM-UP" : [ "13" ]
  },
  "pathParameters" : {
    "proxy" : "/path/to/resource"
  },
  "httpMethod" : "POST",
  "stageVariables" : {
    "baz" : "qux"
  },
  "path" : "/path/to/resource",
  "isBase64Encoded" : false,
  "requestSource" : "API_GATEWAY"
}
2020-01-06 19:09:17 a86d65fa-1f19-15c5-93b8-d87631c80ee2 INFO  App - Lambda was warmed up
?[32mEND RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2?[0m
?[32mREPORT RequestId: a86d65fa-1f19-15c5-93b8-d87631c80ee2     Init Duration: 1984.55 ms       Duration: 42.22 ms      Billed Duration: 100 ms Memory Size: 256 MB     Max Memory Used: 102 MB ?[0m
{"statusCode":201,"multiValueHeaders":{"Access-Control-Allow-Origin":["*"]},"body":{"response":"Lambda was warmed up. V1"},"isBase64Encoded":false}


Selain log lambda, informasi layanan tentang status panggilan dan respons dalam format JSON ditulis ke konsol.

Gateway API, seperti lambda, dapat dijalankan secara lokal.
Kami menjalankan perintah:
sam local start-api

Log konsol saat startup
F:\aws\projects\contact-us-sam-app>sam local start-api
Mounting ContactUsFunction at http://127.0.0.1:3000/contact [POST, OPTIONS]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-01-06 22:20:30  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)


Setelah memulai server, kami dapat menjalankan permintaan. Saya akan menggunakan tukang pos dan mengirim permintaan untuk menghangatkan lambda.

Di konsol kita lihat
Invoking com.gralll.sam.App::handleRequest (java11)
Fetching lambci/lambda:java11 Docker container image......
Mounting F:\aws\projects\contact-us-sam-app\.aws-sam\build\ContactUsFunction as /var/task:ro,delegated inside runtime container
?[32mSTART RequestId: 27868750-3637-1f80-3d80-53a724da16ef Version: $LATEST?[0m
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef INFO  App - Request was received
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef DEBUG App - {
  "body" : "{\r\n  \"subject\": \"Question\",\r\n  \"question\": \"How much does it cost\",\r\n  \"username\": \"Alex\",\r\n  \"phone\": \"+79999999999\",\r\n  \"email\": \"alex@gmail.com\"\r\n}",
  "resource" : "/contact",
  "requestContext" : {
    "resourceId" : "123456",
    "apiId" : "1234567890",
    "resourcePath" : "/contact",
    "httpMethod" : "POST",
    "requestId" : "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "extendedRequestId" : null,
    "accountId" : "123456789012",
    "identity" : {
      "apiKey" : null,
      "apiKeyId" : null,
      "userArn" : null,
      "cognitoAuthenticationType" : null,
      "caller" : null,
      "userAgent" : "Custom User Agent String",
      "user" : null,
      "cognitoIdentityPoolId" : null,
      "cognitoIdentityId" : null,
      "cognitoAuthenticationProvider" : null,
      "sourceIp" : "127.0.0.1",
      "accountId" : null,
      "accessKey" : null
    },
    "authorizer" : null,
    "stage" : "Prod",
    "path" : "/contact",
    "protocol" : null,
    "requestTime" : null,
    "requestTimeEpoch" : 0,
    "elb" : null
  },
  "multiValueQueryStringParameters" : null,
  "multiValueHeaders" : {
    "Accept" : [ "application/json" ],
    "Accept-Encoding" : [ "gzip, deflate, br" ],
    "Accept-Language" : [ "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7" ],
    "Cache-Control" : [ "no-cache" ],
    "Connection" : [ "keep-alive" ],
    "Content-Length" : [ "150" ],
    "Content-Type" : [ "text/plain;charset=UTF-8" ],
    "Host" : [ "127.0.0.1:3000" ],
    "Origin" : [ "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop" ],
    "Postman-Token" : [ "5cadaccd-6fae-5bc2-b4ef-63900a1725ff" ],
    "Sec-Fetch-Mode" : [ "cors" ],
    "Sec-Fetch-Site" : [ "cross-site" ],
    "User-Agent" : [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" ],
    "X-Forwarded-Port" : [ "3000" ],
    "X-Forwarded-Proto" : [ "http" ],
    "X-Warm-Up" : [ "123" ]
  },
  "pathParameters" : null,
  "httpMethod" : "POST",
  "stageVariables" : null,
  "path" : "/contact",
  "isBase64Encoded" : false,
  "requestSource" : "API_GATEWAY"
}
2020-01-06 19:28:09 27868750-3637-1f80-3d80-53a724da16ef INFO  App - Lambda was warmed up
?[32mEND RequestId: 27868750-3637-1f80-3d80-53a724da16ef?[0m
?[32mREPORT RequestId: 27868750-3637-1f80-3d80-53a724da16ef     Init Duration: 1951.87 ms       Duration: 42.91 ms      Billed Duration: 100 ms Memory Size: 256 MB     Max Memory Used: 102 MB ?[0m
2020-01-06 22:28:11 127.0.0.1 - - [06/Jan/2020 22:28:11] "POST /contact HTTP/1.1" 201 -


Log, tentu saja, tidak diformat dengan cara terbaik. Semoga ini akan diperbaiki di masa depan.

Penting: saat mengubah kode lambda, memulai ulang API tidak perlu. Cukup membangun kembali lambda dengan perintah sam build .
Sedikit tentang bug
Java- aws-serverless-java-container-core, : 502 . :
Invalid API Gateway Response Keys: {'base64Encoded'} in {'statusCode': 200, 'headers': {'Content-Type': 'text/plain'}, 'body': 'Hello World', 'base64Encoded': False} 

- , API Gateway AWS JsonProperty. 'isBase64Encoded' 'base64Encoded', , , . , Java- ContactUsProxyResponse AwsProxyRequest.



3. Panggilan lokal dari IDEA


Segala sesuatu yang dijelaskan dalam paragraf di atas adalah fungsionalitas dari alat SAM. Itu dikendalikan dari baris perintah dan dapat diintegrasikan ke dalam antarmuka apa pun. Inilah yang dilakukan dalam plugin untuk IntelljIDEA AWS Toolkit.

Plugin ini menambahkan konfigurasi tambahan untuk meluncurkan lambda langsung dari IDE. Seperti inilah tampilan jendela konfigurasi. Anda harus memilih templat dengan deskripsi lambda, atau mengkonfigurasi pengaturan secara manual. Dalam kasus pertama, jumlah memori dan bahasa untuk kompilasi akan secara otomatis diambil dari templat. Dalam kasus kedua, Anda dapat mengonfigurasi jumlah RAM sendiri dan membuat perkiraan perkiraan batas. Plugin lain memungkinkan Anda untuk menjalankan konfigurasi langsung dari jendela editor kode Java atau yaml-template. Screenshot di bawah ini:











Faktanya, itu saja. Dengan menjalankan konfigurasi khusus, Anda cukup mengotomatisasi panggilan lambda yang sering dari konsol. Setuju, cukup nyaman?


4. Pengujian


Di sini kita berbicara tentang jenis tes untuk lambda. Karena saya menggunakan Java dalam contoh, pengujian akan mencakup alat yang cukup standar untuk pengujian unit dan integrasi: Junit 4, Mockito dan PowerMockito.

Tes unit


Untuk menutupi kode lambda dengan unit test, Anda tidak perlu memiliki pengetahuan khusus. Cukup menerapkan praktik Java standar: mengunci semua dependensi di kelas dan mencoba menguji semua kemungkinan kasus pemrosesan permintaan.

Saya tidak menambahkan semua skenario pengujian dan membatasi diri saya pada dua skenario positif dan dua negatif.

Tes positif pertama memverifikasi bahwa jika ada header X-WARM-UP, tidak ada permintaan di DbService dan EmailService. Kasus kedua memeriksa apakah layanan ini akan dipanggil jika permintaan itu nyata. Ini adalah tes paling sederhana, dan saya menghilangkan sebagian cek di dalamnya.

Skenario negatif adalah pemeriksaan respons jika terjadi kesalahan pemrosesan klien atau server.

Tes integrasi


Adapun tes integrasi, saya memutuskan untuk memeriksa DbService dan kerjanya dengan tabel DynamoDB.

Dalam hal ini, saya menggunakan alat Localstack . Solusi ini menyediakan mokas gratis untuk layanan AWS yang dijalankan sebagai wadah buruh pelabuhan.

Untuk menginstal solusi ini, jalankan perintah:
pip install localstack
localstack start

Atau Anda dapat menggunakan file komposisi buruh pelabuhan .
docker-compose untuk hanya meningkatkan DynamoDB
version: '2.1'
services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack
    ports:
      - "4567-4599:4567-4599"
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
    environment:
      - SERVICES=dynamodb
      - DEBUG=${DEBUG- }
      - DATA_DIR=${DATA_DIR- }
      - PORT_WEB_UI=${PORT_WEB_UI- }
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }
      - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"


Perintah mulai memunculkan semua layanan AWS yang tersedia secara default. Untuk meningkatkan DynamoDB secara khusus, cukup tetapkan variabel lingkungan:
set SERVICES=dynamodb


Ada LocalstackTestRunner khusus untuk Junit yang memungkinkan Anda untuk memulai layanan yang diperlukan menggunakan konfigurasi @LocalstackDockerProperties .
Akibatnya, menulis tes untuk DbService terlihat seperti ini:
  • Tambahkan lebih dari kelas tes.
    @RunWith(LocalstackTestRunner.class)
    @LocalstackDockerProperties(services = { "dynamodb" })
    

  • Buat tabel
    Jawa
    @Before
    public void setUp() {
        AmazonDynamoDB clientDynamoDB = TestUtils.getClientDynamoDB();
        dynamoDB = new DynamoDB(clientDynamoDB);
        dbService = new DbService(dynamoDB);
    
        dynamoDB.createTable(
                new CreateTableRequest()
                        .withTableName("ContactUsTable")
                        .withKeySchema(new KeySchemaElement("Id", KeyType.HASH))
                        .withAttributeDefinitions(new AttributeDefinition("Id", ScalarAttributeType.S))
                        .withProvisionedThroughput(new ProvisionedThroughput(10L, 10L)));
    }
                    


  • Kami menggambarkan skenario pengujian
    Jawa
    // given
    ContactUsRequest contactUsRequest = new ContactUsRequest("subject", "name", "+79991234545", "123@mail.ru", "Qeustion");
    
    // when
    dbService.putContactUsRequest("123", contactUsRequest);
    
    // then
    Item item = dynamoDB.getTable("ContactUsTable").getItem(new PrimaryKey("Id", "123"));
    assertEquals(contactUsRequest.getSubject(), item.get("Subject"));
    assertEquals(contactUsRequest.getUsername(), item.get("Username"));
    assertEquals(contactUsRequest.getPhone(), item.get("Phone"));
    assertEquals(contactUsRequest.getEmail(), item.get("Email"));
    assertEquals(contactUsRequest.getQuestion(), item.get("Question"));
                  


  • Jangan lupa untuk menghapus tabel setelah ujian.
    Jawa
    @After
    public void tearDown() {
        dynamoDB.getTable("ContactUsTable").delete();
    }
                   



Alhasil, dengan menggunakan Localstack, kami mendapatkan serangkaian pengejaran AWS yang cukup luas yang memungkinkan Anda untuk meniru pekerjaan layanan ini.

Tes E2E


Untuk memainkan skenario E2E, lebih baik untuk meningkatkan layanan tes AWS khusus untuk menjalankan tes, jika, tentu saja, ada peluang seperti itu. Ini dapat dilakukan dengan menggunakan templat CloudFormation opsional, di mana sumber daya akan menjadi salinan templat utama.

Tes dapat dilakukan dengan memanggil lambda melalui AWS-CLI dan memproses hasilnya dengan alat yang tersedia. Anda masih dapat melakukan panggilan dalam unit test, tetapi tanpa membuat massa.

Tes kinerja


Karena pengujian kinerja layak mendapatkan artikel terpisah atau bahkan buku, saya tidak akan mencoba untuk memasukkan semua informasi di sini. Singkatnya, ketika berbicara tentang stress testing, Anda harus ingat bahwa menggunakan hampir semua layanan AWS tidak gratis, dan Anda harus siap untuk memperkirakan kemungkinan biaya di muka.

Jika Anda ingin mengevaluasi sumber daya yang diperlukan untuk lambda, gunakan konsol UI dan buat beberapa panggilan percobaan. Selanjutnya, dengan menggunakan logika dan matematika yang umum, evaluasi seberapa besar kinerja lambda Anda meningkat tergantung pada jumlah sumber daya yang tersedia.

Jangan lupa tentang CloudWatch. Dengan bantuannya, Anda dapat membuat dasbor yang cukup indikatif dan berdasarkan pada mereka menentukan parameter apa dari lambda dan pengeluaran yang Anda mampu.


5. Biaya solusi tanpa server


Evaluasi solusi selalu spesifik, karena Anda perlu mempertimbangkan tidak hanya biaya satu panggilan, tetapi juga lalu lintas masuk / keluar, biaya caching, logging dan pemantauan. Jika Anda mempertimbangkan untuk menggunakan lambda, cobalah untuk memprediksi beban yang akan ditangani layanan Anda.

Jika ini adalah panggilan tunggal atau proses ETL yang berjalan setiap beberapa jam / hari, maka lambda lebih cenderung membayar. Jika Anda memperkirakan beban beberapa kueri per detik, pastikan untuk membuat taksiran yang akurat.

Di bawah ini saya memberikan perkiraan perkiraan biaya lambda dan server EC2 termurah, sehingga Anda memahami nilai apa yang dipertanyakan: Parameter berikut untuk lambda diambil untuk menghitung:




  • Waktu pimpin: 150 milidetik
  • Harga: $ 0,00001667 untuk 1GB-s
  • Memori: 256 MB

Untuk EC2 t2.nano:

  • Harga: $ 4,75 per bulan
  • Memori: 512 MB
  • vCPU: 1
  • Beban maksimum: CPU 5% per bulan

Saya mengambil data EC2 dari sini, menurut perhitungan ini, server yang ditentukan dapat menahan beban konstan sebesar 0,3 permintaan per detik. Dengan meningkatnya beban, waktu respons akan meningkat, yang akan mengurangi efisiensi server ini.

Semua perhitungan ini cukup abstrak dan tidak memperhitungkan banyak faktor: diskon pembayaran di muka atau sejumlah besar permintaan, waktu eksekusi lambda, dan sebagainya. Tetapi mereka menunjukkan bahwa dengan beban kurang dari 1 permintaan per detik, biaya lambda kurang dari server EC2 termurah.

Omong-omong, jangan lupa untuk menambahkan harga ALB ke harga EC2 jika Anda perlu menyimpan beberapa replika aplikasi atau IP elastis.


Pengujian dan pengembangan lokal dari solusi Serverless kurang populer dibandingkan layanan microser yang sama. Namun demikian, semakin banyak orang mempelajari dan menerapkan teknologi ini dan memberikan kesempatan kepada berbagai produk sumber terbuka untuk menjadi lebih baik dan lebih efisien. Solusi semacam itu sangat menyederhanakan kehidupan perusahaan yang perlu merilis produk sesegera mungkin dan tidak perlu mengkonfigurasi seluruh infrastruktur. Tetapi bahkan dalam produk yang sudah dikembangkan, saya pikir ada tempat untuk database tanpa server atau lambdas.

Saya tidak mengklaim sebagai ahli di bidang pengujian solusi tanpa server, tetapi, berdasarkan pengalaman positif pribadi saya, saya memutuskan untuk menyoroti poin utama dalam artikel ini. Saya berharap bahwa mereka akan berguna bagi seseorang, dan mungkin beberapa dari Anda dapat menambah atau bahkan memperbaiki saya, yang saya akan sangat senang.


tautan yang bermanfaat



All Articles