2017-06-30 35 views
11

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?

  1. Khách hàng mất kết nối mạng với zk.
  2. Vé một phút.
  3. 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:

  1. Các khách hàng mất khả năng kết nối mạng để ZK.
  2. Vé một phút.
  3. Khách hàng lấy lại kết nối mạng với zk.
  4. 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
  5. 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ênh c.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.)

+3

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

+0

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

+2

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

Trả lời

0

zk.Conn có một phương thức Nhà nước() trả về một enum "Tiểu bang", là một trong những điều sau đây:

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) 
) 

Trạng thái nào là "conn" khi goroutine B gọi conn.Close()?

Một giải pháp có thể là thêm công tắc vào goroutine B, theo đó bạn không gọi conn.Close() nếu bạn đang ở conn.StateConnecting.

Các vấn đề liên quan