幹掉QQProtect.exe

本文使用python3搭配windows的定時任務來實現正常使用TIM而不運行QQProtect.exe的功能。之所以沒有用bat是因為bat會彈出黑色命令行窗口,而使用pythonw則不會彈窗,體驗較好。方法參考自知乎如何禁用QPCore service启动项?

#file:killQQP.pyw
#杀死QQProtect.exe:killQQP.pyw 1
#启动TIM时杀死QQProtect.exe:killQQP.pyw 2

import os,time,sys

def killProgress(targetProgress):
    if targetProgress in os.popen('tasklist /FI \"IMAGENAME eq '+targetProgress+'\"').read():
        os.system('TASKKILL /F /IM '+targetProgress)

progressToBeKill = "QQProtect.exe"
progressToBeLaunch = "TIM.exe"
targetProgressFile = 'E:\\\"Program Files (x86)\"\\Tencent\\TIM\Bin\\QQScLauncher.exe' 
  
if str(sys.argv[1]) == "1":
    killProgress(progressToBeKill)
elif str(sys.argv[1]) == "2":
    count = 0
    time.sleep(5)
    os.system(targetProgressFile)
    time.sleep(2)
    while count < 5:
        killProgress(progressToBeKill)
        time.sleep(10)
        count = count + 1
        
else:
    killProgress(progressToBeKill)

然後在開始菜單運行taskschd.msc,新建定時任務。第一個定時任務:常規選項卡勾選“使用最高權限運行”;觸發器選項卡選擇“登錄時”;操作選項卡,程序或腳本填pythonw的位置,比如我的是C:\Users\42\AppData\Local\Programs\Python\Python35\pythonw.exe,添加參數則填寫上面腳本所在位置加參數,如E:\code\killQQP.pyw 1,保存。第二個定時任務:常規選項卡勾選“使用最高權限運行”;觸發器選項卡選擇“發生事件時”,然後日誌選“應用程序”,源填入QPCore,時間ID填入0;操作選項卡,程序或腳本填pythonw的位置,我的還是C:\Users\42\AppData\Local\Programs\Python\Python35\pythonw.exe,添加參數填寫腳本所在位置加參數,如E:\code\killQQP.pyw 2,保存即可。QQ用戶需要修改targetProgressFile為QQ的啟動文件,可以通過在QQ啟動快捷方式上右鍵查看詳情取得。

附:啟動TIM時幹掉QQProtect.exe的定時任務的導出文件killQQP2.xml。

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2018-11-05T11:11:00.0447223</Date>
    <Author>42-PC\42</Author>
  </RegistrationInfo>
  <Triggers>
    <EventTrigger>
      <Enabled>true</Enabled>
      <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Application"&gt;&lt;Select Path="Application"&gt;*[System[Provider[@Name='QPCore'] and EventID=0]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
    </EventTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>42-PC\42</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\Users\42\AppData\Local\Programs\Python\Python35\pythonw.exe</Command>
      <Arguments>E:\code\killQQP.pyw 2</Arguments>
    </Exec>
  </Actions>
</Task>

python查詢aqicn的空氣質量數據

#!/data/data/com.termux/files/usr/bin/python
# -*- coding: utf8 -*-

#aqicn空氣質量 #https://aqicn.org/api/
#v2 同時指定多個監測站,已防止單個站點很久不更新數據
import json,requests,sys,time

#token從https://aqicn.org/data-platform/token/獲取,只需郵箱即可
token = 'YourToken'
#預設為當前IP位置,可自行指定基站,幫助 --help
stationList = ["@5851","@5855","@5860"]

def getAqi(station):    
    aqiUrl = "https://api.waqi.info/feed/"+station+"/?token="+token
    try:
        res = requests.get(aqiUrl)
        a = res.json()
        if a['status']=="ok":            
            if time.time() - a['data']['time']['v'] < 86400:
                return a
            else:
                return {"status":a['data']['city']['name']+"的數據已過期。"}
        else:
            res = requests.get(aqiUrl)
            a = res.json()
            return a
    except:
        return {"status":"net error"}

def searchStation(keyword):
    searchUrl = "https://api.waqi.info/search/?token="+token+"&keyword="+keyword
    try:
        res = requests.get(searchUrl)
        a = res.json()
        res = []
        if a['status']=="ok":
            for s in a['data']:
                resT={}
                resT['uid']=s['uid']
                resT['name']=s['station']['name']
                resT['aqi']=s['aqi']+" ("+s['time']['stime']+")"
                res.append(resT)
            return res
        else:
            return a
    except:
        return {"status":"net error"}
