mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-05 09:30:26 +08:00
修复HTTP协议下ProxyProtocol只能传递第一个IP的问题;修复每个小时都自动清除所有源站连接池的问题
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
||||||
|
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||||
"github.com/pires/go-proxyproto"
|
"github.com/pires/go-proxyproto"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"net"
|
"net"
|
||||||
@@ -20,6 +21,8 @@ import (
|
|||||||
// SharedHTTPClientPool HTTP客户端池单例
|
// SharedHTTPClientPool HTTP客户端池单例
|
||||||
var SharedHTTPClientPool = NewHTTPClientPool()
|
var SharedHTTPClientPool = NewHTTPClientPool()
|
||||||
|
|
||||||
|
const httpClientProxyProtocolTag = "@ProxyProtocol@"
|
||||||
|
|
||||||
// HTTPClientPool 客户端池
|
// HTTPClientPool 客户端池
|
||||||
type HTTPClientPool struct {
|
type HTTPClientPool struct {
|
||||||
clientsMap map[string]*HTTPClient // backend key => client
|
clientsMap map[string]*HTTPClient // backend key => client
|
||||||
@@ -54,6 +57,14 @@ func (this *HTTPClientPool) Client(req *HTTPRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var key = origin.UniqueKey() + "@" + originAddr
|
var key = origin.UniqueKey() + "@" + originAddr
|
||||||
|
|
||||||
|
// if we are under available ProxyProtocol, we add client ip to key to make every client unique
|
||||||
|
var isProxyProtocol = false
|
||||||
|
if proxyProtocol != nil && proxyProtocol.IsOn {
|
||||||
|
key += httpClientProxyProtocolTag + req.requestRemoteAddr(true)
|
||||||
|
isProxyProtocol = true
|
||||||
|
}
|
||||||
|
|
||||||
var isLnRequest = origin.Id == 0
|
var isLnRequest = origin.Id == 0
|
||||||
|
|
||||||
this.locker.RLock()
|
this.locker.RLock()
|
||||||
@@ -102,8 +113,9 @@ func (this *HTTPClientPool) Client(req *HTTPRequest,
|
|||||||
idleConns = numberCPU * 16
|
idleConns = numberCPU * 16
|
||||||
}
|
}
|
||||||
|
|
||||||
// 可以判断为Ln节点请求
|
if isProxyProtocol { // ProxyProtocol无需保持太多空闲连接
|
||||||
if isLnRequest {
|
idleConns = 3
|
||||||
|
} else if isLnRequest { // 可以判断为Ln节点请求
|
||||||
maxConnections *= 8
|
maxConnections *= 8
|
||||||
idleConns *= 8
|
idleConns *= 8
|
||||||
idleTimeout *= 4
|
idleTimeout *= 4
|
||||||
@@ -195,22 +207,45 @@ func (this *HTTPClientPool) Client(req *HTTPRequest,
|
|||||||
// 清理不使用的Client
|
// 清理不使用的Client
|
||||||
func (this *HTTPClientPool) cleanClients() {
|
func (this *HTTPClientPool) cleanClients() {
|
||||||
for range this.cleanTicker.C {
|
for range this.cleanTicker.C {
|
||||||
var nowTime = time.Now().Unix()
|
var nowTime = fasttime.Now().Unix()
|
||||||
|
|
||||||
this.locker.Lock()
|
var expiredKeys = []string{}
|
||||||
|
var expiredClients = []*HTTPClient{}
|
||||||
|
|
||||||
|
// lookup expired clients
|
||||||
|
this.locker.RLock()
|
||||||
for k, client := range this.clientsMap {
|
for k, client := range this.clientsMap {
|
||||||
if client.AccessTime() < nowTime+86400 { // 超过 N 秒没有调用就关闭
|
if client.AccessTime() < nowTime-86400 ||
|
||||||
|
(strings.Contains(k, httpClientProxyProtocolTag) && client.AccessTime() < nowTime-3600) { // 超过 N 秒没有调用就关闭
|
||||||
|
expiredKeys = append(expiredKeys, k)
|
||||||
|
expiredClients = append(expiredClients, client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.locker.RUnlock()
|
||||||
|
|
||||||
|
// remove expired keys
|
||||||
|
if len(expiredKeys) > 0 {
|
||||||
|
this.locker.Lock()
|
||||||
|
for _, k := range expiredKeys {
|
||||||
delete(this.clientsMap, k)
|
delete(this.clientsMap, k)
|
||||||
|
}
|
||||||
|
this.locker.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// close expired clients
|
||||||
|
if len(expiredClients) > 0 {
|
||||||
|
for _, client := range expiredClients {
|
||||||
client.Close()
|
client.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.locker.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 支持PROXY Protocol
|
// 支持PROXY Protocol
|
||||||
func (this *HTTPClientPool) handlePROXYProtocol(conn net.Conn, req *HTTPRequest, proxyProtocol *serverconfigs.ProxyProtocolConfig) error {
|
func (this *HTTPClientPool) handlePROXYProtocol(conn net.Conn, req *HTTPRequest, proxyProtocol *serverconfigs.ProxyProtocolConfig) error {
|
||||||
if proxyProtocol != nil && proxyProtocol.IsOn && (proxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || proxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
|
if proxyProtocol != nil &&
|
||||||
|
proxyProtocol.IsOn &&
|
||||||
|
(proxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || proxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
|
||||||
var remoteAddr = req.requestRemoteAddr(true)
|
var remoteAddr = req.requestRemoteAddr(true)
|
||||||
var transportProtocol = proxyproto.TCPv4
|
var transportProtocol = proxyproto.TCPv4
|
||||||
if strings.Contains(remoteAddr, ":") {
|
if strings.Contains(remoteAddr, ":") {
|
||||||
|
|||||||
Reference in New Issue
Block a user