Требуется помощь по разработке сервера на Go

485 views
Skip to first unread message

Олег Максимов

unread,
Jul 10, 2016, 3:05:47 AM7/10/16
to Golang Russian
Добрый день!
Недавно попробовал написать впервые свой сервер для игры, до этого из связанного с серверной только давным-давно писал на PHP под популярные CMS.
Основных проблем 2:
1)В качестве платформы для запуска используется OpenShift, на время разработки - бесплатный тариф. Так и смог заставить запуститься этот картридж: https://github.com/smarterclayton/openshift-go-cart в режиме пакета, а не запуска файла web.go, поэтому пришлось всё писать в одном файле. Это ужасно:) Может быть, есть какой-то пример настроенного для openshift картриджа, который может запускаться в виде пакета?
2)В качестве БД используется PostgreSQL со стандартными запросами вроде select, update и delete. Но периодически возникает ошибка "pq: sorry, too many clients already". Это значит, что нужно использовать другую библиотеку, не http://github.com/lib/pq? Или функция main выполняется при каждом обращении к серверу, и, таким образом, при каждом запросе образуется новое соединение? Хотя не похоже на это.
Соединение происходит следующим образом(для REST используется библиотека http://github.com/julienschmidt/httprouter):

dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%s sslmode=disable",
DB_USER, DB_PASSWORD, DB_NAME, os.Getenv("OPENSHIFT_POSTGRESQL_DB_HOST"), os.Getenv("OPENSHIFT_POSTGRESQL_DB_PORT"))
var err error
DatabaseConnection, err = sql.Open("postgres", dbinfo)
handleError(err, nil)
createDatabase()
router := httprouter.New()
router.GET("/", index)
router.GET("/config/:action", configManage)
router.POST("/user/:action", userManage)
router.POST("/event/:action", eventUnlock)
router.GET("/event/:userid", eventsList)
router.GET("/bonus/:userid", bonusesList)
router.POST("/bonus/use/:bonus", decreaseBonus)
router.GET("/resources/:userid", resourcesList)
router.POST("/tramlives/decrease", decreaseTramLives)
router.GET("/tramlives/get/:userid", checkTramLives)
router.POST("/combination/:action", combinationManage)
bind := fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"), os.Getenv("OPENSHIFT_GO_PORT"))
fmt.Printf("listening on %s...", bind)
log.Fatal(http.ListenAndServe(bind, router))

Dmitry Chusovitin

unread,
Jul 11, 2016, 3:00:45 PM7/11/16
to Golang Russian
По второму вопросу.

Эту ошибку шлет база, так что стоит помониторить таблицу pg_stat_activity и определить сколько коннектов висит, а так же есть ли "залипшие" запросы. 
И узнать значение max_connections (SHOW max_connections).
Если в приложении используются транзакции, то стоит их проверить на блокировки.

Функция main не выполняется при каждом запросе (так обычно в PHP, один запрос - один коннект), а только при запуске приложения. В http://github.com/lib/pq и других используется пулл коннектов.
Данная библиотека основывается на стандартном database/sql, так что для настройки пула доступны методы SetConnMaxLifetime, SetMaxIdleConns, SetMaxOpenConns, Stats (https://golang.org/pkg/database/sql/#DB)

В качестве альтернативы (из тех, которые нацелены на Postgres):



воскресенье, 10 июля 2016 г., 10:05:47 UTC+3 пользователь Олег Максимов написал:

Ainar Garipov

unread,
Jul 11, 2016, 3:26:56 PM7/11/16
to Golang Russian
Насчёт второго, обязательно всегда проставляйте SetMaxIdleConns и SetMaxOpenConns. 16 - хорошее число для обоих параметров. Иначе упрётесь в max_connections постгреса.

Олег Максимов

unread,
Jul 22, 2016, 1:34:59 PM7/22/16
to Golang Russian
Понятно, спасибо. А по первому вопросу - если непонятно, что делать с openShift, знаете ли ещё какой-нибудь хостинг, на котором возможно бесплатно использовать Go? 

понедельник, 11 июля 2016 г., 23:00:45 UTC+4 пользователь Dmitry Chusovitin написал:

Олег Максимов

unread,
Jul 22, 2016, 1:38:44 PM7/22/16
to Golang Russian
Спасибо, исправил

понедельник, 11 июля 2016 г., 23:26:56 UTC+4 пользователь Ainar Garipov написал:
Reply all
Reply to author
Forward
0 new messages