前言
首先我們先了解Ribbon是什麼,Ribbon是一個負載均衡客戶端,給我們更多控制的HTTP和TCP調用的行為。Feign默認集成了ribbon,Ribbon是Netflix的子項目,提供客戶端實現負載均衡算法。Ribbon客戶端組件提供如連接超時,重試等。Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨機連接等)去連接這些機器,我們也很容易使用Ribbon實現自定義的負載均衡算法。上篇講了Eureka註冊中心,本文將Ribbon結合Eureka註冊中心做消費端的負載均衡調用。如下圖,Ribbon可以結合Eureka使用,也可以單獨使用Ribbon。
Ribbon簡單使用
以上篇文章的Eureka-client模塊作為Provider,新建Ribbon-client作為消費者,首先Ribbon-client引入ribbon,eureka,在pom文件引入
<dependency>
<groupid>org.springframework.cloud/<groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.cloud/<groupid>
<artifactid>spring-cloud-starter-netflix-ribbon/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>
在application.yml 文件引入相關配置
server:
port: 8768
spring:
application:
name: ribbon-client
eureka:
client:
serviceUrl:
defaultZone: http://eureka-server1:8761/eureka/
新建 RibbonConfig配置類
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
新建controller調用(eureka-client為之前模塊的應用名,以該名在註冊中心註冊的 )
@RestController
public class RibbonClientController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getEurekaServer")
public String getEurekaServer(String name){
return this.restTemplate.getForObject("http://eureka-client/ribbon?name=" + name, String.class);
}
}
啟動類
@SpringBootApplication
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
經過以上幾步,默認的Ribbon客戶完成,很簡單。分別啟動Eureka-server,Eureka-client,Ribbon-client。請求http://localhost:8768/getEurekaServer?name=Ribbon,會請求到Eureka-client模塊的接口。上面的幾步都是使用Ribbon默認的配置,一般微服務中,Provider會有多個,consumer也會有多個,默認情況下是輪詢的方式去調用。當然我們也可以根據我們的需求去定義它。默認情況下,Ribbon自動幫我們做了如下配置
Ribbon自定義客戶端
自定義Ribbon意思就是說自定義上圖中六個Ribbon組件的默認配置,首先我們新建CustomRibbonConfig配置類
@Configuration
public class CustomRibbonConfig {
@Bean
public IRule ribbonRule() {
// 自定義為隨機規則
return new RandomRule();
}
@Bean
public IPing ribbonPing() {
// 如果調用成功,則認為本次心跳成功,表示此服務活著
return new PingUrl();
}
}
上面的代碼我們重新定義負載均衡算法和與Provider端的心跳方式
然後我們的啟動類加上
@SpringBootApplication
@RibbonClient(name = "eureka-client",configuration = CustomRibbonConfig.class)
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
經過上面兩步,自定義Ribbon的負載均衡客戶端完成
但是在官方的文檔上有這樣的一段話
The CustomConfiguration clas must be a @Configuration class, but take care that it is not in a @ComponentScanfor the main application context. Otherwise, it is shared by all the @RibbonClients. If you use @ComponentScan(or @SpringBootApplication), you need to take steps to avoid it being included (for instance, you can put it in a separate, non-overlapping package or specify the packages to scan explicitly in the @ComponentScan)
意思是當我們Spring Boot @ComponentScan的時候應該明確的排除Ribbon自定義客戶端的配置類,也就是要排除CustomRibbonConfig類
所以我們新建一個註解
public @interface Exclude {
}
註解加到CustomRibbonConfig配置類上
@Configuration
@Exclude
public class CustomRibbonConfig
啟動類則變成
@SpringBootApplication
@RibbonClient(name = "eureka-client",configuration = CustomRibbonConfig.class)
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Exclude.class)})
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
值得注意的是 上面的自定義配置只對服務名為 eureka-client 的provider有效
Ribbon不使用Eureka單獨使用
Eureka是用於服務發現和服務註冊、以及使用服務名來解決服務消費者和服務提供者通信時地址的硬編碼問題的。如果Ribbon脫離了Eureka,那麼在服務消費者端就無法根據服務名通過心跳機制從EurekaServer端獲取對應服務提供者的IP以及端口號。這時就需要在服務消費者端配置對應服務提供者的地址列表,然後Ribbon才能通過配置文件或者自定義的RibbonClient或者默認的配置獲取負載均衡的輪詢策略進行請求分發。
我們需要把Ribbon-client 的application.yml 改成
server:
port: 8768
spring:
application:
name: ribbon-client
#eureka:
# client:
# serviceUrl:
# defaultZone: http://eureka-server1:8761/eureka/
ribbon:
eureka:
enabled: false
eureka-client:
ribbon:
listOfServers: localhost:8764,localhost:8765
其中 eureka-client是Provider端的服務名
Ribbon相關配置詳解
Ribbon主要包含如下組件:
- IRule
根據特定算法中從服務列表中選取一個要訪問的服務
- IPing
在後臺運行的一個組件,用於檢查服務列表是否都活
- ServerList
存儲服務列表。分為靜態和動態。如果是動態的,後臺有個線程會定時刷新和過濾服務列表
- ServerListFilter
該接口允許過濾配置或動態獲取的具有所需特性的服務器列表。ServerListFilter是DynamicServerListLoadBalancer用於過濾從ServerList實現返回的服務器的組件。
- ServerListUpdater
被DynamicServerListLoadBalancer用於動態的更新服務列表
- IClientConfig
定義各種配置信息,用來初始化ribbon客戶端和負載均衡器
- ILoadBalancer
定義軟件負載平衡器操作的接口。動態更新一組服務列表及根據指定算法從現有服務器列表中選擇一個服務
閱讀更多 蝸牛與小羊 的文章