开发者社区 > 云存储 > 对象存储OSS > 正文

go语言SDK client 和 bucket 是否并发安全

go语言SDK包 github.com/aliyun/aliyun-oss-go-sdk/oss

代码片段

client, err := oss.New(endpoint, accessID, accessKey)
...
bucket, err := client.Bucket(bucketName)

在go语言中请问是否可以全局只创建一个client和一个bucket,在多个协程中安全地使用,而不用每使用一个功能都都New一个client 和 client.Bucket.

展开
收起
游客yxedcshzn5ex4 2023-06-09 07:53:20 114 0
4 条回答
写回答
取消 提交回答
  • CSDN博客专家,51CTO博主专家,多知名企业认证讲师&签约作者&培训讲师,特邀作者等,华为云专家,资深测试开发专家,金牌面试官,职场面试培训及规划师。

    【回答】

    在Go中,是可以创建一个全局唯一的client和bucket的实例,并在多个协程中安全地使用的。通常可以将这些实例定义为全局变量,并在需要使用的地方进行访问。

    可以参考这段代码

    package main
    
    import (
    	"sync"
    
    	"github.com/aws/aws-sdk-go/aws"
    	"github.com/aws/aws-sdk-go/aws/session"
    	"github.com/aws/aws-sdk-go/service/s3"
    )
    
    // Global client and bucket instance
    var s3Client *s3.S3
    var bucket *s3.Bucket
    
    // Function to upload objects to S3
    func uploadObject(key, filePath string) {
    	// Acquire lock
    	s3ClientMutex.Lock()
    	defer s3ClientMutex.Unlock()
    
    	// Upload object to S3
    	_, err := s3Client.PutObject(&s3.PutObjectInput{
    		Bucket: aws.String(bucket.Name),
    		Key:    aws.String(key),
    		Body:   s3Client.GetObject(&s3.GetObjectInput{
    			Bucket: aws.String(bucket.Name),
    			Key:    aws.String(key),
    		}).Body,
    		ContentType: aws.String("application/octet-stream"),
    	})
    	if err != nil {
    		// Handle error
    		fmt.Println("Error uploading object:", err)
    		return
    	}
    }
    
    // Function to download objects from S3
    func downloadObject(key string) {
    	// Acquire lock
    	bucketMutex.Lock()
    	defer bucketMutex.Unlock()
    
    	// Download object from S3
    	resp, err := s3Client.GetObject(&s3.GetObjectInput{
    		Bucket: aws.String(bucket.Name),
    		Key:    aws.String(key),
    	})
    	if err != nil {
    		// Handle error
    		fmt.Println("Error downloading object:", err)
    		return
    	}
    
    	// Save object to file
    	_, err = os.Create(filePath)
    	if err != nil {
    		// Handle error
    		fmt.Println("Error saving object to file:", err)
    		return
    	}
    
    	// Write object to file
    	_, err = resp.Body.Read(file)
    	if err != nil {
    		// Handle error
    		fmt.Println("Error reading object from file:", err)
    		return
    	}
    }
    
    func main() {
    	// Create AWS session with default credentials
    	sess, err := session.NewSession(&aws.Config{
    		Region: aws.String("us-west-2"),
    	})
    	if err != nil {
    		// Handle error
    		fmt.Println("Error creating AWS session:", err)
    		return
    	}
    
    	// Create S3 client
    	s3Client = s3.New(sess)
    
    	// Create bucket
    	bucket = s3.NewBucket(s3Client)
    
    	// Start upload goroutine
    	go uploadObject("my-key", "./data/file.txt")
    
    	// Start download goroutine
    	go downloadObject("my-key")
    
    	// Wait for upload and download goroutines to finish
    	<-uploadObjectFinished
    	<-downloadObjectFinished
    }
    
    // Goroutine to signal when upload and download goroutines have finished
    func uploadObjectFinished() {
    	uploadObjectMutex.Lock()
    
    
    2023-06-09 09:42:08
    赞同 展开评论 打赏
  • 根据阿里巴巴官方文档,go语言SDK包中的oss.New()函数是线程安全的,因此可以多个goroutine同时调用。但是,对于client.Bucket()方法返回的bucket对象,官方文档并没有明确说明其是否线程安全。

    因此,在使用bucket对象时,建议在每个goroutine中都创建一个新的bucket对象,以避免并发安全问题。例如:

    go client, err := oss.New(endpoint, accessID, accessKey)
    if err != nil {
    // 处理错误
    }

    // 创建新的bucket对象
    bucket, err := client.Bucket(bucketName)
    if err != nil {
    // 处理错误
    }

    // 在多个goroutine中使用新的bucket对象 这样可以确保每个goroutine使用自己的bucket对象,避免了并发安全问题。

    2023-06-09 08:42:18
    赞同 展开评论 打赏
  • aliyun-oss-go-sdk 中的 ClientBucket 对象都是并发安全的,您可以在多个协程中共用同一个 ClientBucket 对象,而不用担心并发问题。

    aliyun-oss-go-sdk 的官方文档中,有如下说明:

    The Client and Bucket objects are both safe for concurrent use by multiple goroutines.

    也就是说,在多个协程中使用 ClientBucket 对象是安全的。

    因此,您可以全局只创建一个 Client 和一个 Bucket,在多个协程中安全地使用,而不用每使用一个功能都都 New 一个 ClientBucket

    当然,如果您需要在不同的协程中使用不同的 Bucket 对象,也可以通过 Client 对象的 Bucket 方法来创建新的 Bucket 对象,并在不同的协程中使用不同的 Bucket 对象,这也是安全的。

    2023-06-09 08:42:19
    赞同 展开评论 打赏
  • 面对过去,不要迷离;面对未来,不必彷徨;活在今天,你只要把自己完全展示给别人看。

    Go 语言 SDK 的 Client 和 Bucket 对象是并发安全的(concurrently safe)。这意味着您可以在多个 goroutine 中使用同一 Client 或 Bucket 对象,而不需要担心数据竞争或其他并发问题。

    2023-06-09 08:42:20
    赞同 1 展开评论 打赏

热门讨论

热门文章

相关电子书

更多
gohbase :HBase go客户端 立即下载
Go构建日请求千亿级微服务实践 立即下载
一个跨平台的云服务SDK需要什么 立即下载