javascript - Node.js 上传到 Heroku 时出错,Web 进程在启动后 60 秒内无法绑定(bind)到 $PORT

标签 javascript node.js mongodb express heroku

我正在尝试将基本的node.js 服务器应用程序上传到heroku。在本地主机中它运行得很好。但是,当我将其上传到 Heroku 时,该应用程序无法正常工作。这是我的代码和日志。非常感谢。

var DEFAULT_PORT = process.env.PORT || 8080;
var DEFAULT_HOST = '127.0.0.1'
var SERVER_NAME = 'healthrecords'
var getRequestCounter = 0;
var postRequestCounter = 0;
var putRequestCounter = 0;
var deleteRequestCounter = 0;
var patientArray = [];

var http = require ('http');
var mongoose = require ("mongoose");

var port = process.env.PORT;
var ipaddress = process.env.IP; // TODO: figure out which IP to use for the heroku

// Here we find an appropriate database to connect to, defaulting to
// localhost if we don't find one.  
var uristring = 
  process.env.MONGODB_URI || 
  'mongodb://tekstil:teksdev07@ds151753.mlab.com:51753/mapd713groupproject';
  //'mongodb://localhost/e-health-db';

// Makes connection asynchronously.  Mongoose will queue up database
// operations and release them when the connection is complete.
mongoose.connect(uristring, function (err, res) {
  if (err) { 
    console.log ('ERROR connecting to: ' + uristring + '. ' + err);
  } else {
    console.log ('Successfully connected to: ' + uristring);
  }
});

// This is the schema.  Note the types, validation and trim
// statements.  They enforce useful constraints on the data.
var patientSchema = new mongoose.Schema({
  first_name: String,
  last_name: String, 
  blood_gorup: String, 
  address: String, 
  date_of_birth: String, 
  date_admitted: String, 
  department: String, 
  doctor: String, 
  ailment:String, 
});

// Compiles the schema into a model, opening (or creating, if
// nonexistent) the 'Patients' collection in the MongoDB database
var Patient = mongoose.model('Patient', patientSchema);

var restify = require('restify')
  // Create the restify server
  , server = restify.createServer({ name: SERVER_NAME})

    if (typeof ipaddress === "undefined") {
        //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
        //  allows us to run/test the app locally.
        console.warn('No process.env.IP var, using default: ' + DEFAULT_HOST);
        ipaddress = DEFAULT_HOST;
    };

    if (typeof port === "undefined") {
        console.warn('No process.env.PORT var, using default port: ' + DEFAULT_PORT);
        port = DEFAULT_PORT;
    };


  server.listen(port, ipaddress, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})


  server
    // Allow the use of POST
    .use(restify.plugins.fullResponse())

    // Maps req.body to req.params so there is no switching between them
    .use(restify.plugins.bodyParser())




   // Get all patients in the system
server.get('/patients', function (req, res, next) {
  getRequestCounter++;
  console.log('received GET request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Find every entity within the given collection
  Patient.find({}, function (error, patients) {

    // Return all of the patients in the system
    res.send(patients)
    console.log('Sending response to GET request.');
  })
})

// Get a single patient by its patient id
server.get('/patients/:id', function (req, res, next) {
  getRequestCounter++;
  console.log('received GET request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);
  // Find a single patient by their id within save
  Patient.findOne({ _id: req.params.id }, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    if (patients) {
      // Send the patient if no issues
      res.send(patient)
      console.log('Sending response to GET request.');
    } else {
      // Send 404 header if the patient doesn't exist
      res.send(404)
      console.log("Error occurred in sending Response.");
    }
  })
})

// Create a new patient
server.post('/patients', function (req, res, next) {
  postRequestCounter++;
  console.log('received POST request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Make sure first_name is defined
  if (req.params.first_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('first_name must be supplied'))
  }
  if (req.params.last_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('last_name must be supplied'))
  }
  if (req.params.blood_group === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('blood_group must be supplied'))
  }
  if (req.params.address === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('address must be supplied'))
  }
  if (req.params.date_of_birth === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_of_birth must be supplied'))
  }
  if (req.params.date_admitted === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_admitted must be supplied'))
  }
  if (req.params.department === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('department must be supplied'))
  }
  if (req.params.doctor === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('doctor must be supplied'))
  }
  if (req.params.ailment === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('ailment must be supplied'))
  }
  var newpatient = {
        first_name: req.params.first_name, 
    last_name: req.params.last_name,
    blood_gorup: req.params.blood_gorup,
    address: req.params.address,
    date_of_birth: req.params.date_of_birth,
    date_admitted: req.params.date_admitted,
    department: req.params.department,
    doctor: req.params.doctor,
    ailment:req.params.ailment
    }

  // Create the patient using the persistence engine
  Patient.create( newpatient, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) {
      console.log('Error on creating patient.');
      return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)));
    }

    // Send the patient if no issues
    res.send(201, patient)
    patientArray.push(patient);
    console.log('patient Array: ' + patientArray);

  })
  console.log('Sending response to POST request.');
})

