基於Kubernetes啟動WebLogic后,發現JVM的最大heap size一直在700多M左右,通過
kubectl logs 察看pod啟動狀態,發現日志中並沒有-Xms和-Xmx參數.日志部分如下:
[root@k8s-master fluentd-elasticsearch]# kubectl logs helloworld-service-4d72j . . JAVA Memory arguments: -Djava.security.egd=file:/dev/./urandom . CLASSPATH=/u01/oracle/wlserver/../oracle_common/modules/javax.persistence_2.1.jar:/u01/oracle/wlserver/../wlserver/modules/com.oracle.weblogic.jpa21support_1.0.0.0_2-1.jar:/usr/java/jdk1.8.0_101/lib/tools.jar:/u01/oracle/wlserver/server/lib/weblogic_sp.jar:/u01/oracle/wlserver/server/lib/weblogic.jar:/u01/oracle/wlserver/../oracle_common/modules/net.sf.antcontrib_1.1.0.0_1-0b3/lib/ant-contrib.jar:/u01/oracle/wlserver/modules/features/oracle.wls.common.nodemanager_2.0.0.0.jar:/u01/oracle/wlserver/../oracle_common/modules/com.oracle.cie.config-wls-online_8.1.0.0.jar:/u01/oracle/wlserver/common/derby/lib/derbyclient.jar:/u01/oracle/wlserver/common/derby/lib/derby.jar:/u01/oracle/wlserver/server/lib/xqrl.jar . PATH=/u01/oracle/wlserver/server/bin:/u01/oracle/wlserver/../oracle_common/modules/org.apache.ant_1.9.2/bin:/usr/java/jdk1.8.0_101/jre/bin:/usr/java/jdk1.8.0_101/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/default/bin:/u01/oracle/oracle_common/common/bin:/u01/oracle/oracle_common/common/bin:/u01/oracle/wlserver/common/bin:/u01/oracle/user_projects/domains/base_domain/bin:/u01/oracle . *************************************************** * To start WebLogic Server, use a username and * * password assigned to an admin-level user. For * * server administration, use the WebLogic Server * * console at http://hostname:port/console * *************************************************** starting weblogic with Java version: java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode) Starting WLS with line: /usr/java/jdk1.8.0_101/bin/java -server -Djava.security.egd=file:/dev/./urandom -Dweblogic.Name=AdminServer -Djava.security.policy=/u01/oracle/wlserver/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -Djava.endorsed.dirs=/usr/java/jdk1.8.0_101/jre/lib/endorsed:/u01/oracle/wlserver/../oracle_common/modules/endorsed -da -Dwls.home=/u01/oracle/wlserver/server -Dweblogic.home=/u01/oracle/wlserver/server -Dweblogic.utils.cmm.lowertier.ServiceDisabled=true weblogic.Server
修改yaml文件中的limit參數,發現並不能影響JVM的size,開始懷疑JVM自己根據虛擬機以及啟動的container實例的多少自動調整內存,調整replicationcontrol的數目,發現仍然每個進程JVM占用700m.
查閱相關材料,發現Linux Kernel cgroups針對JVM的內存控制機制如下:
- kubernetes switch(-limits)以及docker switch(-m, –memory and –memory-swap)設置都是為了讓linux內核決定是否kill掉進程,如果他們消耗比較接近的話,但JVM不會意識到有這個限制。
- JVM的人體工程學機制(JVM ergonomic page)會優化成缺省占用1/4的物理內存,因為JVM並不意識到自己運行在container中,所以一個3G的虛擬機器,JVM最大占用的空間是3*1024/4=768M,正是我們在weblogic管理控制台上看到的jvm最大內存數.
- 如果我們采用limit或者-m 1G的參數,意味着Docker Daemon會限制1G的memory和1G的memory swap,也就是說你進程可以消耗接近2G的內存,不會被kill掉
如果我們想自己控制JVM所占用的heap size,我們可以通過在啟動命令行中加入$JAVA_OPTIONS,比如:
$ docker run -d --name mycontainer8g -p 8080:8080 -m 800M -e JAVA_OPTIONS='-Xmx300m' rafabene/java-container:openjdk-env
如果是在kubernetes環境中,可以設置env環境變量把參數傳入,因為setDomainEnv中,已經把JAVA_OPTIONS作為啟動參數傳入命令行。
示例如:
[root@k8s-master ~]# cat rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: helloworld-service spec: replicas: 2 template: metadata: labels: weblogic-app: "helloworld" version: "0.1" spec: containers: - name: weblogichelloworld image: 1213-helloworld:v1 env: - name: "JAVA_OPTIONS" value: "-Xms1024m -Xmx1024m" ports: - containerPort: 7001 --- apiVersion: v1 kind: Service metadata: name: helloworldsvc labels: weblogic-app: helloworld spec: type: NodePort ports: - port: 7001 protocol: TCP targetPort: 7001 name: http nodePort: 30001 selector: weblogic-app: helloworld
通過kubectl logs察看pods日志,可以看到-Xms和-Xmx已經被設置,
JAVA Memory arguments: -Djava.security.egd=file:/dev/./urandom . CLASSPATH=/u01/oracle/wlserver/../oracle_common/modules/javax.persistence_2.1.jar:/u01/oracle/wlserver/../wlserver/modules/com.oracle.weblogic.jpa21support_1.0.0.0_2-1.jar:/usr/java/jdk1.8.0_101/lib/tools.jar:/u01/oracle/wlserver/server/lib/weblogic_sp.jar:/u01/oracle/wlserver/server/lib/weblogic.jar:/u01/oracle/wlserver/../oracle_common/modules/net.sf.antcontrib_1.1.0.0_1-0b3/lib/ant-contrib.jar:/u01/oracle/wlserver/modules/features/oracle.wls.common.nodemanager_2.0.0.0.jar:/u01/oracle/wlserver/../oracle_common/modules/com.oracle.cie.config-wls-online_8.1.0.0.jar:/u01/oracle/wlserver/common/derby/lib/derbyclient.jar:/u01/oracle/wlserver/common/derby/lib/derby.jar:/u01/oracle/wlserver/server/lib/xqrl.jar . PATH=/u01/oracle/wlserver/server/bin:/u01/oracle/wlserver/../oracle_common/modules/org.apache.ant_1.9.2/bin:/usr/java/jdk1.8.0_101/jre/bin:/usr/java/jdk1.8.0_101/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/default/bin:/u01/oracle/oracle_common/common/bin:/u01/oracle/oracle_common/common/bin:/u01/oracle/wlserver/common/bin:/u01/oracle/user_projects/domains/base_domain/bin:/u01/oracle . *************************************************** * To start WebLogic Server, use a username and * * password assigned to an admin-level user. For * * server administration, use the WebLogic Server * * console at http://hostname:port/console * *************************************************** starting weblogic with Java version: java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode) Starting WLS with line: /usr/java/jdk1.8.0_101/bin/java -server -Djava.security.egd=file:/dev/./urandom -Dweblogic.Name=AdminServer -Djava.security.policy=/u01/oracle/wlserver/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -Xms1024m -Xmx1024m -Djava.endorsed.dirs=/usr/java/jdk1.8.0_101/jre/lib/endorsed:/u01/oracle/wlserver/../oracle_common/modules/endorsed -da -Dwls.home=/u01/oracle/wlserver/server -Dweblogic.home=/u01/oracle/wlserver/server -Dweblogic.utils.cmm.lowertier.ServiceDisabled=true weblogic.Server
轉到WebLogic管理控制台去查看已經設置成功。
參考文檔:
https://developers.redhat.com/blog/2017/03/14/java-inside-docker/
https://fabiokung.com/2014/03/13/memory-inside-linux-containers/