nodejs mysql Hatası: Bağlantı kesildi Sunucu bağlantıyı kapattı


93

mysql düğümünü kullandığımda 12:00 ile 2:00 arasında TCP bağlantısının sunucu tarafından kapatıldığına dair bir hata görüntüleniyor. Bu tam mesaj:

Error: Connection lost: The server closed the connection.
at Protocol.end (/opt/node-v0.10.20-linux-x64/IM/node_modules/mysql/lib/protocol/Protocol.js:73:13)
at Socket.onend (stream.js:79:10)
at Socket.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)

Orada çözüm . Ancak bu şekilde denedikten sonra sorun da ortaya çıkıyor. şimdi nasıl yapacağımı bilmiyorum. Bu problemle karşılaşan var mı?

İşte yazdığım yol, çözümü takip et:

    var handleKFDisconnect = function() {
    kfdb.on('error', function(err) {
        if (!err.fatal) {
            return;
        }
        if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
            console.log("PROTOCOL_CONNECTION_LOST");
            throw err;
        }
        log.error("The database is error:" + err.stack);

        kfdb = mysql.createConnection(kf_config);

        console.log("kfid");

        console.log(kfdb);
        handleKFDisconnect();
    });
   };
   handleKFDisconnect();

Kodunuzda yanlış mesaj olduğuna dikkat edin: if (err.code !== 'PROTOCOL_CONNECTION_LOST') { console.log("PROTOCOL_CONNECTION_LOST"); throw err; }. Sen yürütmek if()Çünkü eğer blok değil PROTOCOL_CONNECTION_LOST ve henüz ileti ... muhtemelen çok kafa karıştırıcı olduğunu hata olduğunu söylüyor.
Alexis Wilke

Yanıtlar:


164

Sunucu bağlantısını kesmek için bu kodu kullanmayı deneyin :

var db_config = {
  host: 'localhost',
    user: 'root',
    password: '',
    database: 'example'
};

var connection;

function handleDisconnect() {
  connection = mysql.createConnection(db_config); // Recreate the connection, since
                                                  // the old one cannot be reused.

  connection.connect(function(err) {              // The server is either down
    if(err) {                                     // or restarting (takes a while sometimes).
      console.log('error when connecting to db:', err);
      setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
    }                                     // to avoid a hot loop, and to allow our node script to
  });                                     // process asynchronous requests in the meantime.
                                          // If you're also serving http, display a 503 error.
  connection.on('error', function(err) {
    console.log('db error', err);
    if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
      handleDisconnect();                         // lost due to either server restart, or a
    } else {                                      // connnection idle timeout (the wait_timeout
      throw err;                                  // server variable configures this)
    }
  });
}

handleDisconnect();

Kodunuzda sonraki kısımları özlüyorum connection = mysql.createConnection(db_config);


tamam, bunu deneyeceğim. ama bu duruma nasıl
benzeyebilirim

1
Sadece bir ipucu: Her şeyin iyi çalıştığından emin olmak için mysql hizmetini yeniden başlatarak yeniden bağlanmayı test ediyorum.
kriskodzi

2
@jackieLin ubuntu sudo hizmetinde mysql hizmetini yeniden başlatarak durumu simüle edebilirsiniz. mysql yeniden başlat
igor

1
Teşekkürler @ user3073745, bu sorun yeniden başlatılarak çözüldü
jackieLin

1
8. *, npm 5.6.0 ve mysql: 5.7 için mükemmel çalışıyor ... Teşekkürler !!
JRichardsz

47

Bu mekanizma için orijinal kullanım durumumu hatırlamıyorum. Bugünlerde, geçerli bir kullanım durumu düşünemiyorum.

İstemciniz bağlantının ne zaman koptuğunu algılayabilmeli ve bağlantıyı yeniden oluşturmanıza izin vermelidir. Program mantığının bir kısmının aynı bağlantı kullanılarak yürütülmesi önemliyse, işlemleri kullanın.

tl; dr; Bu yöntemi kullanmayın.


Pragmatik bir çözüm, MySQL'i bağlantıyı canlı tutmaya zorlamaktır:

setInterval(function () {
    db.query('SELECT 1');
}, 5000);

