Eureka服務節點之間的調用—Ribbon的使用01
經過前邊的調試,現在我們Eureka註冊中心(bigsoft-server)和Eureka服務(bigsoft-product)已經配置完畢,我們之所以使用Eureka微服務做分佈式操作,就是爲了多節點之間相互調用,將複雜的工作分佈到不同的計算機上去操作,那麼現在我們就做多服務節點之間調用的操作
首先配置bigsoft-user節點,其實和product節點配置非常相似,配置如下:
server:
port: 7001
spring:
application:
name: user
eureka:
client:
service-url:
defaultZone: http://peer1:8001/eureka/
instance:
ip-address: 127.0.0.1
prefer-ip-address: true
instance-id: ${eureka.instance.ip-address}:${server.port}:user1
這裏ip-address: 127.0.0.1需要配置真實服務器地址,現在啓用註冊中心server觀察下各個節點有沒有都註冊到服務器上
我們觀察到PRODUCT和USER節點都註冊到了註冊中心
準備好了之後,我們現在就可以完成多服務節點互相調用的實驗了,也就是我們的主角:
Ribbon的學習
Spring Cloud Ribbon是Netflix發佈的負載均衡器,基於Netflix Ribbon實現,spring爲了方便使用對其進行了封裝爲Spring Cloud Ribbon,其底層是基於HTTP和TCP的客戶端負載均衡工具,可以讓我們輕鬆地將面對服務的REST模塊請求自動轉換成客戶端負載均衡的服務調用
歸根結底:它實際就是一個RestTemplate對象
首先我們來看第一個非常重要的概念:負載均衡器,關於負載均衡器我們比較熟悉的應該是服務端負載均衡,最熟悉的應該是我們的nginx了,我們首先看下服務端負載均衡的工作模式:
客戶端在訪問我們的網站的時候,我們爲了讓客戶端得到更快更好的瀏覽質量,如上圖是通過負載均衡設備將某個客戶的訪問隨機落到某臺服務器上(這樣當大量客戶涌入的時候可以很好緩解壓力,最常用的就是nginx了),也就是說當客戶端的請求到達服務端之後再由負載均衡設置決定應該訪問到哪裏,這就是所謂的服務端負載均衡
我們再看Ribbon的解釋中有這樣一段話
基於HTTP和TCP的客戶端負載均衡工具
這裏說ribbon是一個基於客戶端負載均衡工具,也就是說它林論模型應該如下圖所示:
對比之前的如,缺少了負載均衡設備去決定用戶到底訪問哪個服務端,而是 由客戶端節點維護着自己要訪問的服務端清單 需要去訪問那個服務端由自己決定
而這些服務端的清單來自於***服務註冊中心***,同服務端負載均衡的架構類似,在客戶端負載均衡也需要心跳去維護服務端清單的健康性,只是這個步驟需要與服務註冊中配合完成
我們現在來完成一個最簡單的測試:
我們首先在bigsoft-user(這裏把它當作服務提供者,提供user相關的一些服務)創建User類:
package com.bigsoft.bigsoftuser.pojo;
import java.io.Serializable;
public class User implements Serializable {
public User(Long userId, String userName, String userPwd) {
this.userId = userId;
this.userName = userName;
this.userPwd = userPwd;
}
public User() {
}
private Long userId;
private String userName;
private String userPwd;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
直接創建UserController類用於提供User服務,代碼如下:
package com.bigsoft.bigsoftuser.controller;
import com.bigsoft.bigsoftuser.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUserById(@PathVariable("id")long id){
User user=new User();
user.setUserId(id);
user.setUserName("xiaohei");
user.setUserPwd("admin");
return user;
}
}
我們啓動user節點,看到報錯信息如下
這裏報錯的信息主要指的是配置了Eureka但是找不到Server(主要是我們沒有啓動註冊中心,不管它)
訪問剛纔的請求:
我們看到,及時一直報錯(報錯類型是找不到註冊中心)但是依舊能完成對當前服務的訪問,那麼現在我們的服務提供者已經準備好了,接着我們去操作服務調用者,也就是product模塊的更改,首先在pom文件中添加ribbon的依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
我們啓用ribbon的配置,主要配置客戶端負載均衡(LoadBalanced )+RestTemplate這兩塊類容如下:
然後在product的controller中完成對user節點getUserById方法的調用
@RestController
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("product/user/{id}")
public User getUserById(@PathVariable("id") long id){
User user=restTemplate.getForObject("http://USER/user/"+String.valueOf(id),User.class);
return user;
}
}
這樣我們主要是通過RestTemplate 對象的getForObject這個方法完成了對User節點方法的調用
我們訪問
這樣在product的controller裏邊完成了這次多節點的分佈式調用
這裏我們主要依賴的就是RestTemplate對象,這個對象主要包含兩個方法:
restTemplate.getForObject()
以及
restTemplate.getForEntity()
getForObject()其實比getForEntity()多包含了將HTTP轉成POJO的功能,但是getForObject沒有處理response的能力。因爲它拿到手的就是成型的pojo。省略了很多response的信息
也就是說getForEntity 會獲取到整個response對象,而getForObject是直接將response對象中的數據取出,並且封裝成我們需要的pojo,我們可以看到
restTemplate.getForObject("http://USER/user/"+String.valueOf(id),User.class);
我們在這裏引用的時候該方法的第二個參數是User.class(User[].class–>這是什麼類型?),也就是說直接將response對象返回的數據封裝成了User.class類,雖然沒有別的response的屬性,但是我們使用起來很方便
它的第一個參數"http://USER/user/"+String.valueOf(id) 這裏其實就是需要訪問的rest路徑了,http://USER/user
這個位置其實就是在找我們Application那麼(也就是註冊到註冊中心節點的名稱)
當註冊到註冊中心之後我們就不需要寫IP地址了,直接通過USER這個名字就能在註冊中心找到該名字代表的IP地址,進行訪問,對我們的使用也很方便
這樣我們最基礎的ribbon實驗就完成了