【发布时间】:2021-01-29 18:24:58
【问题描述】:
我正在使用 AmazonS3Client 将数据读/写到 S3 对象存储。在我的代码中,每次执行读取、列出存储桶、上传、重命名、删除等操作时,我都会创建一个新连接。将我的应用程序部署到生产环境后,我遇到了一些性能问题。在浏览了几个博客之后,建议使用单个 amazonS3 客户端连接。我的代码如下-> 对于下面的每个 CRUD 操作,如果您看到我正在创建一个新连接,然后使用块处理它。我计划进行单一连接并使用它而不在每次呼叫时使用块。保持单一连接是个好选择吗?我有大约 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;
}
}
计划使用下面的单例并使用块删除 ->
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;
}
}
【问题讨论】:
-
根据亚马逊的说法,
AmazonS3Client对象是线程安全的,旨在同时跨多个请求使用:stackoverflow.com/a/7746922/1204153 -
@Andy:所以 AWS 建议它是线程安全的,我可以使用单例连接,但我的问题是每次都创建新连接并处理它与维护单例连接相比有性能优势吗?
-
是的,当然它有很大的好处。没有理由每次都创建新连接。这样做非常耗费资源。您必须每次都进行身份验证。只需像使用单身人士一样使用它,它就会将你的日常工作速度提高十倍。
-
重用,其他 cmets 已经解释过的好处,我同意这些。辛格尔顿很好。尽管 DI 在您的情况下是更好的选择(测试能力、处置等),但您也可以在 DI 中指定单例服务。有关概述,请在此处阅读 enterprisecraftsmanship.com/posts/…。简单示例 services.AddSingleton
();