記一次 JMeter 壓測 HTTPS 性能問題

作者:拂衣
問題背景
Cloud Native
問題分析
Cloud Native
top -Hp {pid}

java/bin/jstat -gcutil {pid} 1000
?
// 默認緩存大小private final static int DEFAULT_MAX_CACHE_SIZE = 20480;// package privateSSLSessionContextImpl() {cacheLimit = getDefaultCacheLimit(); // default cache size,這里默認是20480timeout = 86400; // default, 24 hours// use soft reference// 這里初始化了2個默認大小20480的緩存,是頻繁GC的原因sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout);sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout);}// 獲取默認緩存大小private static int getDefaultCacheLimit() {try {int defaultCacheLimit = GetIntegerAction.privilegedGetProperty("javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE);if (defaultCacheLimit >= 0) {return defaultCacheLimit;} else if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {SSLLogger.warning("invalid System Property javax.net.ssl.sessionCacheSize, " +"use the default session cache size (" +DEFAULT_MAX_CACHE_SIZE + ") instead");}} catch (Exception e) {// unlikely, log it for safeif (SSLLogger.isOn && SSLLogger.isOn("ssl")) {SSLLogger.warning("the System Property javax.net.ssl.sessionCacheSize is " +"not available, use the default value (" +DEFAULT_MAX_CACHE_SIZE + ") instead");}}return DEFAULT_MAX_CACHE_SIZE;}


問題驗證
Cloud Native
httpclient.reset_state_on_thread_group_iteration=false


/*** Whether SSL State/Context should be reset* Shared state for any HC based implementation, because SSL contexts are the same*/protected static final ThreadLocalresetStateOnThreadGroupIteration = ThreadLocal.withInitial(() -> Boolean.FALSE);/*** Reset SSL State.* In order to do that we need to:**Call resetContext() on SSLManager *Close current Idle or Expired connections that hold SSL State *Remove HttpClientContext.USER_TOKEN from {@link HttpClientContext} ** @param jMeterVariables {@link JMeterVariables}* @param clientContext {@link HttpClientContext}* @param mapHttpClientPerHttpClientKey Map of {@link Pair} holding {@link CloseableHttpClient} and {@link PoolingHttpClientConnectionManager}*/private void resetStateIfNeeded(JMeterVariables jMeterVariables,HttpClientContext clientContext,Map> mapHttpClientPerHttpClientKey) { if (resetStateOnThreadGroupIteration.get()) {// 關閉當前線程對應連接池的超時、空閑連接,重置連接池狀態(tài)closeCurrentConnections(mapHttpClientPerHttpClientKey);// 移除TokenclientContext.removeAttribute(HttpClientContext.USER_TOKEN);// 重置SSL上下文((JsseSSLManager) SSLManager.getInstance()).resetContext();// 標記置為false,保證一次循環(huán)中,只有第一個采樣器走進此邏輯resetStateOnThreadGroupIteration.set(false);}}@Overrideprotected void notifyFirstSampleAfterLoopRestart() {log.debug("notifyFirstSampleAfterLoopRestart called "+ "with config(httpclient.reset_state_on_thread_group_iteration={})",RESET_STATE_ON_THREAD_GROUP_ITERATION);resetStateOnThreadGroupIteration.set(RESET_STATE_ON_THREAD_GROUP_ITERATION);}
總結
Cloud Native
如果希望施壓機發(fā)揮最大性能,可以將 https.sessioncontext.shared 設為 true,這樣所有線程會共享同一個 SSL 上下文,不會頻繁握手,但是不能模擬真實情況下多用戶的場景。 如果希望模擬多個用戶,不停循環(huán)執(zhí)行某一個動作,也就是一個線程組每次循環(huán)模擬同一個用戶的行為,可以將 httpclient.reset_state_on_thread_group_iteration 設置為 false,這樣也可以很大的提高單機壓測 HTTPS 的性能。 如果希望每個線程組每次循環(huán)模擬不同用戶,那需要設置 httpclient.reset_state_on_thread_group_iteration=true,此時壓測會模擬多用戶頻繁 SSL 握手,施壓機性能最低,從經(jīng)驗來看,單機上限 50 并發(fā)左右。這也是 JMeter5.0 版本之后的默認設置。
阿里云?JMeter 壓測
Cloud Native
零運維成本支持分布式壓測,即壓即用 壓測中查看秒級監(jiān)控,實時觀測系統(tǒng)性能水位 支持 RPS 模式,直觀衡量系統(tǒng)吞吐量 全球地域發(fā)起百萬級并發(fā)流量,模擬真實用戶分布 支持阿里云 VPC 壓測,一鍵打通云上內網(wǎng)環(huán)境 支持 JMeter 客戶端插件,本地快速發(fā)起云端壓測
評論
圖片
表情
