Dubbo 併發調優的幾個引數
阿新 • • 發佈:2019-01-22
消費端調優:
一、connections
這個引數可以在服務提供端釋出服務的時候配置,也可以在消費端引用服務的時候配置,但是這個值是隻對消費端生效的,所以一般是服務提供端不建議配置,如果配置,請斟酌一下,詳情請檢視《對connections引數的設定 》。不管是在消費端或者服務提供端,如果對某個服務配置了connections引數,並且該引數大於1,那麼就會導致消費端在建立該服務的遠端socketclient的時候(如果是dubbo協議的話)將會給該服務初始化一個私有的socketclient。所以一般不建議對這個值進行調整。
服務端優化調整:
相對餘消費端,服務端調優的引數相對多一些,但是配置的時候也需要謹慎。
一、executes
這個引數是可以精確到方法級別的引數,就是可以指定呼叫遠端介面某個方法的是該引數的值。具體是怎麼配置的可以到官方文件裡面去看看那,這裡只是描述這個引數實際意義以及使用的時候應該注意點。
上面這段程式碼主要是看兩個地方,分別是第7行和第10行,第7行是獲取配置的executes的值,是一個int型別的,描述數量,然後第10行是獲取當前請求方法當前的狀態,裡面既有一個active屬性(該屬性是AtomacInteger型別的,大家應該懂了為什麼用這個型別),表示當前請求的方法處於執行狀態的執行緒數量,如果這個值大於或者等於配置的值那麼直接丟擲異常,那麼消費端就會收到一個RPC的異常導致呼叫服務失敗,這是這個引數最終導致的效果。
二、actives
這個引數基本上和excetes一樣,但是有一點不同,在說這不同之前,還是看看另一個Filter,看名字你們應該就知道它是做什麼的了——ActiveLimitFilter,下面同樣貼出程式碼:
三、accepts
在看程式碼之前先看看這個引數的意思,這個引數是告知服務提供端能接收多少個消費端連線該服務提供方。下面接著上程式碼,這個引數的體現是在類AbstractServer中。程式碼如下:
這個方法是每個消費端向服務提供端建立一個socket連線的時候都會觸發,上面可以清晰看到如果連線當前服務端的消費端數量超出了配置的值,那麼將會關閉當前消費端連線的請求。這個只是對socket連線的數量限制,而不是像上面兩個引數對呼叫執行緒的配置。
一、connections
這個引數可以在服務提供端釋出服務的時候配置,也可以在消費端引用服務的時候配置,但是這個值是隻對消費端生效的,所以一般是服務提供端不建議配置,如果配置,請斟酌一下,詳情請檢視《對connections引數的設定 》。不管是在消費端或者服務提供端,如果對某個服務配置了connections引數,並且該引數大於1,那麼就會導致消費端在建立該服務的遠端socketclient的時候(如果是dubbo協議的話)將會給該服務初始化一個私有的socketclient。所以一般不建議對這個值進行調整。
服務端優化調整:
相對餘消費端,服務端調優的引數相對多一些,但是配置的時候也需要謹慎。
一、executes
這個引數是可以精確到方法級別的引數,就是可以指定呼叫遠端介面某個方法的是該引數的值。具體是怎麼配置的可以到官方文件裡面去看看那,這裡只是描述這個引數實際意義以及使用的時候應該注意點。
要說這個引數,就要所介紹ExecuteLimitFilter,他是這個引數使用者,看到Filter大家就應該懂了,就是在每個方法請求前後加上業務邏輯。下面貼出裡面的程式碼:
- @Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY)
-
publicclass ExecuteLimitFilter implements
- public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
- URL url = invoker.getUrl();
- String methodName = invocation.getMethodName();
- int max = url.getMethodParameter(methodName, Constants.EXECUTES_KEY, 0);
-
if (max >
- RpcStatus count = RpcStatus.getStatus(url, invocation.getMethodName());
- if (count.getActive() >= max) {
- thrownew RpcException("Failed to invoke method " + invocation.getMethodName() + " in provider " + url + ", cause: The service using threads greater than <dubbo:service executes=\"" + max + "\" /> limited.");
- }
- }
- long begin = System.currentTimeMillis();
- boolean isException = false;
- RpcStatus.beginCount(url, methodName);
- try {
- Result result = invoker.invoke(invocation);
- return result;
- } catch (Throwable t) {
- isException = true;
- if(t instanceof RuntimeException) {
- throw (RuntimeException) t;
- }
- else {
- thrownew RpcException("unexpected exception when ExecuteLimitFilter", t);
- }
- }
- finally {
- RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, isException);
- }
- }
- }
上面這段程式碼主要是看兩個地方,分別是第7行和第10行,第7行是獲取配置的executes的值,是一個int型別的,描述數量,然後第10行是獲取當前請求方法當前的狀態,裡面既有一個active屬性(該屬性是AtomacInteger型別的,大家應該懂了為什麼用這個型別),表示當前請求的方法處於執行狀態的執行緒數量,如果這個值大於或者等於配置的值那麼直接丟擲異常,那麼消費端就會收到一個RPC的異常導致呼叫服務失敗,這是這個引數最終導致的效果。
二、actives
這個引數基本上和excetes一樣,但是有一點不同,在說這不同之前,還是看看另一個Filter,看名字你們應該就知道它是做什麼的了——ActiveLimitFilter,下面同樣貼出程式碼:
- @Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY)
- publicclass ActiveLimitFilter implements Filter {
- public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
- URL url = invoker.getUrl();
- String methodName = invocation.getMethodName();
- int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
- RpcStatus count = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
- if (max > 0) {
- long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, 0);
- long start = System.currentTimeMillis();
- long remain = timeout;
- int active = count.getActive();
- if (active >= max) {
- synchronized (count) {
- while ((active = count.getActive()) >= max) {
- try {
- count.wait(remain);
- } catch (InterruptedException e) {
- }
- long elapsed = System.currentTimeMillis() - start;
- remain = timeout - elapsed;
- if (remain <= 0) {
- thrownew RpcException("Waiting concurrent invoke timeout in client-side for service: "
- + invoker.getInterface().getName() + ", method: "
- + invocation.getMethodName() + ", elapsed: " + elapsed
- + ", timeout: " + timeout + ". concurrent invokes: " + active
- + ". max concurrent invoke limit: " + max);
- }
- }
- }
- }
- }
- try {
- long begin = System.currentTimeMillis();
- RpcStatus.beginCount(url, methodName);
- try {
- Result result = invoker.invoke(invocation);
- RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, true);
- return result;
- } catch (RuntimeException t) {
- RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, false);
- throw t;
- }
- } finally {
- if(max>0){
- synchronized (count) {
- count.notify();
- }
- }
- }
- }
- }
三、accepts
在看程式碼之前先看看這個引數的意思,這個引數是告知服務提供端能接收多少個消費端連線該服務提供方。下面接著上程式碼,這個引數的體現是在類AbstractServer中。程式碼如下:
要說這個引數,就要所介紹ExecuteLimitFilter,他是這個引數使用者,看到Filter大家就應該懂了,就是在每個方法請求前後加上業務邏輯。下面貼出裡面的程式碼:
- @Override
- publicvoid connected(Channel ch) throws RemotingException {
- Collection<Channel> channels = getChannels();
- if (accepts > 0 && channels.size() > accepts) {
- logger.error("Close channel " + ch + ", cause: The server " + ch.getLocalAddress() + " connections greater than max config " + accepts);
- ch.close();
- return;
- }
- super.connected(ch);
- }
這個方法是每個消費端向服務提供端建立一個socket連線的時候都會觸發,上面可以清晰看到如果連線當前服務端的消費端數量超出了配置的值,那麼將會關閉當前消費端連線的請求。這個只是對socket連線的數量限制,而不是像上面兩個引數對呼叫執行緒的配置。