mirror of https://github.com/minio/minio.git
Avoid ListBuckets() call instead rely on simple HTTP GET (#8475)
This is to avoid making calls to backend and requiring gateways to allow permissions for ListBuckets() operation just for Liveness checks, we can avoid this and make our liveness checks to be more performant.
This commit is contained in:
parent
d28bcb4f84
commit
07a556a10b
|
@ -17,8 +17,10 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio/cmd/config"
|
||||
xhttp "github.com/minio/minio/cmd/http"
|
||||
|
@ -286,6 +288,28 @@ func ToMinioClientCompleteParts(parts []CompletePart) []minio.CompletePart {
|
|||
return mparts
|
||||
}
|
||||
|
||||
// IsBackendOnline - verifies if the backend is reachable
|
||||
// by performing a GET request on the URL. returns 'true'
|
||||
// if backend is reachable.
|
||||
func IsBackendOnline(ctx context.Context, clnt *http.Client, urlStr string) bool {
|
||||
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// never follow redirects
|
||||
clnt.CheckRedirect = func(*http.Request, []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, urlStr, nil)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if _, err = clnt.Do(req); err != nil {
|
||||
return !xnet.IsNetworkOrHostDown(err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ErrorRespToObjectError converts MinIO errors to minio object layer errors.
|
||||
func ErrorRespToObjectError(err error, params ...string) error {
|
||||
if err == nil {
|
||||
|
|
|
@ -185,6 +185,8 @@ func (g *Azure) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, erro
|
|||
c.HTTPClient = &http.Client{Transport: minio.NewCustomHTTPTransport()}
|
||||
|
||||
return &azureObjects{
|
||||
endpoint: fmt.Sprintf("https://%s.blob.core.windows.net", creds.AccessKey),
|
||||
httpClient: c.HTTPClient,
|
||||
client: c.GetBlobService(),
|
||||
}, nil
|
||||
}
|
||||
|
@ -343,6 +345,8 @@ func azurePropertiesToS3Meta(meta storage.BlobMetadata, props storage.BlobProper
|
|||
// azureObjects - Implements Object layer for Azure blob storage.
|
||||
type azureObjects struct {
|
||||
minio.GatewayUnsupported
|
||||
endpoint string
|
||||
httpClient *http.Client
|
||||
client storage.BlobStorageClient // Azure sdk client
|
||||
}
|
||||
|
||||
|
@ -447,6 +451,8 @@ func (a *azureObjects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo - Not relevant to Azure backend.
|
||||
func (a *azureObjects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, a.httpClient, a.endpoint)
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ func (g *B2) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
return &b2Objects{
|
||||
creds: creds,
|
||||
b2Client: client,
|
||||
httpClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
ctx: ctx,
|
||||
}, nil
|
||||
}
|
||||
|
@ -138,6 +141,7 @@ type b2Objects struct {
|
|||
mu sync.Mutex
|
||||
creds auth.Credentials
|
||||
b2Client *b2.B2
|
||||
httpClient *http.Client
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
|
@ -225,12 +229,13 @@ func b2MsgCodeToObjectError(code int, msgCode string, msg string, params ...stri
|
|||
// Shutdown saves any gateway metadata to disk
|
||||
// if necessary and reload upon next restart.
|
||||
func (l *b2Objects) Shutdown(ctx context.Context) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
// StorageInfo is not relevant to B2 backend.
|
||||
func (l *b2Objects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.httpClient, "https://api.backblazeb2.com/b2api/v1")
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -208,6 +208,9 @@ func (g *GCS) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
gcs := &gcsGateway{
|
||||
client: client,
|
||||
projectID: g.projectID,
|
||||
httpClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
}
|
||||
|
||||
// Start background process to cleanup old files in minio.sys.tmp
|
||||
|
@ -347,6 +350,7 @@ func isValidGCSProjectIDFormat(projectID string) bool {
|
|||
type gcsGateway struct {
|
||||
minio.GatewayUnsupported
|
||||
client *storage.Client
|
||||
httpClient *http.Client
|
||||
projectID string
|
||||
}
|
||||
|
||||
|
@ -412,8 +416,10 @@ func (l *gcsGateway) Shutdown(ctx context.Context) error {
|
|||
}
|
||||
|
||||
// StorageInfo - Not relevant to GCS backend.
|
||||
func (l *gcsGateway) StorageInfo(ctx context.Context) minio.StorageInfo {
|
||||
return minio.StorageInfo{}
|
||||
func (l *gcsGateway) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.httpClient, "https://storage.googleapis.com")
|
||||
return si
|
||||
}
|
||||
|
||||
// MakeBucketWithLocation - Create a new container on GCS backend.
|
||||
|
|
|
@ -227,7 +227,8 @@ func (n *hdfsObjects) StorageInfo(ctx context.Context) minio.StorageInfo {
|
|||
}
|
||||
sinfo := minio.StorageInfo{}
|
||||
sinfo.Used = []uint64{fsInfo.Used}
|
||||
sinfo.Backend.Type = minio.Unknown
|
||||
sinfo.Backend.Type = minio.BackendGateway
|
||||
sinfo.Backend.GatewayOnline = true
|
||||
return sinfo
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,8 @@ func (n *nasObjects) IsListenBucketSupported() bool {
|
|||
|
||||
func (n *nasObjects) StorageInfo(ctx context.Context) minio.StorageInfo {
|
||||
sinfo := n.ObjectLayer.StorageInfo(ctx)
|
||||
sinfo.Backend.Type = minio.Unknown
|
||||
sinfo.Backend.GatewayOnline = sinfo.Backend.Type == minio.BackendFS
|
||||
sinfo.Backend.Type = minio.BackendGateway
|
||||
return sinfo
|
||||
}
|
||||
|
||||
|
|
|
@ -145,7 +145,9 @@ func (g *OSS) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.HTTPClient = &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
}
|
||||
return &ossObjects{
|
||||
Client: client,
|
||||
}, nil
|
||||
|
@ -341,7 +343,9 @@ func (l *ossObjects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo is not relevant to OSS backend.
|
||||
func (l *ossObjects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
return
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.Client.HTTPClient, l.Client.Config.Endpoint)
|
||||
return si
|
||||
}
|
||||
|
||||
// ossIsValidBucketName verifies whether a bucket name is valid.
|
||||
|
|
|
@ -261,7 +261,11 @@ func (g *S3) NewGatewayLayer(creds auth.Credentials) (minio.ObjectLayer, error)
|
|||
|
||||
s := s3Objects{
|
||||
Client: clnt,
|
||||
HTTPClient: &http.Client{
|
||||
Transport: minio.NewCustomHTTPTransport(),
|
||||
},
|
||||
}
|
||||
|
||||
// Enables single encryption of KMS is configured.
|
||||
if minio.GlobalKMS != nil {
|
||||
encS := s3EncObjects{s}
|
||||
|
@ -284,6 +288,7 @@ func (g *S3) Production() bool {
|
|||
type s3Objects struct {
|
||||
minio.GatewayUnsupported
|
||||
Client *miniogo.Core
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// Shutdown saves any gateway metadata to disk
|
||||
|
@ -294,6 +299,8 @@ func (l *s3Objects) Shutdown(ctx context.Context) error {
|
|||
|
||||
// StorageInfo is not relevant to S3 backend.
|
||||
func (l *s3Objects) StorageInfo(ctx context.Context) (si minio.StorageInfo) {
|
||||
si.Backend.Type = minio.BackendGateway
|
||||
si.Backend.GatewayOnline = minio.IsBackendOnline(ctx, l.HTTPClient, l.Client.EndpointURL().String())
|
||||
return si
|
||||
}
|
||||
|
||||
|
|
|
@ -59,18 +59,15 @@ func LivenessCheckHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// is able to start on orchestration platforms like Docker Swarm.
|
||||
// Refer https://github.com/minio/minio/issues/8140 for more details.
|
||||
// Make sure to add server not initialized status in header
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "Server-not-initialized")
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "server-not-initialized")
|
||||
writeSuccessResponseHeadersOnly(w)
|
||||
return
|
||||
}
|
||||
|
||||
if !globalIsXL && !globalIsDistXL {
|
||||
s := objLayer.StorageInfo(ctx)
|
||||
// Gateways don't provide disk info.
|
||||
if s.Backend.Type == Unknown {
|
||||
// ListBuckets to confirm gateway backend is up
|
||||
if _, err := objLayer.ListBuckets(ctx); err != nil {
|
||||
logger.LogOnceIf(ctx, err, struct{}{})
|
||||
if s.Backend.Type == BackendGateway {
|
||||
if !s.Backend.GatewayOnline {
|
||||
writeResponse(w, http.StatusServiceUnavailable, nil, mimeNone)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ const (
|
|||
BackendFS
|
||||
// Multi disk BackendErasure (single, distributed) backend.
|
||||
BackendErasure
|
||||
// Gateway backend.
|
||||
BackendGateway
|
||||
// Add your own backend.
|
||||
)
|
||||
|
||||
|
@ -49,9 +51,12 @@ type StorageInfo struct {
|
|||
|
||||
// Backend type.
|
||||
Backend struct {
|
||||
// Represents various backend types, currently on FS and Erasure.
|
||||
// Represents various backend types, currently on FS, Erasure and Gateway
|
||||
Type BackendType
|
||||
|
||||
// Following fields are only meaningful if BackendType is Gateway.
|
||||
GatewayOnline bool
|
||||
|
||||
// Following fields are only meaningful if BackendType is Erasure.
|
||||
OnlineDisks madmin.BackendDisks // Online disks during server startup.
|
||||
OfflineDisks madmin.BackendDisks // Offline disks during server startup.
|
||||
|
|
Loading…
Reference in New Issue