// Update a patient by their id
server.put('/patients/:id', function (req, res, next) {
  putRequestCounter++;
  console.log('received PUT request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Make sure first_name is defined
  if (req.params.first_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('first_name must be supplied'))
  }
  if (req.params.last_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('last_name must be supplied'))
  }
  if (req.params.blood_group === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('blood_group must be supplied'))
  }
  if (req.params.address === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('address must be supplied'))
  }
  if (req.params.date_of_birth === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_of_birth must be supplied'))
  }
  if (req.params.date_admitted === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_admitted must be supplied'))
  }
  if (req.params.department === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('department must be supplied'))
  }
  if (req.params.doctor === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('doctor must be supplied'))
  }
  if (req.params.ailment === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('ailment must be supplied'))
  }

  var newpatient = {
        first_name: req.params.first_name, 
    last_name: req.params.last_name,
    blood_group: req.params.blood_group,
    address: req.params.address,
    date_of_birth: req.params.date_of_birth,
    date_admitted: req.params.date_admitted,
    department: req.params.department,
    doctor: req.params.doctor,
    ailment:req.params.ailment
    }

  // Update the patient with the persistence engine
  Patient.update(newpatient, function (error, patient) {
    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    console.log('Sending response to PUT request.');
    // Send a 200 OK response
    res.send(200)
  })
})

// Delete patient with the given id
server.del('/patients/:id', function (req, res, next) {

  deleteRequestCounter++;
  console.log('received DELETE request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Delete the patient with the persistence engine
  Patient.delete(req.params.id, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    // Send a 200 OK response
    res.send()
    console.log('Sending response to DELETE request.');
  })
})

// Delete all patients in the system
server.del('/patients', function (req, res) {

  deleteRequestCounter++;
  console.log('received DELETE request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Find every entity within the given collection
  Patient.deleteMany({}, function (error) {

    // Return all of the patients in the system
    res.send()
    console.log('Sending response to DELETE request.');
  })
})

我的 PACKAGE.JSON

{
    "name": "patients",
    "version": "1.0.0",
    "description": "REST API - Patients",
     "dependencies": {
       "mongod": "^2.0.0",
     "mongodb": "^3.1.8",
     "mongoose": "^5.3.9",
     "restify": "4.1.1",
     "save": "2.3.0"
 },
 "author": "Oguz Bayral",
 "private": true,
 "main": "index.js",
 "scripts": {
     "start": "node index.js"
 }

}

我还有一个 Procfile,如下所示:

web: node index.js

Heroku 日志如下:

2018-11-14T23:56:12.120061+00:00 heroku[web.1]: State changed from 
 crashed to starting
2018-11-14T23:56:12.000000+00:00 app[api]: Build succeeded
2018-11-14T23:56:14.581822+00:00 heroku[web.1]: Starting process with 
command `node index.js`
2018-11-14T23:56:18.630046+00:00 app[web.1]: No process.env.IP var, 
using default: 127.0.0.1
2018-11-14T23:56:18.658574+00:00 app[web.1]: (node:4) 
DeprecationWarning: current URL string parser is deprecated, and will 
be removed in a future version. To use the new parser, pass option { 
useNewUrlParser: true } to MongoClient.connect.
2018-11-14T23:56:18.678981+00:00 app[web.1]: Server healthrecords 
listening at http://127.0.0.1:35354
2018-11-14T23:56:18.679175+00:00 app[web.1]: Resources:
2018-11-14T23:56:18.679289+00:00 app[web.1]:  /patients
2018-11-14T23:56:18.679422+00:00 app[web.1]:  /patients/:id
2018-11-14T23:56:18.982348+00:00 app[web.1]: Successfully connected to: 
mongodb://tekstil:teksdev07@ds151753.mlab.com:51753/mapd713groupproject
2018-11-14T23:57:15.011331+00:00 heroku[web.1]: Error R10 (Boot 
timeout) -> Web process failed to bind to $PORT within 60 seconds of 
launch
2018-11-14T23:57:15.011331+00:00 heroku[web.1]: Stopping process with 
SIGKILL
2018-11-14T23:57:15.126155+00:00 heroku[web.1]: Process exited with 
status 137
2018-11-14T23:57:15.160113+00:00 heroku[web.1]: State changed from 
starting to crashed
2018-11-14T23:57:17.940918+00:00 heroku[router]: at=error code=H10 
desc="App crashed" method=GET path="/" host=mapd713prjct.herokuapp.com 
request_id=bfd7440d-f39b-4823-947f-41fe01b740f2 fwd="199.212.27.182" 
dyno= connect= service= status=503 bytes= protocol=https
2018-11-14T23:57:19.963685+00:00 heroku[router]: at=error code=H10 
desc="App crashed" method=GET path="/favicon.ico" 
host=mapd713prjct.herokuapp.com request_id=67de28c3-268f-4a8f-9f2e- 
5c09142df654 fwd="199.212.27.182" dyno= connect= service= status=503 
bytes= protocol=https

最佳答案

根据您当前的配置,您将服务器绑定(bind)到本地主机 (127.0.0.1),Heroku 没有说明要绑定(bind)到哪个 IP,因此您只需绑定(bind)到所有可用的网络接口(interface),现在 Heroku 应该能够检测到您的应用程序。

// change
server.listen(port, ipaddress, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})
//to
server.listen(port, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})

关于javascript - Node.js 上传到 Heroku 时出错,Web 进程在启动后 60 秒内无法绑定(bind)到 $PORT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53310679/

相关文章:

javascript - 使用 React 等前端技术在网页中显示嵌入的社交数据

javascript - 在像 Object 这样的 Array 上使用 slice() 方法

node.js - 更新 SQLite 数据库而不重新启动应用程序

mongodb - JasperReports 库和 MongoDB

javascript - 为什么dbs调用后数组变量没有保存-node js

javascript - 服务人员 : How to cache the first (dynamic) page

javascript - 如何创建视频文件的 blob

Node.js 视频流 WEBM Live Feed 到 HTML

javascript - MongoDB:如何安全地存储凭证?

javascript - Ember - 使用 View Click 事件触发 File Input 元素的单击