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?
Let's drop the RWMutex, and make contacts a pointer to a []string. Then we'll use atomic get/set operations for the pointer, since we can swap the pointer atomically to a new slice when its updated.