MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

C#云原生应用开发(AWS/Azure SDK实战)

2024-05-073.8k 阅读

C# 云原生应用开发之 AWS SDK 实战

AWS 简介与开发环境搭建

AWS(Amazon Web Services)是全球知名的云计算服务平台,提供了丰富的云服务,如计算资源(EC2)、存储(S3)、数据库(DynamoDB)等。在使用 C# 进行 AWS 云原生应用开发前,首先要搭建开发环境。

  1. 安装 AWS SDK for .NET: 可以通过 NuGet 包管理器来安装 AWS SDK for .NET。在 Visual Studio 中,右键点击项目,选择“管理 NuGet 程序包”,在搜索框中输入“AWS SDK for .NET”,然后点击安装。

  2. 配置 AWS 凭证: 有多种方式配置 AWS 凭证,其中一种常见的是使用 AWS 配置文件。在本地用户目录下创建一个.aws文件夹,然后在其中创建credentials文件,内容格式如下:

[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY

YOUR_ACCESS_KEY_IDYOUR_SECRET_ACCESS_KEY替换为你在 AWS 账户中获取的真实凭证。

使用 AWS S3 存储服务

AWS S3(Simple Storage Service)是一种对象存储服务,可用于存储和检索任意数量的数据。

  1. 创建 S3 桶: 以下是使用 C# 和 AWS SDK 创建 S3 桶的代码示例:
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonS3Client())
        {
            var bucketName = "your-unique-bucket-name";
            var putBucketRequest = new PutBucketRequest
            {
                BucketName = bucketName
            };

            try
            {
                var response = await client.PutBucketAsync(putBucketRequest);
                Console.WriteLine($"Bucket {bucketName} created successfully.");
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine($"Error creating bucket: {e.Message}");
            }
        }
    }
}

在上述代码中,首先创建了一个AmazonS3Client实例,然后定义了桶的名称,并构建了一个PutBucketRequest请求。通过调用PutBucketAsync方法来创建桶,并处理可能出现的异常。

  1. 上传文件到 S3 桶
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonS3Client())
        {
            var bucketName = "your-bucket-name";
            var objectKey = "your-object-key";
            var filePath = "C:\\path\\to\\your\\file.txt";

            var putObjectRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = objectKey,
                FilePath = filePath
            };

            try
            {
                var response = await client.PutObjectAsync(putObjectRequest);
                Console.WriteLine($"File {filePath} uploaded to S3 successfully.");
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine($"Error uploading file: {e.Message}");
            }
        }
    }
}

此代码将本地文件file.txt上传到指定的 S3 桶中,objectKey是对象在桶中的唯一标识。

  1. 从 S3 桶下载文件
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonS3Client())
        {
            var bucketName = "your-bucket-name";
            var objectKey = "your-object-key";
            var downloadPath = "C:\\path\\to\\download\\file.txt";

            var getObjectRequest = new GetObjectRequest
            {
                BucketName = bucketName,
                Key = objectKey
            };

            using (var response = await client.GetObjectAsync(getObjectRequest))
            using (var fileStream = new FileStream(downloadPath, FileMode.Create))
            {
                await response.ResponseStream.CopyToAsync(fileStream);
                Console.WriteLine($"File {objectKey} downloaded from S3 successfully.");
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine($"Error downloading file: {e.Message}");
            }
        }
    }
}

这段代码从指定的 S3 桶中下载对象,并保存到本地指定路径。

使用 AWS EC2 计算服务

AWS EC2(Elastic Compute Cloud)提供了可扩展的计算能力。

  1. 启动 EC2 实例
using Amazon.EC2;
using Amazon.EC2.Model;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonEC2Client())
        {
            var runInstancesRequest = new RunInstancesRequest
            {
                ImageId = "ami - your - image - id",
                InstanceType = InstanceType.T2Micro,
                MinCount = 1,
                MaxCount = 1
            };

            try
            {
                var response = await client.RunInstancesAsync(runInstancesRequest);
                Console.WriteLine($"EC2 instance {response.Reservations[0].Instances[0].InstanceId} launched successfully.");
            }
            catch (AmazonEC2Exception e)
            {
                Console.WriteLine($"Error launching EC2 instance: {e.Message}");
            }
        }
    }
}

在上述代码中,ImageId指定了要使用的 Amazon Machine Image(AMI),InstanceType指定了实例类型,通过RunInstancesAsync方法启动 EC2 实例。

  1. 停止 EC2 实例
