feature/ip优化
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package ip_tool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -15,12 +16,14 @@ import (
|
||||
type HuaChenIpClient struct {
|
||||
AppCode string
|
||||
Host string
|
||||
cache ICacheAdapter
|
||||
}
|
||||
|
||||
func NewHuaChenIpClient(appCode string) *HuaChenIpClient {
|
||||
func NewHuaChenIpClient(appCode string, cache ICacheAdapter) *HuaChenIpClient {
|
||||
return &HuaChenIpClient{
|
||||
AppCode: appCode,
|
||||
Host: "https://c2ba.api.huachen.cn",
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +90,31 @@ func (h *HuaChenIpClient) GetIpInfo(ip string) (res *ApiResult, err error) {
|
||||
return &apiResult, nil
|
||||
}
|
||||
|
||||
func (h *HuaChenIpClient) GetIpInfoFormCache(ctx context.Context, ip string) (res *ApiResult, err error) {
|
||||
getCache, err := h.cache.Get(ctx, h.ipKey(ip))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "获取缓存失败,ip:%s", ip)
|
||||
}
|
||||
if getCache != nil {
|
||||
return getCache, nil
|
||||
}
|
||||
info, err := h.GetIpInfo(ip)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "获取ip:%s信息失败,", ip)
|
||||
}
|
||||
err = h.cache.Set(ctx, h.ipKey(ip), *info, 24*time.Hour)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "缓存ip:%s信息失败,", ip)
|
||||
}
|
||||
res = info
|
||||
return
|
||||
}
|
||||
|
||||
// ipKey 生成Redis key
|
||||
func (h *HuaChenIpClient) ipKey(ip string) string {
|
||||
return fmt.Sprintf("ip:%s", ip)
|
||||
}
|
||||
|
||||
type ApiResult struct {
|
||||
Ret int `json:"ret"`
|
||||
Msg string `json:"msg"`
|
||||
|
@@ -1,8 +1,14 @@
|
||||
package ip_tool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHuaChenIpClient_GetIpInfo(t *testing.T) {
|
||||
@@ -42,3 +48,78 @@ func TestHuaChenIpClient_GetIpInfo(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHuaChenIpClient_GetIpInfo1(t *testing.T) {
|
||||
rdb := redis.NewClient(&redis.Options{
|
||||
Addr: "",
|
||||
Password: "",
|
||||
DB: 1,
|
||||
})
|
||||
|
||||
// 创建IP缓存实例
|
||||
ipCache := NewRedisCache(rdb)
|
||||
h := &HuaChenIpClient{
|
||||
AppCode: "",
|
||||
Host: "https://c2ba.api.huachen.cn",
|
||||
cache: ipCache,
|
||||
}
|
||||
gotRes, err := h.GetIpInfoFormCache(context.Background(), "8.138.116.112")
|
||||
log.Println(gotRes, err)
|
||||
}
|
||||
|
||||
type RedisCache struct {
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewRedisCache(client *redis.Client) *RedisCache {
|
||||
return &RedisCache{client: client}
|
||||
}
|
||||
|
||||
func (r *RedisCache) Set(ctx context.Context, ip string, info ApiResult, ttl time.Duration) error {
|
||||
if ip == "" {
|
||||
return errors.New("ip不能为空")
|
||||
}
|
||||
|
||||
data, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return fmt.Errorf("无法封送IP信息: %w", err)
|
||||
}
|
||||
|
||||
return r.client.Set(ctx, ip, data, ttl).Err()
|
||||
}
|
||||
|
||||
// Get 从Redis获取IP信息
|
||||
func (r *RedisCache) Get(ctx context.Context, ip string) (*ApiResult, error) {
|
||||
if ip == "" {
|
||||
return nil, errors.New("ip不能为空")
|
||||
}
|
||||
|
||||
data, err := r.client.Get(ctx, ip).Bytes()
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, nil // 键不存在,返回nil而不是错误
|
||||
}
|
||||
return nil, fmt.Errorf("无法获取IP信息: %w", err)
|
||||
}
|
||||
|
||||
var info ApiResult
|
||||
if err = json.Unmarshal(data, &info); err != nil {
|
||||
return nil, fmt.Errorf("无法解析IP信息: %w", err)
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// Exists 检查IP是否存在缓存中
|
||||
func (r *RedisCache) Exists(ctx context.Context, ip string) (bool, error) {
|
||||
if ip == "" {
|
||||
return false, errors.New("ip不能为空")
|
||||
}
|
||||
|
||||
exists, err := r.client.Exists(ctx, ip).Result()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("无法检查IP是否存在: %w", err)
|
||||
}
|
||||
|
||||
return exists > 0, nil
|
||||
}
|
||||
|
13
ip_tool/ip_cache.go
Normal file
13
ip_tool/ip_cache.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package ip_tool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Cache 定义缓存接口,遵循接口隔离原则
|
||||
type ICacheAdapter interface {
|
||||
Set(ctx context.Context, ip string, info ApiResult, ttl time.Duration) error
|
||||
Get(ctx context.Context, ip string) (*ApiResult, error)
|
||||
Exists(ctx context.Context, ip string) (bool, error)
|
||||
}
|
Reference in New Issue
Block a user