前提:
先安装好ZooKeeper的环境,搭建参考:http://www.cnblogs.com/EasonJim/p/7482961.html
说明:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1MzNzQTO1MzMtkDM4czM1ITOwAzM5AzNxAjMtYzN4cTM08CX5AzNxAjMvwlN3gzNxQzLcd2bsJ2Lc12bj5ycn9Gbi52YucTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
可以再简单的理解为有两方协作,一个是服务提供这,另一个是服务消费者。
搭建实例:
说明:基于Maven的模块工程
父工程POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jsoft.testzookeeper</groupId>
<artifactId>zookeeperdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>ZooKeeperDemo</name>
<description>This is ZookKeeperDemo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.5.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 健康监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- 负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!-- ZK依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- Web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>zookeeperservice</module>
<module>zookeeperclient</module>
</modules>
</project>
服务提供者POM:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jsoft.testzookeeper</groupId>
<artifactId>zookeeperdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.jsoft.testzookeeper</groupId>
<artifactId>zookeeperservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zookeeperservice</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
</dependencies>
</project>
application.properties:
server.port=8800
spring.application.name=/service-zookeeper
spring.cloud.zookeeper.discovery.root=/spring-cloud-service
spring.cloud.zookeeper.connect-string=localhost:2181
说明:定义端口,应用的名称,服务在ZK的路径,ZK的服务器地址,其中ZK的服务器地址可以有多个,用逗号隔开。
HelloController:
服务接口
package com.jsoft.testzookeeper.service.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String sayHello(@RequestParam(name = "name") String name) {
log.info("param:name->{}", name);
return "hello: " + name;
}
}
App:
程序入口
package com.jsoft.testzookeeper.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}
说明:其中要@EnableDiscoveryClient标注为服务发现注解。
服务消费者POM:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jsoft.testzookeeper</groupId>
<artifactId>zookeeperdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.jsoft.testzookeeper</groupId>
<artifactId>zookeeperclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zookeeperclient</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Feign客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
</project>
说明:由于使用了Feign客户端,所以引入Feign依赖。
server.port=8810
spring.application.name=/client-zookeeper
spring.cloud.zookeeper.discovery.register=false
spring.cloud.zookeeper.discovery.root=/spring-cloud-service
spring.cloud.zookeeper.connect-string=localhost:2181
spring.cloud.zookeeper.dependencies.service-zookeeper.required=true
spring.cloud.zookeeper.dependencies.service-zookeeper.path=/service-zookeeper
spring.cloud.zookeeper.dependencies.service-zookeeper.loadBalancerType=ROUND_ROBIN
说明:由于服务提供者的应用名使用了斜杠,所以必须采用依赖关系spring.cloud.zookeeper.dependencies进行别名的选择,注意,使用了这个之后要引入actuator健康监控组件,不然调用时会报错。
package com.jsoft.testzookeeper.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class,args);
}
}
说明:@EnableCircuitBreaker为断路器的支持,@EnableFeignClients为Feign客户端的支持。
Client的实现:
主要有两种,基于RestTemplate和Feign
RestTemplate
package com.jsoft.testzookeeper.client.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class HelloService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "sayHelloFallback")
public String sayHello(String name) {
return restTemplate.getForEntity("http://service-zookeeper/hello?name=" + name, String.class).getBody();
}
private String sayHelloFallback(String name) {
return "service error";
}
}
说明:@HystrixCommand为断路器写法。
Feign
package com.jsoft.testzookeeper.client.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.jsoft.testzookeeper.client.service.fallback.FeignFallback;
@FeignClient(value = "service-zookeeper", fallback = FeignFallback.class)
public interface ServiceFeign {
@RequestMapping(value = "/hello")
String sayHello(@RequestParam(name = "name") String name);
}
说明:fallback为断路器回调。
消费服务:
package com.jsoft.testzookeeper.client.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.jsoft.testzookeeper.client.service.HelloService;
import com.jsoft.testzookeeper.client.service.ServiceFeign;
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@Autowired
private ServiceFeign serviceFeign;
@RequestMapping(value = "hello")
public String hello(@RequestParam String name) {
return helloService.sayHello(name);
}
@RequestMapping(value = "hello2")
public String hello2(@RequestParam String name) {
return serviceFeign.sayHello(name);
}
}
总结:
Spring Cloud在服务发现和注册上其实很多坑,上面展示的只是核心代码,最全的还是参考例子代码进行调试。
Maven示例:
https://github.com/easonjim/spring-cloud-demo/tree/master/ZooKeeper
参考:
http://theseus.iteye.com/blog/2366237
http://www.cnblogs.com/skyblog/p/5133752.html
http://blog.csdn.net/mn960mn/article/details/51803703
http://www.jianshu.com/p/775c363d0fda