开发一个带缓存的代理

我想实现的功能是:根据 url 请求body 等信息,将响应缓存到redis中。

自己的实现

先是一个普通的服务器,监听 7001 端口

// Handle the requests
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    proxyHandler(w, r, proxy)
})
log.Fatal(http.ListenAndServe("localhost:7001", nil))

proxyHandler函数有两个关键点:

  1. request body 要两份
  2. response body 要 warp 一下才能读到它的内容

结合gin的实现

官方的

https://github.com/gin-contrib/cache

有cache.CachePage、cache.redis、memery等方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import (
	"fmt"
	"time"

	"github.com/gin-contrib/cache"
	"github.com/gin-contrib/cache/persistence"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	store := persistence.NewInMemoryStore(time.Second)
	
	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
	})
	// Cached Page
	r.GET("/cache_ping", cache.CachePage(store, time.Minute, func(c *gin.Context) {
		c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
	}))

	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

三方开源的

https://github.com/chenyahui/gin-cache

有CacheByRequestURI等几个方法,可以自定义缓存策略,即是否缓存、缓存的key、key的前缀等。(但是看代码还没找到怎么设置)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
	"time"

	"github.com/chenyahui/gin-cache"
	"github.com/chenyahui/gin-cache/persist"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

func main() {
	app := gin.New()

	redisStore := persist.NewRedisStore(redis.NewClient(&redis.Options{
		Network: "tcp",
		Addr:    "127.0.0.1:6379",
	}))

	app.GET("/hello",
		cache.CacheByRequestURI(redisStore, 2*time.Second),
		func(c *gin.Context) {
			c.String(200, "hello world")
		},
	)
	if err := app.Run(":8080"); err != nil {
		panic(err)
	}
}
updatedupdated2023-12-012023-12-01