def processAqi(aqiJson):
    s=aqiJson
#     print(json.dumps(s, indent=4))
    res={}
    if s['status']=="ok":
        res['cityName']=s['data']['city']['name']
        res['time']=s['data']['time']['s']
        res['aqi']=s['data']['aqi']
        try:
            res['pm25']=s['data']['iaqi']['pm25']['v']
        except:
            res['pm25']="N/A"
        try:
            res['pm10']=s['data']['iaqi']['pm10']['v']
        except:
            res['pm10']="N/A"
        try:
            res['temp']=s['data']['iaqi']['t']['v']
        except:
            res['temp']="N/A"
        try:
            res['humidity']=s['data']['iaqi']['h']['v']
        except:
            res['humidity']="N/A"
        try:
            res['wind']=s['data']['iaqi']['w']['v']
        except:
            res['wind']="N/A"
    else:
        res=s
    return res

def main():
    global station
    if len(sys.argv)==1:
        for station in stationList:
            res = processAqi(getAqi(station))
            print(json.dumps(res, indent=2, ensure_ascii=False))
    elif len(sys.argv)==2:
        station = str(sys.argv[1])
        if station == "--help":
            res={"@5851":"根據觀測點編號查詢","Nanyang":"根據城市名稱查詢",
                 "here":"根據IP查詢","s shenzhen":"查詢深圳觀測點",}
        else:
            res = processAqi(getAqi(station))
        print(json.dumps(res, indent=2, ensure_ascii=False))
    elif len(sys.argv)==3:
        res = searchStation(str(sys.argv[2]))
        print(json.dumps(res, indent=2, ensure_ascii=False))
    
if __name__ == '__main__':
    main()

前天迎來如秋後的第一場中度霧霾。

python守護tomcat

下面腳本實現定時檢測tomcat是否還活着,如果死了就啟動它,如果活太久了(24小時)就殺掉再啟動。

#!/data/pythons/p35/bin/python
# -*- coding: utf8 -*-

#定時任務 /etc/crontab
#*/5 * * * * root (/data/pythons/p36/bin/python /data/pythons/scripts/serviceDeamon.py tomcat-8780)

import psutil,time,datetime,subprocess,sys

def log42(logFile,logText):
    ts = int(time.time())
    dt = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    with open("/tmp/"+dt[0:10]+logFile+".log", "a") as myfile:
        myfile.write(dt+" "+logText+"\n")
        
def startByCmdline(cmdlineKeyword): 
    command = 'export JAVA_HOME=/usr/local/java/jdk1.7.0_71;/bin/sh /data/web/'+cmdlineKeyword+'/bin/startup.sh'
    status,output = subprocess.getstatusoutput(command)
    log42('service'+cmdlineKeyword,"started"+ str(status))
    
def killByCmdline(cmdlineKeyword):    
    alive = False
    for proc in psutil.process_iter():
        try:
            pinfo = proc.as_dict(attrs=['pid', 'name','cmdline','create_time','ppid'])
        except psutil.NoSuchProcess:
            pass
        else:
            if any('/'+cmdlineKeyword in s for s in pinfo['cmdline']):
                alive = True
                aliveTime = time.time()-pinfo['create_time']
                if aliveTime > 60*60*24:        
                    log42('service'+cmdlineKeyword,"old enough "+str(aliveTime/60))
                    p = psutil.Process(pinfo['pid'])
                    p.kill()
                    time.sleep(3)
                    startByCmdline(cmdlineKeyword)
                else:
                    log42('service'+cmdlineKeyword,"too young "+str(aliveTime/60))
            else:
                pass
            
    if not alive :
        log42('service'+cmdlineKeyword,"died")
        startByCmdline(cmdlineKeyword)
                
if __name__ == '__main__':
    #'tomcat-8780'
    if str(sys.argv[1]).__contains__('tomcat') :
        killByCmdline(str(sys.argv[1]))
    else:
        log42('service',"wrong param")
        print('param like:tomcat-8780')

在win平台處理自定義協議

在IOS上,Safari可以通過網頁跳轉到snssdk141://detail?id=123456789拉起指定應用並展示內容,但是Safari並不顯示此鏈接。通過添加註冊表和Python可以實現在PC上獲取到這個自定義的協議鏈接。

