Spring Cloud實戰系列(二) - 客戶端呼叫Rest + Ribbon
上一篇文章我們介紹了Eureka
服務註冊中心
的搭建,這篇文章介紹一下如何使用Eureka
服務註冊中心
,搭建一個簡單的服務端註冊服務
,由客戶端
通過Ribbon
負載均衡
地去呼叫服務案例。
正文
1. 建立服務提供者
建立一個service-hi
的Module
,建立完成後的pom.xml
如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>io.ostenant.github.springcloud</groupId> <artifactId>service-hi</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-hi</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-cloud-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 複製程式碼
通過註解
@EnableEurekaClient
表明自己是一個Eureka Client
。
@SpringBootApplication @EnableEurekaClient @RestController public class ServiceHiApplication { public static void main(String[] args) { SpringApplication.run(ServiceHiApplication.class, args); } } 複製程式碼
建立一個控制器HelloController
,對外提供一個/hi
的HTTP
的服務。在響應資料中返回當前服務例項
的埠號
。
@RestController public class HelloController { @Value("${server.port}") private String port; @RequestMapping("/hi") public String hi(@RequestParam String name) { return "Hi " + name + ", I am from port: "+ port; } } 複製程式碼
在配置檔案
中註明的服務註冊中心
的地址,application.yml
配置檔案如下:
spring: active: profiles: service-hi1 # service-hi2 --- spring: profiles: service-hi1 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8763 spring: application: name: service-hi --- spring: profiles: service-hi2 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8764 spring: application: name: service-hi 複製程式碼
分別以spring.profiles.active=hi1
和spring.profiles.active=hi2
作為Spring Boot
的啟動命令引數
,在埠號
8763
和8764
啟動2
個服務提供者
例項。
2. 建立服務消費者
重新新建service-ribbon
的Module
,在它的pom.xml
檔案分別引入起步依賴
spring-cloud-starter-eureka
、spring-cloud-starter-ribbon
、spring-boot-starter-web
,程式碼如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>io.ostenant.github.springcloud</groupId> <artifactId>service-ribbon</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-ribbon</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 複製程式碼
在專案的配置檔案
指定服務的服務註冊中心
的地址,應用名稱
為service-ribbon
,埠號
為8762
。完整配置檔案application.yml
如下:
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8762 spring: application: name: service-ribbon 複製程式碼
在應用啟動類
上,通過@EnableDiscoveryClient
向服務中心
註冊自身資訊,向Spring Boot
容器註冊一個RestTemplate
物件,並通過@LoadBalanced
註解表明這個RestRemplate
開啟客戶端負載均衡
的功能。
@SpringBootApplication @EnableDiscoveryClient public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } 複製程式碼
寫一個測試介面
,注入上面的RestTemplate
物件來消費service-hi
服務的/hi
介面。在RestTemplate
的URL
中,我們將具體服務生產者
的主機名稱
和埠號
替換為它的服務名稱
。
@RestController public class HelloController { @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/hi") public String requestForHi(@RequestParam String name){ return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class); } } 複製程式碼
在瀏覽器上多次訪問http://localhost:8762/hi?name=ribbon
,瀏覽器交替顯示:
Hi ribbon, I am from port: 8763 Hi ribbon, I am from port: 8764
在具體的呼叫過程中,Ribbon
提供的@LoadBalanced
註解會從Eureka Server
上查詢服務列表
,根據服務名稱
找到SERVICE-HI
的服務例項
。如果有多個SERVICE-HI
例項,Ribbon
會根據客戶端負載均衡
演算法篩選其中一臺,並把URL
中的SERVICE-HI
替換為具體例項的主機名稱
和埠號
。