Beispiel #1
0
    def insert_song_info(self, ):

        logging.info(u'%s process runing pid:%s' %
                     (sys._getframe().f_code.co_name, os.getpid()))
        print u'%s process runing pid:%s' % (sys._getframe().f_code.co_name,
                                             os.getpid())

        while True:

            try:
                d = self.song_info_queue.get(block=True, timeout=30)
                msi = Multi_Song_Info(d['ids'], d['refer'], self.mysql)
                self.thread_pool.submit(msi.insert_song)
                logging.info(
                    u'%s start new threading, get song ids=%s,threading name is:%s,pid is:%s'
                    % (sys._getframe().f_code.co_name, d['ids'],
                       threading.current_thread().name, os.getpid()))

            except Exception, e:
                if str(e):
                    e = str(e)
                else:  ##queue raise error e , str(e)为空
                    e = 'queue empty'
                logging.warn(
                    u' function %s raise  error cause by %s,traceback info is:%s '
                    % (sys._getframe().f_code.co_name, e,
                       traceback.format_exc()))
                print e
                break
def test():##用于测试网络环境

    info=u'runing %s to test avg_time'%(sys._getframe().f_code.co_name)
    print info
    logging.info(info)
    multiple=g_multiple
    count=0
    t1=time.time()
    results=[]
    times=[]

    while True:

        logging.info(u'wait 100 second try to get element from queue')
        d=song_info_queue.get(timeout=100)
        logging.info(u'get %s from queue'%d)
        msi=Multi_Song_Info(song_ids=d['ids'],refer=d['refer'])
        result=pool.submit(msi.insert_song)##
        # song_info_queue.put(d)## 不需要放回去了,因为已经更新了!!
        results.append(result)
        logging.info(u'%s start new threading, get song ids=%s,threading name is:%s,pid is:%s'%(sys._getframe().f_code.co_name,d['ids'],threading.current_thread().name,os.getpid()))
        count+=1
        if count>=max_pool*multiple:
            print u'generate 60 threading to test avg_time'
            for i in results:
                t=i.result()##该方法是阻塞的
                times.append(t)
            
            t2=time.time()
            print u'test cost time:%s'%(t2-t1)
            # return times,t2-t1
            print u'test finish!'
            return sum(times)/len(times)
def run():
    count = 0
    multiple = 3
    while True:
        try:
            logging.info(u'wait 100 second try to get element from queue')
            d = song_info_queue.get(timeout=100)
            logging.info(u'get %s from queue' % d)
            # mysql=Cloud_Music_MySQL()
            '''
            不使用连接池技术可能会造成mysql连接开销过大,如果对产生的线程数不加限制的话,使用此方法从queue中读取到的数据接近于mysql的max_connections,
            不使用数据库连接池会导致mysql status中thread数暴涨,很快到达瓶颈(网络不好的情况下??)
            '''

            # mysql=Cloud_Music_MySQL_Pool()
            ##使用数据库连接池和不使用目前还没有看出差别

            msi = Multi_Song_Info(song_ids=d['ids'], refer=d['refer'])
            pool.submit(msi.insert_song)  ##
            # mysql.close()
            #不能在此关闭数据库连接,因为主线程非阻塞,子线程数据库相关任务还没有完成,主线程就把数据库连接给关闭了

            logging.info(
                u'%s start new threading, get song ids=%s,threading name is:%s,pid is:%s'
                % (sys._getframe().f_code.co_name, d['ids'],
                   threading.current_thread().name, os.getpid()))
            count += 1
            if count > max_pool * multiple:  ##大于一定值线程数需要等待线程处理,不要回报too many connections。程序线程数大于22,一般在46或是67左右,可能是由于一个线程在
                ##运行结束后没有关闭数据库连接,一定时间内,系统还为其保留数据库连接,导致线程处于闲置状态。(因为其没有任务可以接受)。
                print u'generate 60 threading,so sleep 20 second! current active threading num=%s' % threading.active_count(
                )
                sleeptime = multiple * 6
                time.sleep(sleeptime)
                count = 0
            '''
            系统每创建60个线程就会休息60s,因为线程池的大小为21个,所以同时会运行21个线程,假如每个线程运行时间差不多,每个线程运行时间需要平均3s,
            那么大概9秒的时间,60个线程就会全部运行完毕。所以大概等待9秒左右,能够最大程度的利用系统资源。避免了过多等待时间。
            sleeptime=count最大值/线程池大小*平均每个线程运行时间(sleeptime=60/21*3=9)
            网络环境良好的环境下,数据库线程数很小(宿舍测试max_pool=11,count=22,timesleep=20的情况下,数据库线程数稳定在22)
            网络良好的情况下,sleeptime=30,max_count=60,max_pool=21时,mysql status线程数稳定在30-70左右。(在)
            网络良好的情况下,sleeptime=10,max_count=60,max_pool=21时,mysql status线程数越跑越多。运行5分钟后,线程会跑到500左右
            
            线程平均运行时间最大的影响因素在于网络流畅程度。网络状态良好的话,sleeptime设置20是没问题的。
            如果主线程不sleep的话,创建很多等待的线程,这些线程不能利用到连接池的优势,即一个数据库连接可以被不同的线程利用多次。
            因为数据库连接池中的每一个连接都被等待中的线程占用了。

            '''

        except Exception, e:
            if str(e):
                e = str(e)
            else:  ##queue raise error e , str(e)为空
                e = 'queue empty'

            logging.warn(
                u' function %s raise  error cause by %s,traceback info is:%s '
                % (sys._getframe().f_code.co_name, e, traceback.format_exc()))
            print u'error info is:%s' % e

            if 'many connections' in e:  ##最好使用joinablequeue
                print u'current too many connections,sleep 3 second wait runing connections close'
                song_info_queue.put(d)
                print u'catch too many connections error ,so put d=%s back into queue' % d
                logging.info(
                    u'catch too many connections error ,so put d=%s back into queue'
                    % d)
                ##发生异常在于数据库操作,d的值可以获取到,所以把他重新放回queue中,所以不需要joinablequeue了
                time.sleep(3)
                continue
            else:
                print u'empty queue or other unknown error,so break loop!'
                print u'wait 20 second ensure runing threading done'
                time.sleep(20)
                break
