日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

在上文JAVA自定義DNS解析器實(shí)踐中,我們沒有講到org.Apache.http.conn.DnsResolver具體如何實(shí)現(xiàn)負(fù)載均衡,今天我們就分享一下,負(fù)載均衡的具體實(shí)現(xiàn)。

InMemoryDnsResolver被淘汰

首先上期文章提到的org.apache.http.impl.conn.InMemoryDnsResolver類是無法實(shí)現(xiàn)負(fù)載均衡的,原因是這個(gè)實(shí)現(xiàn)類是將host和IP存在一個(gè)java.util.concurrent.ConcurrentHashMap中,然后解析的時(shí)候從java.util.concurrent.ConcurrentHashMap根據(jù)host獲取到IP的,所以無法進(jìn)行負(fù)載均衡。

使用的Demo如下:

    /**
     * 重寫Java自定義DNS解析器,非負(fù)載均衡
     *
     * @return
     */
    private static DnsResolver getDnsResolver2() {
        InMemoryDnsResolver dnsResolver = new InMemoryDnsResolver();

        try {
            logger.warn("調(diào)用一次");
            dnsResolver.add("fun.tester", InetAddress.getByName("127.0.0.1"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return dnsResolver;

其中org.apache.http.impl.conn.InMemoryDnsResolver#add方法源碼如下:

    public void add(String host, InetAddress... ips) {
        Args.notNull(host, "Host name");
        Args.notNull(ips, "Array of IP addresses");
        this.dnsMap.put(host, ips);
    }

然后我們看一下org.apache.http.impl.conn.InMemoryDnsResolver#dnsMap相關(guān)初始化代碼:

    /**
     * In-memory collection that will hold the associations between a host name
     * and an array of InetAddress instances.
     */
    private final Map<String, InetAddress[]> dnsMap;

    /**
     * Builds a DNS resolver that will resolve the host names against a
     * collection held in-memory.
     */
    public InMemoryDnsResolver() {
        dnsMap = new ConcurrentHashMap<String, InetAddress[]>();
    }

SystemDefaultDnsResolver

最終我放棄了自定義的org.apache.http.conn.DnsResolver接口的方案,選擇了org.apache.http.impl.conn.SystemDefaultDnsResolver重寫resolve方法的方案,具體實(shí)現(xiàn)如下:

    /**
     * 重寫Java自定義DNS解析器,負(fù)載均衡
     *
     * @return
     */
    private static DnsResolver getDnsResolver() {
        return new SystemDefaultDnsResolver() {
            @Override
            public InetAddress[] resolve(final String host) throws UnknownHostException {
                if (host.equalsIgnoreCase("fun.tester")) {
                    return new InetAddress[]{SourceCode.random(ips)};
                } else {
                    return super.resolve(host);
                }
            }
        };
    }

其中ips是全局的靜態(tài)變量,初始化方法如下:

    /**
     * 初始化DNS配置IP
     *
     * @return
     */
    private static List<InetAddress> getAddress() {
        try {

            return Arrays.asList(
                    InetAddress.getByName("127.0.0.1"),
                    InetAddress.getByName("0.0.0.0")
            );
        } catch (Exception e) {
            FailException.fail("DNS IP解析失敗!");
        }
        return null;
    }

PS:如果你選擇使用了自定義的DNS解析器,那么系統(tǒng)hosts配置的功能就會(huì)失效,所以謹(jǐn)慎使用。

測(cè)試

為了驗(yàn)證結(jié)果,我對(duì)com.funtester.httpclient.ClientManage#getDnsResolver方法進(jìn)行了改造,每次獲取到IP的時(shí)候我都打印出來。

    /**
     * 重寫Java自定義DNS解析器,負(fù)載均衡
     *
     * @return
     */
    private static DnsResolver getDnsResolver() {
        return new SystemDefaultDnsResolver() {
            @Override
            public InetAddress[] resolve(final String host) throws UnknownHostException {
                if (host.equalsIgnoreCase("fun.tester")) {
                    InetAddress random = SourceCode.random(ips);
                    logger.info(random);
                    return new InetAddress[]{random};
                } else {
                    return super.resolve(host);
                }
            }
        };
    }

單線程

下面看我的測(cè)試,首先分享測(cè)試用例:

    public static void main(String[] args) {
        String url = "http://fun.tester:12345/"
        def get = getHttpGet(url)
        def test = {
            getHttpResponse(get)
        }
        10.times {
            test()
        }
    }

控制臺(tái)輸出:

INFO-> 13.691 main 
  ###### #     #  #    # ####### ######  #####  ####### ######  #####
  #      #     #  ##   #    #    #       #         #    #       #    #
  ####   #     #  # #  #    #    ####    #####     #    ####    #####
  #      #     #  #  # #    #    #            #    #    #       #   #
  #       #####   #    #    #    ######  #####     #    ######  #    #

INFO-> 14.408 main /0.0.0.0
INFO-> 14.460 main 請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):451 ms , HTTPcode: 200
INFO-> 14.462 main 請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):2 ms , HTTPcode: 200
****省略多余的內(nèi)容****

可以看出,單線程請(qǐng)求HTTP服務(wù),DNS只會(huì)解析一次,經(jīng)過多次嘗試,解析的IP會(huì)在設(shè)定的兩個(gè)IP之間隨機(jī)出現(xiàn),但這明顯不符合我們的需求。

多線程

測(cè)試用例如下:

    public static void main(String[] args) {
        String url = "http://fun.tester:12345/"
        def get = getHttpGet(url)
        def test = {
            fun {
                getHttpResponse(get)
            }
        }
        10.times {
            test()
        }
    }

控制臺(tái)輸出:

INFO-> 03.636 main 
  ###### #     #  #    # ####### ######  #####  ####### ######  #####
  #      #     #  ##   #    #    #       #         #    #       #    #
  ####   #     #  # #  #    #    ####    #####     #    ####    #####
  #      #     #  #  # #    #    #            #    #    #       #   #
  #       #####   #    #    #    ######  #####     #    ######  #    #

INFO-> 04.581 Deamon 守護(hù)線程開啟!
INFO-> 04.843 F-6  /0.0.0.0
INFO-> 04.843 F-4  /127.0.0.1
INFO-> 04.843 F-7  /0.0.0.0
INFO-> 04.844 F-2  /0.0.0.0
INFO-> 04.844 F-10 /0.0.0.0
INFO-> 04.844 F-1  /0.0.0.0
INFO-> 04.844 F-5  /127.0.0.1
INFO-> 04.844 F-3  /127.0.0.1
INFO-> 04.844 F-8  /0.0.0.0
INFO-> 04.844 F-9  /127.0.0.1

INFO-> 04.903 F-7  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):309 ms , HTTPcode: 200
INFO-> 04.903 F-3  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):309 ms , HTTPcode: 200
INFO-> 04.903 F-2  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):309 ms , HTTPcode: 200
****省略多余的內(nèi)容****

