手写数据库连接池01 基础知识

285 阅读4分钟

C++单例模式

单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

定义一个单例类:

  1. 私有化它的构造函数,以防止外界创建单例类的对象;
  2. 使用类的私有静态指针变量指向类的唯一实例;
  3. 使用一个公有的静态方法获取该实例。

根据静态指针变量的初始化时间,可以分成懒汉式(Lazy Singleton)和饿汉式(Eager Singleton):

懒汉式:

class Singleton
{
private:
	static Singleton* instance;
private:
	Singleton() {};
	~Singleton() {};
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton* getInstance() 
        {
		if(instance == NULL) 
			instance = new Singleton();
		return instance;
	}
};

// init static member
Singleton* Singleton::instance = NULL;

饿汉式:

class Singleton
{
private:
	static Singleton instance;
private:
	Singleton();
	~Singleton();
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton& getInstance() {
		return instance;
	}
}

// initialize defaultly
Singleton Singleton::instance;

MySQL的C/S架构

MySQL是Client/Server 的架构模式,分为服务端和客户端,服务端仅一个,而客户端可以有多个,甚至每个Shell都能算一个单独的客户端,而服务器端设置了默认的最大连接数,一般是151个。我们使用的mysql是命令行客户端程序,而mysqld是服务端程序。

因此,我们的客户端与服务器端是需要连接的,这之间就需要协议啦,包括TCP协议,也包括了适用于本地通信的套接字、共享内存、命名管道等。

而MySQL的每一次连接在服务器端都有一个专门的线程来管理,并且采用的网络IO模型是select/poll,并非epoll(主要是因为 select/poll 可移植性好,很多系统都支持。而且 mysql 的瓶颈不在于网络连接上,对于连接数少,并且连接都很活跃的 mysql 而言,select/poll 是更好的选择。)

因此,我们也可以用mysql这个客户端去连接远程的数据库,采用如下命令:

mysql -h ip地址 数据库名 -u用户名 -p

mysql -h 192.168.12.12 db_name -uusername -p

端口默认是3306.

我们使用上述指令就是在建立一个连接:

image.png

我们边执行指令,边抓包,能发现每一次连接都会进行三次握手,这就形成一个TCP连接。

可想而知,如果我们一次性建立大量的连接,这些连接的握手时间会耗费大量的时间,故我们可以维护一个少量的连接,形成一个连接池,这样就不用频繁的握手去建立连接啦。

连接池

连接池(英语:connection pool)是维护的数据库连接的缓存,以便在将来需要对数据库发出请求时可以重用连接。 连接池用于提高在数据库上执行命令的性能。

对于一个连接池,我们有一些性能参数:

  1. 初始连接量:表示连接池事先会和MySQL Server创建initSize个数的connection连接,当 应用发起MySQL访问时,不用再创建和MySQL Server新的连接,直接从连接池中获取一个可用的连接 就可以,使用完成后,并不去释放connection,而是把当前connection再归还到连接池当中。

  2. 最大连接量:当并发访问MySQL Server的请求增多时,初始连接量已经不够使用了,此 时会根据新的请求数量去创建更多的连接给应用去使用,但是新创建的连接数量上限是maxSize,不能 无限制的创建连接,因为每一个连接都会占用一个socket资源,一般连接池和服务器程序是部署在一台 主机上的,如果连接池占用过多的socket资源,那么服务器就不能接收太多的客户端请求了。当这些连 接使用完成后,再次归还到连接池当中来维护。

  3. 最大空闲时间:当访问MySQL的并发请求多了以后,连接池里面的连接数量会动态 增加,上限是maxSize个,当这些连接用完再次归还到连接池当中。如果在指定的maxIdleTime里面, 这些新增加的连接都没有被再次使用过,那么新增加的这些连接资源就要被回收掉,只需要保持初始连 接量initSize个连接就可以了。

  4. 连接超时时间:当MySQL的并发请求量过大,连接池中的连接数量已经到达 maxSize了,而此时没有空闲的连接可供使用,那么此时应用从连接池获取连接无法成功,它通过阻塞 的方式获取连接的时间如果超过connectionTimeout时间,那么获取连接失败,无法访问数据库。