WSGI server - Gunicorn worker調度--timeout問題分析

前一段時間遇到一個問題,gunicorn在啓動以後worker一直報timeout的錯誤,而且一直不斷地重啓。開始覺得是worker內部遇到什麼錯誤才致使gunicorn不斷地重啓worker。
先說一下配置,worker_class咱們採用的是gevent,數據庫鏈接採用的mysql+sqlalchemy。由於在app啓動時須要鏈接不少個數據庫,遇到這個問題就一直在糾結是否是程序的bug,數據庫鏈接太多會有問題,但程序沒有任何日誌打出來啊!?可是將鏈接數據庫的數量改小一點,就不會再出現worker重啓的現象了。爲何數據庫鏈接數變小就不會timeout了呢?是否是master以爲worker的啓動時間太長了,過了必定時間就直接幹掉並重啓?後來將配置中的timeout改大,數據庫鏈接數改成原來的值,問題解決!mysql

爲何會這樣?
看gunicorn源碼:
def run(self):
        servers = []
        ssl_args = {}

        if self.cfg.is_ssl:
            ssl_args = dict(server_side=True, **self.cfg.ssl_options)

        for s in self.sockets:
            s.setblocking(1)
            pool = Pool(self.worker_connections)
            if self.server_class is not None:
                environ = base_environ(self.cfg)
                environ.update({
                    "wsgi.multithread": True,
                    "SERVER_SOFTWARE": VERSION,
                })
                **server = self.server_class(
                    s, application=self.wsgi, spawn=pool, log=self.log,
                    handler_class=self.wsgi_handler, environ=environ,
                    **ssl_args)**
            else:
                hfun = partial(self.handle, s)
                server = StreamServer(s, handle=hfun, spawn=pool, **ssl_args)

            server.start()
            servers.append(server)

        while self.alive:
            **self.notify()**
            gevent.sleep(1.0)

重點在server初始化的過程當中,因爲數據庫鏈接數量過多,這裏耗費時間太久,self.notify在timeout時間內一直沒有執行,致使主進程master在timeout時間事後當即回收並重啓worker進程,因此會致使上面的問題。sql

相關文章
相關標籤/搜索