当其中一个线程(chrome)获得异常时,Uswgi挂起(10 -60秒)

时间:2018-09-06 18:56:26

标签: python multithreading url uwsgi

我有一台服务器,可为约100个客户端提供服务。 我使用sqlite本地数据库存储和检索数据。

代码:

class myThread (threading.Thread):
    def __init__(self, threadID, name, q, q_imme):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
        self.q_imme = q_imme
    def run(self):
        print ("Starting " + self.name)
        worker(self.name, self.q, self.q_imme)
        print ("Exiting " + self.name)


def worker(name, q, q_imme):
    try:
        # Do some chrome-selenium-automation stuff
        while not exitFlag:
            username = None
            donelist = None
            type = 0
            while username is None:
                sleep(1)
                if not q_imme.empty():
                    usernameAndDonelistTuple = q_imme.get(timeout=1)
                    username = usernameAndDonelistTuple[0]
                    type     = usernameAndDonelistTuple[1]
                    donelist = usernameAndDonelistTuple[2]
                elif not q.empty():
                    username = q.get(timeout=1)

            print('{}: start grabbing for {} type: {}'.format(name, username, type))
            time_element_in_dict = {'timestamp': str(datetime.now())}
            if type == 0:  # regular data
                res, data = get_api_info(session, username)

                if res is True:
                    data.update({'status': 'ok'})
                elif res is None:
                    data = {'status': 204}  # No Content
                elif res is False:
                    data = {'status': 503}  # exception

                # TODO: async update database
                data.update(time_element_in_dict)
                userDb[username] = data

                print('{}: done grabbing for {} with status {}'.format(name, username, data['status']))
                if donelist:  # means we need to confirm
                    status = data
                    donelist.put(status)
    except:
        # when we reach here the application hangs!!!, I also manually killed all chrome proceess and it hangs. 

import time
class user_info(Resource):
    def get(self):
        username = request.args.get('username')
        start_time = time.time()
        print('username:{} ~ {}'.format(username, start_time))
        return_data = dict()
        username = username.lower()
        try:
            # first try to grab from database
            #lock.acquire()
            return_data[username] = userDb[username]
            #lock.release()
            print('username: {}'.format(time.time() - start_time))
        except KeyError:
            # grab using chrome
            doneList = doneListsPool.get()
            type = 0
            usernameAndDoneListTuple = (username, type, doneList)
            workQueue_imme.put(usernameAndDoneListTuple)
            #lock.release()
            return_data[username] = doneList.get()  # wait for a thread to finish and confirm
            doneListsPool.put(doneList)  # return doneList back to pool

        return return_data


# threading
exitFlag = 0

# database
userDb = SqliteDict('./usernames.sqlite', encode=json.dumps, decode=json.loads, autocommit=True)

print("1")

threadList = ['1', '2', '3', '4', '5', '6']
NUMBER_OF_THREADS = len(threadList)
NUMBER_OF_PENDING_QUEUES = NUMBER_OF_THREADS*2
queue#lock = threading.#lock()
workQueue = queue.Queue(2000)
workQueue_imme = queue.Queue(100)
threads = []
threadID = 1

# Create new threads
for tName in threadList:
    thread = myThread(threadID, tName, workQueue, workQueue_imme)
    thread.start()
    threads.append(thread)
    threadID += 1
    sleep(5)

# create pool of done lists
doneListsPool = queue.Queue()
for i in range(NUMBER_OF_PENDING_QUEUES):
    doneListsPool.put(queue.Queue())

app = Flask(__name__)
api = Api(app)
api.add_resource(user_info_list, '/userinfolist')  # Route_1
api.add_resource(user_info, '/userinfo')  # Route_2

if __name__ == '__main__':
    app.run(host='0.0.0.0', port='5007')
  • 当甚至有1个工作程序(带线程的“工作程序”功能)无法完成chrome进程,但在此期间没有任何请求得到处理时,也仅需要数据库的请求,我看不到“打印” ('username:{}〜{}'。format(username,start_time))“行打印,直到Chrome重新启动。

  • 本地主机请求也失败

我这样启动服务器:

uwsgi --socket 0.0.0.0:5077 --protocol=http -w wsgi:app --enable-threads --ignore-sigpipe --ignore-write-errors --disable-write-exception --listen 120 --threads 2
  • 我认为当我添加完成列表以确认线程工作器已完成的“ user_info”功能时,这个问题就开始了。

1 个答案:

答案 0 :(得分:0)

您的完成列表会丢失,工作进程中会出现异常。 添加:

        if donelist:  # means we need to confirm
            status = data
            donelist.put(status)

例外。