Я работал над Lambda для некоторых проектов, и недавно мне пришлось спроектировать и написать сервис FAS с использованием функций Lambda и чтения / записи данных в RDS (MySQL). Я делюсь тем, что узнал здесь.
Прежде чем мы начнем
Предпосылки
В этом руководстве предполагается, что вы знакомы с основными лямбда-операциями и консолью AWS, RDS, IAM и Node.js.
Чтобы понять, подходит ли вам серверное приложение или нет, вам необходимо понять ограничения лямбды , что такое холодный старт и как работает параллелизм в лямбде. Модель исполнения Lambda, конечно, отличается от архитектуры традиционных веб-приложений в Spring.
Что такое холодный старт?
Когда пользователь запускает свой первый запрос, Lambda имеет небольшую задержку, пока он раскручивает новый контейнер и загружает наш код и зависимости в память. Это называется холодным стартом. Холодный запуск происходит только в том случае, если свободный контейнер недоступен или ожидает запуска нашего кода. По истечении времени ожидания соединения AWS уничтожает контейнер, и будущие запросы снова будут запускать новый контейнер. Первый запрос всегда будет немного медленнее из-за холодного запуска, но последующие запросы будут быстро попадать в тот же экземпляр.
Вам также может понравиться: Запрос RDS MySQL DB с помощью функции NodeJS Lambda
Мы можем использовать Cloud Watch Timer / фиктивный запрос, чтобы сохранить лямбды в тепле .
совпадение
Параллельные запросы инициируют создание новых экземпляров AWS Lambda. Например, если у вас есть пять одновременных запросов к одной и той же функции Lambda, AWS создаст пять контейнеров для обслуживания запросов. Короче говоря, при первом вызове функции AWS Lambda создает экземпляр функции и запускает ее метод-обработчик для обработки события. Если вы снова вызовете функцию во время обработки первого события, Lambda создаст другой экземпляр.
Вы можете настроить функцию с зарезервированным параллелизмом, чтобы гарантировать, что она всегда может достичь определенного уровня параллелизма. Эта функция может работать с этим максимальным количеством параллелизма без прерывания или ожидания.
Лимит лямбда-валюты по умолчанию равен 1000. Обратите внимание, что одна масштабированная лямбда-функция может ухудшить производительность любой другой лямбда-функции в том же регионе.
Резервный параллелизм не начинается до 20 экземпляров при первом лямбда-вызове. Его резервная емкость для функции может увеличиваться или уменьшаться. Как только предел одновременных выполнений будет достигнут, следующее выполнение будет ограничено.
Повторите Поведение
Лямбда-функции будут повторяться три раза, прежде чем они выйдут из строя из-за необработанной ошибки приложения. Если вы добавили context.succeed
и не обработали исключения должным образом, Lambda не будет повторять функцию и вместо этого будет предполагать, что функция была успешной. Если вы добавили context.fail
, Lambda повторит функцию.
JavaScript
1
module.exports.handler(event, context, callback) {
2
try {
3
// Do you what you want to do.
4
return callback(null, 'Success')
5
} catch (err) {
6
// You probably still want to log it.
7
console.error(err)
8
// Return fail.
9
return callback(null, 'fail')
10
}
11
}
Распространенные ошибки вызова
- Запрос — Событие запроса слишком велико или недопустимо в формате JSON, функция не существует или значение параметра имеет неправильный тип.
- Вызывающая сторона — пользователь или служба не имеют разрешения для вызова функции.
- Учетная запись — максимальное количество экземпляров функций уже запущено или запросы выполняются слишком быстро.
Отладка лямбда
Ниже приведены два подхода к отладке Lambda на локальной машине:
1. Выберите Test в правом верхнем углу вашей лямбда-функции, чтобы открыть экран, который позволяет вам настроить новый тест, который можно запустить для проверки успеха / сбоя, а также вы можете добавить console.log для отладки.
2. Другим наиболее популярным вариантом является Cloudwatch для отладки на консоли Aws. При просмотре файлов журнала или метрик CloudWatch при устранении ошибок, имейте в виду, что они отображаются или хранятся в регионе, ближайшем к месту, где выполнялась функция.
Lambda-local позволяет тестировать функции Amazon Lambda на вашем локальном компьютере, предоставляя упрощенный API и инструмент командной строки.
Оболочка
xxxxxxxxxx
1
npm install -g lambda-local
Вы можете использовать Lambda-local в качестве инструмента командной строки.
Оболочка
xxxxxxxxxx
1
# Simple usage lambda-local -l index.js -h handler -e examples/s3-put.js
2
# Input environment variables lambda-local -l index.js -h handler -e examples/s3-put.js -E '{"key":"value","key2":"value2"}'
Вы можете найти дополнительную информацию по следующей ссылке:
Вы также можете использовать SAM Local для локальной разработки и тестирования функций Lambda с помощью Docker.
Вы можете найти дополнительную информацию по следующей ссылке
Управление версиями и развертывание лямбда-функций
Если вы хотите опубликовать новую версию функции для тестирования качества, не затрагивая стабильную производственную версию, вы можете использовать опцию Lambda version. Когда вы выбираете новую версию, система создает новую версию вашей лямбда-функции каждый раз, когда вы публикуете функцию. Мы можем опубликовать несколько версий функции. Каждая версия может быть вызвана параллельно в отдельном контейнере. По умолчанию версия будет $LATEST
.
Мы можем настроить сине-зеленое / канарское развертывание для непрерывной доставки:
- https://aws.amazon.com/quickstart/architecture/blue-green-deployment/
- https://aws.amazon.com/blogs/compute/implementing-canary-deployments-of-aws-lambda-functions-with-alias-traffic-shifting/
Настроить RDS
Первым шагом для запуска кода является предоставление экземпляра RDS с помощью консоли AWS. Затем попробуйте AWS Free Tier с Amazon RDS.
MySQL 750 часов Amazon RDS Single-AZ db.t2.micro Использование экземпляра под управлением MySQL 20 ГБ хранилища БД общего назначения (SSD) и 20 ГБ хранилища резервных копий для ваших автоматических резервных копий базы данных и любых пользовательских снимков БД по инициативе пользователя
Напишите свою первую лямбда-функцию
Когда вы вызываете функцию, вы можете вызвать ее синхронно или асинхронно. При синхронном вызове вы ожидаете, пока функция обработает событие и вернет ответ. При асинхронном вызове Lambda ставит событие в очередь на обработку и немедленно возвращает ответ. Для асинхронного вызова Lambda обрабатывает повторы и может отправлять сбойные события в очередь недоставленных сообщений.
Вам нужно создать роль для Lambda. В качестве лучшей практики определите политику, которая следует принципу предоставления наименьших привилегий . Другими словами, политики включают в себя только те разрешения, которые требуются пользователям для выполнения своих задач, для целей обучения добавляется широкая роль, но вы можете сузить ее в соответствии со своими требованиями.
AmazonRDSFullAccess
JSON
xxxxxxxxxx
1
{
2
"Version":"2012-10-17",
3
"Statement":[
4
{
5
"Action":[
6
"rds:*",
7
"application-autoscaling:DeleteScalingPolicy",
8
"application-autoscaling:DeregisterScalableTarget",
9
"application-autoscaling:DescribeScalableTargets",
10
"application-autoscaling:DescribeScalingActivities",
11
"application-autoscaling:DescribeScalingPolicies",
12
"application-autoscaling:PutScalingPolicy",
13
"application-autoscaling:RegisterScalableTarget",
14
"cloudwatch:DescribeAlarms",
15
"cloudwatch:GetMetricStatistics",
16
"cloudwatch:PutMetricAlarm",
17
"cloudwatch:DeleteAlarms",
18
"ec2:DescribeAccountAttributes",
19
"ec2:DescribeAvailabilityZones",
20
"ec2:DescribeInternetGateways",
21
"ec2:DescribeSecurityGroups",
22
"ec2:DescribeSubnets",
23
"ec2:DescribeVpcAttribute",
24
"ec2:DescribeVpcs",
25
"sns:ListSubscriptions",
26
"sns:ListTopics",
27
"sns:Publish",
28
"logs:DescribeLogStreams",
29
"logs:GetLogEvents"
30
],
31
"Effect":"Allow",
32
"Resource":"*"
33
},
34
{
35
"Action":"pi:*",
36
"Effect":"Allow",
37
"Resource":"arn:aws:pi:*:*:metrics/rds/*"
38
},
39
{
40
"Action":"iam:CreateServiceLinkedRole",
41
"Effect":"Allow",
42
"Resource":"*",
43
"Condition":{
44
"StringLike":{
45
"iam:AWSServiceName":[
46
"rds.amazonaws.com",
47
"rds.application-autoscaling.amazonaws.com"
48
]
49
}
50
}
51
}
52
]
53
}
AmazonVPCFullAccess
JSON
xxxxxxxxxx
1
{
2
"Version":"2012-10-17",
3
"Statement":[
4
{
5
"Effect":"Allow",
6
"Action":[
7
"ec2:AcceptVpcPeeringConnection",
8
"ec2:AcceptVpcEndpointConnections",
9
"ec2:AllocateAddress",
10
"ec2:AssignIpv6Addresses",
11
"ec2:AssignPrivateIpAddresses",
12
"ec2:AssociateAddress",
13
"ec2:AssociateDhcpOptions",
14
"ec2:AssociateRouteTable",
15
"ec2:AssociateSubnetCidrBlock",
16
"ec2:AssociateVpcCidrBlock",
17
"ec2:AttachClassicLinkVpc",
18
"ec2:AttachInternetGateway",
19
"ec2:AttachNetworkInterface",
20
"ec2:AttachVpnGateway",
21
"ec2:AuthorizeSecurityGroupEgress",
22
"ec2:AuthorizeSecurityGroupIngress",
23
"ec2:CreateCustomerGateway",
24
"ec2:CreateDefaultSubnet",
25
"ec2:CreateDefaultVpc",
26
"ec2:CreateDhcpOptions",
27
"ec2:CreateEgressOnlyInternetGateway",
28
"ec2:CreateFlowLogs",
29
"ec2:CreateInternetGateway",
30
"ec2:CreateNatGateway",
31
"ec2:CreateNetworkAcl",
32
"ec2:CreateNetworkAcl",
33
"ec2:CreateNetworkAclEntry",
34
"ec2:CreateNetworkInterface",
35
"ec2:CreateNetworkInterfacePermission",
36
"ec2:CreateRoute",
37
"ec2:CreateRouteTable",
38
"ec2:CreateSecurityGroup",
39
"ec2:CreateSubnet",
40
"ec2:CreateTags",
41
"ec2:CreateVpc",
42
"ec2:CreateVpcEndpoint",
43
"ec2:CreateVpcEndpointConnectionNotification",
44
"ec2:CreateVpcEndpointServiceConfiguration",
45
"ec2:CreateVpcPeeringConnection",
46
"ec2:CreateVpnConnection",
47
"ec2:CreateVpnConnectionRoute",
48
"ec2:CreateVpnGateway",
49
"ec2:DeleteCustomerGateway",
50
"ec2:DeleteDhcpOptions",
51
"ec2:DeleteEgressOnlyInternetGateway",
52
"ec2:DeleteFlowLogs",
53
"ec2:DeleteInternetGateway",
54
"ec2:DeleteNatGateway",
55
"ec2:DeleteNetworkAcl",
56
"ec2:DeleteNetworkAclEntry",
57
"ec2:DeleteNetworkInterface",
58
"ec2:DeleteNetworkInterfacePermission",
59
"ec2:DeleteRoute",
60
"ec2:DeleteRouteTable",
61
"ec2:DeleteSecurityGroup",
62
"ec2:DeleteSubnet",
63
"ec2:DeleteTags",
64
"ec2:DeleteVpc",
65
"ec2:DeleteVpcEndpoints",
66
"ec2:DeleteVpcEndpointConnectionNotifications",
67
"ec2:DeleteVpcEndpointServiceConfigurations",
68
"ec2:DeleteVpcPeeringConnection",
69
"ec2:DeleteVpnConnection",
70
"ec2:DeleteVpnConnectionRoute",
71
"ec2:DeleteVpnGateway",
72
"ec2:DescribeAccountAttributes",
73
"ec2:DescribeAddresses",
74
"ec2:DescribeAvailabilityZones",
75
"ec2:DescribeClassicLinkInstances",
76
"ec2:DescribeCustomerGateways",
77
"ec2:DescribeDhcpOptions",
78
"ec2:DescribeEgressOnlyInternetGateways",
79
"ec2:DescribeFlowLogs",
80
"ec2:DescribeInstances",
81
"ec2:DescribeInternetGateways",
82
"ec2:DescribeKeyPairs",
83
"ec2:DescribeMovingAddresses",
84
"ec2:DescribeNatGateways",
85
"ec2:DescribeNetworkAcls",
86
"ec2:DescribeNetworkInterfaceAttribute",
87
"ec2:DescribeNetworkInterfacePermissions",
88
"ec2:DescribeNetworkInterfaces",
89
"ec2:DescribePrefixLists",
90
"ec2:DescribeRouteTables",
91
"ec2:DescribeSecurityGroupReferences",
92
"ec2:DescribeSecurityGroups",
93
"ec2:DescribeStaleSecurityGroups",
94
"ec2:DescribeSubnets",
95
"ec2:DescribeTags",
96
"ec2:DescribeVpcAttribute",
97
"ec2:DescribeVpcClassicLink",
98
"ec2:DescribeVpcClassicLinkDnsSupport",
99
"ec2:DescribeVpcEndpointConnectionNotifications",
100
"ec2:DescribeVpcEndpointConnections",
101
"ec2:DescribeVpcEndpoints",
102
"ec2:DescribeVpcEndpointServiceConfigurations",
103
"ec2:DescribeVpcEndpointServicePermissions",
104
"ec2:DescribeVpcEndpointServices",
105
"ec2:DescribeVpcPeeringConnections",
106
"ec2:DescribeVpcs",
107
"ec2:DescribeVpnConnections",
108
"ec2:DescribeVpnGateways",
109
"ec2:DetachClassicLinkVpc",
110
"ec2:DetachInternetGateway",
111
"ec2:DetachNetworkInterface",
112
"ec2:DetachVpnGateway",
113
"ec2:DisableVgwRoutePropagation",
114
"ec2:DisableVpcClassicLink",
115
"ec2:DisableVpcClassicLinkDnsSupport",
116
"ec2:DisassociateAddress",
117
"ec2:DisassociateRouteTable",
118
"ec2:DisassociateSubnetCidrBlock",
119
"ec2:DisassociateVpcCidrBlock",
120
"ec2:EnableVgwRoutePropagation",
121
"ec2:EnableVpcClassicLink",
122
"ec2:EnableVpcClassicLinkDnsSupport",
123
"ec2:ModifyNetworkInterfaceAttribute",
124
"ec2:ModifySubnetAttribute",
125
"ec2:ModifyVpcAttribute",
126
"ec2:ModifyVpcEndpoint",
127
"ec2:ModifyVpcEndpointConnectionNotification",
128
"ec2:ModifyVpcEndpointServiceConfiguration",
129
"ec2:ModifyVpcEndpointServicePermissions",
130
"ec2:ModifyVpcPeeringConnectionOptions",
131
"ec2:ModifyVpcTenancy",
132
"ec2:MoveAddressToVpc",
133
"ec2:RejectVpcEndpointConnections",
134
"ec2:RejectVpcPeeringConnection",
135
"ec2:ReleaseAddress",
136
"ec2:ReplaceNetworkAclAssociation",
137
"ec2:ReplaceNetworkAclEntry",
138
"ec2:ReplaceRoute",
139
"ec2:ReplaceRouteTableAssociation",
140
"ec2:ResetNetworkInterfaceAttribute",
141
"ec2:RestoreAddressToClassic",
142
"ec2:RevokeSecurityGroupEgress",
143
"ec2:RevokeSecurityGroupIngress",
144
"ec2:UnassignIpv6Addresses",
145
"ec2:UnassignPrivateIpAddresses",
146
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
147
"ec2:UpdateSecurityGroupRuleDescriptionsIngress"
148
],
149
"Resource":"*"
150
}
151
]
152
}
AWSLambdaVPCAccessExecutionRole
JSON
xxxxxxxxxx
1
{
2
"Version":"2012-10-17",
3
"Statement":[
4
{
5
"Effect":"Allow",
6
"Action":[
7
"logs:CreateLogGroup",
8
"logs:CreateLogStream",
9
"logs:PutLogEvents",
10
"ec2:CreateNetworkInterface",
11
"ec2:DescribeNetworkInterfaces",
12
"ec2:DeleteNetworkInterface"
13
],
14
"Resource":"*"
15
}
16
]
17
}
Чтобы создать функцию Lambda, перейдите в Консоль AWS и выберите Lambda .
Нажмите « Создать» и выберите Node.js 12.x. Затем выберите существующую роль, которую мы создали выше.
Чтобы поддерживать зависимость MySQL, нам нужно сначала создать код на локальном компьютере, а затем загрузить его на консоль Lambda.
Создайте папку и создайте package.json
Оболочка
xxxxxxxxxx
1
npm init
Как только файл создан, вы можете найти следующий JSON в папке.
JSON
xxxxxxxxxx
1
{
2
"name":"test",
3
"version":"1.0.0",
4
"description":"test",
5
"main":"index.js",
6
"scripts":{
7
"test":"echo \"Error: no test specified\" && exit 1"
8
},
9
"author":"Vaquar khan",
10
"license":"ISC"
11
}
Вам необходимо добавить зависимость узла MYSQL в проект, используя следующую команду
Оболочка
xxxxxxxxxx
1
npm install --save mysql
Теперь добавьте обработчик в приложение, создайте index.js ( index.handler ) и добавьте лямбда-логику.
Сначала в Lambda мы собираемся создать объект подключения, а затем вызвать нашу базу данных.
JavaScript
xxxxxxxxxx
1
const mysql = require('mysql');
2
const connection = mysql.createConnection({
4
//following param coming from aws lambda env variable
5
host: process.env.RDS_LAMBDA_HOSTNAME,
6
user: process.env.RDS_LAMBDA_USERNAME,
7
password: process.env.RDS_LAMBDA_PASSWORD,
8
port: process.env.RDS_LAMBDA_PORT,
9
// calling direct inside code
10
connectionLimit: 10,
11
multipleStatements: true,
12
// Prevent nested sql statements
13
connectionLimit: 1000,
14
connectTimeout: 60 * 60 * 1000,
15
acquireTimeout: 60 * 60 * 1000,
16
timeout: 60 * 60 * 1000,
17
debug: true
18
});
Затем нам нужно вызвать наш Lambda-обработчик.
JavaScript
xxxxxxxxxx
1
exports.handler = async (event) => {
2
try {
3
const data = await new Promise((resolve, reject) => {
4
connection.connect(function (err) {
5
if (err) {
6
reject(err);
7
}
8
connection.query('CREATE DATABASE testdb', function (err, result) {
9
if (err) {
10
console.log("Error->" + err);
11
reject(err);
12
}
13
resolve(result);
14
});
15
})
16
});
17
return {
19
statusCode: 200,
20
body: JSON.stringify(data)
21
}
22
} catch (err) {
24
return {
25
statusCode: 400,
26
body: err.message
27
}
28
}
29
};
30
Теперь создайте zip-файл и загрузите его.
После этого загрузите и нажмите на index.js . Для дальнейших изменений используйте встроенный редактор.
Создайте лямбда-переменную env с ее парами ключ-значение.
xxxxxxxxxx
1
RDS_LAMBDA_HOSTNAME
2
RDS_LAMBDA_USERNAME
3
RDS_LAMBDA_PASSWORD
4
RDS_LAMBDA_PORT
Теперь настройте Lambda с RDS и VPC, перейдите в группу безопасности экземпляра RDS. После выбора группы безопасности по умолчанию, нажмите на нее. На странице EC2 прокрутите вниз, чтобы найти входящие и исходящие настройки.
Во входящих настройках нажмите кнопку «Изменить». Вы можете изменить IP здесь.
- 0.0.0.0/0 - это делает RDS открытым для всего мира и не рекомендуется.
- Настройте VPC внутри сети функции Lambda для работы функции Lambda. Сначала перейдите к функции Lambda, нажмите « Сеть» , затем выберите VPC и скопируйте IP-адрес. Если VPC не выбран, выберите VPC в качестве функции DB и скопируйте IP-адрес. Добавьте этот IP во входящие настройки RDS.
Сохраните его и протестируйте функцию Lambda.
Полученные результаты
Ниже приведены несколько лямбда-обработчиков, чтобы понять, как работают CRUD-операции в Lambda.
Создать базу данных с использованием лямбды
JavaScript
xxxxxxxxxx
1
const mysql = require('mysql');
2
const connection = mysql.createConnection({
4
//following param coming from aws lambda env variable
5
host: process.env.RDS_LAMBDA_HOSTNAME,
7
user: process.env.RDS_LAMBDA_USERNAME,
8
password: process.env.RDS_LAMBDA_PASSWORD,
9
port: process.env.RDS_LAMBDA_PORT,
10
// calling direct inside code
11
connectionLimit: 10,
12
multipleStatements: true,
13
// Prevent nested sql statements
14
connectionLimit: 1000,
15
connectTimeout: 60 * 60 * 1000,
16
acquireTimeout: 60 * 60 * 1000,
17
timeout: 60 * 60 * 1000,
18
debug: true
19
}); exports.handler = async (event) => {
20
try {
21
const data = await new Promise((resolve, reject) => {
22
connection.connect(function (err) {
23
if (err) {
24
reject(err);
25
}
26
connection.query('CREATE DATABASE testdb',
27
function (err, result) {
28
if (err) {
29
console.log("Error->" + err);
30
reject(err);
31
} resolve(result);
32
});
33
})
34
});
35
return {
37
statusCode: 200,
38
body: JSON.stringify(data)
39
}
40
} catch (err) {
42
return {
43
statusCode: 400,
44
body: err.message
45
}
46
} };
Создать таблицу с помощью лямбды
JavaScript
xxxxxxxxxx
1
exports.handler = async (event) => {
2
const sql = "CREATE TABLE MESSAGE (message VARCHAR(255))";
3
con.query(sql, function (err, result) {
4
if (err) throw err;
5
console.log("Table created");
6
});
7
return "Table Created"
8
};
9
const mysql = require('mysql');
11
const connection = mysql.createConnection({
13
//following param coming from aws lambda env variable
14
host: process.env.RDS_LAMBDA_HOSTNAME,
15
user: process.env.RDS_LAMBDA_USERNAME,
16
password: process.env.RDS_LAMBDA_PASSWORD,
17
port: process.env.RDS_LAMBDA_PORT,
18
// calling direct inside code
19
connectionLimit: 10,
20
multipleStatements: true,
21
// Prevent nested sql statements
22
connectionLimit: 1000,
23
connectTimeout: 60 * 60 * 1000,
24
acquireTimeout: 60 * 60 * 1000,
25
timeout: 60 * 60 * 1000,
26
debug: true
27
}); exports.handler = async (event) => {
28
try {
29
const data = await new Promise((resolve, reject) => {
30
connection.connect(function (err) {
31
if (err) {
32
reject(err);
33
}
34
connection.query('CREATE TABLE Employee (message VARCHAR(255))',
35
function (err, result) {
36
if (err) {
37
console.log("Error->" + err);
38
reject(err);
39
}
40
resolve(result);
41
});
42
})
43
});
44
return {
46
statusCode: 200,
47
body: JSON.stringify(data)
48
}
49
} catch (err) {
51
return {
52
statusCode: 400,
53
body: err.message
54
}
55
}
56
};
57
Вставить записи, используя лямбду
xxxxxxxxxx
1
exports.handler = (event, context, callback) => {
2
// allows for using callbacks as finish/error-handlers
3
context.callbackWaitsForEmptyEventLoop = false;
4
const sql = "insert into testdb.Employee values(1,'Vaquar khan');";
5
con.query(sql, (err, res) => {
6
if (err) {
7
throw err
8
}
9
callback(null, '1 records inserted.');
10
})
11
};
12
Выберите записи, используя лямбда
xxxxxxxxxx
1
exports.handler = (event, context, callback) => {
2
// allows for using callbacks as finish/error-handlers
3
context.callbackWaitsForEmptyEventLoop = false;
4
const sql = "select * from testdb.Employee ";
5
con.query(sql, function (err, result) {
6
if (err) throw err;
7
callback(null, result)
8
});
9
};
Выберите записи с критериями, используя лямбду
JavaScript
xxxxxxxxxx
1
exports.handler = (event, context, callback) => {
2
// allows for using callbacks as finish/error-handlers
3
context.callbackWaitsForEmptyEventLoop = false;
4
const sql = "select * from testdb.Employee where emp_id = " + event.emp_id;
5
con.query(sql, function (err, result) {
6
if (err) throw err; callback(null, result)
7
});
8
};
Последний проект
Теперь мы дошли до фактического мяса и картошки того, что мы пытаемся сделать:
Создать таблицу
MySQL
xxxxxxxxxx
1
use testdb;
2
CREATE TABLE `Employee` (
4
`emp_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
5
`emp_name` varchar(100) DEFAULT NULL, PRIMARY KEY (`emp_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
6
insert into Employee values(1,'Vaquar khan');
8
insert into Employee values(2,'Zidan khan');
Создать лямбду
JavaScript
xxxxxxxxxx
1
const mysql = require('mysql');
2
const con = mysql.createConnection({
4
host: process.env.LAMBDA_HOSTNAME,
5
user: process.env.LAMBDA_USERNAME,
6
password: process.env.LAMBDA_PASSWORD,
7
port: process.env.LAMBDA_PORT,
8
connectionLimit: 10,
9
multipleStatements: true,
10
// Prevent nested sql statements
11
connectionLimit: 1000,
12
connectTimeout: 60 * 60 * 1000,
13
acquireTimeout: 60 * 60 * 1000,
14
timeout: 60 * 60 * 1000,
15
debug: true,
16
database:'testdb'
17
});
18
exports.handler = (event, context, callback) => {
20
console.log('inside lambda...'+event.emp_id)
21
// allows for using callbacks as finish/error-handlers
22
context.callbackWaitsForEmptyEventLoop = false;
23
const sql = "select * from Employee where emp_id = " + event.emp_id;
24
con.query(sql, function (err, result) {
25
if (err) throw err;
26
callback(null, result)
27
});
28
};
Создать тестовое событие
JSON
xxxxxxxxxx
1
{ "emp_id":1, "emp_name":"xyz" }
Создать API-шлюз
Количество API на лимит аккаунта составляет 600 региональных API, 600 частных API и 120 пограничных API. Теперь вы можете создавать и импортировать региональные и частные API со скоростью один запрос каждые три секунды и развертывать API со скоростью один запрос каждые пять секунд.
Обратите внимание, что при развертывании API в API Gateway регулирование по умолчанию включено в конфигурациях рабочей области.
В настоящее время в этом руководстве мы не реализуем безопасность на шлюзе API, но необходимо обязательно добавить защиту на шлюзе.
Для аутентификации и авторизации шлюза API могут использоваться следующие механизмы:
- Политики ресурсов позволяют создавать политики на основе ресурсов, чтобы разрешать или запрещать доступ к вашим API и методам с указанных исходных IP-адресов или конечных точек VPC. Дополнительную информацию смотрите в разделе Контроль доступа к API с помощью политик ресурсов Amazon API Gateway .
- Стандартные роли и политики AWS IAM предлагают гибкие и надежные средства управления доступом, которые можно применять ко всему API или отдельным методам. Роли и политики IAM можно использовать для контроля того, кто может создавать и управлять вашими API, а также кто может их вызывать. Для получения дополнительной информации см. Контроль доступа к API с разрешениями IAM .
- Теги IAM могут использоваться вместе с политиками IAM для контроля доступа. Для получения дополнительной информации см. Использование тегов для управления доступом к ресурсам шлюза API .
- Политики конечных точек для интерфейса VPC Конечные точки позволяют вам присоединять политики ресурсов IAM к интерфейсу конечных точек VPC для повышения безопасности ваших частных API . Для получения дополнительной информации см. Раздел Использование политик конечных точек VPC для частных API-интерфейсов в API-шлюзе .
- Лямбда-авторизаторы - это лямбда-функции, которые управляют доступом к методам API REST с использованием аутентификации токенов на предъявителя, а также информации, описываемой заголовками, путями, строками запросов, переменными этапа или параметрами запроса переменных контекста. Авторизаторы лямбды используются для управления тем, кто может вызывать методы REST API. Для получения дополнительной информации см. Использование API-шлюзов лямбда-авторизаторов .
- Пулы пользователей Amazon Cognito позволяют создавать настраиваемые решения для аутентификации и авторизации для ваших REST API. Пулы пользователей Amazon Cognito используются для управления тем, кто может вызывать методы REST API. Дополнительную информацию смотрите в разделе Контроль доступа к API REST с использованием пользовательских пулов Amazon Cognito в качестве авторизатора.
- Безопасный ключ для API
- https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
Создать ресурс
Создать метод добавить GET
Развертывание API
Создайте новый этап и разверните API. После успешного развертывания вы можете увидеть URL.
Тест лямбда с API шлюзом
Загрузите Postman или используйте расширение Postman Chrome для вызова API.
Резюме
In this post, we discussed how to create applications quickly to run in AWS Lambda, which provides low cost, zero maintenance compute, and automatically scales. We also discussed the limitations of Lambda and how to design simple micro-service using AWS API gateway, and RDS. In the next post, we will try to cover AWS Cognito for Authentication/Authorization and how to sync Cognito data into an RDS table.
Further Reading
Dealing With Serverless Cold Starts, Once and For All!
A Simple API Using AWS RDS, Lambda, and API Gateway