使用Ribbon進行負載均衡 在使用Ribbon之前,我們先想一個之前的問題,之前我們將服務提供者註冊進了eureka註冊中心,但是在消費者端,我們還是使用的restTemplate調用的時候,其中寫的還是http://localhost:8001這樣的調用方式,是不是有一些不妥呢?是不是應用像du ...
使用Ribbon進行負載均衡
在使用Ribbon之前,我們先想一個之前的問題,之前我們將服務提供者註冊進了eureka註冊中心,但是在消費者端,我們還是使用的restTemplate調用的時候,其中寫的還是http://localhost:8001這樣的調用方式,是不是有一些不妥呢?是不是應用像dubbo那樣,使用服務名進行調用呢?不然,我們使用註冊中心有什麼用呢?
好的呢,我們先保留這個思考 。來進入Ribbon的學習
什麼是Ribbon?
Ribbon [ˈrɪbən] ,是SpringCloud Netflix中的一個關於客戶端的負載均衡插件。
主要解釋如下:
- 這個客戶端主要是指服務消費者,也就是說,這個插件是用在消費者端的,它自己會根據一些演算法對相同服務的提供者(也就是這幾個服務提供者的application.name要相同)進行甄別,自己決定我要訪問哪一個服務者。
- 而Nginx是整個伺服器的負載均衡,當瀏覽器等設備的訪問請求進來後,它會根據自身的配置,進行服務的路徑選擇。
Ribbon的集成(客戶端,即消費者)
上邊說了,是在消費端進行的負載均衡,所以要修改cousumer端,但為了方便學習,我就新創建了一個項目,demo3-ribbon-consumer,代碼和之前的沒什麼太大的變化。而且,要有多個相同名稱的服務提供者才能進行負載均衡,才能在多個服務提供者之前進行選擇嗎?這就好比,你當了皇上,但是皇宮只有皇後一個人,那還有的選嗎?哈哈,這車開的有點快了啊!
同樣,我們要使用服務名進行調用,而不是使用localhost進行調用了。那是不是也要集成eureka註冊中心呢?只有這樣,才能在註冊中心找到的啊
- 之前說過的使用SpringCloud組件的兩步,第一步,引入依賴(註意,是對Consumer)
<!--ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!--下邊這兩個是ribbon所依賴的-->
<!--eureka的客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--SpringCloud的配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- 在啟動類上添加對應的註解
@EnableEurekaClient //eureka的客戶端
- 修改application.yml
server:
port: 80
# 下邊加eureka的配置就是為了能夠在eureka註冊中心中發現服務提供者
eureka:
client:
register-with-eureka: false
service-url:
# 使用的eureka集群,上一次配置過的
defaultZone: http://eureka1:7001/eureka/,http://eureka2:7002/eureka/,http://eureka3:7003/eureka/
- 在配置RestTemplate的bean的配置類上開啟負載均衡
@Bean
@LoadBalanced //開啟負載均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
- Contoller類,暫時修改如下:
@GetMapping("demo3/consumer/hello/{id}")
public String hello(@PathVariable("id") String id){
//遠程調用provider中的介面,這回使用的這個提供者的名稱
return restTemplate.getForObject("http://demo3-ribbon-provider/demo3/provider/hello/"+id,String.class);
}
創建多個相同名稱的服務提供者
上邊說了,這個一定是要有的。只有當你有選擇的時候,你才能做出選擇。這個步驟太過簡單了,只寫其中一個的代碼,其餘的自己複製就可以了(module名稱為demo3-ribbon-provider-800x)。
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- application.yml
server:
#每個服務提供者對應的埠號肯定要不同
port: 8001
spring:
application:
# 這個應用的名稱,用來註冊在註冊中心的名稱
name: demo3-ribbon-provider
eureka:
client: #客戶端註冊進eureka服務列表內
service-url:
# eureka集群的註冊地址
defaultZone: http://eureka1:7001/eureka,http://eureka2:7002/eureka,http://eureka3:7003/eureka
instance:
instance-id: demo3-ribbon-provider-8001
prefer-ip-address: true #訪問路徑可以顯示IP地址
- Controller類
@RestController
public class HelloController {
@GetMapping("demo3/provider/hello/{id}")
public String hello(@PathVariable("id") Integer id) {
return "這是來自提供者的一條消息,你傳過來的消息" + id+"\n\t你這次訪問的服務提供者8001";
}
}
- 主啟動類加上對應的註解
@SpringBootApplication
@EnableEurekaClient //本服務啟動後會自動註冊進eureka服務中
@EnableDiscoveryClient//這個表明這個服務能被髮現,也就是消費者可以調用它
public class Demo3RibbonProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(Demo3RibbonProvider_8001.class, args);
}
}
最後,齊活。進行測試
啟動三個eureka集群、三個相同名稱的服務提供者、一個消費者。一共七個服務,七個進程,不行,我的電腦已經開始向我示威了,來看一下我的電腦的記憶體。我的是8G記憶體,Idea已經占了我3G多了。
- Eureka集群的圖片
- 連續三次訪問
http://localhost/demo3/consumer/hello/99
的結果
從上邊結果可以看出來,三次連續訪問竟然結果不一樣,這就是ribbon啟動的負載均衡演算法了啊。至於為什麼是這樣?
Ribbon內置的負載均衡演算法
Ribbon預設使用的是輪詢演算法,即對相同的服務提供者進行挨個輪詢,這樣,就能會讓每一個服務提供者都被訪問一次了。當然,Ribbon的負載均衡演算法還支持自定義,下期再說嘍!