Files
EdgeCommon/pkg/serverconfigs/reverse_proxy_config.go

164 lines
4.7 KiB
Go
Raw Normal View History

2020-09-13 19:27:47 +08:00
package serverconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
2020-09-15 14:44:38 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
2020-09-13 19:27:47 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"sync"
)
// 反向代理设置
type ReverseProxyConfig struct {
2020-09-21 20:21:20 +08:00
Id int64 `yaml:"id" json:"id"` // ID
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
PrimaryOrigins []*OriginConfig `yaml:"primaryOrigins" json:"primaryOrigins"` // 主要源站列表
PrimaryOriginRefs []*OriginRef `yaml:"primaryOriginRefs" json:"primaryOriginRefs"` // 主要源站引用
BackupOrigins []*OriginConfig `yaml:"backupOrigins" json:"backupOrigins"` // 备用源站列表
BackupOriginRefs []*OriginRef `yaml:"backupOriginRefs" json:"backupOriginRefs"` // 备用源站引用
Scheduling *SchedulingConfig `yaml:"scheduling" json:"scheduling"` // 调度算法选项
2020-09-13 19:27:47 +08:00
StripPrefix string `yaml:"stripPrefix" json:"stripPrefix"` // 去除URL前缀
RequestHost string `yaml:"requestHost" json:"requestHost"` // 请求Host支持变量
RequestURI string `yaml:"requestURI" json:"requestURI"` // 请求URI支持变量如果同时定义了StripPrefix则先执行StripPrefix
2020-09-27 18:41:21 +08:00
AutoFlush bool `yaml:"autoFlush" json:"autoFlush"` // 是否自动刷新缓冲区在比如SSEserver-sent events场景下很有用
requestHostHasVariables bool
requestURIHasVariables bool
2020-09-26 19:54:20 +08:00
2020-09-15 14:44:38 +08:00
hasPrimaryOrigins bool
hasBackupOrigins bool
2020-09-13 19:27:47 +08:00
schedulingIsBackup bool
2020-09-15 14:44:38 +08:00
schedulingObject schedulingconfigs.SchedulingInterface
2020-09-13 19:27:47 +08:00
schedulingLocker sync.Mutex
}
// 初始化
func (this *ReverseProxyConfig) Init() error {
this.requestHostHasVariables = configutils.HasVariables(this.RequestHost)
this.requestURIHasVariables = configutils.HasVariables(this.RequestURI)
2020-09-15 14:44:38 +08:00
this.hasPrimaryOrigins = len(this.PrimaryOrigins) > 0
this.hasBackupOrigins = len(this.BackupOrigins) > 0
2020-09-13 19:27:47 +08:00
2020-09-15 14:44:38 +08:00
for _, origin := range this.PrimaryOrigins {
err := origin.Init()
if err != nil {
return err
}
}
for _, origin := range this.BackupOrigins {
2020-09-13 19:27:47 +08:00
err := origin.Init()
if err != nil {
return err
}
}
// scheduling
this.SetupScheduling(false)
return nil
}
2020-09-15 14:44:38 +08:00
// 添加主源站配置
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) AddPrimaryOrigin(origin *OriginConfig) {
2020-09-15 14:44:38 +08:00
this.PrimaryOrigins = append(this.PrimaryOrigins, origin)
}
// 添加备用源站配置
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) AddBackupOrigin(origin *OriginConfig) {
2020-09-15 14:44:38 +08:00
this.BackupOrigins = append(this.BackupOrigins, origin)
}
2020-09-13 19:27:47 +08:00
// 取得下一个可用的后端服务
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) NextOrigin(call *shared.RequestCall) *OriginConfig {
2020-09-13 19:27:47 +08:00
this.schedulingLocker.Lock()
defer this.schedulingLocker.Unlock()
if this.schedulingObject == nil {
return nil
}
if this.Scheduling != nil && call != nil && call.Options != nil {
for k, v := range this.Scheduling.Options {
call.Options[k] = v
}
}
candidate := this.schedulingObject.Next(call)
if candidate == nil {
// 启用备用服务器
if !this.schedulingIsBackup {
this.SetupScheduling(true)
candidate = this.schedulingObject.Next(call)
if candidate == nil {
return nil
}
}
if candidate == nil {
return nil
}
}
2020-09-21 20:21:20 +08:00
return candidate.(*OriginConfig)
2020-09-13 19:27:47 +08:00
}
// 设置调度算法
func (this *ReverseProxyConfig) SetupScheduling(isBackup bool) {
if !isBackup {
this.schedulingLocker.Lock()
defer this.schedulingLocker.Unlock()
}
this.schedulingIsBackup = isBackup
if this.Scheduling == nil {
2020-09-15 14:44:38 +08:00
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
2020-09-13 19:27:47 +08:00
} else {
typeCode := this.Scheduling.Code
2020-09-15 14:44:38 +08:00
s := schedulingconfigs.FindSchedulingType(typeCode)
2020-09-13 19:27:47 +08:00
if s == nil {
this.Scheduling = nil
2020-09-15 14:44:38 +08:00
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
2020-09-13 19:27:47 +08:00
} else {
2020-09-15 14:44:38 +08:00
this.schedulingObject = s["instance"].(schedulingconfigs.SchedulingInterface)
2020-09-13 19:27:47 +08:00
}
}
2020-09-15 14:44:38 +08:00
if !isBackup {
for _, origin := range this.PrimaryOrigins {
if origin.IsOn {
2020-09-13 19:27:47 +08:00
this.schedulingObject.Add(origin)
2020-09-15 14:44:38 +08:00
}
}
} else {
for _, origin := range this.BackupOrigins {
if origin.IsOn {
2020-09-13 19:27:47 +08:00
this.schedulingObject.Add(origin)
}
}
}
this.schedulingObject.Start()
}
2020-09-15 14:44:38 +08:00
// 获取调度配置对象
func (this *ReverseProxyConfig) FindSchedulingConfig() *SchedulingConfig {
if this.Scheduling == nil {
this.Scheduling = &SchedulingConfig{Code: "random"}
}
return this.Scheduling
}
// 判断RequestHost是否有变量
func (this *ReverseProxyConfig) RequestHostHasVariables() bool {
return this.requestHostHasVariables
}
// 判断RequestURI是否有变量
func (this *ReverseProxyConfig) RequestURIHasVariables() bool {
return this.requestURIHasVariables
}