Pm2,Nginx或Nodejs确实提供了已部署路由的最新版本

时间:2018-10-08 13:42:12

标签: node.js ubuntu nginx fs pm2

今天,我偶然发现了一个内部软件解决方案的大问题,而且我从来没有想过要在这里开张罚单,但是即使在咨询了另一位同事之后,我们也无法弄清楚找出问题所在。

我想这将是关于Nginx,pm2或Nodejs缓存的一个很好的教训,对于那些正在使用这些Applications / Framework开发的人来说,这可能很有趣。

事实:

设置

  • Ubuntu 16.04服务器
  • 从Windows 10计算机通过pm2部署到服务器
  • 该应用程序是用nodejs v8.9.4编写的

实际错误之前的故事

  • 该应用程序在首次部署后工作了大约一个半月,没有任何问题
  • 今天,应用程序显示了错误:TypeError: Path must be a String. Received undefined
  • 要使程序的当前状态进入计算机,我继续使用pm2(s)更新功能来更新应用程序。
  • 该应用程序在更新后再次工作。部署npm install时再次执行,我认为它只是解决了问题。

实际错误

  • 通过进一步的测试,我发现Zip文件的下载功能之一不再起作用。
  • 在我的本地计算机上尝试/测试(使用mocha)相同的路由后,我得出以下解决方案:保存和从中检索文件的位置的路径出了问题。
  • 进行测试以获取应用程序的进一步日志记录无效。
  • 在进入路线的网页时,Nginx,pm2或应用程序似乎在我编辑之前提供了旧的Page。即使服务器上的代码肯定与我计算机上的代码相同。
  • Cognito也不显示/使用新页面。
  • 如示例中所示,在为要保存的zip文件使用不同的其他路径名多次部署之后,我确实确信了这一事实。他总是试图用以下路径查找文件:'/web/l18n/archive.zip'
  • 即使我在Route文件中提供了其他路径,该zip文件也始终保存在“ /web/archive.zip”中

代码

别忘了我已经使用很多代码来解决一些明显的问题。 if请求的两个部分都将存档.zip路径保存到的路径都对Error Message

无效。

var zip = new JSZip()

	const dictionaryName = process.env.dictionaryNames
	const splitDictionaryName = dictionaryName.split(';')

	for (const dictionary of splitDictionaryName) {
		const tempDictionaryPath = path.join(__dirname, '/../../' + process.env.dictionaryFolder + '/dictionary.' + dictionary + '.json')
		const dictionaryContent = fs.readFileSync(tempDictionaryPath, 'utf8')
		zip.file('dictionary.' + dictionary + '.json', dictionaryContent)
	}
	await zip.generateAsync({
		type: 'nodebuffer'
	})
		.then(async function (content) {
			const stateString = process.env.state | 'local'
			let archivePath = ''

			if (stateString === 'staging') {
				archivePath = '/web/l18n/current/afasfsagf.zip'
			} else {
				archivePath = path.join(__dirname, '/../aasdasfgasfgs.zip')
			}

			await fs.writeFile(archivePath, content, function (err) {
				if (err) {
					global.log.info(err)
					res.send({})
				} else {
					res.download(archivePath)
				}
			})
		}).catch(function (err) {
			global.log.err(err)
		})

路由

正在通过上面提供的文件直接加载路线。每隔一条路径,甚至是更高级的文件处理路径都可以正常工作。

const downloadAll = require('./routes/downloadAll.js')

this.http = express() 

this.http.get('/download_all', downloadAll)

车把“请求”

正在访问的是通过新窗口的路线,当在主本地路线上按下按钮时会打开该窗口。

$('button').click(function (event) {
		let buttonId = $(this).attr('id')
		if (buttonId === 'downloadAllDictionaries') {
			var win = window.open('/download_all')
			window.location.reload()
		}
	})

Nginx

server {
listen 80;


server_name ****;
access_log /var/log/nginx/****.access.log;
error_log /var/log/nginx/****.error.log;
# pass the request to the node.js server with the correct headers
# and much more can be added, see nginx config options


location / {
    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://127.0.0.1:7000;
    proxy_set_header Host **********;
    proxy_redirect off;
}

listen 443 ssl; # managed by Certbot

include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


if ($scheme != "https") {
    return 301 https://$host$request_uri;
} # managed by Certbot
}

2 个答案:

答案 0 :(得分:0)

确保nginx没有缓存代理请求。

将这2行添加到代理位置:

location / { add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; expires off; }

答案 1 :(得分:0)

我有这个问题。 我的nodeJS应用程序修改未激活。 许多人认为这是Nginx或浏览器的缓存,但实际上是PM2将所有JS文件加载到内存中,并提供了不错的加速功能,但是当PM2的标准安装文件发生更改时,它不会更新。 / p>

这是解决方法:https://pm2.keymetrics.io/docs/usage/watch-and-restart/

因此,代替使用来启动您的应用程序

pm2启动MyApp.js

pm2启动MyApp.js --watch

在开发阶段,您可以避免这种神秘的缓存现象。