首先添加註冊表來監聽這種協議,保存下面文本為p.reg運行即可導入:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\snssdk141]
@="\"URL:My Protocol\""
"URL Protocol"=""

[HKEY_CLASSES_ROOT\snssdk141\shell]

[HKEY_CLASSES_ROOT\snssdk141\shell\open]

[HKEY_CLASSES_ROOT\snssdk141\shell\open\command]
@="\"C:\\Users\\42\\AppData\\Local\\Programs\\Python\\Python35\\python.exe\" \"F:\\scripts\\tt.py\" %1"


然後新建F:\\scripts\tt.py內容如下,把鏈接複製到剪切版:

###!C:\Users\42\AppData\Local\Programs\Python\Python35
# coding:utf-8
#snssdk141://detail/?id=123456789
import sys,pyperclip

if __name__ == '__main__':    
    if str(sys.argv[1]) :
        pyperclip.copy(sys.argv[1])
    else:
        pyperclip.copy('fail')

在火狐打開會自動跳轉的網頁,就會彈出選擇框,選擇python運行後就在剪切板里獲取到了snssdk141://detail/?id=123456789。

彎路:火狐並不能添加處理自定義協議的設置。Chrome 58版本在網絡面板可以看到snssdk141://detail/?id=123456789這個鏈接,但是新版Chrome、Chronium和Firefox ESR均無法顯示出網頁中試圖訪問自定義鏈接的請求。requests的作者新開發了個工具叫requests-html,可以支持js和用chrome渲染頁面,及跟蹤網頁跳轉,但是文檔似乎還不完整。

參考:Launching applications using custom browser protocols

時間比較




網頁版使用了moment.js。家裡的菲利普電飯鍋的預約功能需要輸入幾個小時後做好飯,而不是幾點幾分做好飯,每次都要扳着指頭數距離明天早上7點還有幾個小時。下面還有一個python版,可以放到termux里跑:

#!/data/data/com.termux/files/usr/bin/python
# -*- coding: utf8 -*-

#時間比較
import sys,datetime

#str轉換成datetime
def strTodaTime(s):
    if len(s)==19:
        return datetime.datetime(int(s[0:4]),int(s[5:7]),int(s[8:10]),
                                      int(s[11:13]),int(s[14:16]),int(s[17:19]))
    else:
        print("格式錯誤,--help查看幫助。")
        
#計算時間
def showTimeDuration(dtStr2='',dtStr1=''):
    if dtStr1 == '':
        datetime1 = datetime.datetime.now()
    else:
        datetime1 = strTodaTime(dtStr1)
    
    if dtStr2 == '':
        date2 = datetime.date.today() + datetime.timedelta(days=1)    
        time2 = datetime.time(7, 0)
        datetime2 = datetime.datetime.combine(date2, time2)
    else:
        datetime2 = strTodaTime(dtStr2)
        
    print(datetime2 - datetime1)

if __name__ == '__main__':
    if len(sys.argv) == 3 :
        showTimeDuration(sys.argv[1],sys.argv[2])
    elif len(sys.argv) == 2 :
        if sys.argv[1]=='--help':
            print('參數1默認是第二天早上七點,如2017-11-16T07:00:00。\n參數2默認是當前時間,格式同參數一。')
        else:
            showTimeDuration(sys.argv[1])
    else:
        showTimeDuration()

使用xtrabackup備份mysql數據庫

本文主要記錄下使用percona xtrabackup 2.4來備份mysql數據。最終效果是實現mysql所在主機定時進行全量備份和增量備份並自動刪除舊備份文件。另有一台數據存儲機,定時通過ssh抓取各個mysql主機上的備份文件,保存更長時間後刪除舊文件。

用到的軟件和技術有:xtrabackup(免費的mysql備份程序),qpress(xtrabackup壓縮需要的依賴,據說壓縮比很高),python3.5(ssh的遠程抓取,因為我不會bash)。

mkdir -p /root/42/script
cd /root/42/script
#安裝qpress
wget http://www.quicklz.com/qpress-11-linux-x64.tar
tar xf qpress-11-linux-x64.tar
mv qpress /usr/local/bin/
#centos6安裝xtrabackup
yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
yum install libev -y
yum install percona-xtrabackup-24 -y
#新建backup.sh(來源未知)內容如下:
#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
 
