在spring cloud体系中,有多种手段实现注册中心,本例中采用zookeeper作为注册中心的角色。服务提供者向zookeeper注册,服务消费者从zookeeper中发现服务提供者的相关信息,从而远程调用服务提供方。
服务提供者
引入相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring cloud与zookeeper的集成主要依赖spring-cloud-starter-zookeeper-discovery模块
定义DTO对象
public class UserDTO { private Long id; private String name; private Date birthday; /* 省略getter,setter方法 */ }
定义服务提供接口
@RestController public class ComputeController { @Autowired private DiscoveryClient client; @RequestMapping(value = "/show", method = {RequestMethod.POST}) @ResponseBody public UserDTO show(@RequestParam(value="id") Long id) { ServiceInstance instance = client.getLocalServiceInstance(); UserDTO dto = new UserDTO(); dto.setId(id); dto.setName("scott"); dto.setBirthday(new Date()); return dto; } }
在show方法中返回了dto对象。
配置文件
application.properties server.port=8080 spring.application.name=server bootstrap.properties spring.cloud.zookeeper.connectString=192.168.179.200:2181 spring.cloud.zookeeper.discovery.instanceHost=127.0.0.1 spring.cloud.zookeeper.discovery.instancePort=${server.port}
启动项目
@SpringBootApplication @EnableDiscoveryClient public class AppStart { public static void main(String[] args) { SpringApplication.run(AppStart.class, args); } }
启动项目后可以在zookeeper中看到新增了/service节点,该节点有一个子节点server
服务消费者
引入与依赖项,这里用feign作为rest调用工具
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</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-hystrix-dashboard</artifactId> </dependency> <!-- 热部署工具 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies>
定义远程调用代理对象
@Component @FeignClient(value="server",fallback=FeignConsumerClientHystrix.class) public interface FeignConsumerClient { @RequestMapping(method = RequestMethod.POST, value = "/show") public String getUser(@RequestParam(value = "id") Long id); }
以POST方式发起远程调用,调用地址根据@FeignClient中value值决定。
通过@FeignClient创建消费端代理对象。value指定服务名,该值与服务提供者的spring.application.name参数值相等,fallback指定异常处理类,异常处理类需实现本接口。
异常处理
@Component public class FeignConsumerClientHystrix implements FeignConsumerClient{ @Override public String getUser(@RequestParam("id") Long id) { return "error"; } }
所实现方法即为异常处理代码
注入代理对象,发起远程调用
@RestController public class ClientController { @Autowired private FeignConsumerClient feignConsumerClient; @RequestMapping(value = "/get", method = RequestMethod.GET) @ResponseBody public String add(@RequestParam(value = "id") Long id) { return feignConsumerClient.getUser(id); } }
配置文件
application.properties server.port=8081 spring.application.name=client #断路器,断路器跳闸后等待多长时间重试 hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=1000 #断路器,请求发出后多长时间超时 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000 #ribbon连接到服务端的超时时间 ribbon.ConnectTimeout=5000 #ribbon连接到服务端后,多长时间没有获取到响应的超时时间 ribbon.ReadTimeout=5000 bootstrap.properties spring.cloud.zookeeper.connectString=192.168.179.200:2181 #不向zookeeper注册 spring.cloud.zookeeper.discovery.register=false
服务消费者启动项目
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableHystrix @EnableHystrixDashboard @EnableCircuitBreaker public class AppStart { public static void main(String[] args) { SpringApplication.run(AppStart.class, args); } }
启动项目后浏览器访问http://127.0.0.1:8081/get?id=xxx,正常情况即可看到由userDTO对象转换得到的json字符串。