using Amazon.EC2;
using Amazon.EC2.Model;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonEC2Client())
        {
            var instanceId = "i - your - instance - id";
            var stopInstancesRequest = new StopInstancesRequest
            {
                InstanceIds = new[] { instanceId }
            };

            try
            {
                var response = await client.StopInstancesAsync(stopInstancesRequest);
                Console.WriteLine($"EC2 instance {instanceId} stopped successfully.");
            }
            catch (AmazonEC2Exception e)
            {
                Console.WriteLine($"Error stopping EC2 instance: {e.Message}");
            }
        }
    }
}

此代码用于停止指定InstanceId的 EC2 实例。

使用 AWS DynamoDB 数据库服务

AWS DynamoDB 是一个 NoSQL 数据库,具有高可用性和可扩展性。

  1. 创建 DynamoDB 表
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonDynamoDBClient())
        {
            var tableName = "your - table - name";
            var createTableRequest = new CreateTableRequest
            {
                TableName = tableName,
                AttributeDefinitions = new[]
                {
                    new AttributeDefinition
                    {
                        AttributeName = "Id",
                        AttributeType = ScalarAttributeType.N
                    }
                },
                KeySchema = new[]
                {
                    new KeySchemaElement
                    {
                        AttributeName = "Id",
                        KeyType = KeyType.HASH
                    }
                },
                ProvisionedThroughput = new ProvisionedThroughput
                {
                    ReadCapacityUnits = 5,
                    WriteCapacityUnits = 5
                }
            };

            try
            {
                var response = await client.CreateTableAsync(createTableRequest);
                Console.WriteLine($"DynamoDB table {tableName} created successfully.");
            }
            catch (AmazonDynamoDBException e)
            {
                Console.WriteLine($"Error creating DynamoDB table: {e.Message}");
            }
        }
    }
}

上述代码定义了一个名为your - table - name的 DynamoDB 表,表的主键为Id,并设置了读写容量单位。

  1. 向 DynamoDB 表插入数据
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonDynamoDBClient())
        {
            var tableName = "your - table - name";
            var item = new Dictionary<string, AttributeValue>
            {
                { "Id", new AttributeValue { N = "1" } },
                { "Name", new AttributeValue { S = "John Doe" } }
            };

            var putItemRequest = new PutItemRequest
            {
                TableName = tableName,
                Item = item
            };

            try
            {
                var response = await client.PutItemAsync(putItemRequest);
                Console.WriteLine($"Item inserted into DynamoDB table {tableName} successfully.");
            }
            catch (AmazonDynamoDBException e)
            {
                Console.WriteLine($"Error inserting item: {e.Message}");
            }
        }
    }
}

此代码向指定的 DynamoDB 表中插入了一条数据,数据包含IdName两个属性。

  1. 从 DynamoDB 表查询数据
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new AmazonDynamoDBClient())
        {
            var tableName = "your - table - name";
            var key = new Dictionary<string, AttributeValue>
            {
                { "Id", new AttributeValue { N = "1" } }
            };

            var getItemRequest = new GetItemRequest
            {
                TableName = tableName,
                Key = key
            };

            try
            {
                var response = await client.GetItemAsync(getItemRequest);
                if (response.Item.Count > 0)
                {
                    Console.WriteLine($"Item retrieved from DynamoDB table {tableName}:");
                    foreach (var pair in response.Item)
                    {
                        Console.WriteLine($"{pair.Key}: {pair.Value.S}");
                    }
                }
                else
                {
                    Console.WriteLine($"Item not found in DynamoDB table {tableName}.");
                }
            }
            catch (AmazonDynamoDBException e)
            {
                Console.WriteLine($"Error retrieving item: {e.Message}");
            }
        }
    }
}

这段代码根据主键Id从 DynamoDB 表中查询数据,并输出查询结果。

C# 云原生应用开发之 Azure SDK 实战

Azure 简介与开发环境搭建

Azure 是微软提供的云计算平台,拥有广泛的云服务,涵盖计算、存储、数据库等多个领域。在使用 C# 进行 Azure 云原生应用开发时,需要搭建相应的开发环境。

  1. 安装 Azure SDK for .NET: 同样可以通过 NuGet 包管理器来安装。在 Visual Studio 中,右键点击项目,选择“管理 NuGet 程序包”,搜索“Azure SDK for .NET”相关的包,如Azure.Storage.Blobs用于 Azure Blob 存储服务,Azure.ResourceManager.Compute用于 Azure 计算资源管理等,并进行安装。

  2. 配置 Azure 凭证: 可以使用 Azure CLI 来进行身份验证和配置凭证。首先安装 Azure CLI,然后在命令行中运行az login,按照提示完成登录过程。登录成功后,Azure SDK 可以自动使用这些凭证进行操作。