BACKUP_BASE_DIR="/data/backup/xtrabackup"
INC_BASE_LIST="${BACKUP_BASE_DIR}/inc_list.txt"
XTRABACKUP_PATH="/usr/bin/innobackupex"
 
MYSQL_CNF="/etc/my.cnf"
MYSQL_HOSTNAME=127.0.0.1
MYSQL_USERNAME=root
MYSQL_PASSWORD=""
 
LOCK_FILE="/tmp/innobackupex.lock"
THREAD=3
 
mkdir -p ${BACKUP_BASE_DIR}
CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M)"
[[ -d ${CURRENT_BACKUP_PATH} ]] && CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M-%S)"
 
print_help(){
    echo "--------------------------------------------------------------"
    echo "Usage: $0 full | inc | help               "
    echo "--------------------------------------------------------------"
    exit 1
}
 
[[ $# -lt 1 || "$1" == "help" ]] && print_help
 
[[ -f "$LOCK_FILE" ]] && echo -e "Usage: rm -f $LOCK_FILE\nUsage: chattr -i $LOCK_FILE && rm -f $LOCK_FILE" && exit 1
 
FullBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    ${XTRABACKUP_PATH} \
    --defaults-file=${MYSQL_CNF} \
    --user=${MYSQL_USERNAME} \
    --password=${MYSQL_PASSWORD} \
    --host=${MYSQL_HOSTNAME} \
    --compress \
    --compress-threads=${THREAD} \
    --parallel=${THREAD} \
    --no-timestamp ${CURRENT_BACKUP_PATH} > ${CURRENT_BACKUP_PATH}_full.log 2>&1
    grep ".*\ completed\ OK\!" ${CURRENT_BACKUP_PATH}_full.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "NULL|${CURRENT_BACKUP_PATH}|full" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}
 
IncBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    PREV_BACKUP_DIR=$(sed '/^$/d' ${INC_BASE_LIST} | tail -1 | awk -F '|' '{print $2}')
    ${XTRABACKUP_PATH} \
    --defaults-file=${MYSQL_CNF} \
    --user=${MYSQL_USERNAME} \
    --password=${MYSQL_PASSWORD} \
    --host=${MYSQL_HOSTNAME} \
    --compress \
    --compress-threads=${THREAD} \
    --no-timestamp --incremental ${CURRENT_BACKUP_PATH} \
    --incremental-basedir=${PREV_BACKUP_DIR} > ${CURRENT_BACKUP_PATH}_inc.log 2>&1
    grep ".*\ completed\ OK\!" ${CURRENT_BACKUP_PATH}_inc.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "${PREV_BACKUP_DIR}|${CURRENT_BACKUP_PATH}|inc" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}
 
## 全量備份
if [ "$1" == "full" ];then
    FullBackup
fi
 
## 增量備份
if [ "$1" == "inc" ];then
    ## 若全量備份不存在,則執行全量備份
    if [[ ! -f ${INC_BASE_LIST} || $(sed '/^$/d' ${INC_BASE_LIST} | wc -l) -eq 0 ]];then
        FullBackup
    else
        IncBackup
    fi
fi
 
## 刪除22天前的備份
if [[ -d ${BACKUP_BASE_DIR} && $(pwd) != "/" ]];then
    find ${BACKUP_BASE_DIR} -name "$(date -d '22 days ago' +'%F')_*" | xargs chattr -i
    find ${BACKUP_BASE_DIR} -name "$(date -d '22 days ago' +'%F')_*" | xargs rm -rf
fi

#可能需要修改backup.sh中的如下參數
BACKUP_BASE_DIR="/data/backup/xtrabackup"
XTRABACKUP_PATH="/usr/bin/innobackupex"
 
MYSQL_CNF="/etc/my.cnf"
MYSQL_HOSTNAME=127.0.0.1
MYSQL_USERNAME=root
MYSQL_PASSWORD=""
#給腳本添加執行權限
chmod 755 /root/42/script/backup.sh
#执行一次全量备份
/root/42/script/backup.sh full
#如果沒有錯誤信息,就可以看到BACKUP_BASE_DIR下生成了備份文件
#檢查下cron是否啟動
service crond status
#如果未啟動則將cron設置為開機啟動並手動啟動下
chkconfig crond on
service crond start
#添加定時任務
crontab -e
#在底部新增內容
## 每周六凌晨3:30一次全量备份
## 每周二、四、日的凌晨3:30点执行增量备份
30 3 * * 6 /root/42/script/backup.sh full
30 3 * * 2,4,7 /root/42/script/backup.sh inc

