閱讀的書籍爲《Spring Cloud 微服務實戰》。
在《Spring Cloud學習(2)——高可用Eureka Server》中,我搭了一個雙節點的服務註冊中心集羣。
同時在《Spring Cloud學習(1)——單節點Eureka Server》中,創建了一個名爲hello-world-service的服務提供者。
這裏,爲了測試Ribbon的客戶端負載均衡功能,需要啓動hello-world-service服務的兩個實例。
實例名配置
在eureka中,實例名,即InstanceInfo中的instanceId,它是區分同一服務中不同實例的唯一標識。
在Netflix Eureka的原生實現中,實例名採用主機名作爲默認值,這樣的配置使得在同一主機上無法啓動多個相同的服務實例。
而在Spring Cloud Eureka中,針對這一情況,對實例名的默認值做了更爲合理的擴展,規則如下:
${spring.cloud.client.hostname}:${spring.application.name}:{spring.application.instance_id:${server.port}}
對於實例名的命名規則可以通過eureka.instance.instanceId參數來配置。
例如,在同一臺機器上需要啓動同一服務的多個實例,如果直接啓動同一個應用,必然會產生端口衝突。
可以設置:
eureka.instance.instanceId=${spring.application.name}:${random.int}
修改hello-world-service服務application.properties,修改如下:
spring.application.name=hello-world-service
server.port=0
eureka.instance.instanceId=${spring.application.name}:${random.int}
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
通過java -jar命令行的方式啓動兩個實例:
java -jar helloworld-0.0.1-SNAPSHOT.jar
創建服務消費者
- 使用IDEA搭建一個基礎的Spring Boot工程作爲服務消費者,起名ribbon-demo,在pom.xml中引入必要的依賴內容。
相較之前的hello-world-service,需要新增Ribbon模塊的依賴spring-cloud-starter-ribbon。
- 主類中加上@EnableDiscoveryClient註解,同時創建RestTemplate的Spring Bean實例,並通過@LoadBalanced註解開啓客戶端的負載均衡。
package com.example.ribbondemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonDemoApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonDemoApplication.class, args);
}
}
- 在該工程的主類同級目錄下創建一個RESTful API實現代碼。通過上面創建的RestTemplate來訪問HELLO-WORLD-SERVICE服務提供的/helloworld接口。
package com.example.ribbondemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class ConsumerController {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/ribbon-test", method = RequestMethod.GET)
public String ribbonTest() {
return restTemplate.getForEntity("http://HELLO-WORLD-SERVICE/helloworld",String.class).getBody();
}
}
- 在application.properties中增加如下配置:
spring.application.name=ribbon-demo
server.port=9000
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
- 啓動服務
測試
啓動上文的ribbon-demo服務。
在eureka的信息面板中,可以看見多了RIBBON-DEMO服務。
觀察啓動的兩個HELLO-WORLD-SERVICE服務控制檯,可以看出,有一個控制檯響應了RIBBON-DEMO服務的調用。
觀察啓動的兩個HELLO-WORLD-SERVICE服務控制檯,可以看出,兩個實例交替響應RIBBON-DEMO服務的調用。