負載均衡策略的使用
負載均衡策略
1. 啥是負載均衡?
首先我們想象一個場景,在分散式系統中有許多個服務,在實際生產環境中,一個服務肯定不止一個例項;但是對於使用者或者呼叫方而已,如果需要我自己去選擇,那未免也太麻煩了;並沒有達到微服務架構所提倡的效率高;但是如果我們只是訪問一個,那麼又如何保證不會單點被爆破呢? 我們設想一下,最好的情況就是每一個例項所承受的相差無幾的訪問壓力。這就是負載均衡;可以整體提高資料吞吐量。
1.1 負載均衡的分類
1.1.1 軟硬體的角度
硬體解決方案:可供選擇的有 NetScaler、F5、Radware和Array等商用的負載均衡器。
軟體解決方案:Nginx 等。
1.1.2 兩端的角度
可分為服務端的負載均衡與客戶端的負載均衡.
1.2 負載均衡的做法
大體上有 節點輪詢(用的最多);設定權重(我們可以給配置高的機器權重增高,這個是很好理解的)
2. 具體的負載均衡器介紹與使用
2.1 Ribbon
Ribbon 是 客戶端的負載均衡器,通過Spring Cloud 封裝,所以不必要額外引入依賴,我們直接通過註解使用
@Bean
@LoadBalanced // 這幾是Ribbon的註解
public RestTemplate restTemplate() {
return new RestTemplate();
}
我依然沿用微服務系列第一篇的 訂單服務和 視訊服務作為例子
// 在上述添加了 @LoadBalance 的註解之後
// 我們去呼叫 視訊服務的 find_by_id 介面
Video video = restTemplate.getForObject("http://video-service/api/v1/video/find_by_id 介面?videoId="+videoId, Video.class);
其實這就可以了;那麼如何看有沒有生效呢? 下圖用 Postman 測試一下
1. 首先我生成兩個例項,分別設定埠 為9000 和 9001
然後連續訪問兩遍,列印 埠資訊
兩次的埠不一樣
說明負載均衡 Ribbon 生效了。
到這個地方,我們發現了一個問題,就是依舊沒有結局可調整性的問題,我們還是以 URL (http://video-service/api/v1/video/find_by_id)的形式去呼叫服務,那麼有沒有更優的解決方案呢?
這就引出了 如下 的 feign
2.2 Feign
原先 Ribbon 存在的問題:不規範,風格不統一,維護性比較差;
Feign 封裝了 Ribbon;同時保證了程式碼的維護性和規範性,下面我們看看Feign是如何使用的;看過流程之後能更好的理解它的優點。
2.2.1 匯入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2.2 註解
在啟動類上註明註解
@EnableFeignClients
2.2.3 增添介面
例如 我們作為訂單 orderService,需要呼叫 videoService 的介面,我們在 orderService 服務中新建一個 videoService 的介面。
這個介面上不注 @Service;而註上@FeignClient(name=“video-service”),
name 與 nacos 中註冊的保持一致 (nacos 支援Feign)
然後
我們在這個介面中寫相應的方法,並註上註解
@FeignClient(name="video-service")
public interface videoService{
@GetMapping(value = "/api/v1/video/find_by_id")
Video findById(@RequestParam("videoId") int videoId);
}
我們可以再 controller層進行 service 的使用了,就好像在本地同一個服務中一樣。
其實 Feign 是一個 SpringCloud 提供的一個偽http;相比較 Ribbon 來看,我們彷彿就是把原先的 URL 語句拆分成了一個個註解。 是的,Feign 在啟動之後會將這些註解中我們寫好的引數拼接成一個完整的 URL 語句。
注意:對於 Get 請求,我們使用 @GetMapping;如果我們在呼叫介面的過程中需要傳遞引數,那麼 Post 請求如何做呢?
// 使用 PostMapping 註解
// 同時 對於引數我們要用 @RequestBody 註解
@PostMapping("save")
public Object save(@RequestBody Video video){
System.out.println(video.getTitle());
return video;
}
綜上,我們完全可以使用 Feign,因為 Feign 預設就是集成了 Ribbon,同時代碼更加友好