Simplify `EtcdLocator.Contacts()`

* Replace channels with a `sync.RWMutex`.
* Use a ticker to refresh the contact list.
* Use `rand.Perm()` instead of re-shuffling the list for every `Contacts()` invocation.

@jrconlin, @bbangert r?
I'd feel better if this was a copy op as well just so its clear that the contacts here will never refer to the same underlying array as l.contacts.