移除不必要的 user_host 字段及相关索引;优化通道缓存方式,直接缓存通道授权信息
This commit is contained in:
@@ -4,9 +4,6 @@
|
||||
- 页面 提取记录
|
||||
- 页面 使用记录
|
||||
|
||||
- 保存 session 到数据库
|
||||
- 移除 PayloadType,使用 Grant_Type
|
||||
|
||||
### 长效业务
|
||||
|
||||
- 支付回调处理
|
||||
|
||||
@@ -628,7 +628,6 @@ create table channel (
|
||||
node_host varchar(255),
|
||||
protocol int,
|
||||
auth_ip bool not null default false,
|
||||
user_host varchar(255),
|
||||
auth_pass bool not null default false,
|
||||
username varchar(255),
|
||||
password varchar(255),
|
||||
@@ -644,7 +643,6 @@ create index channel_proxy_host_index on channel (proxy_host);
|
||||
create index channel_proxy_port_index on channel (proxy_port);
|
||||
create index channel_node_host_index on channel (node_host);
|
||||
create index channel_auth_ip_index on channel (auth_ip);
|
||||
create index channel_user_host_index on channel (user_host);
|
||||
create index channel_auth_pass_index on channel (auth_pass);
|
||||
create index channel_username_index on channel (username);
|
||||
create index channel_expiration_index on channel (expiration);
|
||||
@@ -661,7 +659,6 @@ comment on column channel.proxy_port is '转发端口';
|
||||
comment on column channel.node_host is '节点地址';
|
||||
comment on column channel.protocol is '协议类型:1-http,2-https,3-socks5';
|
||||
comment on column channel.auth_ip is 'IP认证';
|
||||
comment on column channel.user_host is '用户地址';
|
||||
comment on column channel.auth_pass is '密码认证';
|
||||
comment on column channel.username is '用户名';
|
||||
comment on column channel.password is '密码';
|
||||
|
||||
@@ -23,7 +23,6 @@ type Channel struct {
|
||||
NodeHost string `gorm:"column:node_host;comment:节点地址" json:"node_host"` // 节点地址
|
||||
Protocol int32 `gorm:"column:protocol;comment:协议类型:1-http,2-https,3-socks5" json:"protocol"` // 协议类型:1-http,2-https,3-socks5
|
||||
AuthIP bool `gorm:"column:auth_ip;not null;comment:IP认证" json:"auth_ip"` // IP认证
|
||||
UserHost string `gorm:"column:user_host;comment:用户地址" json:"user_host"` // 用户地址
|
||||
AuthPass bool `gorm:"column:auth_pass;not null;comment:密码认证" json:"auth_pass"` // 密码认证
|
||||
Username string `gorm:"column:username;comment:用户名" json:"username"` // 用户名
|
||||
Password string `gorm:"column:password;comment:密码" json:"password"` // 密码
|
||||
|
||||
@@ -36,7 +36,6 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
||||
_channel.NodeHost = field.NewString(tableName, "node_host")
|
||||
_channel.Protocol = field.NewInt32(tableName, "protocol")
|
||||
_channel.AuthIP = field.NewBool(tableName, "auth_ip")
|
||||
_channel.UserHost = field.NewString(tableName, "user_host")
|
||||
_channel.AuthPass = field.NewBool(tableName, "auth_pass")
|
||||
_channel.Username = field.NewString(tableName, "username")
|
||||
_channel.Password = field.NewString(tableName, "password")
|
||||
@@ -63,7 +62,6 @@ type channel struct {
|
||||
NodeHost field.String // 节点地址
|
||||
Protocol field.Int32 // 协议类型:1-http,2-https,3-socks5
|
||||
AuthIP field.Bool // IP认证
|
||||
UserHost field.String // 用户地址
|
||||
AuthPass field.Bool // 密码认证
|
||||
Username field.String // 用户名
|
||||
Password field.String // 密码
|
||||
@@ -96,7 +94,6 @@ func (c *channel) updateTableName(table string) *channel {
|
||||
c.NodeHost = field.NewString(table, "node_host")
|
||||
c.Protocol = field.NewInt32(table, "protocol")
|
||||
c.AuthIP = field.NewBool(table, "auth_ip")
|
||||
c.UserHost = field.NewString(table, "user_host")
|
||||
c.AuthPass = field.NewBool(table, "auth_pass")
|
||||
c.Username = field.NewString(table, "username")
|
||||
c.Password = field.NewString(table, "password")
|
||||
@@ -120,7 +117,7 @@ func (c *channel) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (c *channel) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 17)
|
||||
c.fieldMap = make(map[string]field.Expr, 16)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["user_id"] = c.UserID
|
||||
c.fieldMap["proxy_id"] = c.ProxyID
|
||||
@@ -130,7 +127,6 @@ func (c *channel) fillFieldMap() {
|
||||
c.fieldMap["node_host"] = c.NodeHost
|
||||
c.fieldMap["protocol"] = c.Protocol
|
||||
c.fieldMap["auth_ip"] = c.AuthIP
|
||||
c.fieldMap["user_host"] = c.UserHost
|
||||
c.fieldMap["auth_pass"] = c.AuthPass
|
||||
c.fieldMap["username"] = c.Username
|
||||
c.fieldMap["password"] = c.Password
|
||||
|
||||
@@ -3,7 +3,6 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
@@ -97,12 +96,6 @@ func (s *channelService) RemoveChannels(ctx context.Context, authCtx *auth.Conte
|
||||
return ChannelServiceErr("删除通道失败")
|
||||
}
|
||||
|
||||
// 删除缓存
|
||||
err = deleteCache(ctx, channels)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用代理端口并下线用过的节点
|
||||
if env.DebugExternalChange {
|
||||
var step = time.Now()
|
||||
@@ -276,7 +269,7 @@ func (s *channelService) CreateChannel(
|
||||
}
|
||||
|
||||
// 缓存通道数据
|
||||
err = cacheChannels(ctx, rid, newChannels)
|
||||
err = cacheChannels(ctx, rid, newChannels, whitelist)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -612,8 +605,28 @@ func saveChannels(channels []*m.Channel) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cacheChannels(ctx context.Context, rid string, channels []*m.Channel) (err error) {
|
||||
err = cache(ctx, channels)
|
||||
func cacheChannels(ctx context.Context, rid string, channels []*m.Channel, whitelists *[]string) (err error) {
|
||||
if len(channels) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
pipe := g.Redis.TxPipeline()
|
||||
|
||||
zList := make([]redis.Z, 0, len(channels))
|
||||
for _, channel := range channels {
|
||||
expiration := time.Time(channel.Expiration)
|
||||
keys := chAuthItems(channel, whitelists)
|
||||
for _, key := range keys {
|
||||
pipe.Set(ctx, key, true, time.Since(expiration))
|
||||
}
|
||||
zList = append(zList, redis.Z{
|
||||
Score: float64(expiration.Unix()),
|
||||
Member: channel.ID,
|
||||
})
|
||||
}
|
||||
pipe.ZAdd(ctx, "tasks:channel", zList...)
|
||||
|
||||
_, err = pipe.Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -642,62 +655,35 @@ func genPassPair() (string, string) {
|
||||
return string(username), string(password)
|
||||
}
|
||||
|
||||
func chKey(channel *m.Channel) string {
|
||||
return fmt.Sprintf("channel:%d", channel.ID)
|
||||
}
|
||||
|
||||
func cache(ctx context.Context, channels []*m.Channel) error {
|
||||
if len(channels) == 0 {
|
||||
return nil
|
||||
func chAuthItems(channel *m.Channel, whitelists *[]string) []string {
|
||||
var count = 1
|
||||
var ips = make([]string, 0)
|
||||
if channel.AuthIP && whitelists != nil {
|
||||
count = len(*whitelists)
|
||||
ips = *whitelists
|
||||
}
|
||||
|
||||
pipe := g.Redis.TxPipeline()
|
||||
|
||||
zList := make([]redis.Z, 0, len(channels))
|
||||
for _, channel := range channels {
|
||||
marshal, err := json.Marshal(channel)
|
||||
if err != nil {
|
||||
return err
|
||||
var proxy = channel.ProxyHost + ":" + strconv.Itoa(int(channel.ProxyPort))
|
||||
var sb = strings.Builder{}
|
||||
var items = make([]string, count)
|
||||
for i := range items {
|
||||
// 权限 key 格式:<proxy_host>:<proxy_port>:<user_ip>?:<username>?:<password>?
|
||||
sb.WriteString(proxy)
|
||||
if channel.AuthIP {
|
||||
sb.WriteString(":" + ips[i])
|
||||
}
|
||||
if channel.AuthPass {
|
||||
sb.WriteString(":" + channel.Username + ":" + channel.Password)
|
||||
}
|
||||
expiration := time.Time(channel.Expiration)
|
||||
pipe.Set(ctx, chKey(channel), string(marshal), time.Until(expiration))
|
||||
zList = append(zList, redis.Z{
|
||||
Score: float64(expiration.Unix()),
|
||||
Member: channel.ID,
|
||||
})
|
||||
}
|
||||
pipe.ZAdd(ctx, "tasks:channel", zList...)
|
||||
|
||||
_, err := pipe.Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteCache(ctx context.Context, channels []*m.Channel) error {
|
||||
if len(channels) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
keys := make([]string, len(channels))
|
||||
for i := range channels {
|
||||
keys[i] = chKey(channels[i])
|
||||
}
|
||||
_, err := g.Redis.Del(ctx, keys...).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return items
|
||||
}
|
||||
|
||||
type ChannelAuthType int
|
||||
|
||||
const (
|
||||
ChannelAuthTypeAll ChannelAuthType = iota
|
||||
ChannelAuthTypeIp
|
||||
ChannelAuthTypeIp ChannelAuthType = iota + 1
|
||||
ChannelAuthTypePass
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user