add support for unix socket binding service
parent
e8104e2d81
commit
6945655be2
|
@ -3,6 +3,7 @@
|
|||
### Features
|
||||
|
||||
- [#7120](https://github.com/influxdata/influxdb/issues/7120): Add additional statistics to query executor.
|
||||
- [#7135](https://github.com/influxdata/influxdb/pull/7135): Support enable HTTP service over unix domain socket. Thanks @oiooj
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
|
|
@ -173,6 +173,9 @@ reporting-disabled = false
|
|||
max-row-limit = 10000
|
||||
realm = "InfluxDB"
|
||||
|
||||
unix-socket-enabled = false # enable http service over unix domain socket
|
||||
# bind-socket = "/var/run/influxdb.sock"
|
||||
|
||||
###
|
||||
### [subsciber]
|
||||
###
|
||||
|
|
|
@ -6,6 +6,9 @@ const (
|
|||
|
||||
// DefaultRealm is the default realm sent back when issuing a basic auth challenge.
|
||||
DefaultRealm = "InfluxDB"
|
||||
|
||||
// DefaultBindSocket is the default unix socket to bind to.
|
||||
DefaultBindSocket = "/var/run/influxdb.sock"
|
||||
)
|
||||
|
||||
// Config represents a configuration for a HTTP service.
|
||||
|
@ -22,17 +25,21 @@ type Config struct {
|
|||
MaxConnectionLimit int `toml:"max-connection-limit"`
|
||||
SharedSecret string `toml:"shared-secret"`
|
||||
Realm string `toml:"realm"`
|
||||
UnixSocketEnabled bool `toml:"unix-socket-enabled"`
|
||||
BindSocket string `toml:"bind-socket"`
|
||||
}
|
||||
|
||||
// NewConfig returns a new Config with default settings.
|
||||
func NewConfig() Config {
|
||||
return Config{
|
||||
Enabled: true,
|
||||
BindAddress: DefaultBindAddress,
|
||||
LogEnabled: true,
|
||||
HTTPSEnabled: false,
|
||||
HTTPSCertificate: "/etc/ssl/influxdb.pem",
|
||||
MaxRowLimit: DefaultChunkSize,
|
||||
Realm: DefaultRealm,
|
||||
Enabled: true,
|
||||
BindAddress: DefaultBindAddress,
|
||||
LogEnabled: true,
|
||||
HTTPSEnabled: false,
|
||||
HTTPSCertificate: "/etc/ssl/influxdb.pem",
|
||||
MaxRowLimit: DefaultChunkSize,
|
||||
Realm: DefaultRealm,
|
||||
UnixSocketEnabled: false,
|
||||
BindSocket: DefaultBindSocket,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ log-enabled = true
|
|||
write-tracing = true
|
||||
https-enabled = true
|
||||
https-certificate = "/dev/null"
|
||||
unix-socket-enabled = true
|
||||
bind-socket = "/var/run/influxdb.sock"
|
||||
`, &c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -37,6 +39,10 @@ https-certificate = "/dev/null"
|
|||
t.Fatalf("unexpected https enabled: %v", c.HTTPSEnabled)
|
||||
} else if c.HTTPSCertificate != "/dev/null" {
|
||||
t.Fatalf("unexpected https certificate: %v", c.HTTPSCertificate)
|
||||
} else if c.UnixSocketEnabled != true {
|
||||
t.Fatalf("unexpected unix socket enabled: %v", c.UnixSocketEnabled)
|
||||
} else if c.BindSocket != "/var/run/influxdb.sock" {
|
||||
t.Fatalf("unexpected bind unix socket: %v", c.BindSocket)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,10 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/models"
|
||||
|
@ -46,6 +49,10 @@ type Service struct {
|
|||
limit int
|
||||
err chan error
|
||||
|
||||
unixSocket bool
|
||||
bindSocket string
|
||||
unixSocketListener net.Listener
|
||||
|
||||
Handler *Handler
|
||||
|
||||
Logger *log.Logger
|
||||
|
@ -54,14 +61,16 @@ type Service struct {
|
|||
// NewService returns a new instance of Service.
|
||||
func NewService(c Config) *Service {
|
||||
s := &Service{
|
||||
addr: c.BindAddress,
|
||||
https: c.HTTPSEnabled,
|
||||
cert: c.HTTPSCertificate,
|
||||
key: c.HTTPSPrivateKey,
|
||||
limit: c.MaxConnectionLimit,
|
||||
err: make(chan error),
|
||||
Handler: NewHandler(c),
|
||||
Logger: log.New(os.Stderr, "[httpd] ", log.LstdFlags),
|
||||
addr: c.BindAddress,
|
||||
https: c.HTTPSEnabled,
|
||||
cert: c.HTTPSCertificate,
|
||||
key: c.HTTPSPrivateKey,
|
||||
limit: c.MaxConnectionLimit,
|
||||
err: make(chan error),
|
||||
unixSocket: c.UnixSocketEnabled,
|
||||
bindSocket: c.BindSocket,
|
||||
Handler: NewHandler(c),
|
||||
Logger: log.New(os.Stderr, "[httpd] ", log.LstdFlags),
|
||||
}
|
||||
if s.key == "" {
|
||||
s.key = s.cert
|
||||
|
@ -101,6 +110,29 @@ func (s *Service) Open() error {
|
|||
s.ln = listener
|
||||
}
|
||||
|
||||
// Open unix socket listener.
|
||||
if s.unixSocket {
|
||||
if runtime.GOOS == "windows" {
|
||||
return fmt.Errorf("unable to use unix socket on windows")
|
||||
}
|
||||
if err := os.MkdirAll(path.Dir(s.bindSocket), 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := syscall.Unlink(s.bindSocket); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
listener, err := net.Listen("unix", s.bindSocket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Logger.Println("Listening on unix socket:", listener.Addr().String())
|
||||
s.unixSocketListener = listener
|
||||
|
||||
go s.serveUnixSocket()
|
||||
}
|
||||
|
||||
// Enforce a connection limit if one has been given.
|
||||
if s.limit > 0 {
|
||||
s.ln = LimitListener(s.ln, s.limit)
|
||||
|
@ -120,14 +152,21 @@ func (s *Service) Open() error {
|
|||
}
|
||||
|
||||
// Begin listening for requests in a separate goroutine.
|
||||
go s.serve()
|
||||
go s.serveTCP()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the underlying listener.
|
||||
func (s *Service) Close() error {
|
||||
if s.ln != nil {
|
||||
return s.ln.Close()
|
||||
if err := s.ln.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if s.unixSocketListener != nil {
|
||||
if err := s.unixSocketListener.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -156,11 +195,21 @@ func (s *Service) Statistics(tags map[string]string) []models.Statistic {
|
|||
return s.Handler.Statistics(models.Tags{"bind": s.addr}.Merge(tags))
|
||||
}
|
||||
|
||||
// serveTCP serves the handler from the TCP listener.
|
||||
func (s *Service) serveTCP() {
|
||||
s.serve(s.ln)
|
||||
}
|
||||
|
||||
// serveUnixSocket serves the handler from the unix socket listener.
|
||||
func (s *Service) serveUnixSocket() {
|
||||
s.serve(s.unixSocketListener)
|
||||
}
|
||||
|
||||
// serve serves the handler from the listener.
|
||||
func (s *Service) serve() {
|
||||
func (s *Service) serve(listener net.Listener) {
|
||||
// The listener was closed so exit
|
||||
// See https://github.com/golang/go/issues/4373
|
||||
err := http.Serve(s.ln, s.Handler)
|
||||
err := http.Serve(listener, s.Handler)
|
||||
if err != nil && !strings.Contains(err.Error(), "closed") {
|
||||
s.err <- fmt.Errorf("listener failed: addr=%s, err=%s", s.Addr(), err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue