天天看點

一次帶你解決所有微服務架構的高并發問題!

作者:馬士兵教育

通過注冊中心已經實作了微服務的服務注冊和服務發現,并且通過Ribbon實作了負載均衡,已經借助Feign可以優雅的進行微服務調用。那麼我們編寫的微服務的性能怎麼樣呢,是否存在問題呢?

1.1性能工具Jmetter

一次帶你解決所有微服務架構的高并發問題!

Apache JMeter是Apache組織開發的基于Java的壓力測試工具。用于對軟體做壓力測試,它最初被設計用于Web應用測試,但後來擴充到其他測試領域。 它可以用于測試靜态和動态資源,例如靜态檔案、Java 小服務程式、CGI 腳本、Java 對象、資料庫、FTP 伺服器,等等。JMeter 可以用于對伺服器、網絡或對象模拟巨大的負載,來自不同壓力類别下測試它們的強度和分析整體性能。另外JMeter能夠對應用程式做功能/回歸測試,通過建立帶有斷言的腳本來驗證你的程式傳回了你期望的結果。為了最大限度的靈活性,JMeter允許使用正規表達式建立斷言。

1.1.1 安裝Jmetter

Jmetter安裝十分簡單,使用資料中的 apache-jmeter-2.13.zip 完整壓縮包,解壓找到安裝目錄下bin/jmeter.bat 已管理者身份啟動即可

一次帶你解決所有微服務架構的高并發問題!

1.1.2 配置Jmetter

(1)建立新的測試計劃

一次帶你解決所有微服務架構的高并發問題!

(2)測試計劃下建立發起請求的線程組

一次帶你解決所有微服務架構的高并發問題!
  • 可以配置請求的線程數
  • 以及每個請求發送的請求次數

(3)建立http請求模闆

一次帶你解決所有微服務架構的高并發問題!

(4)配置測試的接口資訊

1.2 系統負載過高存在的問題

1.2.1 問題分析

在微服務架構中,我們将業務拆分成一個個的服務,服務與服務之間可以互相調用,由于網絡原因或者自身的原因,服務并不能保證服務的100%可用,如果單個服務出現問題,調用這個服務就會出現網絡延遲,此時若有大量的網絡湧入,會形成任務累計,導緻服務癱瘓。

在SpringBoot程式中,預設使用内置tomcat作為web伺服器。單tomcat支援最大的并發請求是有限的,如果某一接口阻塞,待執行的任務積壓越來越多,那麼勢必會影響其他接口的調用。

1.2.2 線程池的形式實作服務隔離

(1)配置坐标

為了友善實作線以線程池的形式完成資源隔離,需要引入如下依賴

<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.5.12</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.12</version>
</dependency>
           

(2)配置線程池

配置HystrixCommand接口的實作類,再實作類中可以對線程池進行配置

public class OrderCommand extends HystrixCommand<String> {
private RestTemplate restTemplate;
private Long id;
public OrderCommand(RestTemplate restTemplate, Long id) {
super(setter());
this.restTemplate = restTemplate;
this.id = id;
}
private static Setter setter() {
// 服務分組
HystrixCommandGroupKey groupKey =
HystrixCommandGroupKey.Factory.asKey("order_product");
// 服務辨別
HystrixCommandKey commandKey =
HystrixCommandKey.Factory.asKey("product");
// 線程池名稱
HystrixThreadPoolKey threadPoolKey =
HystrixThreadPoolKey.Factory.asKey("order_product_pool");
/**
* 線程池配置
* withCoreSize : 線程池大小為10
* withKeepAliveTimeMinutes: 線程存活時間15秒
* withQueueSizeRejectionThreshold :隊列等待的門檻值為100,超過100執行拒絕
政策
*/
HystrixThreadPoolProperties.Setter threadPoolProperties =
HystrixThreadPoolProperties.Setter().withCoreSize(50)
.withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);
// 指令屬性配置Hystrix 開啟逾時
HystrixCommandProperties.Setter commandProperties =
HystrixCommandProperties.Setter()
// 采用線程池方式實作服務隔離
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrat
egy.THREAD)
// 禁止
.withExecutionTimeoutEnabled(false);
return
HystrixCommand.Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThread
PoolKey(threadPoolKey)
.andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefau
lts(commandProperties);
}
@Override
protected String run() throws Exception {
return restTemplate.getForObject("http://shop-service
product/product/"+id, String.class);
}
@Override
protected String getFallback(){
return "熔斷降級";
}
}           

(3)配置調用

修改 OrderController ,使用自定義的OrderCommand完成調用

@Autowired
private RestTemplate restTemplate;
@GetMapping("/buy/{id}")
public String order(@PathVariable Long id) throws ExecutionException,
InterruptedException, TimeoutException {
return new OrderCommand(restTemplate,id).execute();
}           

繼續閱讀