Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
This commit is contained in:
commit
15e744da49
107 files changed
+61762
No files matched your search
@@ -0,0 +1,257 @@
|
||||
# Serverless архитектура и FaaS
|
||||
|
||||
## Навигация
|
||||
- [🏠 Главная страница курса](../../../README.md)
|
||||
- [📚 Модуль 2](../README.md)
|
||||
|
||||
---
|
||||
|
||||
## Что такое Serverless
|
||||
|
||||
**Serverless** — это модель облачных вычислений, где разработчики не управляют серверами, а платформа автоматически выделяет ресурсы по требованию.
|
||||
|
||||
## Ключевые характеристики Serverless
|
||||
|
||||
### 1. Event-Driven Execution
|
||||
- Функции запускаются по событиям
|
||||
- Автоматическое масштабирование
|
||||
- Оплата только за время выполнения
|
||||
|
||||
### 2. Stateless Functions
|
||||
- Функции не хранят состояние
|
||||
- Внешнее хранение данных
|
||||
- Горизонтальное масштабирование
|
||||
|
||||
## FaaS (Функция как сервис)
|
||||
|
||||
**FaaS** — это подмодель Serverless, где код выполняется в виде отдельных функций.
|
||||
|
||||
### AWS Lambda
|
||||
|
||||
```python
|
||||
# AWS Lambda Function
|
||||
import json
|
||||
import boto3
|
||||
|
||||
def lambda_handler(event, context):
|
||||
"""
|
||||
Lambda function для обработки заказов
|
||||
"""
|
||||
# Парсинг события
|
||||
order_data = json.loads(event['body'])
|
||||
|
||||
# Валидация данных
|
||||
if not validate_order(order_data):
|
||||
return {
|
||||
'statusCode': 400,
|
||||
'body': json.dumps({'error': 'Invalid order data'})
|
||||
}
|
||||
|
||||
# Обработка заказа
|
||||
order_id = process_order(order_data)
|
||||
|
||||
# Отправка уведомления
|
||||
send_notification(order_id)
|
||||
|
||||
return {
|
||||
'statusCode': 200,
|
||||
'body': json.dumps({
|
||||
'orderId': order_id,
|
||||
'status': 'processed'
|
||||
})
|
||||
}
|
||||
|
||||
def validate_order(order_data):
|
||||
"""Валидация данных заказа"""
|
||||
required_fields = ['customerId', 'items', 'total']
|
||||
return all(field in order_data for field in required_fields)
|
||||
|
||||
def process_order(order_data):
|
||||
"""Обработка заказа"""
|
||||
# Логика обработки заказа
|
||||
return f"ORD-{order_data.get('customerId')}-{int(time.time())}"
|
||||
|
||||
def send_notification(order_id):
|
||||
"""Отправка уведомления"""
|
||||
sns = boto3.client('sns')
|
||||
sns.publish(
|
||||
TopicArn='arn:aws:sns:us-east-1:123456789012:order-notifications',
|
||||
Message=f'Order {order_id} has been processed',
|
||||
Subject='Order Processed'
|
||||
)
|
||||
```
|
||||
|
||||
### Azure Functions
|
||||
|
||||
```csharp
|
||||
// Azure Function
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public static class OrderProcessor
|
||||
{
|
||||
[FunctionName("ProcessOrder")]
|
||||
public static async Task<IActionResult> Run(
|
||||
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "orders")] HttpRequest req,
|
||||
ILogger log)
|
||||
{
|
||||
log.LogInformation("Processing order request");
|
||||
|
||||
try
|
||||
{
|
||||
// Чтение данных запроса
|
||||
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
|
||||
var orderData = JsonSerializer.Deserialize<OrderData>(requestBody);
|
||||
|
||||
// Валидация
|
||||
if (!ValidateOrder(orderData))
|
||||
{
|
||||
return new BadRequestObjectResult("Invalid order data");
|
||||
}
|
||||
|
||||
// Обработка заказа
|
||||
var orderId = await ProcessOrderAsync(orderData);
|
||||
|
||||
// Отправка уведомления
|
||||
await SendNotificationAsync(orderId);
|
||||
|
||||
return new OkObjectResult(new { orderId, status = "processed" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError(ex, "Error processing order");
|
||||
return new StatusCodeResult(500);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ValidateOrder(OrderData orderData)
|
||||
{
|
||||
return !string.IsNullOrEmpty(orderData.CustomerId) &&
|
||||
orderData.Items?.Count > 0 &&
|
||||
orderData.Total > 0;
|
||||
}
|
||||
|
||||
private static async Task<string> ProcessOrderAsync(OrderData orderData)
|
||||
{
|
||||
// Логика обработки заказа
|
||||
await Task.Delay(100); // Имитация обработки
|
||||
return $"ORD-{orderData.CustomerId}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}";
|
||||
}
|
||||
|
||||
private static async Task SendNotificationAsync(string orderId)
|
||||
{
|
||||
// Отправка уведомления
|
||||
await Task.Delay(50); // Имитация отправки
|
||||
}
|
||||
}
|
||||
|
||||
public class OrderData
|
||||
{
|
||||
public string CustomerId { get; set; }
|
||||
public List<OrderItem> Items { get; set; }
|
||||
public decimal Total { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### Google Cloud Functions
|
||||
|
||||
```javascript
|
||||
// Google Cloud Function
|
||||
const functions = require('@google-cloud/functions-framework');
|
||||
const { PubSub } = require('@google-cloud/pubsub');
|
||||
|
||||
const pubsub = new PubSub();
|
||||
|
||||
functions.http('processOrder', async (req, res) => {
|
||||
// Установка CORS
|
||||
res.set('Access-Control-Allow-Origin', '*');
|
||||
res.set('Access-Control-Allow-Methods', 'POST');
|
||||
res.set('Access-Control-Allow-Headers', 'Content-Type');
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.status(204).send('');
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method !== 'POST') {
|
||||
res.status(405).send('Method Not Allowed');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const orderData = req.body;
|
||||
|
||||
// Валидация данных
|
||||
if (!validateOrder(orderData)) {
|
||||
res.status(400).json({ error: 'Invalid order data' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Обработка заказа
|
||||
const orderId = await processOrder(orderData);
|
||||
|
||||
// Отправка уведомления
|
||||
await sendNotification(orderId);
|
||||
|
||||
res.status(200).json({
|
||||
orderId: orderId,
|
||||
status: 'processed'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error processing order:', error);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
function validateOrder(orderData) {
|
||||
const requiredFields = ['customerId', 'items', 'total'];
|
||||
return requiredFields.every(field => orderData.hasOwnProperty(field));
|
||||
}
|
||||
|
||||
async function processOrder(orderData) {
|
||||
// Логика обработки заказа
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
return `ORD-${orderData.customerId}-${Date.now()}`;
|
||||
}
|
||||
|
||||
async function sendNotification(orderId) {
|
||||
const topic = pubsub.topic('order-notifications');
|
||||
const message = {
|
||||
data: Buffer.from(JSON.stringify({
|
||||
orderId: orderId,
|
||||
message: `Order ${orderId} has been processed`
|
||||
}))
|
||||
};
|
||||
|
||||
await topic.publish(message);
|
||||
}
|
||||
```
|
||||
|
||||
## Преимущества Serverless
|
||||
|
||||
### Технические:
|
||||
- Автоматическое масштабирование
|
||||
- Оплата только за использование
|
||||
- Отсутствие управления серверами
|
||||
- Быстрое развертывание
|
||||
|
||||
### Экономические:
|
||||
- Снижение операционных расходов
|
||||
- Предсказуемые затраты
|
||||
- Отсутствие простоев серверов
|
||||
|
||||
## Недостатки Serverless
|
||||
|
||||
### Ограничения:
|
||||
- Cold Start задержки
|
||||
- Ограничения времени выполнения
|
||||
- Ограничения памяти
|
||||
- Vendor Lock-in
|
||||
|
||||
### Сложности:
|
||||
- Сложность отладки
|
||||
- Ограниченный контроль
|
||||
- Проблемы с состоянием
|
||||
Reference in new issue
Block a user