色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

Nginx 504 Gateway Time-out的兩種最新解決方案

瀏覽:172日期:2023-03-13 15:37:39
目錄
  • 背景:
  • 問題:
  • 504從哪來:本文的場景下504是nginx返回的。
  • 兩種解決方案
  • 其他問題:
  • 總結(jié)

背景:

Nginx做反向代理,springboot為后端服務(wù)。

問題:

通過瀏覽器向后臺發(fā)起請求夠,由于后臺處理時(shí)間長,出現(xiàn)504 Gateway Time-out,實(shí)際后臺程序依然在執(zhí)行。如何解決?

504從哪來:本文的場景下504是nginx返回的。

nginx配置中控制該超時(shí)時(shí)間的屬性:

Syntax:proxy_read_timeout time;Default:
proxy_read_timeout 60s;
Context:http, server, location

官方地址:Module ngx_http_proxy_module (nginx.org)

官方描述如下:Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.

一個(gè)請求有三方參與:瀏覽器,nginx,后臺服務(wù)器。

504的錯(cuò)誤碼是有nginx返回的。結(jié)合官網(wǎng)的解釋,我們可以得出結(jié)論:

當(dāng)nginx與后臺的鏈接兩次讀取有效數(shù)據(jù)之間超過配置的時(shí)間時(shí),就會產(chǎn)生504超時(shí)。nginx會主動關(guān)閉與后臺服務(wù)器的鏈接。注意是兩次成功讀取的間隔,不是整個(gè)reponse的時(shí)間。

默認(rèn)情況下proxy_read_timeout時(shí)60s。

如果你百度或google,通常解決方式有兩種:提高后臺處理效率增大proxy_read_timeout

增大方法很簡單,proxy_read_timeout  [你期望的時(shí)間]。

But,后臺效率提升總是有極限的。而proxy_read_timeout是固定值。總會有些正常業(yè)務(wù)場景,超過了設(shè)置的timeout值。

兩種解決方案

本人解決的問題:上傳excel文件后,由于文件大小無法預(yù)計(jì),所以后臺處理時(shí)間也無法預(yù)計(jì)。同時(shí)還要支持大文件的上傳。上傳后由后臺解析處理。post請求,返回的是json。

一,關(guān)閉read-timout,可以實(shí)現(xiàn),但是生產(chǎn)環(huán)境下你敢不設(shè)置超時(shí)時(shí)間么?所以不建議。

二,既然nginx只要從reponse成功讀取數(shù)據(jù)兩次的間隔在proxy_read_timeout設(shè)置的時(shí)間內(nèi),就不會超時(shí)。那么我們是不是可以通過持續(xù)的向response中寫入數(shù)據(jù)來保證不超時(shí)呢。

答案是肯定的。

想通了這一點(diǎn),實(shí)現(xiàn)就十分簡單。

1,正常上傳文件。

2,新建一個(gè)線程。持有response的引用,含有標(biāo)志位,滿足條件時(shí)循環(huán)執(zhí)行,程序開始處理數(shù)據(jù)前,啟動線程。

3,線程的功能只有一個(gè),以固定間隔向response中寫入數(shù)據(jù)。使nginx與后臺鏈接不超時(shí)。

4,這里就需要注意,我的方法是返回json,同時(shí)要持續(xù)向response寫入數(shù)據(jù),所以我手動拼裝json字符串。相當(dāng)于在之前返回的json中增加一個(gè)屬性,名稱隨意,我的叫pending,值隨意,非空即可。我是用英文半角的句號" . "。

5,數(shù)據(jù)處理完后,回調(diào)線程的stop方法,終止線程中的循環(huán)。

注意:如有雷同純屬巧合。如果已經(jīng)有大佬講過這種解決方式,請艾特我,我立即刪除本文。

保持線程代碼如下:

#上下文代碼
//獲取鮮橙池executor,具體方式看個(gè)人。不會的直接百度,有很多
response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
ResponseKeeper responseKeeper = new ResponseKeeper(response);
executorService.execute(responseKeeper);
#上下文代碼
 
 
public class ResponseKeeper implements Runnable {
 
/**
* 循環(huán)標(biāo)志:true時(shí)停止循環(huán),終止線程
*/
private boolean done = false;

private HttpServletResponse response;
 
public void stop(){
    done = true;
}
 
public ResponseKeeper(HttpServletResponse response) {
    this.response = response;
}
 
@Override
public void run() {
    try {
response.getWriter().write("{\"pending\":\"");
while(!done){
    response.getWriter().write(".");
    response.getWriter().flush();
    LOGGER.error("flush-{}", System.currentTimeMillis());
    Thread.sleep(1000);
}
response.getWriter().write("\", \"status\": \"0\", \"msg\":\"success\"}");
    } catch (Exception e) {
e.printStackTrace();
    }
}
    }

其他問題:

如果你遇到異常

IllegalStateException – if the getOutputStream method has already been called for this response object

那就說明你的程序中有地方調(diào)用過了,response.getOutputStream();

只需要與已有程序保持一致使用outputStream即可。

即將response.getWriter() 提換成 response.getOutputStream();

原因簡單來講就是這兩個(gè)方法互斥。調(diào)用了一個(gè)就不能調(diào)用另一個(gè)。

總結(jié)

到此這篇關(guān)于Nginx 504 Gateway Time-out的兩種解決方案的文章就介紹到這了,更多相關(guān)Nginx 504 Gateway Time-out內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標(biāo)簽: Nginx
主站蜘蛛池模板: 国产精品亚洲成在人线 | 亚洲三级在线看 | 免费国产成人高清视频网站 | 国产精亚洲视频 | 国产成年女一区二区三区 | 91精品国产免费久久久久久青草 | 午夜欧美精品久久久久久久久 | 在线日韩国产 | 美女大片高清特黄a大片 | 美一级片| 国产欧美网站 | 久草免费手机视频 | 欧美大片一级特黄 | 99视频在线看 | a毛片免费全部播放毛 | 九九热视频在线播放 | 国产精品分类视频分类一区 | 18在线观看国内精品视频 | 国产成人精品一区二区三在线观看 | 亚洲精品美女在线观看 | vr18成人资源| 先锋影音xfyy5566男人资源 | 精品国产不卡一区二区三区 | 免费人成激情视频在线观看冫 | 在线亚洲日产一区二区 | 国产成人在线免费 | 一级不卡毛片免费 | 国产精品视频免费一区二区三区 | 久久精品6| v片免费看 | 久草在线国产 | 日韩在线三级视频 | 国产网站免费 | 国产成人一区二区三中文 | 91青青国产在线观看免费 | 日韩一级影片 | 成人香蕉视频 | 6080伦理久久亚洲精品 | 97国内免费久久久久久久久久 | 大片毛片女女女女女女女 | 亚洲欧美卡通成人制服动漫 |