Trong các trường hợp sau:Làm thế nào để tránh kết nối kép gần khi lấy lại kết nối?
- Khách hàng mất kết nối mạng với zk.
- Vé một phút.
- Khách hàng lấy lại kết nối mạng với zk.
tôi nhận được sự hoảng loạn sau:
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
Đây là chuỗi chi tiết về sự kiện:
- Các khách hàng mất khả năng kết nối mạng để ZK.
- Vé một phút.
- Khách hàng lấy lại kết nối mạng với zk.
- goroutine A gọi
s.ReregisterAll()
->Conn()
->checkTimeout()
->reset
(bc phút 1 đã trôi qua) ->closeAndReset()
->conn.Close()
mà có thể chặn một giây - goroutine B xử lý
zk.StateExpired
(cụm zk gửi bc này nó coi khách hàng này là đã chết vì nó không ping trong thời gian 2.) ->reset
->closeAndReset()
->conn.Close()
gây hoảng loạn vìconn.Close()
đã đóng kênhc.shouldQuit
của kết nối và không bao giờ được gọi bởi goroutine A vì nó đang chặn thứ hai nên không có kết nối mới.
Một giải pháp ngây thơ tôi đã thử là chỉ sử dụng một mutex trên reset
, nhưng bây giờ tôi nhận được helper.GetConnectionString()
bằng chuỗi rỗng. Cách tốt nhất để tránh tai nạn này là gì và cố gắng để có được một trạng thái tốt khi khách hàng mất và sau đó lấy lại kết nối mạng? Nên sửa chữa được trong thực hiện github.com/samuel/go-zookeeper của không cho phép bạn đóng một kết nối đã đóng?
(Tôi đã nộp vấn đề này here, nhưng dự án dường như được thiếu trong điều kiện của cuộc thảo luận vì vậy tôi đang hỏi về SO.)
Tôi không quen thuộc với các thư viện này, nhưng sau khi đọc mã một chút, tôi có một câu hỏi. Bạn có cần nó để loại bỏ 'zk.Conn' hoàn toàn và quay số mới, hay bạn cần nó để tồn tại và cho phép kết nối lại. Nếu bạn muốn hủy bỏ, sau đó vấn đề của bạn có khả năng với 'github.com/curator-go/curator', khác vấn đề nằm trong' github.com/samuel/go-zookeeper'. Tôi không chắc liệu tôi có thể thực sự giúp đỡ nhiều ở đây hay không, nhưng nó có thể là thứ mà bạn có thể giải quyết với thư viện khác. – RayfenWindspear
Tôi nghĩ rằng một trong hai sẽ làm việc. Sự khác biệt đó có ý nghĩa với tôi như một điểm khởi đầu tốt để giải quyết vấn đề này. – lf215
Tôi nghĩ rằng cách dễ dàng để giải quyết vấn đề này là làm cho ngã ba của đi-zookeeper kể từ khi vấn đề này đã được nộp trong một thời gian dài trước đây. https://github.com/samuel/go-zookeeper/issues/148 – mattn