接下來在整個微服務架構中,我們比較關心的就是服務間的服務改如何呼叫,有哪些呼叫方式?

總結:
在springcloud中服務間呼叫方式主要是使用 http restful方式進行服務間呼叫
1. 基于RestTemplate的服務呼叫
在上面的基礎上,使用的是consul注冊,pom.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>04-products9998</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>04-products9998</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入consul依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 這個包是用做健康度監控的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<!--全域管理springcloud版本,并不會引入具體依賴-->
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1. 說明
- spring框架提供的RestTemplate類可用于在應用中呼叫rest服務,它簡化了與http服務的通信方式,統一了RESTful的標準,封裝了http鏈接, 我們只需要傳入url及回傳值型別即可,相較于之前常用的HttpClient,RestTemplate是一種更優雅的呼叫RESTful服務的方式,
2. RestTemplate 服務呼叫
- 創建兩個服務并注冊到consul注冊中心中
- users 代表用戶服務 埠為 9999
- products 代表商品服務 埠為 9998
`注意:這里服務僅僅用來測驗,沒有實際業務意義


3. 在商品服務中提供服務方法
@RestController
@Slf4j
public class ProductController {
@Value("${server.port}")
private int port;
@GetMapping("/product/findAll")
public Map<String,Object> findAll(){
log.info("商品服務查詢所有呼叫成功,當前服務埠:[{}]",port);
Map<String, Object> map = new HashMap<String,Object>();
map.put("msg","服務呼叫成功,服務提供埠為: "+port);
map.put("status",true);
return map;
}
}

4. 在用戶服務中使用restTemplate進行呼叫

@RestController
@Slf4j
public class UserController {
@GetMapping("/user/findAll")
public String findAll(){
log.info("呼叫用戶服務...");
//1. 使用restTemplate呼叫商品服務
RestTemplate restTemplate = new RestTemplate();
// get請求getxxx,post請求postxxx
// 引數1:請求路徑,引數2:回傳的型別是String的
String forObject = restTemplate.getForObject("http://localhost:9998/product/findAll",
String.class);
return forObject;
}
}
5. 啟動服務


6. 測驗服務呼叫
- 瀏覽器訪問用戶服務 http://localhost:9999/user/findAll


7. 總結
- rest Template是直接基于服務地址呼叫沒有在服務注冊中心獲取服務,也沒有辦法完成服務的負載均衡如果需要實作服務的負載均衡需要自己書寫服務負載均衡策略,
restTemplate直接呼叫存在問題 - 1.直接使用restTemplate方式呼叫沒有經過服務注冊中心獲取服務地址,代碼寫死不利于維護,當服務宕機時不能高效剔除
- 2.呼叫服務時沒有負載均衡需要自己實作負載均衡策略
2. 基于Ribbon的服務呼叫
0. 說明
- 官方網址: https://github.com/Netflix/ribbon
- Spring Cloud Ribbon是一個基于HTTP和TCP的客戶端負載均衡工具,它基于Netflix Ribbon實作,通過Spring Cloud的封裝,可以讓我們輕松地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務呼叫,
再創建一個服務類,和上面的服務類一樣,只有埠不同
server.port=9997
spring.application.name=products
spring.cloud.consul.port=8500
spring.cloud.consul.host=localhost
其他一樣
@RestController
@Slf4j
public class ProductController {
@Value("${server.port}")
private int port;
@GetMapping("/product/findAll")
public Map<String,Object> findAll(){
log.info("商品服務查詢所有呼叫成功,當前服務埠:[{}]",port);
Map<String, Object> map = new HashMap<String,Object>();
map.put("msg","服務呼叫成功,服務提供埠為: "+port);
map.put("status",true);
return map;
}
}
1. Ribbon 服務呼叫
# 1.專案中引入依賴
- 說明:
1.如果使用的是eureka client 和 consul client,無須引入依賴,因為在eureka,consul中默認集成了ribbon組件
2.如果使用的client中沒有ribbon依賴需要顯式引入如下依賴
<!--引入ribbon依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
# 2.查看consul client中依賴的ribbon

# 3.使用restTemplate + ribbon進行服務呼叫
- 使用discovery client 進行客戶端呼叫
- 使用loadBalanceClient 進行客戶端呼叫
- 使用@loadBalanced 進行客戶端呼叫
# 3.1 使用discovery Client形式呼叫
@Autowired
private DiscoveryClient discoveryClient;
//獲取服務串列,回傳全部的,服務id,上面的products
List<ServiceInstance> products = discoveryClient.getInstances("服務ID");
for (ServiceInstance product : products) {
log.info("服務主機:[{}]",product.getHost());
log.info("服務埠:[{}]",product.getPort());
log.info("服務地址:[{}]",product.getUri());
log.info("====================================");
}
# 3.2 使用loadBalance Client形式呼叫
@Autowired
private LoadBalancerClient loadBalancerClient;
//根據負載均衡策略選取某一個服務呼叫,服務id=products
ServiceInstance product = loadBalancerClient.choose("服務ID");//地址 默認輪詢策略
log.info("服務主機:[{}]",product.getHost());
log.info("服務埠:[{}]",product.getPort());
log.info("服務地址:[{}]",product.getUri());
# 3.3 使用@loadBalanced(常用)
//1.整合restTemplate + ribbon
@Configuration
public class RestTemplateConfig {
// 在工廠中創建一個restTemplate物件
@Bean
// 加上這個注解代表當前的restTemplate物件帶有ribbon負載均衡
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
//2.呼叫controller服務位置注入RestTemplate
// 此時的restTemplate就具有了負載均衡的功能
@Autowired
private RestTemplate restTemplate;
//3.呼叫
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/user/findAll")
public String findAll(){
// 服務id就是在組態檔中的當前服務名products
String forObject = restTemplate.getForObject("http://服務ID/product/findAll",
String.class);
return forObject;
}
}
默認的輪訓策略,也就是當前訪問的9998,之后是9997,回圈訪問
2. Ribbon負載均衡策略
ribbon負載均衡演算法
-
RoundRobinRule 輪訓策略 按順序回圈選擇 Server
-
RandomRule 隨機策略 隨機選擇 Server
-
AvailabilityFilteringRule 可用過濾策略
`會先過濾由于多次訪問故障而處于斷路器跳閘狀態的服務,還有并發的連接數量超過閾值的服務,然后對剩余的服務串列按照輪詢策略進行訪問 -
WeightedResponseTimeRule 回應時間加權策略
`根據平均回應的時間計算所有服務的權重,回應時間越快服務權重越大被選中的概率越高,剛啟動時如果統計資訊不足,則使用RoundRobinRule策略,等統計資訊足夠會切換到 -
RetryRule 重試策略
`先按照RoundRobinRule的策略獲取服務,如果獲取失敗則在制定時間內進行重試,獲取可用的服務, -
BestAviableRule 最低并發策略
`會先過濾掉由于多次訪問故障而處于斷路器跳閘狀態的服務,然后選擇一個并發量最小的服務

3.修改服務的默認負載均衡策略
# 1.修改服務默認隨機策略
- 服務id.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
`下面的products為服務的唯一標識
products.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

4.Ribbon停止維護
# 1.官方停止維護說明
- https://github.com/Netflix/ribbon

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231780.html
標籤:其他
下一篇:C++基礎知識篇:C++ 數字