使用 Azure Blob 存储服务

Azure Blob 存储是一种用于存储大量非结构化数据的对象存储服务。

  1. 创建 Blob 容器
using Azure.Storage.Blobs;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string connectionString = "your - connection - string";
        string containerName = "your - container - name";

        BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);

        try
        {
            await containerClient.CreateIfNotExistsAsync();
            Console.WriteLine($"Blob container {containerName} created successfully.");
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error creating blob container: {e.Message}");
        }
    }
}

上述代码通过连接字符串创建了一个BlobServiceClient实例,然后获取BlobContainerClient并尝试创建指定名称的 Blob 容器。

  1. 上传 Blob
using Azure.Storage.Blobs;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string connectionString = "your - connection - string";
        string containerName = "your - container - name";
        string blobName = "your - blob - name";
        string filePath = "C:\\path\\to\\your\\file.txt";

        BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
        BlobClient blobClient = containerClient.GetBlobClient(blobName);

        using (FileStream fileStream = File.OpenRead(filePath))
        {
            try
            {
                await blobClient.UploadAsync(fileStream, true);
                Console.WriteLine($"Blob {blobName} uploaded successfully.");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error uploading blob: {e.Message}");
            }
        }
    }
}

此代码将本地文件上传为指定容器中的 Blob。

  1. 下载 Blob
using Azure.Storage.Blobs;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string connectionString = "your - connection - string";
        string containerName = "your - container - name";
        string blobName = "your - blob - name";
        string downloadPath = "C:\\path\\to\\download\\file.txt";

        BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
        BlobClient blobClient = containerClient.GetBlobClient(blobName);

        using (FileStream fileStream = File.OpenWrite(downloadPath))
        {
            try
            {
                await blobClient.DownloadToAsync(fileStream);
                Console.WriteLine($"Blob {blobName} downloaded successfully.");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error downloading blob: {e.Message}");
            }
        }
    }
}

这段代码从指定容器中下载 Blob 到本地指定路径。

使用 Azure VM 计算服务

Azure 虚拟机(VM)提供了灵活的计算资源。

  1. 创建 Azure VM
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Network;
using Azure.ResourceManager.Network.Models;
using Azure.ResourceManager.Resources;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        ArmClient armClient = new ArmClient(new DefaultAzureCredential());
        SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();

        string resourceGroupName = "your - resource - group - name";
        string location = "eastus";
        string vmName = "your - vm - name";
        string nicName = "your - nic - name";

        ResourceGroupResource resourceGroup = await subscription.GetResourceGroups().CreateOrUpdateAsync(WaitUntil.Completed, resourceGroupName, new ResourceGroupData(location));

        NetworkResource network = await resourceGroup.GetNetworks().CreateOrUpdateAsync(WaitUntil.Completed, "your - vnet - name", new NetworkData(location)
        {
            AddressSpace = new AddressSpace { AddressPrefixes = { "10.0.0.0/16" } }
        });

        NetworkInterfaceResource nic = await resourceGroup.GetNetworkInterfaces().CreateOrUpdateAsync(WaitUntil.Completed, nicName, new NetworkInterfaceData(location)
        {
            IpConfigurations =
            {
                new NetworkInterfaceIpConfigurationData()
                {
                    Name = "ipconfig1",
                    Subnet = new SubnetData()
                    {
                        AddressPrefix = "10.0.0.0/24",
                        Id = network.Data.Subnets.FirstOrDefault()?.Id
                    },
                    Primary = true,
                    PrivateIPAllocationMethod = NetworkInterfaceIPAllocationMethod.Dynamic
                }
            }
        });

        var vm = await resourceGroup.GetVirtualMachines().CreateOrUpdateAsync(WaitUntil.Completed, vmName, new VirtualMachineData(location)
        {
            HardwareProfile = new HardwareProfile { VmSize = VirtualMachineSizeTypes.StandardB1s },
            StorageProfile = new StorageProfile
            {
                ImageReference = new ImageReference
                {
                    Publisher = "MicrosoftWindowsServer",
                    Offer = "WindowsServer",
                    Sku = "2019 - Datacenter",
                    Version = "latest"
                },
                OsDisk = new OsDisk
                {
                    CreateOption = DiskCreateOptionTypes.FromImage,
                    Name = "your - os - disk - name"
                }
            },
            OsProfile = new OSProfile
            {
                ComputerName = vmName,
                AdminUsername = "your - username",
                AdminPassword = "your - password"
            },
            NetworkProfile = new NetworkProfile
            {
                NetworkInterfaces =
                {
                    new NetworkInterfaceReference { Id = nic.Data.Id }
                }
            }
        });

        Console.WriteLine($"Azure VM {vmName} created successfully.");
    }
}

