DAY3 | 高质量编程与性能调优实战
实现一个简单的图片分享网站的案例,用户可以上传和分享图片
优化思路:
- 图片优化: 使用Go语言对上传的图片进行压缩和调整大小,减少文件大小并提高加载速度。
- 数据请求优化: 使用Go语言的并发特性对图片资源进行异步加载,并使用CDN加速图片加载,减少页面加载时间。
图片优化的步骤
首先,我们来看一下Go语言中图片优化的部分:
实现一个简单的go语言HTTP服务器,接收用户上传的图片,进行优化处理
使用标准库net/http和第三方库github.com/nfnt/resize
import (
"fmt"
"image"
"image/jpeg"
_ "image/png" // Import required for png image decoding
"log"
"net/http"
"os"
"github.com/nfnt/resize"
)
第一步,处理HTTP请求
使用http.HandleFunc将handleImageUpload函数与"/upload"路径绑定。这样当用户向服务器发送HTTP POST请求,路径为"/upload"时,就会调用handleImageUpload函数来处理上传的图片
第二步,解析HTTP请求中的Multipart表单
r.ParseMultipartForm(10 << 20) // 限制上传文件大小为10MB
r是http.Request类型的参数,它包含了客户端发送的HTTP请求信息。在这行代码中,调用
ParseMultipartForm函数的作用是解析Multipart表单,并将上传的文件和表单字段存储在r.Form和r.MultipartForm中,以供后续的处理函数使用
第三步,图片处理
使用image.Decode函数将上传的图片解码为image.Image对象,这样可以对图片进行后续处理。然后,通过resize.Resize函数对图片进行大小调整,将其缩小为宽度为800像素,高度按比例缩放。这样可以在不明显影响视觉质量的前提下,减少文件大小,提高图片加载速度
// 解码图片
img, _, err := image.Decode(file)
if err != nil {
http.Error(w, "无法解码图片", http.StatusInternalServerError)
return
}
// 调整图片大小
resizedImg := resize.Resize(800, 0, img, resize.Lanczos3)
第四步,文件保存
将优化后的图片保存到服务器上的"uploads"目录中,文件名前缀加上"optimized_"以区别原始图片。这样保存了优化后的图片,用户可以在之后通过URL来访问这些优化后的图片
// 创建输出文件
outputFile, err := os.Create("uploads/" + "optimized_" + file.Filename)
if err != nil {
http.Error(w, "无法保存图片", http.StatusInternalServerError)
return
}
defer outputFile.Close()
// 使用JPEG编码器将图片保存到输出文件中
err = jpeg.Encode(outputFile, resizedImg, nil)
if err != nil {
http.Error(w, "无法保存图片", http.StatusInternalServerError)
return
}
第五步,错误处理
返回适当的HTTP错误状态码和错误信息
数据请求优化
通过将图片URL列表的获取和处理逻辑分离,实现了数据请求优化
首先定义一个结构体
import (
"encoding/json"
"fmt"
"net/http"
)
type Image struct {
URL string `json:"url"`
}
Image结构体用于表示图片的URL信息,包含一个URL字段,该字段对应JSON中的url键
实现一个处理函数
func handleImageList(w http.ResponseWriter, r *http.Request) {
images := []Image{
{URL: "uploads/optimized_image1.jpg"},
{URL: "uploads/optimized_image2.jpg"},
{URL: "uploads/optimized_image3.jpg"},
// 添加更多图片URL
}
直接定义了一个图片URL列表,但在实际应用中,这里可能会从数据库或其他存储中获取图片信息,这样的设计可以将图片信息的获取和处理与HTTP服务器的逻辑分离,实现了优化请求的目的
接着设置响应头和编码响应
首先通过w.Header().Set("Content-Type", "application/json")设置响应头,指定返回的内容类型为JSON格式
使用json.NewEncoder(w).Encode(images)将images切片编码为JSON,并将编码后的JSON数据写入w(http.ResponseWriter)
服务器将以JSON格式返回图片URL列表给客户端
存在的问题
- 如果同时有多个用户上传图片,服务器可能会因为大量的图片调整计算而导致性能下降。优化方案可以考虑异步处理图片调整操作,将图片调整放到消息队列中,由后台进程逐个处理图片,减轻主服务器的负担
- 简单的文件保存方式可能会导致大量图片堆积在同一个目录下,造成目录过于庞大和文件查找性能下降
- 对于高并发场景,这可能导致请求排队等待,造成响应时间增加。优化方案可以考虑使用Go语言的并发模式,使用Goroutines来处理请求,从而提高并发处理能力
- 使用数据库索引、缓存和批量操作等手段来优化数据库性能