0. 前言
- springboot版本:2.1.9.RELEASE
- springcloud版本:Greenwich.SR4
1. 服务实例变更状态
Eureka 整合了 Actuator ,可以通过 Actuator 变更实例在服务端的状态
@Endpoint(id = "service-registry")
public class ServiceRegistryEndpoint {
// ......
@WriteOperation
public ResponseEntity<?> setStatus(String status) {
Assert.notNull(status, "status may not by null");
if (this.registration == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body("no registration found");
}
// 2 变更状态
this.serviceRegistry.setStatus(this.registration, status);
return ResponseEntity.ok().build();
}
@ReadOperation
public ResponseEntity getStatus() {
if (this.registration == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body("no registration found");
}
// 3 获取状态
return ResponseEntity.ok()
.body(this.serviceRegistry.getStatus(this.registration));
}
}
2. 变更状态
// EurekaServiceRegistry.class
public void setStatus(EurekaRegistration registration, String status) {
// 获取实例信息
InstanceInfo info = registration.getApplicationInfoManager().getInfo();
// TODO: howto deal with delete properly?
if ("CANCEL_OVERRIDE".equalsIgnoreCase(status)) {
// 如果变更状态请求传过来 status = "CANCEL_OVERRIDE",向服务端发起 Jersey 删除状态请求
registration.getEurekaClient().cancelOverrideStatus(info);
return;
}
// TODO: howto deal with status types across discovery systems?
InstanceInfo.InstanceStatus newStatus = InstanceInfo.InstanceStatus
.toEnum(status);
// 如果不是删除状态,则向服务端发起 Jersey 变更状态请求
registration.getEurekaClient().setStatus(newStatus, info);
}
3. 获取状态
// EurekaServiceRegistry.class
public Object getStatus(EurekaRegistration registration) {
String appname = registration.getApplicationInfoManager().getInfo().getAppName();
String instanceId = registration.getApplicationInfoManager().getInfo().getId();
// 获取本地实例信息
InstanceInfo info = registration.getEurekaClient().getInstanceInfo(appname,
instanceId);
HashMap<String, Object> status = new HashMap<>();
if (info != null) {
// 从实例信息取出相应状态返回
status.put("status", info.getStatus().toString());
status.put("overriddenStatus", info.getOverriddenStatus().toString());
}
else {
// 如果实例信息不存在,则返回 UNKNOWN 状态
status.put("status", UNKNOWN.toString());
}
return status;
}