SpringCloud五大神獸02-Ribbon/Feign負載均衡
1.簡介
- Ribbon是Netflix釋出的雲中間層服務開源專案,主要功能是提供客戶端負載均衡演算法。使用Ribbon的時候,只要服務提供者的名稱相同,就自動形成了叢集,並且有預設的負載均衡策略(輪詢)。
- Feign是對Ribbon的封裝,簡化了服務的呼叫方式,即呼叫服務的時候,不再需要拼接需要傳遞的引數到訪問地址上,而是採用定義介面(遵循Feign提供的模板)的方式去實現,Feign會完全代理HTTP請求。
2.使用
建立兩個微服務,一個叫Consumer,一個叫Provider,用Consumer去呼叫Provider。當然,Eureka也是必不可少的。這三個微服務作為子模組,它們的父模組的pom.xml還是採用依賴版本管理的方式。
<properties>
<spring.cloud-version>Finchley.SR4</spring.cloud-version>
<spring.boot-version>2.0.5.RELEASE</spring.boot-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
< 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>
2.1.Ribbon
2.1.1.匯入依賴
- 服務消費者Consumer:Eureka客戶端、Ribbon場景啟動器
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Ribbon場景啟動器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
- 服務提供者Provider:Eureka客戶端(不需要Ribbon依賴)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.1.2.寫啟動類
- 服務消費者Consumer:配置RestTemplate、配置負載均衡策略
@SpringBootApplication
@EnableEurekaClient //可寫可不寫
public class RibbonConsumerApp {
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApp.class,args);
}
/**
* @LoadBalanced: 開啟負載均衡策略,預設是輪詢
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* 修改負載均衡策略(IRule是一個介面,只能new它的實現類)
* new RandomRule():隨機策略
* new WeightedResponseTimeRule():權重策略
* new RoundRobinRule():輪詢策略--預設
* @return
*/
@Bean
public IRule iRule(){
return new RoundRobinRule();
}
}
- 服務提供者Provider:正常寫即可
@SpringBootApplication
@EnableEurekaClient //可寫可不寫
public class Provider8082App {
public static void main(String[] args) {
SpringApplication.run(Provider8082App.class,args);
}
}
2.1.3.寫yml配置
- 服務消費者Consumer:配置埠和服務名稱、註冊服務到Eureka註冊中心
server:
port: 9090
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: ribbon-consumer:9090 #自定義一個服務id名稱,否則就預設使用當前計算機名稱作為服務的id
spring:
application:
name: RIBBON-CONSUMER #服務名稱標識 如果不配置,則預設是UNKNOWN
- 服務提供者Provider:配置埠和服務名稱、註冊服務到Eureka註冊中心
server:
port: 8082
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: service-provider-ribbon:8082 #自定義一個服務id名稱,否則就預設使用當前計算機名稱作為服務的id
spring:
application:
name: SERVICE-PROVIDER-RIBBON #服務名稱標識 如果不配置,則預設是UNKNOWN
2.1.4.寫Controller
僅做一個簡單的測試,在瀏覽器訪問服務消費者,服務消費者呼叫服務提供者的服務,返回一個字串在瀏覽器上展示
- 服務消費者Consumer:用RestTemplate來發HTTP請求,呼叫Provider
@RestController
public class RibbonConsumerController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/ribbon/consumer")
public String consumer(){
System.out.println("consumer...................");
//傳送get請求,訪問另一個provider服務
//如果需要傳遞引數,需要拼接到URL上
String s = restTemplate.getForObject("http://SERVICE-PROVIDER-RIBBON/ribbon/provider", String.class);
return s;
}
}
- 服務提供者Provider:返回一個字串
@RestController
public class ProviderController8082 {
/**
* @return
*/
@GetMapping("/ribbon/provider")
public String provider(){
System.out.println("provider..............");
return "*****8082*****";
}
}
2.1.5.瀏覽器訪問測試
2.2.Feign
Ribbon和Feign都是配置在服務消費者上,服務提供者的配置是一樣的
2.2.1.匯入依賴
- 服務消費者Consumer:Eureka客戶端、Feign場景啟動器(注意:依賴的名字叫openfeign)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- feign場景啟動器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2.2.2.寫啟動類
- 服務消費者Consumer:
注意:一定要加@EnableFeignClients註解
/**
* @EnableFeignClients 這個註解表示開啟動態代理
* 會自動遞迴掃描當前啟動類所在的包【掃描所有添加了@FeignClient註解的介面,然後採用動態代理技術生成實現類,
* 建立物件儲存到Spring容器中】
*/
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
public class FeignConsumerApp {
public static void main(String[] args) {
SpringApplication.run(FeignConsumerApp.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2.2.3.寫yml配置
- 服務消費者Consumer:埠和服務名稱配置、服務註冊到Eureka服務中心
server:
port: 9091
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: feign-consumer:9091 #自定義一個服務id名稱,否則就預設使用當前計算機名稱作為服務的id
spring:
application:
name: FEIGN-CONSUMER #服務名稱標識 如果不配置,則預設是UNKNOWN
2.2.4.寫Feign客戶端介面
Feign客戶端介面寫在服務消費者方,它是一個介面,介面上需要添加@FeignClient註解。
介面中的方法引數、返回值、請求地址必須和對應的服務提供者Controller中的方法定義的一致。
為方便起見,可以直接把服務提供者中對應的方法copy過來,刪除方法體即可。
/**
* @FeignClient 表明當前介面是Feign的客戶端介面,並在value屬性中指定所呼叫的服務名稱
*/
@FeignClient(value = "SERVICE-PROVIDER")
@Component
public interface ProviderClient {
@GetMapping("/feign/provider")
String provider();
}
2.2.5.寫Controller
- 服務消費者Consumer:依賴注入Client物件,呼叫方法即可(使用方式類似於mapper層介面)
@RestController
public class FeignConsumerController {
@Autowired
private ProviderClient providerClient;
@GetMapping("/feign/consumer")
public String feignConsumer(){
System.out.println("feignConsumer.....................");
String s = providerClient.provider();
return s;
}
}
2.2.6.瀏覽器訪問測試
3.Ribbon和Feign的區別
Feign是通過定義FeignClient介面的方式呼叫(類似於mapper層介面的使用方式),我們只需要定義好介面,在介面上加@FeignClient註解並指定要呼叫的服務名稱或者服務叢集名稱,在啟動類上加@EnableFeignClients註解,Feign底層就會動態代理生成FeignClient介面的實現類,實現類中重寫介面的方法,內部還是採用的Ribbon的方式去呼叫(用RestTemplate傳送HTTP請求)。
由於Feign是對Ribbon進行的封裝,所以Feign也有Ribbon的負載均衡。
另外,Feign內部也集成了Hystrix,所以我們一般會使用Feign。
4.總結
簡單理解,Ribbon是SpringCloud中微服務之間的呼叫方式,有了它,我們可以通過微服務的名稱去呼叫對應的微服務,如果多個微服務有相同的名稱,就自動形成了叢集,並且Ribbon會自動對叢集進行負載均衡,預設的策略是輪詢,也可以自己定義負載均衡策略。
Feign是對Ribbon進行的封裝,擁有Ribbon的所有功能,優化的地方在於採用了定義FeignClient介面的方式去呼叫微服務,傳送HTTP請求的步驟封裝到了底層自動實現,使用更方便。