2017-06-30 27 views
11

:Bağlantının yeniden kazanılmasıyla çift bağlantı nasıl engellenir? Bu koşullar altında

  1. müşteri ZK ağ bağlantısı kaybeder.
  2. Bir dakika geçer.
  3. İstemci ağ bağlantısını zk'ye döndürür.

    1. istemci ZK ağ bağlantısı kaybeder:

      panic: close of closed channel 
      
      goroutine 2849 [running]: 
      github.com/samuel/go-zookeeper/zk.(*Conn).Close(0xc420795180) 
          github.com/samuel/go-zookeeper/zk/conn.go:253 47 
      github.com/curator-go/curator.(*handleHolder).internalClose(0xc4203058f0, 0xc420302470, 0x0) 
          github.com/curator-go/curator/state.go:136 +0x8d 
      github.com/curator-go/curator.(*handleHolder).closeAndReset(0xc4203058f0, 0xc42587cd00, 0x1e) 
          github.com/curator-go/curator/state.go:122 +0x2f 
      github.com/curator-go/curator.(*connectionState).reset(0xc420302420, 0x1b71d87, 0xf) 
          github.com/curator-go/curator/state.go:234 +0x55 
      github.com/curator-go/curator.(*connectionState).handleExpiredSession(0xc420302420) 
          github.com/curator-go/curator/state.go:351 +0xd9 
      github.com/curator-go/curator.(*connectionState).checkState(0xc420302420, 0xffffff90, 0x0, 0x0, 0xc425ed2600, 0xed0e5250a) 
          github.com/curator-go/curator/state.go:318 +0x9c 
      github.com/curator-go/curator.(*connectionState).process(0xc420302420, 0xc425ed2680) 
          github.com/curator-go/curator/state.go:299 +0x16d 
      created by github.com/curator-go/curator.(*Watchers).Fire 
          github.com/curator-go/curator/watcher.go:64 +0x96 
      

      Bu olayların ayrıntılı dizisidir:

    aşağıdaki panik alıyorum.

  4. Bir dakika geçer.
  5. İstemci ağ bağlantısını zk'ye döndürür. >reset (bc 1 dakika geçtikten sonra) - ->Conn() - ->checkTimeout()
  6. goroutine bir s.ReregisterAll() aramaları closeAndReset()> - ikinci
  7. goroutine B bloke>conn.Close()kolları zk.StateExpired (zk küme bu bc gönderir o 2. sırasında ping yoktu çünkü) bu istemci olarak ölü ele ->reset ->closeAndReset()-conn.Close() zaten bağlantının c.shouldQuit kanalı kapatıldı VE bunun için engelleme çünkü s.zooKeeper.getZookeeperConnection goroutine a ile hiç çağrılmadı çünkü panik neden olur>conn.Close() İkincisi, yeni bir bağlantı yok.

denedim Saf bir çözüm sadece reset bir muteksi kullanmaktır, ama şimdi boş bir dizeye eşit helper.GetConnectionString() alıyorum. Bu kilitlenmeyi önlemenin en iyi yolu nedir ve müşteri kaybettiğinde ve ağ bağlantısını yeniden kazanırken iyi bir duruma geçmeye çalışın mı? Düzeltme, github.com/samuel/go-zookeeper'un zaten kapalı bir bağlantıyı kapatmanıza izin vermeyecek şekilde uygulanıyor mu?

(Ben bu sorunu here bulundum, fakat proje yüzden SO üzerinde soruyorum tartışma açısından eksik gibi görünüyor.)

+3

Bu kitaplıklara aşina değilim, ancak kodu biraz kullantıktan sonra bir sorum var. Zk.Conn'u tamamen silmek ve yeni bir tane aramak için ona ihtiyacınız var mı, yoksa devam etmek ve yeniden bağlanmaya izin vermek için buna ihtiyacınız var mı? Eğer atmak istiyorsanız, sorun muhtemelen 'github.com/curator-go/curator' ile ilgili olabilir, aksi takdirde sorun 'github.com/samuel/go-zookeeper'de bulunmaktadır. Burada gerçekten çok yardımcı olabileceğime emin değilim, ama diğer kütüphaneyle konuşabileceğin bir şey olabilir. – RayfenWindspear

+0

Sanırım işe yarayacaktı. Bu ayrım, bunu çözmek için iyi bir başlangıç ​​noktası olarak bana mantıklı geliyor. – lf215

+2

Bence bu problemi çözmenin kolay bir yolu, bu konu uzun bir süre önce yayınlandığından beri go-zookeeper'ın çatalını yapmaktır. https://github.com/samuel/go-zookeeper/issues/148 – mattn

cevap

0

zk.Conn Bir enum döndüren bir Devlet() yöntemi vardır aşağıdakilerden biridir "Devlet",:

ne devlet goroutine B conn.Close çağırdığında içinde "conn" dır
type State int32 
const (
    StateUnknown   State = -1 
    StateDisconnected  State = 0 
    StateConnecting  State = 1 
    StateAuthFailed  State = 4 
    StateConnectedReadOnly State = 5 
    StateSaslAuthenticated State = 6 
    StateExpired   State = -112 

    StateConnected = State(100) 
    StateHasSession = State(101) 
) 

()?

Mümkün olan bir çözüm, gondut B'ye bir anahtar eklemek olabilir; böylece conn.StateConnecting içinde iseniz conn.Close() öğesini çağırmazsınız.

İlgili konular