阿里開源JDK dragonwell8在容器環境使用


Alibaba Dragonwell 是阿里巴巴的Open JDK 發行版,提供長期支持。 阿里宣傳稱在阿里生產環境實現了應用。Alibaba Dragonwell兼容 Java SE 標准,因此可以方便切換。

下載

可以到https://github.com/alibaba/dragonwell8/releases?spm=5176.cndragonwell.0.0.4c5a7568DpYPsp 下載,當前的最新版是8.4.4 GA

ali jdk8

阿里也提供了鏡像下載地址,可以加速下載:

8.4.4GA

File name 中國大陸 United States
Alibaba_Dragonwell_8.4.4-GA_Linux_x64.tar.gz download download
Alibaba_Dragonwell_8.4.4-GA_source.tar.gz download download
Alibaba_Dragonwell_8.4.4-Experimental_Windows_x64.tar.gz download download
java8-api-8.4.4-javadoc.jar download download
java8-api-8.4.4-sources.jar download download
java8-api-8.4.4.jar download download

SHA256 checksum

使用

wget https://dragonwell.oss-cn-shanghai.aliyuncs.com/8/8.4.4-GA/Alibaba_Dragonwell_8.4.4-GA_Linux_x64.tar.gz
tar zxvf Alibaba_Dragonwell_8.4.4-GA_Linux_x64.tar.gz 
cd jdk8u262-b10/
 bin/java -version

輸出:

openjdk version "1.8.0_262"
OpenJDK Runtime Environment (Alibaba Dragonwell 8.4.4) (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (Alibaba Dragonwell 8.4.4) (build 25.262-b10, mixed mode)

容器環境使用

我們需要准備一個基礎鏡像包,我們以openjdk:8-jdk-slim為基礎包,把jdk替換為dragonwell8

 FROM openjdk:8-jdk-slim
 MAINTAINER jadepeng
 
 RUN sed -i 's#http://deb.debian.org#https://mirrors.163.com#g' /etc/apt/sources.list \
     && apt-get update\
     && apt-get install -y procps unzip curl bash tzdata ttf-dejavu \
     && rm -rf /var/cache/apt/ \
     && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
     && echo "Asia/Shanghai" > /etc/timezone
 
 RUN rm -r -f /usr/local/openjdk-8
 
 ADD jdk8u262-b10  /usr/local/openjdk-8

構建:

docker build -t dragonwell8:8.4.4 .

java應用就可以用dragonwell8:8.4.4 為底包執行了。

dragonwell8 協程使用

dragonwell8的一大特色就是協程(Coroutine )

官方有一個demo:

以一個pingpong 1,000,000次的程序為例,這是一個需要阻塞,切換密集型的應用。

           o      .   _______ _______
              \_ 0     /______//______/|   @_o
                /\_,  /______//______/     /\
               | \    |      ||      |     / |

static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

public static void main(String[] args) throws Exception {
    BlockingQueue<Byte> q1 = new LinkedBlockingQueue<>(), q2 = new LinkedBlockingQueue<>();
    THREAD_POOL.submit(() -> pingpong(q2, q1)); // thread A
    Future<?> f = THREAD_POOL.submit(() -> pingpong(q1, q2)); // thread B
    q1.put((byte) 1);
    System.out.println(f.get() + " ms");
}

private static long pingpong(BlockingQueue<Byte> in, BlockingQueue<Byte> out) throws Exception {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 1_000_000; i++) out.put(in.take());
    return System.currentTimeMillis() - start;
}

運行,查看執行時間:

$java PingPong
13212 ms

// 開啟Wisp2
$java -XX:+UseWisp2 -XX:ActiveProcessorCount=1 PingPong
882 ms

開啟Wisp2后整體運行效率提升了近十多倍,只需要啟動時增加參數-XX:+UseWisp2即可。不用修改一行代碼,即可享受協程帶來的優勢。

隨后可以通過jstack觀察到起來的線程都以協程的方式在運行了。

 - Coroutine [0x7f6d6d60fb20] "Thread-978" #1076 active=1 steal=0 steal_fail=0 preempt=0 park=0/-1
        at java.dyn.CoroutineSupport.unsafeSymmetricYieldTo(CoroutineSupport.java:138)
--
 - Coroutine [0x7f6d6d60f880] "Thread-912" #1009 active=1 steal=0 steal_fail=0 preempt=0 park=0/-1
        at java.dyn.CoroutineSupport.unsafeSymmetricYieldTo(CoroutineSupport.java:138)

...

可以看到最上方的frame上的方法是協程切換,因為線程調用了sleep,yield出了執行權。

開啟Wisp2后,Java線程不再簡單地映射到內核級線程,而是對應到一個協程,JVM在少量內核線上調度大量協程執行,以減少內核的調度開銷,提高web服務器的性能。

在阿里的生產環境,性能指標:

  • 在復雜的業務應用中(tomcat + 大量基於netty的中間件)我們獲得了大約10%的性能提升。
  • 在中間件應用(數據庫代理,MQ)中我們獲得大約20%的性能提升。

更多Wisp的設計實現與API相關信息,請參考Wisp文檔


作者:Jadepeng
出處:jqpeng的技術記事本--http://www.cnblogs.com/xiaoqi
您的支持是對博主最大的鼓勵,感謝您的認真閱讀。
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM