本文介绍如何使用Go语言对京东云对象存储OSS进行基本的操做,帮助客户快速经过Go SDK接入京东云对象存储,提升应用开发的效率。git
在实际操做以前,咱们先看一下京东云OSS的API接口支持范围和能力。从对象存储的API文档能够看到,京东云提供两套接口:github
一、兼容S3 API,支持AWS S3接口,兼容大部分重要功能,做为后续重点开发和优化版本。因为并非彻底兼容S3的接口,所以须要重点阅读兼容接口列表,相关介绍见
https://docs.jdcloud.com/cn/object-storage-service/compatibility-api-overview编程
二、旧版OSS API,京东云前期独立封装的restful接口,支持基本的service、bucket、object等操做。该版本目前仍能使用,但后续再也不开发。vim
很明显,京东云提供兼容S3的接口,一方面能够快速支持原有基于AWS S3开发的应用程序,另外一方面帮助客户的数据从AWS S3迁移过来。建议您使用兼容S3的接口,而同时京东云提供了丰富的多种语言版本的SDK,能够根据您项目开发的须要进行不一样语言SDK的选择。
相关介绍见api
https://docs.jdcloud.com/cn/object-storage-service/introduction-3restful
这里须要注意查看兼容接口列表,对比京东云OSS和AWS S3接口的兼容状况。譬如Put Bucket接口仅使用通用的请求header,默认建立权限为private的bucket。因为不支持x-amz-acl, x-amz-grant-*等请求头,没法使用标准权限来设置ACL(即Canned ACL)。若是须要建立时指定bucket ACL,须要经过另外的接口实现,这个下文会说起。
兼容接口列表:
https://docs.jdcloud.com/cn/object-storage-service/compatibility-api-overviewsession
下面以Go SDK介绍京东云OSS的基本操做,实现对象资源的上传下载等功能。并发
一、安装或更新Go 1.5及以上版本(参考1 - Mac下安装Go语言环境配置)。oracle
二、(可选)经过可视化IDE Atom搭建Go编译环境。相比于sublime text或者传统的vim编辑方式,Atom是更为先进的文本代码编辑器,是由Github打造的编程开发工具,除了界面美观,还有各类强大的插件。本文以Atom开发环境做为展现(参考2 – Mac下基于Atom构建Go开发环境)编辑器
三、在使用Go SDK发起请求以前,需提早在京东云用户中心帐户管理下的AccessKey管理页面申请accesskey和secretKey密钥对(简称AK/SK)。这个秘钥对会在后续程序初始化使用到。
一、命令行安装
go get github.com/aws/aws-sdk-go
二、Atom安装(可选)
菜单【Packages】-> 【Go】-> 【Get Package】,而后输入github.com/aws/aws-sdk-go,稍等片刻便下载和安装完成。代码会被下载到GOPATH环境变量中第一个路径src目录中,效果与命令行安装方法同样。
在具体编码以前,建议了解AWS SDK的构成,主要包括SDK core和service clients两个部分。SDK core适用于全部AWS的服务,service中的client仅适用于对应的service,做为该服务的客户端进行调用。
SDK core包括一些通用的类,帮助更容易地构造API参数,譬如Config、Logger等。其中,
awserr:进程异常的接口,返回进程中遇到的异常和错误,对应错误码和信息。
credential:API调用须要身份认证,须要使用京东云的AK/SK进行认证,而且须要修改默认的Config配置项。
endpoints:服务的调用入口,有区域属性,须要在Config中配置。
session:提供配置的初始化,能够自定义配置中的参数进行初始化,包括region、endpoints、credential等。
request:提供API请求和重试,能够自定义请求及其处理方法。
建立s3 client的示例
在发起OSS(S3协议)的请求以前,须要初始化s3 client,如下为建立client的例子。
1 ak := "your accesskey" 2 sk := "your secretkey" 3 token := "" //Token留空 4 creds := credentials.NewStaticCredentials(ak, sk, token) 5 _,err := creds.Get() 6 7 config := &aws.Config{ 8 Region: aws.String("cn-north-1"), //Bucket所在Region 9 Endpoint: aws.String("s3.cn-north-1.jcloudcs.com"), //Bucket所在Endpoint 10 DisableSSL :aws.Bool(false), 11 Credentials :creds, 12 } 13 client := s3.New(session.New(config))
建立完s3 client以后,就能够对bucket、object等oss资源进行请求操做了。下面分别介绍建立bucket、上传文件(PutObject、Upload)、分片上传文件进行demo展现。
目标:在京东云华北区建立一个名字为go-sdk-sample的bucket,并设置ACL为公有读私有写(public-read)。
示例代码:
1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/aws/credentials" 8 "github.com/aws/aws-sdk-go/aws/session" 9 "github.com/aws/aws-sdk-go/service/s3" 10) 11 12func main() { 13 bucket := "go-sdk-sample" 14 // Create S3 service client 15 svc := s3.New(newSession()) 16 17 crParams := &s3.CreateBucketInput{ 18 Bucket: aws.String(bucket), 19 } 20 21 _, err := svc.CreateBucket(crParams) 22 23 if err != nil { 24 exitErrorf("Unable to create bucket %q, %v", bucket, err) 25 } 26 27 // Wait until bucket is created before finishing 28 fmt.Printf("Waiting for bucket %q to be created...\n", bucket) 29 30 err = svc.WaitUntilBucketExists(&s3.HeadBucketInput{ 31 Bucket: aws.String(bucket), 32 }) 33 if err != nil { 34 exitErrorf("Error occurred while waiting for bucket to be created, %v", bucket) 35 } 36 37 fmt.Printf("Bucket %q successfully created\n", bucket) 38 39 puParams := &s3.PutBucketAclInput{ 40 Bucket: aws.String(bucket), 41 } 42 puParams.SetACL("public-read") //set bucket ACL 43 44 _, err = svc.PutBucketAcl(puParams) 45 if err != nil { 46 exitErrorf(err.Error()) 47 } 48 fmt.Println("Set", bucket, "ACL to public-read") 49 50} 51 52func newSession() *session.Session { 53 ak := " your accesskey " 54 sk := " your secretkey " 55 token := "" //Token留空 56 57 creds := credentials.NewStaticCredentials(ak, sk, token) 58 creds.Get() 59 60 config := &aws.Config{ 61 Region: aws.String("cn-north-1"), //Bucket所在Region 62 Endpoint: aws.String("s3.cn-north-1.jcloudcs.com"), //Bucket所在Endpoint 63 DisableSSL: aws.Bool(false), 64 Credentials: creds, 65 } 66 return session.New(config) 67} 68 69func exitErrorf(msg string, args ...interface{}) { 70 fmt.Fprintf(os.Stderr, msg+"\n", args...) 71 os.Exit(1) 72}
示例中能够看出,咱们经过CreatBucket的接口建立bucket,并经过PutBucketAcl的接口设置bucket的ACL。目前京东云支持三种访问权限,包括私有读写(private)、公有读私有写(public-read)、公有读写(public-read-write)。
执行结果:
执行成功,控制台显示对应的bucket建立成功。
目标:把一个object上传到bucket中,并加入MD5校验确保数据完整性。
示例代码:
1package main 2 3import ( 4 "crypto/md5" 5 "encoding/hex" 6 "fmt" 7 "io" 8 "os" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/aws/credentials" 12 "github.com/aws/aws-sdk-go/aws/session" 13 "github.com/aws/aws-sdk-go/service/s3" 14) 15 16func main() { 17 filename := "your file path" //file path 18 19 file, err := os.Open(filename) 20 if err != nil { 21 exitErrorf("Unable to open file %q, %v", err) 22 } 23 defer file.Close() 24 25 md5_file := CreateMd5(filename) 26 27 // Create S3 service client 28 svc := s3.New(newSession()) 29 30 input := &s3.PutObjectInput{ 31 Body: file, 32 Bucket: aws.String("go-sdk-sample"), 33 Key: aws.String(filename), 34 ContentMD5: aws.String(md5_file), //MD5 校验(可选) 35 } 36 37 result, err := svc.PutObject(input) 38 39 if err != nil { 40 exitErrorf("Put Object Error, %v", err) 41 } 42 43 fmt.Println(result) 44 45} 46// MD5校验 47func CreateMd5(filename string) string { 48 49 f, err := os.Open(filename) 50 if err != nil { 51 exitErrorf("Unable to open file %q, %v", err) 52 } 53 defer f.Close() 54 55 md5hash := md5.New() 56 io.Copy(md5hash, f) 57 58 return hex.EncodeToString(md5hash.Sum(nil)) 59 60} 61 62func newSession() *session.Session { 63 ak := " your accesskey " 64 sk := " your secretkey " 65 token := "" //Token留空 66 67 creds := credentials.NewStaticCredentials(ak, sk, token) 68 creds.Get() 69 70 config := &aws.Config{ 71 Region: aws.String("cn-north-1"), //Bucket所在Region 72 Endpoint: aws.String("s3.cn-north-1.jcloudcs.com"), //Bucket所在Endpoint 73 DisableSSL: aws.Bool(false), 74 Credentials: creds, 75 } 76 return session.New(config) 77} 78 79func exitErrorf(msg string, args ...interface{}) { 80 fmt.Fprintf(os.Stderr, msg+"\n", args...) 81 os.Exit(1) 82}
示例中能够看出,咱们经过PutObject接口上传本地文件,同时为了校验数据的准确性,加入了CreateMd5方法生成文件的MD5值,并传参到ContentMD5中,OSS服务端会校验文件,若是为相同值会返回成功的result,即文件的ETAG值。
执行结果:
能够从控制台看到文件已经正确上传,ETag与文件计算的MD5值相符。能够尝试修改ContentMD5的参数为其余值,会返回错误结果,这里就不具体展现了。
上面经过PutObject的方法进行文件上传,那么若是文件比较大,通常经过分片上传的方式来实现分块、并发和重试机制,确保大,文件的上传。这里须要用到CreateMultipartUpload、UploadPart、CompletedPart、AbortMultipartUpload等多个接口来完成整个过程,同时须要自行实现重试、并行等逻辑,相对比较复杂。S3提供了S3 Upload Manager来帮助用户实现以上逻辑,可以自动判断文件大小来选择单次上传或分块上传的方式来完成。同时,用户能够自定义块大小(PartSize)、并发数(Concurrency)以及最大块数量(MaxUploadParts)等参数,知足不一样场景的须要。
示例代码:
1package main 2 3import ( 4 "fmt" 5 "os" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/credentials" 9 "github.com/aws/aws-sdk-go/aws/session" 10 "github.com/aws/aws-sdk-go/service/s3/s3manager" 11) 12 13func main() { 14 bucket := " go-sdk-sample " //bucket name 15 filename := " your file path " //file url 16 17 file, err := os.Open(filename) 18 if err != nil { 19 exitErrorf("Unable to open file %q, %v", err) 20 } 21 defer file.Close() 22 23 sess := newSession() 24 uploader := s3manager.NewUploader(sess) 25 26 upParams := &s3manager.UploadInput{ 27 Bucket: aws.String(bucket), 28 Key: aws.String(filename), 29 Body: file, 30 } 31 32 // 33 result, err := uploader.Upload(upParams, func(u *s3manager.Uploader) { 34 u.PartSize = 10 * 1024 * 1024 //自定义分块大小,10M每一个分片 35 u.LeavePartsOnError = true //true,上传出错会保留已成功上传的分块 36 u.Concurrency = 3 //定义并发数,即goroutines数量 37 u.MaxUploadParts = 10000 //定义最大可上传块数量 38 }) 39 40 if err != nil { 41 exitErrorf("Put Object Error, %v", err) 42 } 43 44 fmt.Printf("Successfully uploaded!\n") 45 fmt.Println("File URL: " + result.Location) 46} 47 48func newSession() *session.Session { 49 ak := " your accesskey " 50 sk := " your secretkey " 51 token := "" //Token留空 52 53 creds := credentials.NewStaticCredentials(ak, sk, token) 54 creds.Get() 55 56 config := &aws.Config{ 57 Region: aws.String("cn-north-1"), //Bucket所在Region 58 Endpoint: aws.String("s3.cn-north-1.jcloudcs.com"), //Bucket所在Endpoint 59 DisableSSL: aws.Bool(false), 60 Credentials: creds, 61 } 62 return session.New(config) 63} 64 65func exitErrorf(msg string, args ...int,erface{}) { 66 fmt.Fprintf(os.Stderr, msg+"\n", args...) 67 os.Exit(1) 68}
能够看到,与前面PutObject不一样,这里使用s3manager.NewUploader来构造上传服务,经过uploader.Upload方法上传文件。Upload的具体实现逻辑能够参考源码:
https://github.com/aws/aws-sdk-go/blob/master/service/s3/s3manager/upload.go
譬如自动判断是否分块上传的逻辑以下:
执行结果:
本次上传的文件大小为16M,比PartSize的10M大,所以会执行分块上传。在上传过程当中,能够在控制台-分片管理看到对应正在上传的分片任务,说明正在分片上传。upload的上传成功后会返回文件访问地址location。
至此,咱们已经把主要的OSS操做示例介绍完毕,其他的操做咱们根据实际须要继续整理,譬如不使用s3manager,直接用MultipartUpload等基础接口来实现分块上传,你们能够尝试一下,咱们下回分解。
一、安装Go
使用brew进行安装,brew是Mac下的一个包管理工具,相似于CentOS下的 yum,能够很方便地进行安装、卸载和更新各类软件包。
brew install go
安装后在终端输入go version查看安装的版本,个人显示go version go1.12.5 darwin/amd64,表示安装的是v1.12.5版本。
二、配置环境变量
查看go的环境变量设置
go env
一、安装Atom
https://atom.io/ Atom官网,能够直接下载软件安装。
二、安装Go语言环境(参考1的步骤)
三、安装go-plus插件
go-plus是Atom上面的一款开源的Golang开发环境插件,项目地址:
https://github.com/joefitzgerald/go-plus
在Atom中的Preference中能够找到install菜单,输入go-plus。
点击:install,就会开始安装go-plus,go-plus插件会自动安装对应的依赖插件,若是没有安装对应的Golang类库可使用go get安装。
安装完咱们就能够进行编码,为了方便编译、测试和编译,须要配合terminal使用,能够经过view-Terminal打开终端,不须要另外切换界面。
go-plus有很是多的特性,可以实时反馈语法错误和编译错误。每保存一个文件,go-plus就会在后台运行你提早配置好的要执行的go tools,例如:go vet、 go oracle、go build等等,而后将错误和警告在编辑器底部显示出来。
go-plus一样可以在编辑器的对应行上显示该行的编译错误提示和错误信息,这样你就能很快的定位哪一行有错。你们能够尝试一下。
欢迎点击“连接”了解更多精彩内容