Introduction
This article describes the use of zookeeper to register services in the spring boot environment. The pseudo-clustered environment of zookeeper was built in the local environment.
This article refers to the book "Architecture Adventure," a lightweight microservices architecture. build zookeeper pseudo-cluster Download and install
After downloading zookeeper related package on official website, unzip to/etc/zookeeper, and copy 3 copies (zookeeper when building a cluster, the official website recommends deploying odd nodes).
Modify Configuration
Rename the conf/zoo_sample.cfg to Zoo.cfg, and change the node 1 to the following configuration, specifically, please Baidu, here is not detailed, because the pseudo-cluster configured here, so the requirements of each port is different.
Note: you need to create a myID file in the path/home/billjiang/zookeeper/zkserver1 directory and write the contents in the file 1
Node 1 configuration
# The number of milliseconds of each tick
ticktime=2000
initlimit=10
synclimit=5
datadir=/home/ Billjiang/zookeeper/zkserver1
clientport=2181
#cluster
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
Node 2 configuration
# The number of milliseconds of each tick
ticktime=2000
initlimit=10
synclimit=5
datadir=/home/ Billjiang/zookeeper/zkserver2
clientport=2182
#cluster
server.1=127.0.0.1:2888:3888
server.2= 127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
Node 3 configuration
# The number of milliseconds of each tick
ticktime=2000
initlimit=10
synclimit=5
datadir=/home/ Billjiang/zookeeper/zkserver3
clientport=2183
#cluster
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
bulk boot cluster shell scripts
In order to start the cluster, you can start with a single boot, or you can write a Shell script batch boot:
zookeeper_start.sh
#!/bin/bash
servers= "ZkServer1 zkServer2 zkServer3" for
SERVER in $SERVERS
do
echo "current" $SERVER "starting ... "
#ssh root@ $SERVER" source/etc/profile;/usr/apps/zookeeper-3.4.9/bin/zkserver.sh start "--------"
sudo/etc/zookeeper/$SERVER/bin/zkserver.sh start
echo $SERVER " Start end--------------------------------------------"Done"
Of course, you can also write a shell script for bulk stop. After executing the volume Start command, the following:
After you start the cluster, you can use the bin/zkcli.sh command to view the Zookeeper node data.
The above completed the construction of zookeeper pseudo-cluster. Service Registration Implementation
To demonstrate the registration process for the service on zookeeper, this article launches a MAVEN project Zookeeper-learn with three module core registered Core Logic Client Client Service 1 CLIENT2 Client Service 2
The Client/client2 project is dependent on the core project. The dependencies are configured in their pom.xml.
<dependency>
<groupId>com.cnpc</groupId>
<artifactId>core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
core code for a core project
Defining the Service Registration interface Serviceregistry
Package com.example.core;
Public interface Serviceregistry {
/**
* Registration Service Information
*
* @param serviceName service name
* @param Serviceaddress Service Address
*
/Void Register (String serviceName, String serviceaddress);
}
Service Registration Implementation Serviceregistryimpl
The service implementation will connect the zookeeper cluster, create the node, and store the invocation address of the service on that node as the value of the node.
Package Com.example.core;
Import org.apache.zookeeper.*;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;
Import org.springframework.stereotype.Component;
Import Java.util.concurrent.CountDownLatch; @Component public class Serviceregistryimpl implements Serviceregistry, watcher {private static Logger Logger = Logge
Rfactory.getlogger (Serviceregistryimpl.class);
private static Countdownlatch latch = new Countdownlatch (1);
Private ZooKeeper ZK;
private static final int session_timeout = 5000; Public Serviceregistryimpl () {} public Serviceregistryimpl (String zkservers) {try {ZK = n
EW ZooKeeper (zkservers, session_timeout, this);
Latch.await ();
Logger.debug ("connected to Zookeeper");
} catch (Exception ex) {logger.error ("Create Zookeeper client Failure", ex);
}} private static final String Registry_path = "/registry"; @Override public void Register (String sErvicename, String serviceaddress) {try {string registrypath = Registry_path; if (Zk.exists (Registrypath, false) = = null) {zk.create (Registrypath, NULL, ZooDefs.Ids.OPEN_ACL_UNSAFE, C
Reatemode.persistent);
Logger.debug ("Create Registry node:{}", Registrypath);
}//Create service node (persistent node) String ServicePath = Registrypath + "/" + serviceName; if (Zk.exists (ServicePath, false) = = null) {zk.create (ServicePath, NULL, ZooDefs.Ids.OPEN_ACL_UNSAFE, Cre
Atemode.persistent);
Logger.debug ("Create service node:{}", ServicePath);
}//Create address node String Addresspath = ServicePath + "/address-"; String Addressnode = zk.create (Addresspath, Serviceaddress.getbytes (), ZooDefs.Ids.OPEN_ACL_UNSAFE,
Createmode.ephemeral_sequential);
Logger.debug ("Create address node:{} = {}", Addressnode, serviceaddress); } catch (Exception e) {logger.error ("Create node Failure", e); }} @Override public void process (Watchedevent watchedevent) {if (watchedevent.getstate () = = EVENT.K
eeperstate.syncconnected) Latch.countdown ();
}
}
Client Registration Service
When the client starts, it registers its service node with the zookeeper cluster.
application.properties Configuration
server.address=127.0.0.1
server.port=8080
registry.servers= 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
Service registration Configuration Registryconfig
This allows the client to read the Appliaction.properties zookeeper configuration
Package com.example.client;
Import Com.example.core.ServiceRegistry;
Import Com.example.core.ServiceRegistryImpl;
Import org.springframework.boot.context.properties.ConfigurationProperties;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties (prefix = "Registry") public
class Registryconfig {
private String servers;
@Bean public
serviceregistry serviceregistry () {
return new Serviceregistryimpl (servers);
}
public void Setservers (String servers) {
this.servers = servers;
}
}
Service interface for testing:TestController
@RestController public
class TestController {
@RequestMapping (name= "HelloService", method = Requestmethod.get,path = "/hello") public
String Hello () {
return "Hello";
}
}
When the project starts, the method that has the value of the name attribute in the annotation is registered in the Zookeeper cluster,
Package com.example.client;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.beans.factory.annotation.Value;
Import Org.springframework.context.ApplicationContext;
Import org.springframework.stereotype.Component;
Import Javax.servlet.ServletContext;
Import javax.servlet.ServletContextEvent;
Import Javax.servlet.ServletContextListener;
Import Com.example.core.ServiceRegistry;
Import Org.springframework.web.context.support.WebApplicationContextUtils;
Import Org.springframework.web.method.HandlerMethod;
Import Org.springframework.web.servlet.mvc.method.RequestMappingInfo;
Import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
Import Java.util.Map; @Component public class Weblistener implements Servletcontextlistener {@Value ("${server.address}") Private Strin
G ServerAddress;
@Value ("${server.port}") private int serverport;
@Autowired public Serviceregistry Serviceregistry; @OvErride public void contextinitialized (Servletcontextevent sce) {ServletContext servletcontext=sce.getservletc
Ontext (); ApplicationContext applicationcontext= Webapplicationcontextutils.getrequiredwebapplicationcontext (
ServletContext);
Requestmappinghandlermapping Mapping=applicationcontext.getbean (Requestmappinghandlermapping.class);
Map<requestmappinginfo,handlermethod> Infomap=mapping.gethandlermethods ();
For (Requestmappinginfo Info:infoMap.keySet ()) {String servicename=info.getname ();
System.out.println ("-----------------" +servicename); if (servicename!=null) {//Registration service Serviceregistry.register (Servicename,string.format ("%s:%d", s
Erveraddress,serverport));
}}} @Override public void contextdestroyed (Servletcontextevent sce) {}}
Also in the CLIENT2 project, the same code, the only difference is Client2 's application.properties server.port=8082
After starting two CLIENT2 projects at the same time, connect to any one of the zookeeper nodes via the bin/zkcli.sh command (because the data between zookeeper is kept in sync). The following information is displayed:
[Zk:localhost:2181 (CONNECTED)] Ls/registry/helloservice
[address-0000000004, address-0000000003]
To view the values of a child node by using get
get/registry/helloservice/address-0000000003
127.0.0.1:8080
czxid = 0x100000026
CTime = Wed 09 18:00:56 CST
mzxid = 0x100000026
mtime = Wed-18:00:56 CST pzxid
=
0x100000026 cversion = 0
dataversion = 0
aclversion = 0
ephemeralowner = 0x15dc5782fe8000d
datalength =
Numchildren = 0
get/registry/helloservice/address-0000000004
127.0.0.1:8081
czxid = 0x100000028
CTime = Wed 09 18:03:05 CST
mzxid = 0x100000028
mtime = Wed-18:03:05 CST pzxid
=
0x100000028 cversion = 0
dataversion = 0
aclversion = 0
ephemeralowner = 0x15dc5782fe8000e
datalength =
Numchildren = 0
Once you have stopped one of the client clients, use the LS command again to display only the address-0000000004
The above code completes the Zookeeper service registration.