这是 <分布式对象存储 原理架构及Go语言实现>的学习笔记的第一篇
我们简单的实现一个REST(表述性状态传递,英文:Representational State Transfer)服务接口,用来单机存储对象
单机版的REST接口极其简单 只提供对象的PUT和GET方法 顾名思义 就是对象的存取方法
来看下代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 func main() { 2 http.HandleFunc("/objects/", objects.Handler) //注册HTTP处理函数,如果有客户端访问本机的HTTP服务且URL是以"objects"开头,那么就交由handler函数处理 3 log.Fatal(http.ListenAndServe(os.Getenv("LISTEN_ADDRESS"), nil)) //若出现错误 日志打印错误信息 4 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 func Handler(w http.ResponseWriter, r *http.Request) { 2 m := r.Method 3 if m == http.MethodPut { 4 // PUT请求进入下列函数处理 5 put(w, r) 6 return 7 } 8 if m == http.MethodGet { 9 // GET请求进入下列函数处理 10 get(w, r) 11 return 12 } 13 //其他请求 默认返回不允许操作提示 14 w.WriteHeader(http.StatusMethodNotAllowed) 15 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 func put(w http.ResponseWriter, r *http.Request) { 2 //获取代码运行时设置的保存路径(Getenv("STORAGE_ROOT"))下的objects文件夹 3 f, e := os.Create(os.Getenv("STORAGE_ROOT") + "/objects/" + 4 strings.Split(r.URL.EscapedPath(), "/")[2]) 5 //strings.Split(r.URL.EscapedPath(), "/")[2] 分解http请求中的字符串 获取要写入的对象的名称 6 if e != nil { 7 log.Println(e) 8 w.WriteHeader(http.StatusInternalServerError) 9 return 10 } 11 defer f.Close() 12 //将http请求的内容写入到本地磁盘中 13 io.Copy(f, r.Body) 14 } 15 16 func get(w http.ResponseWriter, r *http.Request) { 17 //获取代码运行时设置的保存路径(Getenv("STORAGE_ROOT"))下的objects文件夹 18 f, e := os.Open(os.Getenv("STORAGE_ROOT") + "/objects/" + 19 strings.Split(r.URL.EscapedPath(), "/")[2]) 20 //strings.Split(r.URL.EscapedPath(), "/")[2] 分解http请求中的字符串 获取要读取的对象的名称 21 if e != nil { 22 //如果出现错误 日志打印错误 返回未找寻到状态值 23 log.Println(e) 24 w.WriteHeader(http.StatusNotFound) 25 return 26 } 27 //延迟关闭 并且将读取到的对象写入到HTTP的主体W里 并且返回 28 defer f.Close() 29 io.Copy(w, f) 30 }
下面运行代码
运行环境为 unbuntu
首先在存储根目录下创建相应的objects文件夹
以监听本地地址端口12345 存储根目录为/tmp 运行go代码
再开启一个终端 GET一个名为test的对象
由于没有PUT对象 此时返回的是404 NOT FOUND
下面再PUT一个对象
再来尝试打开test对象
OK 这次成功获取之前PUT上去的那个对象的内容了
下一个章节将加强可扩展性 当前服务器无法满足等性能指标时 可以自如的调整扩展服务器集群