AmazonS3Client单连接与每次呼叫的新连接C#

AmazonS3Client单连接与每次呼叫的新连接C#,c#,amazon-s3,C#,Amazon S3,我正在使用AmazonS3Client将数据读/写到S3对象存储。在我的代码中,每次在执行诸如读取、列出存储桶、上载、重命名、删除等操作时,我都会创建一个新连接。将应用程序部署到生产环境后,我遇到一些性能问题。在浏览了几个博客之后,建议使用单个amazonS3客户端连接。下面是我的代码-> 对于下面的每一个CRUD操作,如果您看到我正在创建一个新连接,然后使用block处理它。我计划使用单连接,并且在每次通话中不使用阻塞。保持单一连接是一个好的选择吗?我有大约400个用户同时访问应用程序 pub

我正在使用AmazonS3Client将数据读/写到S3对象存储。在我的代码中,每次在执行诸如读取、列出存储桶、上载、重命名、删除等操作时,我都会创建一个新连接。将应用程序部署到生产环境后,我遇到一些性能问题。在浏览了几个博客之后,建议使用单个amazonS3客户端连接。下面是我的代码-> 对于下面的每一个CRUD操作,如果您看到我正在创建一个新连接,然后使用block处理它。我计划使用单连接,并且在每次通话中不使用阻塞。保持单一连接是一个好的选择吗?我有大约400个用户同时访问应用程序

public ObjectFileInfo(string path)
{
    StorageClient = ObjectFileManager.GetClient();
    objectFileInfo = ObjectFileManager.getFileInfo(StorageClient, path);
}

public class ObjectFileManager
{
    public static Amazon.S3.AmazonS3Client GetClient()
    {
    AmazonS3Config Config = new AmazonS3Config();
    AmazonS3Client StorageClient;

    Config.RegionEndpoint = null;
    Config.ServiceURL = ConfigurationManager.NGDMSobjECSEndPoint;
    Config.AllowAutoRedirect = true;
    Config.ForcePathStyle = true;
    Config.Timeout = TimeSpan.FromMinutes(30);
            
    StorageClient = new AmazonS3Client(ConfigurationManager.NGDMSobjECSUser, ConfigurationManager.NGDMSobjECSKey, Config);
    return StorageClient;
    }
    
    
     public static string[] ListBuckets()
        {
            ListBucketsResponse Response;
            //Creating AmazonS3Client and disposing it in using
            using (AmazonS3Client StorageClient = GetClient())
            {
                Response = StorageClient.ListBuckets();
            }

            var BucketNames = from Bucket in Response.Buckets select Bucket.BucketName;
            return BucketNames.ToArray();
        }
        
        public static bool DeleteFile(string keyName)
        {
            var delRequest = new DeleteObjectRequest
            {
                BucketName = bucketName,
                Key = keyName
            };
            //Creating AmazonS3Client and disposing it in using
            using (AmazonS3Client StorageClient = GetClient())
            {
                StorageClient.DeleteObject(delRequest);
            }
            return true;
        }
}
计划使用Singleton,如下所示,并使用block->

