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

1 回复

更多关于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)
}

最佳实践

  1. 合理设置TTL:根据数据变更频率设置适当的过期时间
  2. 使用命名空间:为不同业务数据使用不同的key前缀,如"user:", “product:”
  3. 处理缓存雪崩:为关键缓存设置随机的TTL偏移量
  4. 监控缓存命中率:定期检查缓存效率,调整缓存策略

总结

CouchCache为Golang微服务提供了简单易用的Couchbase缓存集成方案,通过中间件可以轻松为现有API添加缓存层,同时提供了丰富的API满足各种缓存需求。它的轻量级设计使得它可以方便地集成到现有项目中,而不会带来太多额外复杂性。

完整的文档和示例代码可以参考项目的GitHub仓库。

回到顶部