科普向
forward
在后端连接数据库的时候,测试时我们一般初始化一个连接对象,把所有的操作都引入这个对象,然后进行数据库的操作。在实际生产时这样有一个问题,如果这个连接对象崩掉了,那么服务器就肯定挂掉。或者同时有大量访问请求的时候,可能访问会变慢。而每次访问去生成一个连接对象,处理完之后就close肯定是不现实的,因为会吃服务器资源。所以我们需要一个连接池,用于处理比较复杂的实际情况。这就是我对连接池的初步理解。
socket_pool
以实际代码为例:
一开始先创建10个连接对象,放入一个连接池中
1 2 3 4 5 6 7 8 9 10
| def get_conn(): return pymysql.Connect(host='127.0.0.1',user=MyConfig.USERNAME,passwd=MyConfig.PASSWORD,db='ec_forum',charset='utf8') '''pymysql socket pool''' socket_limit = 10 socket_pool = [] socket_update = socket_limit for i in range(socket_limit): socket_pool.append(get_conn())
|
以ID筛选方法为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def id_select(self, ec_id, table='ec_user'): '''select ec_event just by t_id, and extension''' conn = socket_pool.pop() cursor = conn.cursor() err,res = True,() query_name = self.get_query_name(table) sql = "select * from %s where %s=%r;" % (table,query_name,ec_id) try: if cursor.execute(sql) == 1: rs = cursor.fetchone() if bool(rs): err,res = False,rs except BrokenPipeError as e: conn = get_conn() raise e except Exception as e: conn.rollback() raise e finally: cursor.close() socket_pool.append(conn) return err,res
|
从连接池中pop和push连接对象,这样能处理多个用户同时处理的线程问题。当然最好要做个同步锁,我这里没做,因为两个用户如果不小心用到了一个连接对象,也不会造成什么问题。
最后定期更新池中对象的有效性
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def update_conn(): global socket_update socket_update+=1 if socket_update >= socket_limit: socket_update = 0 print("[update pymysql connection.. Pipe %s]"%socket_update) socket_pool[socket_update] = get_conn() global t t = threading.Timer(7200.0, update_conn) t.start() t = threading.Timer(7200.0, update_conn) if not MyConfig.TESTING: t.start()
|