curator 实现服务注册与发现
AppInstance 实例
@AllArgsConstructor
@Data
public class AppInstance {
private String address;
private int port;
}
ServerRegistar 服务注册和发现
@Component
public class ServerRegistar {
@Autowired
private CuratorFramework client;
private Map<String, List<AppInstance>> services = new HashMap<>();
@Value(value = "${spring.application.name}")
private String service;
public void register(String address, int port) {
try {
String path = "/services/" + service + "/" + address + ":" + port;
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
System.out.println("服务注册成功,路径为:" + path);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void discover() {
CuratorCache cache = CuratorCache.builder(client, "/services").build();
CuratorCacheListener listener = CuratorCacheListener.builder()
.forTreeCache(client, new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
TreeCacheEvent.Type type = event.getType();
if (event.getData()==null){
return;
}
String path = event.getData().getPath();
System.out.println("事件类型:" + type + ",路径:" + path);
if (StrUtil.isEmpty(path)) {
return;
}
String[] paths = path.split("/");
if (paths.length <= 3){
return;
}
// /services/serviceName/ip:port
if (type == TreeCacheEvent.Type.NODE_ADDED) {
System.out.println("服务发现:" + event.getData().getPath());
String serviceName = paths[2];
String address = paths[3].split(":")[0];
int port = Integer.parseInt(paths[3].split(":")[1]);
AppInstance appInstance = new AppInstance(address, port);
services.computeIfAbsent(serviceName, k -> {
List<AppInstance> appInstances = new ArrayList<>();
return appInstances;
}).add(appInstance);
}else if(type == TreeCacheEvent.Type.NODE_REMOVED){
System.out.println("服务移除:" + event.getData().getPath());
String serviceName = paths[2];
String address = paths[3].split(":")[0];
int port = Integer.parseInt(paths[3].split(":")[1]);
AppInstance appInstance = new AppInstance(address, port);
services.computeIfAbsent(serviceName, k -> {
List<AppInstance> appInstances = new ArrayList<>();
return appInstances;
}).remove(appInstance);
}
}
}).build();
cache.listenable().addListener(listener);
cache.start();
}
public Map<String, List<AppInstance>> getServices() {
return services;
}
}
SeviceRegistrListener 启动监听
在 spring boot 应用启动的时候 去进行服务注册 和 服务发现
@Component
public class SeviceRegistrListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private ServerRegistar serverRegistar;
@Value(value = "${server.port}")
private int port;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
String hostAddress = NetUtil.getLocalhost().getHostAddress();
serverRegistar.register(hostAddress, port);
//发现
serverRegistar.discover();
}
}
ServiceDiscoveryController 服务暴露
@RestController
public class ServiceDiscoveryController {
@Autowired
private ServerRegistar serverRegistar;
@GetMapping("/services")
public Map<String, List<AppInstance>> index() {
return serverRegistar.getServices();
}
}
服务启动
事件类型:NODE_ADDED,路径:/services/boot-curator/172.23.0.1:8081
服务发现:/services/boot-curator/172.23.0.1:8081
事件类型:NODE_REMOVED,路径:/services/boot-curator/172.23.0.1:8081
服务移除:/services/boot-curator/172.23.0.1:8081
事件类型:NODE_ADDED,路径:/services/boot-product
事件类型:NODE_ADDED,路径:/services/boot-product/172.23.0.1:8081
服务发现:/services/boot-product/172.23.0.1:8081
事件类型:NODE_REMOVED,路径:/services/boot-product/172.23.0.1:8081
服务移除:/services/boot-product/172.23.0.1:8081
http://localhost:8080/services
:
{
"boot-product": [
{
"address": "172.23.0.1",
"port": 8081
}
],
"boot-curator": [
{
"address": "172.23.0.1",
"port": 8080
}
]
}