SpringCloud+Consul 服務注冊與服務發現
1. 服務注冊:
在Spring.factories有一段:
# Discovery Client Configuration
org.springframework.cloud.client.discovery.EnableDiscoveryClient=\
org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration
這是SpringCloud時Consul實現服務注冊的關鍵。
發現有一個ConsulLifecycle的bean注入:
@Bean
@ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
public ConsulLifecycle consulLifecycle(ConsulDiscoveryProperties discoveryProperties,
HeartbeatProperties heartbeatProperties) {
ConsulLifecycle lifecycle = new ConsulLifecycle(consulClient, discoveryProperties, heartbeatProperties);
if (this.ttlScheduler != null) {
lifecycle.setTtlScheduler(this.ttlScheduler);
}
if (this.servletContext != null) {
lifecycle.setServletContext(this.servletContext);
}
if (this.serverProperties != null && this.serverProperties.getPort() != null && this.serverProperties.getPort() > 0) {
// no need to wait for events for this to start since the user has explicitly set the port.
lifecycle.setPort(this.serverProperties.getPort());
}
return lifecycle;
}
ConsulLifecycle繼承自AbstractDiscoveryLifecycle,而AbstractDiscoveryLifecycle實現了ApplicationListener
@Override
@Retryable(interceptor = "consulRetryInterceptor")
public void start() {
super.start();
}
是支持重新注冊的。
//第一個配置
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
tags: dev
instance-id: cosulservice
service-name: app
application:
name: cosulservice
server:
port: 8088
//第二個配置
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
# health-check-path: /health
# health-check-interval: 15s
tags: dev
instance-id: cosulservice2
service-name: app
application:
name: cosulservice
server:
port: 8088
運行兩個應用,注冊,查看consul中相關服務:
app
Tags
dev
Nodes
node-client-v-5-1 172.17.0.8 2 passing
Service 'app' check service:cosulservice2
passing
Serf Health Status serfHealth
passing
node-client-v-5-1 172.17.0.8 2 passing
Service 'app' check service:cosulservice
passing
Serf Health Status serfHealth
注冊兩個服務。服務均為app。至此已經兩個服務已經注冊。
2. 服務發現:
@Bean
@ConditionalOnMissingBean
public ConsulDiscoveryClient consulDiscoveryClient(ConsulLifecycle consulLifecycle,
ConsulDiscoveryProperties discoveryProperties) {
ConsulDiscoveryClient discoveryClient = new ConsulDiscoveryClient(consulClient,
consulLifecycle, discoveryProperties);
discoveryClient.setServerProperties(serverProperties); //null ok
return discoveryClient;
}
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("app");
}
簡單的單元測試:
@Test
public void testServicess() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.get("/services").contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(new ResultHandler() {
@Override
public void handle(MvcResult result) throws Exception {
System.out.println(result.getResponse().getContentAsString());
}
});
}
[{"serviceId":"app","host":"192.168.1.103","port":8088,"secure":false,"metadata":{"dev":"dev"},"uri":"http://192.168.1.103:8088"},{"serviceId":"app","host":"192.168.1.103","port":8080,"secure":false,"metadata":{"dev":"dev"},"uri":"http://192.168.1.103:8080"}]