Bu çözümü bağlantı havuzu ve bağlantı kesme işlemine tercih ediyorum çünkü kodunuzu bağlantı varlığının farkında olacak şekilde yapılandırmanız gerekmez. Her 5 saniyede bir sorgu yapmak, bağlantının canlı kalmasını ve PROTOCOL_CONNECTION_LOSTgerçekleşmemesini sağlar.

Dahası, bu yöntem , yeniden bağlanmak yerine aynı bağlantıyı canlı tutmanızı sağlar . Bu önemli. Betiğinize güvenirseniz LAST_INSERT_ID()ve mysql bağlantınız siz farkında olmadan sıfırlanırsa ne olacağını düşünün.

Ancak, bu yalnızca bağlantı zaman aşımının ( wait_timeoutve interactive_timeout) oluşmamasını sağlar. Diğer tüm senaryolarda beklendiği gibi başarısız olacaktır. Bu nedenle, diğer hataları işlediğinizden emin olun.


1
Merak ediyorum, bu db sorgusunu nereye koyardınız? Nodejs sunucusunun altında değil mi? Tek sorun, bir kullanıcının kimliğini doğrulamak için yalnızca bir kez mysql kullanıyorum ve ardından verilerini, rpg oyunum için geçici bir kullanıcı nesnesinde depoluyorum. Bugün neden bu mysql kapalı hatayı rastgele aldım bilmiyorum, hmm. Ben de bağlantıyı düzgün bir şekilde kapatıyorum vb.
NiCk Newman

1
Veritabanına bağlanmalı ve isteğe bağlı olarak bağlantıyı kesmelisiniz. Bu çözüm, sürekli çalışan ve her zaman veritabanı bağlantısını kullanan hizmetler içindir.
Gajus

1
Kodunuzun açıklanan kalıbı ( gist.github.com/gajus/5bcd3c7ec5ddcaf53893'e benzer bir şey ) izlediği düşünüldüğünde, kulağa pek olası gelmiyor . Bu, binlerce sorudan yalnızca bir veya iki kez meydana geldiyse, bağlantı sorunları, sunucu aşırı yüklenmesi veya bu satırlarda bir şey olduğunu varsayardım.
Gajus

3
Bu muhtemelen şimdiye kadarki en kötü öneriydi! Bağlantının gitmemesi için veritabanını sorgularla birleştirmenizi öneren bir kişi? 100 kişi bunu yaparsa ne olur? veya neden 10 000 değil, Eğer uygulamanız bunu yapmıyorsa, iş parçacığı MYSQL İş Parçacığı Havuzuna döndürülmelidir, böylece zayıf kodunuz kırılmaz! ! Bu inanılmaz, çok şükür ki FB seni baş mimara almadı !!
Patrik Forsberg

2
Bu yaklaşımı önermediğimi yansıtmak için cevabı güncelledim. Uyarılar için teşekkürler Patrik.
Gajus


4

daha iyi çözüm havuzu kullanmaktır - bunu sizin için halledebilirsiniz.

const pool = mysql.createPool({
  host: 'localhost',
  user: '--',
  database: '---',
  password: '----'
});

// ... later
pool.query('select 1 + 1', (err, rows) => { /* */ });

https://github.com/sidorares/node-mysql2/issues/836


Kabul edilen cevap bu olmalıdır. Havuz mekanizmasını kullanmak, bağlantı zaman aşımlarının nasıl ele alınacağına dair tüm karmaşık ayrıntıları gizleyecektir. Ayrıca, node_modules/mysql/Readme.mdMySQL düğüm modülüyle birlikte gelen dosyada nasıl kullanılacağına dair belgeler vardır .
Alexis Wilke

1

Her sorgudaki bağlantıları oluşturmak ve yok etmek karmaşık olabilir, MySQL yerine MariaDB'yi kurmaya karar verdiğimde sunucu geçişinde bazı baş ağrılarım oldu. Etc / my.cnf dosyasındaki bazı nedenlerden dolayı wait_timeout parametresinin varsayılan değeri 10 sn'dir (kalıcılığın uygulanamamasına neden olur). Ardından çözüm 28800'e ayarlandı, yani 8 saat. Pekala, umarım bu "güevonada" ile birine yardım et ... kötü ingilizcem için kusura bakma.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.