Catalog

TIPS

This article is based on Spring Cloud Hoxton, theoretical support Spring Cloud All versions .

This article discusses how to customize microservice registration to Consul Of InstanceId.

Consul hold InstanceId As a unique identifier , and Spring Cloud Consul default InstanceId yes ${spring.application.name}-${server.port} .

The problem is : Even if there are multiple instances of a microservice , As long as the ports are the same , that Consul I will keep it 1 Data ! To solve this problem , Just let different instances , Have a different InstanceId that will do .

The way 1: Splice random values

Add the configuration :

1
2
3
4
5
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${random.long}

At present, some articles on the market are also playing like this . But to do so , There is still a little problem in some scenarios .

for instance : Suppose a microservice instance crashes , And then in a very short time (Consul There is no time to delete this instance ); Application rebooted , It will lead to Consul There are two pieces of data , But in fact, it represents an example ( Although after a while ,Consul Will delete useless instances , But over a period of time 2 It's still weird ).

TIPS

${random.long} yes Spring Boot Self contained “ Extended configuration ”, There are a lot of postures . Documents can be found in https://docs.spring.io/spring-boot/docs/2.2.0.M5/reference/html/spring-boot-features.html#boot-features-external-config-random-values

The way 2: Unique identification of splicing machine


Here we are. , Smart students will think of , A reasonable instanceid The following two needs should be met :

  • Different examples of instanceid Different ;
  • The same instance starts more than once ,instanceid It should be the same .

To achieve these two demands , As long as instanceid Add the only mark on the machine OK 了 , such as IP Or host name and so on .

1
2
3
4
5
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${spring.cloud.client.hostname}

perhaps :

1
2
3
4
5
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${spring.cloud.client.ip-address}

TIPS

here ,${spring.cloud.client.hostname} as well as ${spring.cloud.client.ip-address} , It is used. Spring Boot Configuration files can read the characteristics of environment variables .

Your application only needs to integrate Spring Boot Actuator , You can go through /actuator/env Check all environment variables ! Environment variable Key value , Can be written to the configuration file .

The way 3: Code extension

If the above two ways still can not meet your needs , Then you can extend it by writing code .

Code :

1
2
3
4
5
6
7
8
9
10
11
12
13
public class WiiConsulAutoRegistration extends ConsulAutoRegistration {
public WiiConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context, HeartbeatProperties heartbeatProperties, List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers) {
super(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties, managementRegistrationCustomizers);
}

public static String getInstanceId(WiiProperties wiiProperties,
Environment environment) {
return String.format("%s-%s-%s",
environment.getProperty("spring.application.name"),
wiiProperties.getIp(),
wiiProperties.getPort());
}
}

To configure :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class XXXConfiguration {
@Bean
public ConsulAutoRegistration consulRegistration(
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties,
ApplicationContext applicationContext,
ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
HeartbeatProperties heartbeatProperties) {
return WiiConsulAutoRegistration.registration(autoServiceRegistrationProperties,
properties, applicationContext, registrationCustomizers.getIfAvailable(),
managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties);
}
}

TIPS

  • This way is more flexible , Play as you like . You can InstanceId Top splicing mac Address or something …… however , Just to customize a unique logo , Play like this The cost is a little high 了 , I suggest : If there's no hard work to do , Don't bother .
  • My personal project Spring Cloud Wii ( That's what we have now Spring Cloud Alibaba Sidecar) This is the way to customize InstanceId Of . but Wii The reason for this is , Because Wii It's about expanding WiiConsulAutoRegistration , Customize it InstanceId Just by the way . The relevant code is here , If you are interested, you can have a look at : https://github.com/eacdy/spring-cloud-wii/blob/master/spring-cloud-wii/src/main/java/com/itmuch/wii/consul/WiiConsulAutoRegistration.java

future …

In the future, if this Pull Request Be merged , Don't bother …… See :https://github.com/spring-cloud/spring-cloud-consul/pull/570

Related articles