Golang sobre a implementação do pool de conexões Mysql

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
Insira a descrição da imagem aqui

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
Insira a descrição da imagem aqui

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.

Acho que você gosta

Origin blog.csdn.net/weixin_43832080/article/details/128901991
Recomendado
Clasificación