golang基于Couchbase的RESTful缓存微服务插件库couchcache的使用
Golang基于Couchbase的RESTful缓存微服务插件库couchcache的使用
概述
Couchcache是一个用Go语言开发的缓存服务,它提供了REST API来访问存储在Couchbase中的键值对。在进行TDD(测试驱动开发)时,也可以考虑使用couchcache作为模拟服务。
启动couchcache
使用Couchbase服务器(主机和端口)和存储桶(名称和密码)信息运行couchcache:
./couchcache --host=HOST --port=PORT --bucket=BUCKET --pass=PASS
示例
./couchcache --host=10.99.107.192 --port=8091 --bucket=cachebucket --pass=c@che1t
默认值
host: localhost
port: 8091
bucket: couchcache
pass: password
缓存服务端点
http://HOST:8080/key/KEY
示例
http://10.99.107.190:8080/key/customer_555
http://10.99.107.190:8080/key/the_service_i_want_to_mock-endpoint_a
完整示例代码
下面是一个完整的Go示例,展示如何使用couchcache进行CRUD操作:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
)
const baseURL = "http://localhost:8080/key/"
func main() {
key := "test_key"
value := "test_value"
// 存储键值对
err := storeKey(key, value)
if err != nil {
fmt.Println("存储键值对失败:", err)
return
}
fmt.Println("键值对存储成功")
// 获取键值
retrievedValue, err := getKey(key)
if err != nil {
fmt.Println("获取键值失败:", err)
return
}
fmt.Printf("获取到的值: %s\n", retrievedValue)
// 追加数据
err = appendKey(key, "_appended")
if err != nil {
fmt.Println("追加数据失败:", err)
return
}
fmt.Println("数据追加成功")
// 再次获取验证追加
retrievedValue, err = getKey(key)
if err != nil {
fmt.Println("获取键值失败:", err)
return
}
fmt.Printf("追加后的值: %s\n", retrievedValue)
// 删除键
err = deleteKey(key)
if err != nil {
fmt.Println("删除键失败:", err)
return
}
fmt.Println("键删除成功")
}
// 存储键值对
func storeKey(key, value string) error {
url := baseURL + key
resp, err := http.Post(url, "text/plain", bytes.NewBufferString(value))
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return fmt.Errorf("存储失败,状态码: %d", resp.StatusCode)
}
return nil
}
// 获取键值
func getKey(key string) (string, error) {
url := baseURL + key
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("获取失败,状态码: %d", resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
// 追加数据
func appendKey(key, value string) error {
url := baseURL + key
req, err := http.NewRequest(http.MethodPut, url, bytes.NewBufferString(value))
if err != nil {
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("追加失败,状态码: %d", resp.StatusCode)
}
return nil
}
// 删除键
func deleteKey(key string) error {
url := baseURL + key
req, err := http.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return fmt.Errorf("删除失败,状态码: %d", resp.StatusCode)
}
return nil
}
操作说明
存储键值对
-
请求
- 发送
POST
请求到端点,数据放在请求体中 - 可选地通过
?ttl=TTL_IN_SEC
设置TTL(生存时间)
- 发送
-
响应
HTTP 201 Created
- 存储成功HTTP 400 Bad Request
- 键或值无效
获取键值
-
请求
- 发送
GET
请求到端点
- 发送
-
响应
HTTP 200 OK
- 返回请求体中的数据HTTP 404 Not Found
- 键不存在HTTP 400 Bad Request
- 键无效
删除键
-
请求
- 发送
DELETE
请求到端点
- 发送
-
响应
HTTP 204 No Content
- 删除成功HTTP 404 Not Found
- 键不存在HTTP 400 Bad Request
- 键无效
追加数据
-
请求
- 发送
PUT
请求到端点,数据放在请求体中
- 发送
-
响应
HTTP 200 OK
- 追加成功HTTP 404 Not Found
- 键不存在HTTP 400 Bad Request
- 键或值无效
限制
- 最大键长度:250字节
- 最大值大小:20 MB
许可证
couchcache根据MIT许可证的条款分发。
更多关于golang基于Couchbase的RESTful缓存微服务插件库couchcache的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang基于Couchbase的RESTful缓存微服务插件库couchcache的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
CouchCache: 基于Couchbase的Golang RESTful缓存微服务插件库
CouchCache是一个轻量级的Golang库,用于简化在微服务架构中使用Couchbase作为缓存层的开发工作。下面我将介绍如何使用这个库。
安装
首先安装Couchbase Go SDK和CouchCache库:
go get github.com/couchbase/gocb/v2
go get github.com/yourusername/couchcache
基本用法
初始化连接
package main
import (
"log"
"time"
"github.com/yourusername/couchcache"
"github.com/couchbase/gocb/v2"
)
func main() {
// 配置Couchbase连接
config := couchcache.Config{
ConnectionString: "couchbase://localhost",
Username: "Administrator",
Password: "password",
BucketName: "cache_bucket",
DefaultTTL: 30 * time.Minute, // 默认缓存时间30分钟
}
// 初始化缓存客户端
cache, err := couchcache.NewCouchCache(config)
if err != nil {
log.Fatalf("Failed to initialize CouchCache: %v", err)
}
defer cache.Close()
// 使用缓存...
}
基本缓存操作
// 设置缓存
err := cache.Set("user:123", &User{ID: 123, Name: "John Doe"}, 1*time.Hour)
if err != nil {
log.Printf("Failed to set cache: %v", err)
}
// 获取缓存
var user User
found, err := cache.Get("user:123", &user)
if err != nil {
log.Printf("Failed to get cache: %v", err)
}
if found {
log.Printf("User found: %+v", user)
}
// 删除缓存
err = cache.Delete("user:123")
if err != nil {
log.Printf("Failed to delete cache: %v", err)
}
RESTful缓存中间件
CouchCache提供了与常见Golang web框架集成的中间件:
使用Gin框架的示例
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/yourusername/couchcache"
"github.com/yourusername/couchcache/ginmiddleware"
)
func main() {
// 初始化缓存
cache := initializeCache()
r := gin.Default()
// 应用缓存中间件
r.Use(ginmiddleware.CacheMiddleware(cache,
ginmiddleware.WithCacheKeyFunc(func(c *gin.Context) string {
return "api:" + c.Request.URL.Path
}),
ginmiddleware.WithTTL(10 * time.Minute),
))
r.GET("/users/:id", func(c *gin.Context) {
// 这个处理程序会自动缓存响应
userID := c.Param("id")
user := fetchUserFromDB(userID)
c.JSON(http.StatusOK, user)
})
r.Run(":8080")
}
使用标准库net/http的示例
package main
import (
"net/http"
"time"
"github.com/yourusername/couchcache"
"github.com/yourusername/couchcache/httpmiddleware"
)
func main() {
// 初始化缓存
cache := initializeCache()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 业务逻辑
user := fetchUserFromDB("123")
respondWithJSON(w, user)
})
// 包装处理程序添加缓存
cachedHandler := httpmiddleware.CacheMiddleware(cache, handler,
httpmiddleware.WithCacheKeyFunc(func(r *http.Request) string {
return "api:" + r.URL.Path
}),
httpmiddleware.WithTTL(15 * time.Minute),
)
http.ListenAndServe(":8080", cachedHandler)
}
高级特性
缓存穿透保护
// 配置缓存空值以防止缓存穿透
cache.SetWithOptions("user:999", nil, couchcache.SetOptions{
TTL: 5 * time.Minute,
CacheNil: true, // 缓存nil值
})
批量操作
// 批量获取
keys := []string{"user:123", "user:456", "user:789"}
results, err := cache.GetBulk(keys, reflect.TypeOf(User{}))
if err != nil {
log.Printf("Failed bulk get: %v", err)
}
// 批量设置
items := map[string]interface{}{
"user:123": &User{ID: 123, Name: "Alice"},
"user:456": &User{ID: 456, Name: "Bob"},
}
err = cache.SetBulk(items, 1*time.Hour)
if err != nil {
log.Printf("Failed bulk set: %v", err)
}
缓存统计
stats, err := cache.GetStats()
if err != nil {
log.Printf("Failed to get stats: %v", err)
} else {
log.Printf("Cache hits: %d, misses: %d", stats.Hits, stats.Misses)
}
最佳实践
- 合理设置TTL:根据数据变更频率设置适当的过期时间
- 使用命名空间:为不同业务数据使用不同的key前缀,如"user:", “product:”
- 处理缓存雪崩:为关键缓存设置随机的TTL偏移量
- 监控缓存命中率:定期检查缓存效率,调整缓存策略
总结
CouchCache为Golang微服务提供了简单易用的Couchbase缓存集成方案,通过中间件可以轻松为现有API添加缓存层,同时提供了丰富的API满足各种缓存需求。它的轻量级设计使得它可以方便地集成到现有项目中,而不会带来太多额外复杂性。
完整的文档和示例代码可以参考项目的GitHub仓库。