consul客戶端必須配置微服務實例名稱和ID,微服務啟動的時候需要將名稱和ID注冊到注冊中心,后續微服務之間調用也需要用到.
名稱可以通過以下兩種方式配置,優先級從高到低.兩個都不配置則默認服務名稱為application
spring.cloud.consul.discovery.service-name
spring.application.name
ID可以通過多個配置項配置,下面的五種配置都可以,優先級從高到低.
spring.cloud.consul.discovery.instance-id
vcap.application.instance_id
spring.application.name和spring.application.instance_id搭配,'-'分隔
spring.application.name和server.port搭配,'-'分隔
spring.application.name
spring.application.instance_id
如果不配置啟動會報錯,相關日志如下,從日志中也可以看出,配置要求必須以字母開始,字母或數字結尾.
Caused by: java.lang.IllegalArgumentException: Consul service ids must not be empty, must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen: 8081
at org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration.normalizeForDns(ConsulAutoRegistration.java:179) ~[spring-cloud-consul-discovery-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration.getInstanceId(ConsulAutoRegistration.java:170) ~[spring-cloud-consul-discovery-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration.registration(ConsulAutoRegistration.java:78) ~[spring-cloud-consul-discovery-2.0.1.RELEASE.jar:2.0.1.RELEASE]
代碼詳見org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration
public static ConsulAutoRegistration registration(AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context, List<ConsulRegistrationCustomizer> registrationCustomizers, HeartbeatProperties heartbeatProperties) {
NewService service = new NewService();
//注冊到consul服務端時顯示的微服務名稱,優先級從高到低:
//配置項spring.cloud.consul.discovery.service-name
//配置項spring.application.name
//默認值application
String appName = getAppName(properties, context.getEnvironment());
//注冊到consul服務端時顯示的微服務Id,優先級從高到低:
//配置項spring.cloud.consul.discovery.instance-id
//配置項vcap.application.instance_id
//配置項spring.application.name和spring.application.instance_id,用':'拼接
//配置項spring.application.name和server.port,用':'拼接
//配置項spring.application.name
//配置項spring.application.instance_id
//注意,內部的normalizeForDns方法,用於規范化應用名稱、ID等,把非數字字符串轉換成'-'連接符
//比如spring.application.name=sc--test,server.port=8080,拼成的id為sc--test:8080,經過normalizeForDns方法就轉換成了sc-test-8080
service.setId(getInstanceId(properties, context));
if(!properties.isPreferAgentAddress()) {
service.setAddress(properties.getHostname());
}
//微服務應用名稱也必須符合規范,字母開始,字母或數字結尾
service.setName(normalizeForDns(appName));
//設置標簽,spring.cloud.consul.discovery.tags
service.setTags(createTags(properties));
if(properties.getPort() != null) {
service.setPort(properties.getPort());
setCheck(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties);
}
<span class="token class-name">ConsulAutoRegistration</span> registration <span class="token operator">=</span> <span class="token keyword"><span class="hljs-keyword">new</span></span> <span class="token class-name">ConsulAutoRegistration</span><span class="token punctuation">(</span>service<span class="token punctuation">,</span> autoServiceRegistrationProperties<span class="token punctuation">,</span> properties<span class="token punctuation">,</span> context<span class="token punctuation">,</span> heartbeatProperties<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">customize</span><span class="token punctuation">(</span>registrationCustomizers<span class="token punctuation">,</span> registration<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword"><span class="hljs-keyword">return</span></span> registration<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
//字符串不能為空,首字符必須為字母,尾字符必須為字母或數字,所有非字母數字的字符統一轉換成'-'連接符,同時多個連續連接符轉換成一個'-'.
public static String normalizeForDns(String s) {
if(s != null && Character.isLetter(s.charAt(0)) && Character.isLetterOrDigit(s.charAt(s.length() - 1))) {
StringBuilder normalized = new StringBuilder();
Character prev = null;
char[] var3 = s.toCharArray();
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
char curr = var3[var5];
Character toAppend = null;
if(Character.isLetterOrDigit(curr)) {
toAppend = Character.valueOf(curr);
}
//不為數字和字母的字符轉換成'-'分隔符,連續多個非字母數字字符轉換成一個'-'分隔符
//這里做了一層判斷,只有在前一個字符為字母數字的時候,才把當前的字符轉換成'-'; 如果前一個為'-'則這個字符忽略不拼接.
//其實這里的prev只有在第一次的時候為null但是第一次的時候走不到else if這個條件
else if(prev == null || prev.charValue() != 45) {
toAppend = Character.valueOf('-');
}
if(toAppend != null) {
normalized.append(toAppend);
prev = toAppend;
}
}
return normalized.toString();
} else {
throw new IllegalArgumentException("Consul service ids must not be empty, must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen: " + s);
}
}