У меня есть служба, которая хочет открыть 28 соединений с различными объектами S3, чтобы сохранить их там для последующего повторного использования.
В настоящее время я проверяю свой код на localstack , чтобы убедитесь, что он будет работать, и избегайте путаницы в нашей реальной среде S3.
Когда я открываю до 8 соединений в сыром виде, все работает как положено. Почти каждый раз, когда я go превышаю это число, он начинает выдавать ошибки «соединение сервера не используется». Ниже приведен пример ошибки во всей ее полноте:
Put http://192.168.26.95: 4572 / bucket-name / test-12.mp3? PartNumber = 1 & uploadId = ofutQ7QNwlpy0q4jYAofwhZQ130mMqk5hKkKsI2b1BUHHI http: сервер закрыл простаивающее соединение
На всякий случай я попробовал с одним соединением, оставил его открытым какое-то время, ничего не отправляя, и все работало нормально. Нет ошибок "простоя соединения". Так что я уверен, что метка ошибки неправильная. Скорее всего, это ошибка из-за перегруженного прослушивателя (то есть слишком много соединений подряд, канал соединений заполнен).
У меня есть два основных вопроса:
Есть ли способ исправить проблему на стороне клиента? Я попытался увеличить скорость соединений, но даже при перерыве в 1 секунду между каждым соединением (что слишком долго) я все еще получаю сообщение об ошибке.
Будет ли способ настройки localstack, чтобы позволить больше соединений происходить подряд? Я использую Docker версию.
Для (1) я посмотрел немного в MinIO, PutObject () , похоже, не имеет каких-либо способ увеличить время ожидания для успешного подключения или несколько повторных попыток, которые облегчили бы мою жизнь.
Для (2) это должно соответствовать тому, что позволяет реальная среда S3. Так что, если существующие настройки localstack уже соответствуют реальному S3, я боюсь, что нам нужно заставить (1) работать.
Следующий пример не так плох, как основной код, но со счетом 28, он по-прежнему не работает в большинстве случаев. Длина данных или ожидание перед записью в каналы или нет, похоже, не влияет на PutObject()
, который генерирует эту ошибку "простоя соединения". Количество соединений (звонков на PutObject()
) действительно сильно влияет.
package main
import (
"fmt"
"io"
"os"
"time"
"github.com/minio/minio-go"
)
func main() {
var mc *minio.Client
var err error
var size int64
var count int = 28
var outputRC []io.ReadCloser
var inputPipe []*os.File
mc, err = minio.New("192.168.2.95:4572", "localstack", "localstack", false)
if err != nil {
fmt.Printf("error: minio.New(): %v\n", err)
os.Exit(1)
}
outputRC = make([]io.ReadCloser, count)
inputPipe = make([]*os.File, count)
// create pipes which are used to send data to the S3 objects
for i := 0; i < count; i++ {
// reader, writer, err = os.Pipe()
outputRC[i], inputPipe[i], err = os.Pipe()
if err != nil {
fmt.Printf("error: os.Pipe() #%d: %v\n", i, err)
os.Exit(1)
}
}
// now setup the readers (read pipe output and save in S3 objects)
for i := 0; i < count; i++ {
time.Sleep(100 * time.Millisecond)
idx := i
go func() {
filename := fmt.Sprintf("whatever-%d.mp3", idx)
size, err = mc.PutObject("bucket-name", filename, outputRC[idx], -1, minio.PutObjectOptions{ContentType:"audio/mpeg"})
if err != nil {
fmt.Printf("error: mc.PutObject() #%d: %v\n", idx, err)
//os.Exit(1)
}
}()
}
//time.Sleep(5 * time.Second)
for i := 0; i < count; i++ {
fmt.Fprintf(inputPipe[i], "FILE #%d\n", i)
}
//time.Sleep(10 * time.Second)
for i := 0; i < count; i++ {
inputPipe[i].Close()
}
time.Sleep(60 * time.Second)
}