這下我們就能看出每個(gè)線程都執(zhí)行了一次org.apache.http.impl.conn.SystemDefaultDnsResolver#resolve方法,獲取到了IP也是隨機(jī)的,而且每次請(qǐng)求的耗時(shí)都是比較長(zhǎng)的。這里讓我心生疑惑,相當(dāng)于每個(gè)線程請(qǐng)求都是重新重建了連接,于是就有了下面的測(cè)試。

單個(gè)連接

這里我把HttpClient的連接池的最大連接數(shù)改成了1:public static int MAX_PER_ROUTE_CONNECTION = 1;或者public static int MAX_TOTAL_CONNECTION = 1;,這個(gè)之前分享過,這里不多講了,上用例:

用例同多線程用例

控制臺(tái)輸出:

INFO-> 02.928 main 
  ###### #     #  #    # ####### ######  #####  ####### ######  #####
  #      #     #  ##   #    #    #       #         #    #       #    #
  ####   #     #  # #  #    #    ####    #####     #    ####    #####
  #      #     #  #  # #    #    #            #    #    #       #   #
  #       #####   #    #    #    ######  #####     #    ######  #    #

INFO-> 03.648 Deamon 守護(hù)線程開啟!
INFO-> 03.910 F-5  /0.0.0.0
INFO-> 03.961 F-6  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):299 ms , HTTPcode: 200
INFO-> 03.961 F-5  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):299 ms , HTTPcode: 200
INFO-> 03.961 F-4  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-7  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-3  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-2  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-1  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-9  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-8  請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
INFO-> 03.961 F-10 請(qǐng)求uri:http://fun.tester:12345/ , 耗時(shí):300 ms , HTTPcode: 200
WARN-> 04.673 Deamon 異步線程池關(guān)閉!

這里看到雖然我起了10個(gè)線程分別執(zhí)行請(qǐng)求,但是每個(gè)請(qǐng)求的耗時(shí)都是非常長(zhǎng)的,但是只有F-5這個(gè)線程執(zhí)行了一次org.apache.http.impl.conn.SystemDefaultDnsResolver#resolve方法,由于HttpClient只有一個(gè)連接。所以應(yīng)當(dāng)是每個(gè)連接創(chuàng)建的時(shí)候會(huì)調(diào)用org.apache.http.impl.conn.SystemDefaultDnsResolver#resolve方法,而每個(gè)線程請(qǐng)求耗時(shí)比較高,原因是因?yàn)槊總€(gè)線程去獲取到鏈接資源之后,會(huì)重新進(jìn)行建聯(lián)的過程導(dǎo)致的。

實(shí)踐出真知,奇怪的知識(shí)又增加了。

分享到:
標(biāo)簽:解析 DNS
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定