Diretório de artigos
Prefácio
À medida que o volume de negócios aumenta, você inevitavelmente encontrará problemas de desempenho do banco de dados. A partir de instruções SQL razoáveis, índices de campo, sub-bancos de dados e tabelas, separação leitura-gravação, etc., juntamente com a tecnologia de cache, você pode basicamente resolver quase todos os negócios. é suficiente para atualizar o hardware, e o próprio Go implementou um pool de conexões para resolver o atraso causado pela conexão e assim melhorar o desempenho (troca-se espaço por tempo), então gostaria de saber como melhorá-lo.
Descrição do parâmetro MYSQL
Pool de conexões : mantendo um conjunto de conexões de banco de dados na memória para que as conexões possam ser rapidamente alocadas e liberadas quando necessário. Isso evita a abertura e o fechamento freqüentes de conexões de banco de dados, melhorando assim a eficiência e o desempenho do sistema.
Portanto, ele é armazenado na memória na forma de uma conexão longa, e deve haver dois estados: ocupado/inativo . No estado inativo , o tempo limite precisa ser considerado. Além do limite de tempo limite do próprio cliente, haverá também haverá um limite de tempo limite no servidor; a mesma conexão Um pool é um pool, portanto haverá muitas conexões, e o número correspondente na configuração também estará sujeito a limitações no servidor.
Portanto, antes de configurarmos o pool de conexões, devemos entender a configuração dos parâmetros e funções relevantes do mysql, caso contrário, será contraproducente.
Campo | Descrição breve | Informações adicionais |
---|---|---|
max_connection | Número máximo de conexões tratadas simultaneamente | O valor padrão para esse parâmetro geralmente é 100, mas pode ser ajustado com base na configuração do servidor e nas necessidades de desempenho. Se o servidor atingir o limite max_connections, novas solicitações de conexão serão rejeitadas até que o número atual de conexões caia abaixo de max_connections. Portanto, se o seu servidor encontrar frequentemente erros "Muitas conexões", você pode resolver esse problema aumentando o valor de max_connections. No entanto, lembre-se também de que aumentar max_connections pode aumentar o consumo de recursos no servidor, portanto, ajuste adequadamente. |
extra_max_connections | Número máximo de conexões aceitas após exceder o número máximo de conexões | Ele especifica o número máximo de conexões que o servidor pode manipular simultaneamente. Se o servidor estiver ocupado e o limite max_connections tiver sido atingido, o servidor não aceitará mais novas solicitações de conexão até que apareça uma conexão inativa. O parâmetro extra_max_connections permite que o servidor aceite mais solicitações de conexão em circunstâncias especiais para fornecer mais flexibilidade em situações de emergência. Por exemplo, se você definir extra_max_connections como 10, o servidor ainda poderá aceitar 10 solicitações de conexão adicionais depois que max_connections atingir o limite. Deve-se observar que o uso do parâmetro extra_max_connections pode afetar o desempenho do servidor, portanto deve ser utilizado quando necessário. |
wait_timeout | Tempo máximo de espera após inatividade não interativa | Se a conexão não enviar nenhuma solicitação durante este período, o MySQL irá desconectar a conexão. O valor padrão para este parâmetro geralmente é 8 horas, mas seu valor pode ser alterado modificando o arquivo de configuração. O objetivo deste parâmetro é evitar vazamentos de conexão, ou seja, se uma conexão ficar inativa por muito tempo, o MySQL irá desconectá-la para economizar recursos. Obviamente, se o seu aplicativo exigir uma conexão de longo prazo, você poderá aumentar o valor desse parâmetro de forma adequada. |
Na descrição de wait_timeout, não- interativo refere-se à execução do código, enquanto o interativo correspondente refere-se ao controle interativo_timeout, que se refere a clientes como o navicat que se conectam ao banco de dados.
Isto é mencionado porque quando modificamos o valor correspondente, se modificarmos apenas o anterior, descobriremos que não há alteração (na verdade, entrou em vigor) ao imprimir os parâmetros do sistema no cliente. desordem, você pode modificar ambos.
Frases relacionadas
-- 查询语句
SHOW VARIABLES LIKE '%max_connections';
SHOW VARIABLES LIKE 'wait_timeout%' ;
SHOW VARIABLES LIKE '%interactive_timeout%';
-- 设置全局变量
SET GLOBAL max_connections = 100;
SET GLOBAL wait_timeout = 10;
SET GLOBAL interactive_timeout = 10;
Descrição do pool de conexões Go
Configuração de parâmetros do pool de conexões
=// 全局 db 对象
var DB *sql.DB
// ConnectionPool 连接池的学习
func ConnectionPool() {
// 连接 db
db, err := sql.Open("mysql", "root:123456@/db?charset=utf8")
if err != nil {
panic(err)
}
//defer db.Close()
db.SetMaxOpenConns(100) // 设置连接数总数, 需要根据实际业务来测算, 应小于 mysql.max_connection (应该远远小于), 后续根据指标进行调整
db.SetMaxIdleConns(50) // 设置最大空闲连接数, 该数值应该小于等于 SetMaxOpenConns 设置的值
db.SetConnMaxLifetime(0) // 设置连接最大生命周期, 默认为 0(不限制), 我不建议设置该值, 只有当 mysql 服务器出现问题, 会导致连接报错, 恢复后可以自动恢复正常, 而我们配置了时间也不能卡住出问题的时间, 配置小还不如使用 SetConnMaxIdleTime 来解决
db.SetConnMaxIdleTime(4 * time.Second) // 设置空闲状态最大生命周期, 该值应小于 mysql.wait_timeout 的值, 以避免被服务端断开连接, 产生报错影响业务, 一般可以配置 1天。
// 赋值 db 对象
DB = db
}
Exemplo de erro de tempo limite de conexão do servidor relacionado
Indicadores e descrições de parâmetros de pools de conexões em banco de dados/sql
Indicadores de dados sobre DBStats
Campo | ilustrar |
---|---|
MaxOpenConnections | O número máximo de conexões, MaxOpenConnections, definido por SetMaxOpenConns |
Conexões abertas | O número total de conexões ativas, este valor não excederá o valor MaxOpenConnections |
Em uso | O número de conexões em uso. Se você executar close ou scan (com close), a conexão será retornada. Caso contrário, ela ficará ocupada até que a conexão expire. |
Parado | Número de conexões atualmente inativas |
Contagem de espera | O número total de conexões de banco de dados atualmente aguardando |
EsperaDuração | Hora de esperar pela conexão com o banco de dados |
MaxIdleFechado | O número total de conexões inativas que foram fechadas quando o número de conexões inativas excedeu o limite é limitado por SetMaxIdleConns. |
MaxIdleTimeClosed | O número total de conexões inativas fechadas devido ao tempo limite, limitado por SetMaxIdleTime |
MaxLifetimeFechado | O número total de conexões fechadas devido ao tempo limite, limitado por SetMaxLiftTime |
Método de chamada
func getDbStats(w http.ResponseWriter, r *http.Request) {
info := fmt.Sprintf("最大连接数:%d, 当前总连接数;%d, 已使用: %d, 空闲数量:%d \n", DB.Stats().MaxOpenConnections, DB.Stats().OpenConnections, DB.Stats().InUse, DB.Stats().Idle)
info2 := fmt.Sprintf("数量指标 :) \n等待连接数量;%d, 等待创建新连接时长(秒): %f, 空闲超限关闭数量:%d, 空闲超时关闭数量:%d, 连接超时关闭数量:%d \n",
DB.Stats().WaitCount,
DB.Stats().WaitDuration.Seconds(),
DB.Stats().MaxIdleClosed,
DB.Stats().MaxIdleTimeClosed,
DB.Stats().MaxLifetimeClosed,
)
_, _ = fmt.Fprintln(w, info+info2)
}
Exemplo de retorno
Código
mdb.go
/*
Package study_package
*/
package study_package
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"time"
)
// 全局 db 对象
var DB *sql.DB
// ConnectionPool 连接池的学习
func ConnectionPool() {
fmt.Println("mysql 连接池实践 -- ")
// 连接 db
db, err := sql.Open("mysql", "root:12345678@/spider?charset=utf8")
if err != nil {
panic(err)
}
//defer db.Close()
db.SetMaxOpenConns(100) // 设置连接数总数
db.SetMaxIdleConns(50) // 设置最大空闲连接数, 该数值应该小于等于 SetMaxOpenConns 设置的值
db.SetConnMaxLifetime(0) // 设置连接最大生命周期, 默认为 0(不限制), 我不建议设置该值, 只有当 mysql 服务器出现问题, 会导致连接报错, 恢复后可以自动恢复正常, 而我们配置了时间也不能卡住出问题的时间, 配置小还不如使用 SetConnMaxIdleTime 来解决
db.SetConnMaxIdleTime(86400 * time.Second) // 设置空闲状态最大生命周期, 该值应小于 mysql.wait_timeout 的值, 以避免被服务端断开连接, 产生报错影响业务。
// 创建连接池
DB = db
}
web.go
// Copyright 2023 The wangkai. ALL rights reserved.
package study_package
import (
"fmt"
"net/http"
)
// Pool 学习搭建 数据库连接池相关概念
func Pool(w http.ResponseWriter, r *http.Request) {
var count int
// 对应数据库查询
row := DB.QueryRow("SELECT COUNT(1) count FROM `xz_house`")
// 遍历数据
err := row.Scan(&count)
if err != nil {
fmt.Println(err)
}
_, _ = fmt.Fprintln(w, count)
}
// getDbStats 获取 DB 状态和指标
func getDbStats(w http.ResponseWriter, r *http.Request) {
info := fmt.Sprintf("最大连接数:%d, 当前总连接数;%d, 已使用: %d, 空闲数量:%d \n", DB.Stats().MaxOpenConnections, DB.Stats().OpenConnections, DB.Stats().InUse, DB.Stats().Idle)
info2 := fmt.Sprintf("数量指标 :) \n等待连接数量;%d, 等待创建新连接时长(秒): %f, 空闲超限关闭数量:%d, 空闲超时关闭数量:%d, 连接超时关闭数量:%d \n",
DB.Stats().WaitCount,
DB.Stats().WaitDuration.Seconds(),
DB.Stats().MaxIdleClosed,
DB.Stats().MaxIdleTimeClosed,
DB.Stats().MaxLifetimeClosed,
)
_, _ = fmt.Fprintln(w, info+info2)
}
web_test.go
package study_package
import (
"net/http"
"testing"
)
func TestPool(t *testing.T) {
type args struct {
w http.ResponseWriter
r *http.Request
}
tests := []struct {
name string
args args
}{
{
"base", args{
w: nil,
r: nil,
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 创建连接池
ConnectionPool()
http.HandleFunc("/pool", Pool)
http.HandleFunc("/getDbStats", getDbStats)
// 创建 Listen Socket, 监听 9090 端口
err := http.ListenAndServe(":9090", nil)
if err == nil {
log.Fatal(" ListenAndServe:", err)
}
})
}
}
Resumir
Somente dominando a configuração dos parâmetros relacionados à função do próprio Go e entendendo a configuração do mysql você poderá se tornar mais proficiente no uso da função do pool de conexões do Go, garantindo assim a robustez do serviço.
Claro, não podemos nos concentrar apenas no nível do código, mas também precisamos entender os indicadores de hardware, como memória, leitura e gravação de E/S, CPU, etc. intervir no apoio, afinal, nossos negócios diários e pessoais como Tudo o que foi mencionado no prefácio podem ser devidamente resolvidos.