improve http handler
This commit is contained in:
@ -16,6 +16,121 @@ import (
|
||||
"github.com/go-gost/gost/pkg/service"
|
||||
)
|
||||
|
||||
func buildService(cfg *config.Config) (services []*service.Service) {
|
||||
if cfg == nil || len(cfg.Services) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
chains := buildChain(cfg)
|
||||
|
||||
for _, svc := range cfg.Services {
|
||||
listenerLogger := log.WithFields(map[string]interface{}{
|
||||
"kind": "listener",
|
||||
"type": svc.Listener.Type,
|
||||
"service": svc.Name,
|
||||
})
|
||||
ln := registry.GetListener(svc.Listener.Type)(
|
||||
listener.AddrOption(svc.Addr),
|
||||
listener.LoggerOption(listenerLogger),
|
||||
)
|
||||
if err := ln.Init(metadata.MapMetadata(svc.Listener.Metadata)); err != nil {
|
||||
listenerLogger.Fatal("init:", err)
|
||||
}
|
||||
|
||||
var chain *chain.Chain
|
||||
for _, ch := range chains {
|
||||
if svc.Chain == ch.Name {
|
||||
chain = ch
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
handlerLogger := log.WithFields(map[string]interface{}{
|
||||
"kind": "handler",
|
||||
"type": svc.Handler.Type,
|
||||
"service": svc.Name,
|
||||
})
|
||||
h := registry.GetHandler(svc.Handler.Type)(
|
||||
handler.ChainOption(chain),
|
||||
handler.LoggerOption(handlerLogger),
|
||||
)
|
||||
if err := h.Init(metadata.MapMetadata(svc.Handler.Metadata)); err != nil {
|
||||
handlerLogger.Fatal("init:", err)
|
||||
}
|
||||
|
||||
s := (&service.Service{}).
|
||||
WithListener(ln).
|
||||
WithHandler(h)
|
||||
services = append(services, s)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func buildChain(cfg *config.Config) (chains []*chain.Chain) {
|
||||
if cfg == nil || len(cfg.Chains) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, ch := range cfg.Chains {
|
||||
c := &chain.Chain{
|
||||
Name: ch.Name,
|
||||
}
|
||||
|
||||
selector := selectorFromConfig(ch.LB)
|
||||
for _, hop := range ch.Hops {
|
||||
group := &chain.NodeGroup{}
|
||||
for _, v := range hop.Nodes {
|
||||
node := chain.NewNode(v.Name, v.Addr)
|
||||
|
||||
connectorLogger := log.WithFields(map[string]interface{}{
|
||||
"kind": "connector",
|
||||
"type": v.Connector.Type,
|
||||
"hop": hop.Name,
|
||||
"node": node.Name(),
|
||||
})
|
||||
cr := registry.GetConnector(v.Connector.Type)(
|
||||
connector.LoggerOption(connectorLogger),
|
||||
)
|
||||
if err := cr.Init(metadata.MapMetadata(v.Connector.Metadata)); err != nil {
|
||||
connectorLogger.Fatal("init:", err)
|
||||
}
|
||||
|
||||
dialerLogger := log.WithFields(map[string]interface{}{
|
||||
"kind": "dialer",
|
||||
"type": v.Dialer.Type,
|
||||
"hop": hop.Name,
|
||||
"node": node.Name(),
|
||||
})
|
||||
d := registry.GetDialer(v.Dialer.Type)(
|
||||
dialer.LoggerOption(dialerLogger),
|
||||
)
|
||||
if err := d.Init(metadata.MapMetadata(v.Dialer.Metadata)); err != nil {
|
||||
dialerLogger.Fatal("init:", err)
|
||||
}
|
||||
|
||||
tr := (&chain.Transport{}).
|
||||
WithConnector(cr).
|
||||
WithDialer(d)
|
||||
|
||||
node.WithTransport(tr)
|
||||
group.AddNode(node)
|
||||
}
|
||||
|
||||
sel := selector
|
||||
if s := selectorFromConfig(hop.LB); s != nil {
|
||||
sel = s
|
||||
}
|
||||
group.WithSelector(sel)
|
||||
c.AddNodeGroup(group)
|
||||
}
|
||||
|
||||
chains = append(chains, c)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func logFromConfig(cfg *config.LogConfig) logger.Logger {
|
||||
opts := []logger.LoggerOption{
|
||||
logger.FormatLoggerOption(logger.LogFormat(cfg.Format)),
|
||||
@ -41,100 +156,29 @@ func logFromConfig(cfg *config.LogConfig) logger.Logger {
|
||||
return logger.NewLogger(opts...)
|
||||
}
|
||||
|
||||
func buildService(cfg *config.Config) (services []*service.Service) {
|
||||
if cfg == nil || len(cfg.Services) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
chains := buildChain(cfg)
|
||||
|
||||
for _, svc := range cfg.Services {
|
||||
s := &service.Service{}
|
||||
|
||||
ln := registry.GetListener(svc.Listener.Type)(
|
||||
listener.AddrOption(svc.Addr),
|
||||
listener.LoggerOption(
|
||||
log.WithFields(map[string]interface{}{
|
||||
"kind": "listener",
|
||||
"type": svc.Listener.Type,
|
||||
}),
|
||||
),
|
||||
)
|
||||
ln.Init(metadata.MapMetadata(svc.Listener.Metadata))
|
||||
s.WithListener(ln)
|
||||
|
||||
var chain *chain.Chain
|
||||
for _, ch := range chains {
|
||||
if svc.Chain == ch.Name {
|
||||
chain = ch
|
||||
break
|
||||
}
|
||||
}
|
||||
h := registry.GetHandler(svc.Handler.Type)(
|
||||
handler.ChainOption(chain),
|
||||
handler.LoggerOption(
|
||||
log.WithFields(map[string]interface{}{
|
||||
"kind": "handler",
|
||||
"type": svc.Handler.Type,
|
||||
}),
|
||||
),
|
||||
)
|
||||
h.Init(metadata.MapMetadata(svc.Handler.Metadata))
|
||||
s.WithHandler(h)
|
||||
|
||||
services = append(services, s)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func buildChain(cfg *config.Config) (chains []*chain.Chain) {
|
||||
if cfg == nil || len(cfg.Chains) == 0 {
|
||||
func selectorFromConfig(cfg *config.LoadbalancingConfig) chain.Selector {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, ch := range cfg.Chains {
|
||||
c := &chain.Chain{
|
||||
Name: ch.Name,
|
||||
}
|
||||
for _, hop := range ch.Hops {
|
||||
group := &chain.NodeGroup{}
|
||||
for _, v := range hop.Nodes {
|
||||
node := chain.NewNode(v.Name, v.Addr)
|
||||
|
||||
tr := &chain.Transport{}
|
||||
|
||||
cr := registry.GetConnector(v.Connector.Type)(
|
||||
connector.LoggerOption(
|
||||
log.WithFields(map[string]interface{}{
|
||||
"kind": "connector",
|
||||
"type": v.Connector.Type,
|
||||
}),
|
||||
),
|
||||
)
|
||||
cr.Init(metadata.MapMetadata(v.Connector.Metadata))
|
||||
tr.WithConnector(cr)
|
||||
|
||||
d := registry.GetDialer(v.Dialer.Type)(
|
||||
dialer.LoggerOption(
|
||||
log.WithFields(map[string]interface{}{
|
||||
"kind": "dialer",
|
||||
"type": v.Dialer.Type,
|
||||
}),
|
||||
),
|
||||
)
|
||||
d.Init(metadata.MapMetadata(v.Dialer.Metadata))
|
||||
tr.WithDialer(d)
|
||||
|
||||
node.WithTransport(tr)
|
||||
|
||||
group.AddNode(node)
|
||||
}
|
||||
c.AddNodeGroup(group)
|
||||
}
|
||||
|
||||
chains = append(chains, c)
|
||||
var strategy chain.Strategy
|
||||
switch cfg.Strategy {
|
||||
case "round":
|
||||
strategy = &chain.RoundRobinStrategy{}
|
||||
case "random":
|
||||
strategy = &chain.RandomStrategy{}
|
||||
case "fifio":
|
||||
strategy = &chain.FIFOStrategy{}
|
||||
default:
|
||||
strategy = &chain.RoundRobinStrategy{}
|
||||
}
|
||||
|
||||
return
|
||||
return chain.NewSelector(
|
||||
strategy,
|
||||
&chain.InvalidFilter{},
|
||||
&chain.FailFilter{
|
||||
MaxFails: cfg.MaxFails,
|
||||
FailTimeout: cfg.FailTimeout,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -4,46 +4,77 @@ log:
|
||||
format: json # text, json
|
||||
|
||||
services:
|
||||
- url: "http://gost:gost@:8000"
|
||||
- name: http+tcp
|
||||
url: "http://gost:gost@:8000"
|
||||
addr: ":8000"
|
||||
handler:
|
||||
type: http
|
||||
metadata:
|
||||
proxyAgent: "gost/3.0"
|
||||
retry: 3
|
||||
auths:
|
||||
- user1:pass1
|
||||
- user2:pass2
|
||||
# probeResist: code:404 # code, web, host, file
|
||||
# knock: example.com
|
||||
listener:
|
||||
type: tcp
|
||||
metadata:
|
||||
keepAlive: 15s
|
||||
# chain: chain01
|
||||
chain: chain01
|
||||
|
||||
chains:
|
||||
- name: chain01
|
||||
# chain level load balancing
|
||||
lb:
|
||||
strategy: round
|
||||
filters:
|
||||
- filter1
|
||||
maxFails: 1
|
||||
failTimeout: 30s
|
||||
hops:
|
||||
- name: level01
|
||||
- name: hop01
|
||||
# hop level load balancing
|
||||
lb:
|
||||
strategy: rand
|
||||
filters:
|
||||
- filter1
|
||||
strategy: round
|
||||
maxFails: 1
|
||||
failTimeout: 30s
|
||||
nodes:
|
||||
- name: node01
|
||||
addr: ":8080"
|
||||
url: "http://gost:gost@:8080"
|
||||
addr: ":8081"
|
||||
url: "http://gost:gost@:8081"
|
||||
connector:
|
||||
type: http
|
||||
metadata:
|
||||
userAgent: "gost/3.0"
|
||||
auth: username:password
|
||||
auth: user1:pass1
|
||||
dialer:
|
||||
type: tcp
|
||||
metadata: {}
|
||||
|
||||
|
||||
- name: node02
|
||||
addr: ":8082"
|
||||
url: "http://gost:gost@:8082"
|
||||
connector:
|
||||
type: http
|
||||
metadata:
|
||||
userAgent: "gost/3.0"
|
||||
auth: user1:pass1
|
||||
dialer:
|
||||
type: tcp
|
||||
metadata: {}
|
||||
- name: hop02
|
||||
# hop level load balancing
|
||||
lb:
|
||||
strategy: round
|
||||
maxFails: 1
|
||||
failTimeout: 30s
|
||||
nodes:
|
||||
- name: node03
|
||||
addr: ":8083"
|
||||
url: "http://gost:gost@:8083"
|
||||
connector:
|
||||
type: http
|
||||
metadata:
|
||||
userAgent: "gost/3.0"
|
||||
auth: user1:pass1
|
||||
dialer:
|
||||
type: tcp
|
||||
metadata: {}
|
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
stdlog "log"
|
||||
|
||||
"github.com/go-gost/gost/pkg/config"
|
||||
"github.com/go-gost/gost/pkg/logger"
|
||||
)
|
||||
@ -10,6 +12,7 @@ var (
|
||||
)
|
||||
|
||||
func main() {
|
||||
stdlog.SetFlags(stdlog.LstdFlags | stdlog.Lshortfile)
|
||||
cfg := &config.Config{}
|
||||
if err := cfg.Load(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
Reference in New Issue
Block a user