Flask簡易搭建

最近用python寫了個小服務,既然都用python寫了,不如順便用python的服務器來運行,簡單搜索後決定用Flask+uwsgi+nginx來實現。virtualenv的安裝就不多說了。

#新建一個python3虛擬環境emailApp
mkdir pythons
cd pythons
virtualenv --python=/usr/local/bin/python3.5 emailApp
source emailApp/bin/activate
#安裝uwsgi和Flask
pip install uwsgi Flask
cd emailApp
#新建emailApp1.py
#!/root/42/pythons/emailApp/bin/python
# -*- coding: utf8 -*-

from flask import Flask,request
import json

app = Flask(__name__)

def getTS():
    TS={}

    nowTS=int(time.time())
    TS['当前时间戳']=str(nowTS)
    localTimeString=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(nowTS)))
    TS['服務器時間']=str(localTimeString)
    gmtTimeString=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(nowTS)))
    TS['GMT時間']=str(gmtTimeString)
    localTSToday=int(time.mktime(time.strptime(localTimeString[:10], '%Y-%m-%d')))
    TS['服務器今天時間戳']=str(localTSToday)
    print('服務器今天時間戳'+str(localTSToday))
    TS['GMT今天時間戳']=str(localTSToday+time.timezone)

    return TS

@app.route('/')
def hello_world():
    return 'Good luck!'

@app.route('/taskCms/service/getTS')
def checkTS():
    TS = getTS()


    return json.dump(TS)
            
if __name__ == '__main__':
#     app.debug = True
#     app.run(host='0.0.0.0',port=8080)
    app.run()
#此時執行
python emailApp1.py
#即可在本地http://127.0.0.1:5000/訪問到服務了。
#Ctrl+C關閉測試,新建nginx站點配置文件emailApp.conf
#nginx站點配置通常在/etc/nginx/conf.d
server {
        listen 8042;
        server_name 127.0.0.1;
        charset utf-8;

        location /  { try_files $uri @yourapplication; }
        location @yourapplication {
                include uwsgi_params;
                uwsgi_pass 127.0.0.1:3031;
        }
}
#測試nginx配置文件是否有誤
nginx -t
#重新加載nginx
nginx -s reload
#此時訪問你的ip加端口號8042,出現502 Bad Gateway則證明nginx已配置好
#若出現訪問超時則可能是有防火牆阻擋
#接下來在項目目錄下新建config.ini作為uwsgi的配置文件
[uwsgi]
socket = 127.0.0.1:3031
chdir = /root/42/pythons/emailApp
master = true
binary-path = /root/42/pythons/emailApp/bin/uwsgi
virtualenv = /root/42/pythons/emailApp
module = emailApp1:app
processes = 2
threads = 4
#使用uwsgi運行Flask程序
/root/42/pythons/emailApp/bin/uwsgi --ini /root/42/pythons/emailApp/config.ini
#如果遇到uwsgi: error while loading shared libraries: libpcre.so.1可嘗試
ln -s /usr/local/lib/libpcre.so.1 /lib64
#正常的話此時應該能通過8042訪問到服務
#開機啟動我使用的centos6自帶的Upstart
nano /etc/init/uwsgi.conf
# simple uWSGI script

description "uwsgi tiny instance"
start on runlevel [2345]
stop on runlevel [06]

respawn

exec /root/42/pythons/emailApp/bin/uwsgi --ini /root/42/pythons/emailApp/config.ini

最後可以通過screen執行uwsgi,然後退出服務器。這樣就完成了一個簡單Flask項目的搭建。Flask就是簡單快速。

如果是通過Upstart自動啟動的,可以通過initctl reload uwsgi和initctl restart uwsgi來重啟uwsgi。


Connection reset by peer鏈接被中斷

過了幾天發現接口不穩定,有時能正常返回數據,有時出現Connection reset by peer鏈接被中斷。從firebug里看發現數據返回有時是先返回個0,就是什麼也沒有然後真是數據才回來,這是瀏覽器已經報錯了。此時可嘗試在uwsgi配置中增加buffer-size=65535和post-buffering = 1。以及在nginx的conf中設置

http{
    ...
    keepalive_timeout  0;

    uwsgi_read_timeout 86400;
    uwsgi_send_timeout 86400;
    ....

}