Recently tried a little etcd to do the registration discovery of the service
"Etcd Service"
Download the binary file from Etcd's official website and allocate three machines to do the cluster
10.0.1.98 etcd-001
10.0.1.205 etcd-002
10.0.1.182 etcd-003
Then start the service with a script
Etcd--name etcd-002--initial-advertise-peer-urls http://10.0.1.205:2380--listen-peer-urls http://10.0.1.205:2380- -listen-client-urls http://10.0.1.205:2379,http://127.0.0.1:2379--advertise-client-urls http://10.0.1.205:2379-- Initial-cluster-token Etcd-cluster--initial-cluster etcd-001=http://10.0.1.98:2380,etcd-002=http:// 10.0.1.205:2380,etcd-003=http://10.0.1.182:2380--initial-cluster-state New
Etcd--name etcd-001--initial-advertise-peer-urls http://10.0.1.98:2380--listen-peer-urls-- Listen-client-urls http://10.0.1.98:2379,http://127.0.0.1:2379--advertise-client-urls http://10.0.1.98:2379-- Initial-cluster-token Etcd-cluster--initial-cluster etcd-001=http://10.0.1.98:2380,etcd-002=http:// 10.0.1.205:2380,etcd-003=http://10.0.1.182:2380--initial-cluster-state New
Etcd--name etcd-003--initial-advertise-peer-urls http://10.0.1.182:2380--listen-peer-urls http://10.0.1.182:2380- -listen-client-urls http://10.0.1.182:2379,http://127.0.0.1:2379--advertise-client-urls http://10.0.1.182:2379-- Initial-cluster-token Etcd-cluster--initial-cluster etcd-001=http://10.0.1.98:2380,etcd-002=http:// 10.0.1.205:2380,etcd-003=http://10.0.1.182:2380--initial-cluster-state New
Can.
"Service Publishing"
Unlike ZK, ETCD has no temporary nodes of his own and needs to be implemented by the client itself. The approximate logic of implementation is this:
Set up a period of time to timeout the node, such as 60 seconds timeout, if the timeout on the ETCD can not find this node,
The client then refreshes the node timeout at a smaller interval, such as refreshing every 40 seconds, and setting the TTL back to 60 seconds. This can ensure that as long as the service nodes on the ETCD must exist, when the service is turned off, the node has disappeared for a while.
Of course, if you can detect a service shutdown send a del to ETCD active delete node is more perfect.
adding dependencies in Maven
<dependency>
<groupId>org.mousio</groupId>
<artifactid>etcd4j</artifactid >
<version>2.13.0</version>
</dependency>
Take spring boot as an example
Package COM.SEEPLANT.ETCD;
Import java.io.IOException;
Import Java.net.URI;
Import java.util.concurrent.TimeoutException;
Import Org.springframework.context.annotation.Scope;
Import org.springframework.stereotype.Component;
Import Com.seeplant.util.Property;
Import Com.seeplant.util.ServerLogger;
Import mousio.client.retry.RetryOnce;
Import mousio.etcd4j.EtcdClient;
Import mousio.etcd4j.promises.EtcdResponsePromise;
Import mousio.etcd4j.responses.EtcdAuthenticationException;
Import mousio.etcd4j.responses.EtcdException;
Import Mousio.etcd4j.responses.EtcdKeysResponse;
@Component @Scope ("singleton") public class Etcdutil {private etcdclient client; Private final String ServerName = Property.getproperty ("ServerName");
Custom service name, which I define as Roomserver private final String dirstring = "/roomserverlist"; Private final String ZoneID = Property.getproperty ("Zeonid"); A custom logo that I define as 1 private final String Etcdkey = dirstring + "/" + ZoneID + "/" + serverName; This is the release.Node public etcdutil () {int nodecount = Integer.parseint (Property.getproperty ("Etcdgroupnodecount")); uri[] URIs = new Uri[nodecount]; For clusters, add all cluster node addresses, ETCD's code polls these addresses to publish nodes until successful for (int iter = 0; iter < Nodecount; iter++) {Strin
G urlstring = Property.getproperty ("etcdhost" + new Integer (ITER). toString ());
System.out.println (urlstring);
Uris[iter] = uri.create (urlstring);
Client = new Etcdclient (URIs); Client.setretryhandler (New Retryonce (20)); Retry policy} public void Regist () {//Registration node, placed in the entry of program startup try {//Publish a node with the Put method Etcdresponsepromis E<etcdkeysresponse> p = client. Putdir (Etcdkey + "_" + property.getproperty ("ServerIP") + "_" +
Property.getproperty ("ServerPort"))-TTL. Send (); P.get (); Plus this get () is used to ensure that the settings are complete, and the next step is that get blocks, and the retry policy of the above client determines the blocking mode of new Thread (New Guardetcd ()). Start (); StartA daemon thread periodically refreshes node} catch (Exception e) {//Todo:handle Exception ServerLogger.log ("Etcd Se
RVer not available. ");}}
public void Destory () {try {etcdresponsepromise<etcdkeysresponse> p = Client . Deletedir (Etcdkey + "_" + property.getproperty ("ServerIP") + "_" + Property.getproperty ("
ServerPort ")). Recursive (). Send ();
P.get ();
Client.close (); catch (IOException | etcdexception | etcdauthenticationexception |
TimeoutException e) {//TODO auto-generated catch block E.printstacktrace (); } Private class Guardetcd implements Runnable {@Override public void run () {//T Odo auto-generated Method Stub while (true) {try {thread.sleep (40*1000l)
; Client.refreSH (Etcdkey + "_" + property.getproperty ("ServerIP") + "_" + property.getproperty ("ServerPort"
). Send (); catch (IOException |
Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace ();
}
}
}
}
}
For the spring boot framework, Commandlinerunner can be implemented to complete the active invocation of loading and destruction
Package com.seeplant;
Import Javax.annotation.PreDestroy;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.boot.CommandLineRunner;
Import org.springframework.boot.SpringApplication;
Import org.springframework.boot.autoconfigure.SpringBootApplication;
Import Org.springframework.context.annotation.Bean;
Import Com.seeplant.etcd.EtcdUtil;
Import Com.seeplant.netty.RoomServer;
Import Com.seeplant.util.Property;
Import Io.netty.channel.ChannelFuture;
@SpringBootApplication public class APP implements commandlinerunner{@Autowired private Roomserver roomserver;
@Autowired private Etcdutil Etcdutil;
public static void Main (string[] args) {Springapplication.run (app.class, args); @Bean public Roomserver Roomserver () {return new Roomserver (integer.parseint property.getproperty ("se
Rverport "));
@Override public void Run (String ... args) throws Exception {etcdutil.regist (); Channelfuture FuturE = Roomserver.start ();
Runtime.getruntime (). Addshutdownhook (New Thread () {@Override public void run () {Roomserver.destroy ();
}
});
Future.channel (). Closefuture (). syncuninterruptibly ();
@PreDestroy public void Destory () {etcdutil.destory (); }
}
The above retry strategy is to try to give up once, and also write a retry policy is a wait time linear growth strategy, for reference only
Package COM.SEEPLANT.ETCD;
Import Com.seeplant.util.ServerLogger;
Import mousio.client.ConnectionState;
Import Mousio.client.retry.RetryPolicy;
/**
* Provides a multiplier retry policy for ETCD
* @author Yuantao * * */Public
class Retrydoublepolicy extends Retrypolicy {
private final int timeslot;//step size
private int steptimes = 1;//Multiple public
retrydoublepolicy (int startretryt IME) {
super (startretrytime);
TODO auto-generated constructor stub
this.timeslot = Startretrytime;
}
@Override Public
Boolean shouldretry (ConnectionState connectionstate) {
//TODO auto-generated method stub< C19/>steptimes *= 2;
Connectionstate.msbeforeretry = Steptimes*timeslot; Reset Time
System.out.println ("try" + steptimes);
if (Steptimes > 128) {
ServerLogger.log ("ETCD Connection Failed");
Steptimes = 1;
}
return true;
}
The above is the registration service, for service management, load balancing side, only need to follow http://127.0.0.1:2379/v2/keys/roomServerList/1/this way get can obtain node content. For example, the nodes that my service publishes are returned through get are as follows:
{
"Action": "Get",
"Node": {
"Key": "/ROOMSERVERLIST/1",
"dir": true,
"Nodes": [
{
"Key": "/roomserverlist/1/roomserver0_127.0.0.1_9090",
"dir": true,
"Expiration": "2017-09-04t05:10:21.214199005z",
"TTL": 42,
"Modifiedindex": 202,
"Createdindex": 202
}
],
"Modifiedindex": 36,
"Createdindex": 36
}
}