so my app is written in nodejs and am using digitalocean droplet ( 2GB RAM | 1 CPU | 50gb SSD )
所以我的应用程序是用NodeJS编写的,我使用的是DigitalOcean Droplet(2 GB内存|1个CPU|50 GB固态硬盘)
so I am getting the error as mentioned in the title only for one particular GET request. That GET requests processes data and renders a PDF file.
因此,我只针对一个特定的GET请求收到标题中提到的错误。GET请求处理数据并呈现PDF文件。
When i checked the nginx error logs, I see three lines of error throw up each time this URL is hit. Following are the errors
当我检查nginx错误日志时,我看到每次点击这个URL时都会出现三行错误。以下是错误
- upstream prematurely closed connection while reading response header from upstream
- connect() failed (111 connection refused) while connecting to upstream
- no live upstreams while connecting to upstream
So, I started my research on these errors, and as suggested tried a lot of configuration changes in my nginx config file like
所以,我开始研究这些错误,并按照建议在我的nginx配置文件中尝试了很多配置更改,如
- adding increased read timeouts, etc
- adding increased proxy buffering
- disabling gzip
- adding an upstream block and such
This is my first time using nginx. I followed a youtube tutorial to deploy my app on a domain and then add a SSL certificate as well (though have to admit I do understand now the basic concepts of how reverse proxy works and configuring after spending two full days trying to troubleshoot this problem, so I wonder what is it that is causing this issue).
这是我第一次使用ngix。我按照YouTube的教程在一个域上部署了我的应用程序,然后也添加了一个SSL证书(尽管我必须承认,在花了整整两天试图解决这个问题后,我现在确实理解了反向代理如何工作和配置的基本概念,所以我想知道是什么导致了这个问题)。
Before this I had deployed the app on the free tier of heroku and I faced no issue with this GET request on this particular URL.
在此之前,我已经在heroku的免费层上部署了应用程序,并且我在这个特定URL上的GET请求没有遇到任何问题。
Following is my current configuration file. It is at this path
以下是我当前的配置文件。它就在这条路上
/etc/nginx/sites-available/default
upstream localhost:3000 {
zone upstreams 64K;
server 127.0.0.1:3000 max_fails=0 fail_timeout=2s;
keepalive 8;
}
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name digitalawb.in www.digitalawb.in;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:3000/;
proxy_read_timeout 90;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 24 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;
proxy_redirect http://localhost:3000/ https://digitalawb.in/;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/digitalawb.in/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/digitalawb.in/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
if ($host = www.digitalawb.in){
return 301 https://$host$request_uri;
}
if ($host = digitalawb.in){
return 301 https://$host$request_uri;
}
listen 80 default_server;
listen [::]:80 default_server;
server_name digitalawb.in www.digitalawb.in;
return 404;
}
Also following is the content of the nginx.conf file which is at the following location
下面是位于以下位置的nginx.conf文件的内容
/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
#multi_accept on;
}
http {
# Basic Settings
sendfile on;
top_nopush on;
top_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
#SSL settings
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
#Logging settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
#Gzip settings
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+res text/javascript;
#virtual host configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Following are my nodejs code details
以下是我的NodeJS代码详细信息
- Main function
exports.boxSticker = async(req, res, next) => {
try{
let orderId = req.params.orderId
let userId = req.user.id
let order = await Order.findById(orderId).populate('client').exec()
let user = await User.findById(userId)
const doc = new PDFdocument({
autoFirstPage: false
})
if(order.boxDetails.length == 0){
return res.render('error', {message: `No Box Details added. Please add Box Details first before generating AWB`, statusCode: '400'})
}
const canvas = createCanvas()
const context = canvas.getContext('2d')
JsBarcode(canvas, order.awbNumber)
canvas.toBuffer((err, buffer) => {
if(err) next(err)
fsPromises.writeFile(`box_${order.awbNumber}.png`, buffer)
.then(() => {
for(let i = 0; i < order.numberOfBoxes; i++){
doc.addPage()
boxstickergenerate(i, doc, order, user)
}
})
.catch((err) => next(err))
})
res.setHeader('Content-type', 'application/pdf')
res.set({ 'Content-Disposition': `inline; filename=boxsticker_${order.awbNumber}.pdf` })
stream = doc.pipe(res)
doc.end()
stream.on('finish', () => {
fs.unlink(`box_${order.awbNumber}.png`, (err) => {
if(err) next(err)
})
})
}catch(err){
next(err)
}
}
- boxstickergenerate function
exports.boxstickergenerate = (current, doc, order, user) => {
doc.info['Title'] = `boxsticker${order.awbNumber}`
doc
.fillColor('black')
.rect(40, 75, 150, 30).fill()
.lineWidth(1.5)
.moveTo(40, 120)
.lineTo(560, 120).stroke()
doc
.fillColor('white')
.font('Helvetica-Bold')
.fontSize(20)
.text(order.service, 40, 80)
doc.fillColor('black')
.font('Helvetica-Bold')
.fontSize(11)
.text('FROM', 40, 140)
.font('Helvetica')
.text(order.consignor, 40, 155)
.text(`${order.consignorAddress1}, ${order.consignorAddress2}, ${order.consignorCity}, ${order.consignorState}, ${order.consignorPincode}`, 40, 170, {width: 350, align:'left'})
.font('Helvetica-Bold')
.text(order.origin, 40, 215)
.font('Helvetica')
.text(`TEL NO: ${order.consignorContactNumber}`, 40, 230)
.lineWidth(1.5)
.moveTo(40, 260)
.lineTo(560, 260).stroke()
.font('Helvetica-Bold')
.fontSize(16)
.text(`BOX NO ${current + 1}/${order.numberOfBoxes}`, 465, 140, {width: 100, align:'left'})
.rect(440, 160, 115, 30).fill()
.rect(440, 210, 115, 30).fill()
.fillColor('white')
.fontSize(11)
.text(order.client.username, 445, 165)
.text(order.service, 445, 215)
.fillColor('black')
.font('Helvetica-Bold')
.fontSize(16)
.text('TO', 40, 270)
.font('Helvetica')
.text(order.consignee, 40, 290)
.text(`${order.consigneeAddress1}, ${order.consigneeAddress2}, ${order.consigneeCity}, ${order.consigneeState}, ${order.consigneePincode}`, 40, 310, {width: 450, align:'left'})
.font('Helvetica-Bold')
.text(order.destination, 40, 370)
.font('Helvetica')
.text(`TEL NO: ${order.consigneeContactNumber}`, 40, 390)
.lineWidth(1.5)
.moveTo(40, 410)
.lineTo(560, 410).stroke()
.fontSize(14)
.text(`SHIPMENT DATE:`, 40, 430)
.text(moment(order.bookingDate).format(shortDateFormat), 160, 430)
.text(`SHIPMENT WEIGHT: ${order.chargeableWeight}`, 40, 450)
.text(`NO OF BOX: ${order.numberOfBoxes}`, 40, 470)
.text(`WAYBILL NO: ${order.awbNumber}`, 300, 450)
//.image(`box_${order.awbNumber}.png`, 265, 490, {width: 80, align:'center'})
.lineWidth(1.5)
.moveTo(40, 550)
.lineTo(560, 550).stroke()
.text('Office Purpose Only', 230, 570, {width: 150, align:'center'})
//.image(`box_${order.awbNumber}.png`, 265, 590, {width: 80, align:'center'})
.lineWidth(1.5)
.moveTo(40, 650)
.lineTo(560, 650).stroke()
.text(user.username, 230, 670, {width: 150, align:'center'})
}
更多回答
are you using pm2 with --watch? That was actually my issue, all the things around the internet is to increase your timeouts in the Nginx config file, I tried everything, and I didn't realized that the issue was because I was uploading a file, therefore changing a folder in the process, so pm2 will restart my app right before sending the response I was expecting in the front end. I hope this give you an idea.
你把PM2和--Watch一起使用了吗?这实际上是我的问题,互联网上所有的事情都是增加你在Nginx配置文件中的超时,我尝试了所有的方法,但我没有意识到问题是因为我正在上传一个文件,因此在这个过程中更改了一个文件夹,所以PM2会在发送我期待的前端响应之前重新启动我的应用程序。我希望这能给你一个想法。
I don't know if you solved your problem or not but I had the same issue and found a solution that is not the same as above (but it could be this one too).
我不知道你是否解决了你的问题,但我有同样的问题,并找到了一个与上面不同的解决方案(但也可能是这个)。
My problem was coming from the fact that the subdirectory where the file was generated didn't not exist on the new server.
Worked on my local machine since I had created the subdir, I simply created the subdirectory in the correct path that was needed to create the file and it worked like a charm afterwards.
我的问题是来自这样一个事实,即生成文件的服务器在新服务器上不存在。在我的本地机器上工作,因为我已经创建了子目录,我只是在创建文件所需的正确路径中创建了子目录,之后它就像一个魔法一样工作了。
更多回答
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
您的答案可以通过其他支持信息来改进。请编辑以添加更多详细信息,如引用或文档,以便其他人可以确认您的答案是正确的。你可以在帮助中心找到更多关于如何写出好答案的信息。
我是一名优秀的程序员,十分优秀!