# IP记录管理

<cite>
**本文档引用文件**   
- [ip_record.go](file://internal/logic/restriction/ip_record.go)
- [v_1_restrict_ip_record.go](file://internal/dao/internal/v_1_restrict_ip_record.go)
- [restriction.go](file://internal/service/restriction.go)
- [model.go](file://internal/model/restriction.go)
- [cache.go](file://utility/cache/cache.go)
- [location.go](file://utility/integration/restriction/location.go)
</cite>

## 目录
1. [简介](#简介)
2. [数据结构设计](#数据结构设计)
3. [核心操作实现](#核心操作实现)
4. [Redis缓存集成](#redis缓存集成)
5. [IP记录与用户行为关联](#ip记录与用户行为关联)
6. [最佳实践](#最佳实践)
7. [结论](#结论)

## 简介
本文档详细阐述了kami_backend系统中IP记录管理的完整实现方案。系统通过精细化的IP记录管理机制，实现了对用户访问行为的全面追踪和安全控制。IP记录系统不仅存储基本的IP地址信息，还集成了地理位置识别、访问模式分析和异常行为检测等功能，为系统的安全防护提供了坚实的数据基础。

## 数据结构设计

IP记录系统采用分层的数据结构设计，包含数据库表结构、数据访问对象（DAO）和业务模型三个层次。

### 数据库表结构
IP记录的核心数据存储在`restrict_ip_record`数据库表中，其字段定义如下：

| 字段名 | 数据类型 | 说明 |
|--------|---------|------|
| id | BIGINT | 主键，自增ID |
| ip | VARCHAR | IP地址 |
| ip_province | VARCHAR | IP地址所在省份或地区 |
| is_public | TINYINT | 是否是公共地址（1:是，0:否） |
| raw_data | TEXT | 原始地理位置数据 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
| deleted_at | DATETIME | 删除时间（软删除） |

```mermaid
erDiagram
restrict_ip_record {
BIGINT id PK
VARCHAR ip
VARCHAR ip_province
TINYINT is_public
TEXT raw_data
DATETIME created_at
DATETIME updated_at
DATETIME deleted_at
}
```

**Diagram sources**
- [v_1_restrict_ip_record.go](file://internal/dao/internal/v_1_restrict_ip_record.go#L14-L19)

### 业务模型设计
在业务逻辑层，IP记录通过`RestrictionIPRecordOutput`结构体进行封装，该结构体继承了数据库实体并添加了业务相关的扩展字段。

```mermaid
classDiagram
class RestrictionIPRecordOutput {
+g.Meta orm : "table : restrict_ip_record"
+V1RestrictIpRecord
+RawData Response
}
class V1RestrictIpRecord {
+uint Id
+string Ip
+string IpProvince
+bool IsPublic
}
class Response {
+string City
+string Isp
+string Province
+string Region
+string RawData
}
RestrictionIPRecordOutput --> V1RestrictIpRecord : "继承"
RestrictionIPRecordOutput --> Response : "包含"
```

**Diagram sources**
- [model.go](file://internal/model/restriction.go#L11-L17)

**Section sources**
- [model.go](file://internal/model/restriction.go#L11-L17)
- [v_1_restrict_ip_record.go](file://internal/dao/internal/v_1_restrict_ip_record.go#L14-L19)

## 核心操作实现

IP记录管理系统提供了完整的CRUD（创建、读取、更新、删除）操作接口，其中最核心的是IP记录的获取与创建逻辑。

### IP记录创建与获取
系统通过`GetOrSetIPRecord`方法实现IP记录的获取或创建。该方法采用"先查询后创建"的策略，确保同一IP地址不会重复记录。

```mermaid
flowchart TD
Start([开始]) --> TrimIP["清理IP地址空白字符"]
TrimIP --> QueryDB["查询数据库是否存在该IP记录"]
QueryDB --> RecordExists{"记录已存在?"}
RecordExists --> |是| ReturnRecord["返回现有记录"]
RecordExists --> |否| CheckPublicIP["检查是否为公共IP"]
CheckPublicIP --> |是| GetLocation["获取地理位置信息"]
CheckPublicIP --> |否| SetEmptyLocation["设置空地理位置"]
GetLocation --> InsertRecord["插入新IP记录到数据库"]
SetEmptyLocation --> InsertRecord
InsertRecord --> CreateOutput["创建输出模型"]
CreateOutput --> End([结束])
```

**Diagram sources**
- [ip_record.go](file://internal/logic/restriction/ip_record.go#L20-L53)

**Section sources**
- [ip_record.go](file://internal/logic/restriction/ip_record.go#L20-L53)
- [restriction.go](file://internal/service/restriction.go#L30-L32)

### 地理位置信息获取
系统通过集成多个第三方IP地理位置服务，实现了高可用的地理位置查询功能。当一个服务不可用时，系统会自动尝试其他服务。

```mermaid
sequenceDiagram
participant Service as "Restriction服务"
participant Location as "地理位置接口"
participant Impl1 as "PCOnline客户端"
participant Impl2 as "CSDN客户端"
participant Impl3 as "其他客户端"
Service->>Location : GetLocationByIP(ctx, ip)
Location->>Location : retry.Retry()
Location->>Impl1 : QueryLocationByIP(ctx, ip)
alt 成功且数据有效
Impl1-->>Location : 返回地理位置
Location-->>Service : 返回结果
else 失败或数据无效
Location->>Impl2 : QueryLocationByIP(ctx, ip)
alt 成功且数据有效
Impl2-->>Location : 返回地理位置
Location-->>Service : 返回结果
else 失败或数据无效
Location->>Impl3 : QueryLocationByIP(ctx, ip)
Impl3-->>Location : 返回地理位置
Location-->>Service : 返回结果
end
end
```

**Diagram sources**
- [location.go](file://utility/integration/restriction/location.go#L29-L38)
- [impl.go](file://utility/integration/restriction/impl.go#L0-L44)

**Section sources**
- [location.go](file://utility/integration/restriction/location.go#L29-L38)
- [consts.go](file://utility/integration/restriction/consts.go#L0-L23)

## Redis缓存集成

为了提高IP记录的读写性能，系统集成了Redis缓存机制，通过缓存适配器实现了数据库与缓存的协同工作。

### 缓存初始化
系统在启动时初始化缓存实例，并设置Redis作为底层存储适配器。

```go
func NewCache() *Cache {
	if cache == nil {
		once.Do(func() {
			cache = &Cache{
				Cache: gcache.New(),
			}
			cache.SetAdapter(gcache.NewAdapterRedis(g.Redis()))
		})
	}
	return cache
}
```

### 计数器缓存
系统提供了原子性的计数器操作，用于统计特定键的访问次数。

```mermaid
flowchart TD
Start([Incr方法开始]) --> GetCache["获取缓存值"]
GetCache --> IsNil{"缓存值为空?"}
IsNil --> |是| SetInitial["设置初始值为1"]
IsNil --> |否| UpdateValue["更新值为原值+1"]
SetInitial --> ReturnSuccess["返回成功"]
UpdateValue --> ReturnSuccess
ReturnSuccess --> End([方法结束])
```

**Diagram sources**
- [cache.go](file://utility/cache/cache.go#L63-L71)

**Section sources**
- [cache.go](file://utility/cache/cache.go#L41-L86)

## IP记录与用户行为关联

IP记录系统与用户行为分析紧密集成，通过多维度的数据关联，实现了对异常访问模式的精准追踪。

### 设备与IP关联
系统通过`SaveDeviceInfo`方法将用户设备信息与IP地址进行关联，建立完整的访问链路。

```mermaid
classDiagram
class RestrictionDeviceInput {
+[]string IPs
+string RemoteIP
+string DeviceID
+string DeviceModel
+string UserAgent
}
class V1RestrictClientAccessRecord {
+int Id
+string VisitorId
+string DeviceModel
+string UserAgent
+bool IsUseProxy
}
class V1RestrictClientAccessIpRelation {
+int Id
+string Ip
+bool IsRemoteIp
+int RestrictIpRecordId
+int RestrictClientAccessRecordId
+string SessionId
}
RestrictionDeviceInput --> V1RestrictClientAccessRecord : "映射"
V1RestrictClientAccessRecord --> V1RestrictClientAccessIpRelation : "包含"
V1RestrictClientAccessIpRelation --> V1RestrictIpRecord : "关联"
```

**Diagram sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L0-L44)
- [restriction_v1_user_info_collection.go](file://internal/controller/restriction/restriction_v1_user_info_collection.go#L31-L59)

**Section sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L0-L44)
- [model.go](file://internal/model/restriction.go#L11-L17)

### 异常访问模式检测
系统通过分析IP记录与设备信息的关联关系，可以检测出多种异常访问模式，如代理使用、IP伪装等。

```mermaid
flowchart TD
Start([开始检测]) --> GetDeviceRecord["获取设备访问记录"]
GetDeviceRecord --> GetLastAccess["获取最后一次访问信息"]
GetLastAccess --> GetIPRelation["获取IP关联关系"]
GetIPRelation --> CountSameSession["统计同一会话中的IP数量"]
CountSameSession --> SingleIP{"只有一个IP?"}
SingleIP --> |是| NotUseProxy["未使用代理"]
SingleIP --> |否| UseProxy["使用代理"]
NotUseProxy --> End([检测结束])
UseProxy --> End
```

**Diagram sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L74-L112)

**Section sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L74-L112)

## 最佳实践

### 数据清理策略
建议定期清理过期的IP记录，特别是那些长时间未再次访问的记录。可以通过创建定时任务，每月清理一次超过一年未更新的IP记录。

### 存储优化
对于`raw_data`字段，建议采用压缩存储的方式，减少数据库存储空间占用。同时，对`ip`和`ip_province`字段建立索引，提高查询性能。

### 性能监控
建立完善的性能监控体系，重点关注以下几个指标：
- IP记录查询响应时间
- 地理位置服务调用成功率
- Redis缓存命中率
- 数据库查询性能

可以通过集成OpenTelemetry等监控工具，实现对IP记录管理系统的全面监控。

### 安全考虑
- 对敏感的IP记录数据进行访问控制
- 定期备份IP记录数据
- 监控异常的IP访问模式，及时发现潜在的安全威胁
- 对地理位置服务API调用进行限流，防止被滥用

## 结论
kami_backend的IP记录管理系统通过精心设计的数据结构和高效的实现逻辑，为系统的安全防护提供了强有力的支持。系统不仅能够准确记录和追踪用户IP访问行为，还能通过与设备信息的关联分析，识别出复杂的异常访问模式。结合Redis缓存的使用，系统在保证数据准确性的同时，也实现了高性能的读写操作。通过遵循本文档提供的最佳实践，可以进一步优化系统的性能和安全性，为业务的稳定运行提供保障。