此代码创建了一个资源组、虚拟网络、网络接口,并最终创建了一个 Windows Server 2019 的虚拟机。

  1. 停止 Azure VM
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        ArmClient armClient = new ArmClient(new DefaultAzureCredential());
        SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();

        string resourceGroupName = "your - resource - group - name";
        string vmName = "your - vm - name";

        var vm = await subscription.GetResourceGroup(resourceGroupName).GetVirtualMachineAsync(vmName);
        await vm.Value.StopAsync(Azure.ResourceManager.Compute.Models.PowerState.Shutdown);

        Console.WriteLine($"Azure VM {vmName} stopped successfully.");
    }
}

这段代码停止了指定资源组中的指定虚拟机。

使用 Azure Cosmos DB 数据库服务

Azure Cosmos DB 是一种多模型数据库服务,支持 NoSQL 等多种数据模型。

  1. 创建 Cosmos DB 数据库和容器
using Azure;
using Azure.Cosmos;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string endpointUri = "your - endpoint - uri";
        string primaryKey = "your - primary - key";

        CosmosClient cosmosClient = new CosmosClient(endpointUri, primaryKey);

        string databaseName = "your - database - name";
        string containerName = "your - container - name";

        DatabaseResponse database = await cosmosClient.CreateDatabaseIfNotExistsAsync(databaseName);
        Console.WriteLine($"Cosmos DB database {databaseName} created successfully.");

        ContainerResponse container = await database.Database.CreateContainerIfNotExistsAsync(containerName, "/partitionKey");
        Console.WriteLine($"Cosmos DB container {containerName} created successfully.");
    }
}

上述代码创建了一个 Cosmos DB 数据库和一个容器,并指定了容器的分区键。

  1. 向 Cosmos DB 容器插入数据
using Azure.Cosmos;
using System;
using System.Threading.Tasks;

class Program
{
    class Item
    {
        public string id { get; set; }
        public string partitionKey { get; set; }
        public string name { get; set; }
    }

    static async Task Main()
    {
        string endpointUri = "your - endpoint - uri";
        string primaryKey = "your - primary - key";

        CosmosClient cosmosClient = new CosmosClient(endpointUri, primaryKey);

        string databaseName = "your - database - name";
        string containerName = "your - container - name";

        Container container = cosmosClient.GetContainer(databaseName, containerName);

        var item = new Item
        {
            id = "1",
            partitionKey = "pk1",
            name = "Sample Item"
        };

        try
        {
            var response = await container.CreateItemAsync(item, new PartitionKey(item.partitionKey));
            Console.WriteLine($"Item inserted into Cosmos DB container {containerName} successfully.");
        }
        catch (CosmosException e)
        {
            Console.WriteLine($"Error inserting item: {e.Message}");
        }
    }
}

此代码向指定的 Cosmos DB 容器中插入了一条数据,数据模型通过Item类定义。

  1. 从 Cosmos DB 容器查询数据
using Azure.Cosmos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Program
{
    class Item
    {
        public string id { get; set; }
        public string partitionKey { get; set; }
        public string name { get; set; }
    }

    static async Task Main()
    {
        string endpointUri = "your - endpoint - uri";
        string primaryKey = "your - primary - key";

        CosmosClient cosmosClient = new CosmosClient(endpointUri, primaryKey);

        string databaseName = "your - database - name";
        string containerName = "your - container - name";

        Container container = cosmosClient.GetContainer(databaseName, containerName);

        string query = "SELECT * FROM c WHERE c.id = '1'";
        var queryIterator = container.GetItemQueryIterator<Item>(query);

        List<Item> results = new List<Item>();
        while (queryIterator.HasMoreResults)
        {
            var response = await queryIterator.ReadNextAsync();
            results.AddRange(response.ToList());
        }

        if (results.Count > 0)
        {
            Console.WriteLine($"Items retrieved from Cosmos DB container {containerName}:");
            foreach (var item in results)
            {
                Console.WriteLine($"Id: {item.id}, Name: {item.name}");
            }
        }
        else
        {
            Console.WriteLine($"No items found in Cosmos DB container {containerName}.");
        }
    }
}

这段代码根据指定的 SQL 查询语句从 Cosmos DB 容器中查询数据,并输出查询结果。

通过以上对 AWS 和 Azure SDK 在 C# 云原生应用开发中的实战介绍,开发者可以利用这些云服务和 SDK 快速构建可扩展、可靠的云原生应用。在实际开发中,还需要根据具体的业务需求进行更深入的优化和定制。