Dubbo 併發調優的幾個參數

歡迎加入DUBBO交流羣:259566260

消費端調優: 
1、connections 
這個參數能夠在服務提供端發佈服務的時候配置,也能夠在消費端引用服務的時候配置,可是這個值是隻對消費端生效的,因此通常是服務提供端不建議配置,若是配置,請斟酌一下,詳情請查看《對connections參數的設置 》。無論是在消費端或者服務提供端,若是對某個服務配置了connections參數,而且該參數大於1,那麼就會致使消費端在建立該服務的遠程socketclient的時候(若是是dubbo協議的話)將會給該服務初始化一個私有的socketclient。因此通常不建議對這個值進行調整。 
服務端優化調整: 
相對餘消費端,服務端調優的參數相對多一些,可是配置的時候也須要謹慎。 
1、executes 
這個參數是能夠精確到方法級別的參數,就是能夠指定調用遠程接口某個方法的是該參數的值。具體是怎麼配置的能夠到官方文檔裏面去看看那,這裏只是描述這個參數實際意義以及使用的時候應該注意點。 
要說這個參數,就要所介紹ExecuteLimitFilter,他是這個參數使用者,看到Filter你們就應該懂了,就是在每一個方法請求先後加上業務邏輯。下面貼出裏面的代碼:  php


@Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY)
public class ExecuteLimitFilter implements Filter {
    
    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 > 0) {
            RpcStatus count = RpcStatus.getStatus(url, invocation.getMethodName());
            if (count.getActive() >= max) {
                throw new 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 {
                throw new RpcException("unexpected exception when ExecuteLimitFilter", t);
            }
        }
        finally {
            RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, isException);
        }
    }
    
}



上面這段代碼主要是看兩個地方,分別是第7行和第10行,第7行是獲取配置的executes的值,是一個int類型的,描述數量,而後第10行是獲取當前請求方法當前的狀態,裏面既有一個active屬性(該屬性是AtomacInteger類型的,你們應該懂了爲何用這個類型),表示當前請求的方法處於執行狀態的線程數量,若是這個值大於或者等於配置的值那麼直接拋出異常,那麼消費端就會收到一個RPC的異常致使調用服務失敗,這是這個參數最終致使的效果。  
2、actives  
這個參數基本上和excetes同樣,可是有一點不一樣,在說這不一樣以前,仍是看看另外一個Filter,看名字大家應該就知道它是作什麼的了—— ActiveLimitFilter,下面一樣貼出代碼:  


@Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY)
public class 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) {
                            throw new 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();
                }
            }
        }
    }
    
}



上面代碼大體上和executes同樣,惟一不一樣的就是多了一個等待時間,噹噹前執行該方法的線程超出了最大限制,那麼能夠等待一個timeout時間,若是時間過了仍是超出了最大限制,那麼就拋出異常。這個相對餘executes來講溫柔那麼點。這就是那點不一樣!  
3、accepts 
在看代碼以前先看看這個參數的意思,這個參數是告知服務提供端能接收多少個消費端鏈接該服務提供方。下面接着上代碼,這個參數的體現是在類AbstractServer中。代碼以下:
 


@Override
    public void 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鏈接的數量限制,而不是像上面兩個參數對調用線程的配置。  


以上概括出的幾個參數建議服務端生效的在服務端配置,消費端生效的在消費端配置,否則會致使一些不可控的現象出現。這也叫改哪裏的東西就應該在哪裏,而不能亂放。
相關文章
相關標籤/搜索