Я работаю над проектом Go, который использует gRPC в качестве сервера и Voltdb в качестве БД. У меня проблема при отправке большого количества запросов на чтение / запись БД на сервер gRPC. Запрос был обработан, но он не освобождает соединение с БД после завершения оператора. Поэтому, когда соединение в пуле заканчивается, я получаю эту ошибку:
Отклонено соединение с /127.0.0.1:63015, поскольку достигнут предел соединения 9940
файл прото
syntax = "proto3";
package grpc;
import "google/protobuf/struct.proto";
option java_multiple_files = true;
option java_package = "com.io.test";
service TestService {
rpc updateUser (UserRequest) returns (Status) {};
}
message UserRequest {
string userId = 1;
string name = 2;
}
message Status {
string code = 1;
}
Реализация Grpc в Go
package service
import (
"context"
"log"
api "testgrpc/pkg/api/grpc"
"testgrpc/pkg/db"
"testgrpc/pkg/model"
)
var voltDbClient *db.VoltDBClient
func init() {
voltDbClient = db.NewVoltDBClient()
}
type GrpcService struct {
}
func NewGrpcService() *GrpcService {
return &GrpcService{}
}
func (sv *GrpcService) UpdateUser(ctx context.Context, req *api.UserRequest) (*api.Status, error) {
user, err := voltDbClient.FindByID(req.GetUserId())
if user == nil || err != nil {
log.Print("error while reading")
} else {
log.Println(user.(*model.User).UserId)
log.Println(user.(*model.User).Name)
}
err = voltDbClient.Put(req.GetUserId(), req.GetName())
if err != nil {
log.Print("error while writing")
}
return &api.Status{Code: "0"}, nil
}
Клиент БД
package db
import (
"database/sql"
"log"
"testgrpc/pkg/model"
_ "github.com/VoltDB/voltdb-client-go/voltdbclient"
)
var Db *sql.DB
func init() {
if Db == nil {
var err error
Db, err = sql.Open("voltdb", "localhost:21212")
if err != nil {
log.Fatal(err)
}
//limit max connection to reproduce issue
Db.SetMaxOpenConns(20)
}
}
type VoltDBClient struct {
}
func NewVoltDBClient() *VoltDBClient {
return &VoltDBClient{}
}
//Put add or update record
func (dbClient *VoltDBClient) Put(key interface{}, value interface{}) error {
res, err := Db.Exec("GROUPINFO.upsert", key, value)
if err != nil {
log.Println(err)
return err
}
rowCnt, err := res.RowsAffected()
if err != nil {
log.Println(err)
return err
}
log.Printf("affected = %d\n", rowCnt)
return nil
}
//FindByID find a record by ID
func (dbClient *VoltDBClient) FindByID(key interface{}) (interface{}, error) {
rows, err := Db.Query("GROUPSELECT", key)
if err != nil {
log.Println(err)
return nil, err
}
for rows.Next() {
user := model.User{UserId: "", Name: ""}
err := rows.Scan(&user.UserId, &user.Name)
if err != nil {
log.Println(err)
return nil, err
}
return &user, nil
}
return nil, nil
}
Примечание: я попытался запустить проект без grpc, операторы чтения / записи работают хорошо.