Beispiel #4
0
 def func(d):
     msi = Multi_Song_Info(song_ids=d['ids'], refer=d['refer'])
     return msi.insert_song(
     )  #传递结果,不能传递函数对象,不加括号,表示返回的是函数对象,需要真正调用msi.insert_song需要以func(d=d)()的形式调用
def run():
    '''主函数'''

    avg_time=test()##平均一个线程花费的时间
    logging.info(u'from function test get avg_time=%s'%avg_time)
    print u'from function test get avg_time=%s'%avg_time
    count=0
    start_time=time.time()
    multiple=g_multiple
    
    while True:
        try:
            logging.info(u'max wait 100 second try to get element from queue')
            d=song_info_queue.get(timeout=100)
            logging.info(u'get %s from queue'%d)

            msi=Multi_Song_Info(song_ids=d['ids'],refer=d['refer'])
            pool.submit(msi.insert_song)

            logging.info(u'%s start new threading, get song ids=%s,threading name is:%s,pid is:%s'%(sys._getframe().f_code.co_name,d['ids'],threading.current_thread().name,os.getpid()))
            count+=1

            if count>=max_pool*multiple:
                sleeptime=multiple*avg_time
                print u'generate 60 threading,so sleep %s second! current active threading num=%s'%(sleeptime,threading.active_count())
                time.sleep(sleeptime)
                count=0

                end_time=time.time()
                if end_time - start_time>=600:##每过10十分做一次检测,确保数据库连接数最好介于30到150之间,保证程序稳定运行

                    mysql=Cloud_Music_MySQL()
                    Threads_connected=mysql.show_Threads_connected()
                    mysql.close_connect()

                    if Threads_connected<=30:   ##说明程序运行效率不高,可以适当提高multiple,或是降低avg_time
                        avg_time=test()
                        multiple=multiple+1
                        info=u'程序闲置过多,current Threads_connected=%s,重设avg_time=%s,multiple=%s'%(Threads_connected,avg_time,multiple)
                        print info
                        logging.info(info)


                    elif Threads_connected>=150: ##说明程序负荷过重,可以适当降低multiple,或是提高avg_time
                        avg_time=test()
                        multiple=max(multiple-1,2)##multiple最小为2
                        info=u'程序负荷过重,current Threads_connected=%s,重设avg_time=%s,multiple=%s'%(Threads_connected,avg_time,multiple)
                        print info
                        logging.info(info)

                    else:
                        info=u'程序运行良好,current Threads_connected=%s,保持avg_time=%s,multiple=%s'%(Threads_connected,avg_time,multiple)
                        print info
                        logging.info(info)

                    start_time=time.time()##重设start_time



         

        except Exception,e:              
            if str(e):
                e=str(e)
            else:##queue raise error e , str(e)为空
                e='queue empty'

            logging.warn(u' function %s raise  error cause by %s,traceback info is:%s '%(sys._getframe().f_code.co_name,e,traceback.format_exc()))
            print u'error info is:%s'%e

            if 'many connections' in e:##最好使用joinablequeue,##经过600秒一次的性能检测,很难抛出too many connections 异常了
                print u'current too many connections,sleep 3 second wait runing connections close'
                song_info_queue.put(d)
                print u'catch too many connections error ,so put d=%s back into queue'%d
                logging.info(u'catch too many connections error ,so put d=%s back into queue'%d)

                ##发生异常在于数据库操作,d的值可以获取到,所以把他重新放回queue中,所以不需要joinablequeue了

                mysql=Cloud_Music_MySQL()
                Threads_connected=mysql.show_Threads_connected()
         
                while Threads_connected>=100: 
                    info=u'current Threads_connected is:%s,also too much,so sleep 3 second!'%Threads_connected
                    print info
                    logging.debug(info)
                    time.sleep(3)
                    Threads_connected=mysql.show_Threads_connected()
                mysql.close_connect()
                continue

            elif 'empty' in e:
                print u'empty queue,break loop!'
                print u'wait 20 second ensure runing threading done'
                time.sleep(20)
                break

            else:
                info=u'unexcept error,here is traceback info:%s'%(traceback.format_exc())
                print info
                logging.error(info)
                song_info_queue.put(d)
                print u'catch unexcept error ,so put d=%s back into queue'%d
                break