class S3ObjectStorageClient
    {
        /// <summary>
        /// Singleton implementation of Object Storage Client
        /// </summary>
        private S3ObjectStorageClient()
        {
            
        }    

        public static AmazonS3Client Client
        {
            get
            {
                return S3Client.clientInstance;
            }
        }

        /// <summary>
        /// Nested private class to ensure Singleton
        /// </summary>
        private class S3Client
        {
            static S3Client()
            {

            }

            internal static readonly AmazonS3Client clientInstance = ObjectFileManager.GetClient();
        }
    }

 public ObjectFileInfo(string path)
{
    StorageClient = S3ObjectStorageClient.Client; //Singleton
    objectFileInfo = ObjectFileManager.getFileInfo(StorageClient, path);
}
    
    
     public static string[] ListBuckets()
        {
            ListBucketsResponse Response;
            
            //Singleton and removed using block
           AmazonS3Client StorageClient = S3ObjectStorageClient.Client;
           Response = StorageClient.ListBuckets();
            

            var BucketNames = from Bucket in Response.Buckets select Bucket.BucketName;
            return BucketNames.ToArray();
        }
        
        public static bool DeleteFile(string keyName)
        {
            var delRequest = new DeleteObjectRequest
            {
                BucketName = bucketName,
                Key = keyName
            };
            //Singleton and removed using block
            AmazonS3Client StorageClient = S3ObjectStorageClient.Client;
            StorageClient.DeleteObject(delRequest);            
            return true;
        }
}
类S3ObjectStorageClient
{
/// 
///对象存储客户端的单例实现
/// 
私有S3ObjectStorageClient()
{
}    
公共静态AmazonS3Client客户端
{
收到
{
返回S3Client.clientInstance;
}
}
/// 
///嵌套私有类以确保单例
/// 
私有类客户端
{
静态S3Client()
{
}
内部静态只读AmazonS3Client clientInstance=ObjectFileManager.GetClient();
}
}
公共ObjectFileInfo(字符串路径)
{
StorageClient=S3ObjectStorageClient.Client;//单例
objectFileInfo=ObjectFileManager.getFileInfo(StorageClient,路径);
}
公共静态字符串[]ListBuckets()
{
Listbuckets响应;
//使用block删除Singleton和
AmazonS3Client-StorageClient=S3ObjectStorageClient.Client;
Response=StorageClient.listbakes();
var BucketNames=来自响应中的Bucket。Bucket选择Bucket.BucketName;
返回BucketNames.ToArray();
}
公共静态bool DeleteFile(字符串键名)
{
var delRequest=新的DeleteObjectRequest
{
BucketName=BucketName,
Key=keyName
};
//使用block删除Singleton和
AmazonS3Client-StorageClient=S3ObjectStorageClient.Client;
StorageClient.DeleteObject(delRequest);
返回true;
}
}

实际上,您可以安全地重用它,因为创建和重用客户机不是一个坏主意。但创建新客户并不十分昂贵:

用于.NET的AWS SDK最著名的方面是可用于与AWS交互的各种服务客户端。客户端对象是线程安全的、一次性的,并且可以重用。(客户机对象很便宜,因此构建多个实例不会产生很大的开销,但创建和重用客户机也不是一个坏主意。)

因此,根据这一点,性能优势可能没有那么大。但是,由于创建一个新客户机的成本很小,所以我总是重复使用该客户机。也就是说,根据你的代码

使用(AmazonS3Client-StorageClient=GetClient())
{
Response=StorageClient.listbakes();
}

这并不是很糟糕,只是比使用单例的效率要低一点。如果您认为这会明显影响您的性能,最好的办法是测量它,并确定它是否真的是使用单例进行重构的原因。

事实上,您可以安全地重用它,因为创建和重用客户机不是一个坏主意。但创建新客户并不十分昂贵:

用于.NET的AWS SDK最著名的方面是可用于与AWS交互的各种服务客户端。客户端对象是线程安全的、一次性的,并且可以重用。(客户机对象很便宜,因此构建多个实例不会产生很大的开销,但创建和重用客户机也不是一个坏主意。)

因此,根据这一点,性能优势可能没有那么大。但是,由于创建一个新客户机的成本很小,所以我总是重复使用该客户机。也就是说,根据你的代码

使用(AmazonS3Client-StorageClient=GetClient())
{
Response=StorageClient.listbakes();
}

这并不是很糟糕,只是比使用单例的效率要低一点。如果您认为这会明显影响您的性能,那么最好的办法就是对其进行测量,并确定这是否真的是使用单例进行重构的原因。

这两种方法都是有效的,但使用单例肯定会提高代码效率

此外,在使用客户机时,AWS将依赖注入作为正确的模式加以推广。例如,新的AWS服务CodeGuru profiler突出显示多个客户端实例作为优化源


另请参见:

这两种方法都是有效的,但使用单例肯定会提高代码效率

此外,在使用客户机时,AWS将依赖注入作为正确的模式加以推广。例如,新的AWS服务CodeGuru profiler突出显示多个客户端实例作为优化源


另请参见:

作为AWS.NETSDK的作者之一,我可以提供更多的上下文。在封面下,AmazonS3Client与SDK中的所有其他服务客户端一起管理一个HttpClient池,这是一个昂贵的创建对象。因此,当您创建新的AmazonS3Client时,SDK正在从SDK管理的池中重用HttpClient

如果使用具有代理凭据的代理,则SDK必须在每次创建服务客户端时创建新的HttpClient

一个有潜力的地方