在完成〈服務註冊伺服器〉的設置之後,接著來試著修改〈@RepositoryRestResource〉中的專案,令其能向伺服器註冊,基本上,需要有以下的相依:
implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
不過〈分離 gossip 組態〉中談過,在撰寫本文的這個時間點上,mavenCentral
中沒有 Spring Cloud 的相關相依程式庫,如果是基於〈@RepositoryRestResource〉中的專案修改,你必須增加 repositories
等額外資訊,不然會抓不到相關 JAR 檔案。例如:
...略
repositories {
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
}
ext['springCloudVersion'] = 'Greenwich.RC2'
dependencies {
...略
implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
...略
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
接著,可以在 bootstrap.properties 中設定服務註冊伺服器的資訊:
server.port=8762
spring.application.name=msg-service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
#eureka.instance.preferIpAddress=true
spring.application.name
會是這個服務註冊時使用之名稱,如果有多個服務註冊伺服器,eureka.client.serviceUrl.defaultZone
的設定中可以用逗號區隔,接著就可以啟動專案了,你可以在 Eureka 資訊頁面上看到有實例註冊了:
在資訊頁面上,可以看到服務的實體位置,目前使用主機名稱,然而,在實際上線之後,通常會使用 IP 位址,這時可以設定 eureka.instance.preferIpAddress=true
。
你可以試著啟動多個實例,同一名稱下就會有多個服務的實體位置資訊:
若想查找出伺服器上同一服務的全部實例,可以透過 DiscoveryClient
,在標註了 @EnableDiscoveryClient
的情況下,就可以透過自動綁定來取得,例如:
...略
@RunWith(SpringRunner.class)
@EnableDiscoveryClient
@SpringBootTest
public class RestTmplApplicationTests {
@Autowired
private DiscoveryClient client;
private String serviceUri;
@Before
public void setUp() {
serviceUri = client.getInstances("msg-service").get(0).getUri().toString();
}
...略
透過 DiscoveryClient
的 getInstances
,可以取得 List<ServiceInstance>
實例,就目前來說,會取得兩個服務實例,每次呼叫就會向伺服器查找一次,因此實際上並不直接使用 DiscoveryClient
,因為這沒有運用到本地快取的註冊表,而且 Spring 還有其他更便捷的方式來查找服務並自動負載平衡。
(如果你沒有要查找服務實例,可以將 eureka.client.fetchRegistry
設為 false
,這樣就不會維謢本地的註冊表。)
在上面的 setUp
方法中,取得註冊表中第一個服務實例之 URI,因此就可以提供給 RestTemplate
使用,例如:
private RestTemplate restTemplate = restTemplate();
@Test
public void show() {
RequestEntity<Void> request = RequestEntity
.get(URI.create(String.format("%s/messages/%s", serviceUri, "1")))
.build();
ResponseEntity<Resource<Message>> response =
restTemplate.exchange(request, new ParameterizedTypeReference<Resource<Message>>(){});
assertNotNull(response.getBody().getContent());
}
你可以在 DataREST 找到以上的範例專案。