一個服務正常情況下,應該只會註冊一個節點,但是出於某些原因,需要把多個節點合併爲一個節點,但是不能影響到其它節點的調用,除非去通知服務調用人員,改一下調用接口.但是要把所有調用端都改完,還是得花些時間的…
這裏就是以最小時間成本,合併服務.
spring知識整理之服務發現
這裏以consul爲例,其它服務發現Eureka/k8s的api應該也都是類似的作法
基於 spring cloud /consul服務發現
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
.... 略
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
定義一個類,添加節點的詳細信息
節點id
節點名稱
設置健康檢查地址
等等
除了節點id,其它其它的信息都可以重複
@Component
public class MultipleConsulNode implements CommandLineRunner {
@Autowired
private ConsulDiscoveryProperties properties;
@Autowired
private HeartbeatProperties heartbeatProperties;
@Autowired
private AutoServiceRegistrationProperties autoServiceRegistrationProperties;
@Autowired
ConsulServiceRegistry ConsulServiceRegistry;
@Autowired
AnnotationConfigServletWebServerApplicationContext js_context;
@Autowired(required = false)
private TtlScheduler ttlScheduler;
@Autowired
private ConsulAutoConfiguration consulAutoConfiguration;
@Autowired
private DisposableBeanAdapterSub disposableBeanAdapter;
public static List<Map<String,Object>> regs = new ArrayList<>();
static {
Map<String,Object> rej1 = new HashMap<>();
rej1.put("before","service1");
rej1.put("service_name","service1-micros");
regs.add(rej1);
Map<String,Object> rej2 = new HashMap<>();
rej2.put("before","service2");
rej2.put("service_name","service2-micros");
regs.add(rej2);
}
@Override
public void run(String... args) throws Exception {
registration();
}
private void registration(){
Integer agentPort = Integer.parseInt(properties.getInstanceId().substring(properties.getInstanceId().lastIndexOf("-") + 1));
//構造client
ConsulClient client = consulAutoConfiguration.consulClient(consulAutoConfiguration.consulProperties());
ConsulDiscoveryProperties jsProperties = new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties()));
for(Map<String,Object> bean : regs) {
bean.put("client", client);
BeanUtils.copyProperties(properties, jsProperties);
jsProperties.setServiceName(bean.get("service_name").toString());
jsProperties.setPort(agentPort);
ConsulServiceRegistry consulService = new ConsulServiceRegistry(client, properties, ttlScheduler, heartbeatProperties);
bean.put("consulService", consulService);
//生成節點信息
NewService service = new NewService();
String appName = ConsulAutoRegistration.getAppName(jsProperties, js_context.getEnvironment());
String id = bean.get("before").toString() + ConsulAutoRegistration.getInstanceId(jsProperties, js_context);
service.setId(id);
if (!jsProperties.isPreferAgentAddress()) {
service.setAddress(jsProperties.getHostname());
}
service.setName(ConsulAutoRegistration.normalizeForDns(appName));
service.setTags(ConsulAutoRegistration.createTags(jsProperties));
if (jsProperties.getPort() != null) {
service.setPort(jsProperties.getPort());
// we know the port and can set the check
ConsulAutoRegistration.setCheck(service, autoServiceRegistrationProperties, jsProperties, js_context, heartbeatProperties);
}
ConsulRegistration reg = new ConsulRegistration(service, jsProperties);
bean.put("consulRegistration", reg);
//註冊節點
consulService.register(reg);
}
disposableBeanAdapter.start();
}
}
刪除節點,這裏要做到自動刪除,也要依賴springboot啓動和註銷順序觸發的事件去刪除
@Component
public class DisposableBeanAdapterSub implements SmartLifecycle {
private Logger log = LoggerFactory.getLogger(this.getClass());
private AtomicBoolean running = new AtomicBoolean(false);
@Override
public boolean isAutoStartup() {
return false;
}
@Override
public void stop(Runnable callback) {
callback.run();
if(this.running.compareAndSet(true, false) ) {
//當服務停止時,需要把服務發現列表刪除註銷當前服務
for(Map<String,Object> bean : MultipleConsulNode.regs) {
ConsulServiceRegistry consulService = (ConsulServiceRegistry) bean.get("consulService");
ConsulRegistration consulRegistration = (ConsulRegistration) bean.get("consulRegistration");
consulService.deregister(consulRegistration);
}
}
}
@Override
public void start() {
this.running.compareAndSet(false, true);
}
@Override
public void stop() {
}
@Override
public boolean isRunning() {
//return false;
return this.running.get();
}
@Override
public int getPhase() {
//執行順序在這裏設置,類似aop,filter的執行鏈原理,0=啓動時最先執行,停止最後執行
return 1;
}
}