Beispiel #6
0
def run():

   
    avg_time=test()##平均一个线程花费的时间
    logging.info(u'from function test get avg_time=%s'%avg_time)
    print u'u'from function test get avg_time=%s'%avg_time'
    count=0
    
    while True:
        try:
            logging.info(u'max wait 100 second try to get element from queue')
            d=song_info_queue.get(timeout=100)
            logging.info(u'get %s from queue'%d)

            msi=Multi_Song_Info(song_ids=d['ids'],refer=d['refer'])
            pool.submit(msi.insert_song)

            logging.info(u'%s start new threading, get song ids=%s,threading name is:%s,pid is:%s'%(sys._getframe().f_code.co_name,d['ids'],threading.current_thread().name,os.getpid()))
            count+=1

            if count>=max_pool*multiple:
                sleeptime=multiple*avg_time
                print u'generate 60 threading,so sleep %s second! current active threading num=%s'%(sleeptime,threading.active_count())
                time.sleep(sleeptime)
                count=0
            '''
            系统每创建60个线程就会休息60s,因为线程池的大小为21个,所以同时会运行21个线程,假如每个线程运行时间差不多,每个线程运行时间需要平均3s,
            那么大概9秒的时间,60个线程就会全部运行完毕。所以大概等待9秒左右,能够最大程度的利用系统资源。避免了过多等待时间。
            sleeptime=count最大值/线程池大小*平均每个线程运行时间(sleeptime=60/21*3=9)
            网络环境良好的环境下,数据库线程数很小(宿舍测试max_pool=11,count=22,timesleep=20的情况下,数据库线程数稳定在22)
            网络良好的情况下,sleeptime=30,max_count=60,max_pool=21时,mysql status线程数稳定在30-70左右。(在)
            网络良好的情况下,sleeptime=10,max_count=60,max_pool=21时,mysql status线程数越跑越多。运行5分钟后,线程会跑到500左右
            
            线程平均运行时间最大的影响因素在于网络流畅程度。网络状态良好的话,sleeptime设置20是没问题的。
            如果主线程不sleep的话,创建很多等待的线程,这些线程不能利用到连接池的优势,即一个数据库连接可以被不同的线程利用多次。
            因为数据库连接池中的每一个连接都被等待中的线程占用了。

            '''

        except Exception,e:              
            if str(e):
                e=str(e)
            else:##queue raise error e , str(e)为空
                e='queue empty'

            logging.warn(u' function %s raise  error cause by %s,traceback info is:%s '%(sys._getframe().f_code.co_name,e,traceback.format_exc()))
            print u'error info is:%s'%e

            if 'many connections' in e:##最好使用joinablequeue
                print u'current too many connections,sleep 3 second wait runing connections close'
                song_info_queue.put(d)
                print u'catch too many connections error ,so put d=%s back into queue'%d
                logging.info(u'catch too many connections error ,so put d=%s back into queue'%d)
                ##发生异常在于数据库操作,d的值可以获取到,所以把他重新放回queue中,所以不需要joinablequeue了
                time.sleep(3)

                continue
            else:
                print u'empty queue or other unknown error,so break loop!'
                print u'wait 20 second ensure runing threading done'
                time.sleep(20)
                break