笔者在本系列文章基于docker容器化部署微服务完成了服务的容器化部署,在运维过程中发现服务占用内存过大,于是希望通过调整JVM
参数的方式调整进程大小,尽可能减小对服务器内存的占用。
可以看到笔者的上方的文章,笔者对每一个服务都调整的JVM
参数,就以account-service
的Dockerfile
为例,如下所示,可以看到笔者调整了初始化堆大小和最大堆大小:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD account-service-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
# 将堆大小设置为64M
ENTRYPOINT exec java -Xmx64m -Xms64m -Djava.security.egd=file:/dev/./urandom -jar /app.jar
完成后我们键入下面这条docker
命令查看性能开销
docker stats
可以看到内存占用也小了许多,但第一行进程nacos
占用还是很大。
我们键入top
查看实际CPU
和内存占用情况。发现第一行有个内存占用很大的进程。
我们通过cd /proc/pid
定位具体进程
cd /proc/27899
经过确认还真的是nacos
,所以我们需要对nacos
进行调整。
我们输入htop
命令间隔2min
来看看nacos
启动的参数
htop -d 120000
如下图所示,可以看到nacos
启动的jvm
参数指定的堆区大小默认为512m
,所以我们需要对其进行调整。
笔者一开始也尝试在docker-compose.yml
用environment设置JVM
参数,但是查看htop似乎没有生效,经过查阅网上资料得知,nacos
只有1.40+
才支持调整JVM
参数,所以我们需要对nacos
进行一次升级。
根据官网文档,笔者将docker-compose
调整成下面这个模样,可以看到JVM
参数采用JVM_XMS
、JVM_XMX
进行调整
nacos:
image: nacos/nacos-server:1.4.0
container_name: nacos
environment:
- PREFER_HOST_MODE=hostname
# 设置JVM参数
- JVM_XMS=100m
- JVM_XMX=100m
- MODE=standalone
- MYSQL_DATABASE_NUM=1
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_MASTER_SERVICE_HOST=mysql
- MYSQL_MASTER_SERVICE_DB_NAME=nacos_config
- MYSQL_MASTER_SERVICE_PORT=3306
- MYSQL_MASTER_SERVICE_USER=root
- MYSQL_MASTER_SERVICE_PASSWORD=xxxxx
volumes:
- /app/cloud/nacos/logs:/home/nacos/logs
ports:
- "8848:8848"
depends_on:
- mysql
restart: always
完成后重启nacos
,查阅日志发现naocs
报了这样一个错误,MYSQL_SERVICE_HOST
参数未知。
可是笔者的docker-compose
确实有配置这个参数。笔者由此推测新版本配置方式可能有所不同,查阅网上资料后找到一个发现nacos1.4.0
中始终有一个名为custom.properties
的文件。查看后发现这里面确实有关于数据的配置,所以新版本的nacos
我们需要通过这个配置文件进行nacos
参数配置,所以笔者在宿主机创建/app/cloud/nacos/init.d/custom.properties
文件,键入以下内容:
server.servlet.contextPath=/nacos
server.port=8848
# 数据库配置信息
db.num=1
db.url.0=jdbc:mysql://ip:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=Z120194199
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i
server.tomcat.basedir=
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
nacos.core.auth.system.type=nacos
nacos.core.auth.caching.enabled=false
nacos.istio.mcp.server.enabled=false
# 注意人证的不需要记得去掉,否则不会使用的读者可能会出现服务无法注册到nacos上的问题(报一个503的错误)
#nacos.core.auth.enabled=true
#nacos.core.auth.default.token.expire.seconds=18000
#nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
完成后在docker-compose
中建立宿主机文件和nacos
容器中custom.properties
的映射。完整文件如下:
version: "3"
services:
mysql:
container_name: mysql
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=Z120194199
volumes:
- /app/cloud/mysql/data:/var/lib/mysql
ports:
- "3306:3306"
restart: always
nacos:
image: nacos/nacos-server:1.4.0
container_name: nacos
environment:
- PREFER_HOST_MODE=hostname
- JVM_XMS=64m
- JVM_XMX=64m
- JVM_XMN=16m
- MODE=standalone
- MYSQL_DATABASE_NUM=1
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_MASTER_SERVICE_HOST=ip
- MYSQL_MASTER_SERVICE_DB_NAME=nacos_config
- MYSQL_MASTER_SERVICE_PORT=3306
- MYSQL_MASTER_SERVICE_USER=root
- MYSQL_MASTER_SERVICE_PASSWORD=Z120194199
volumes:
- /app/cloud/nacos/logs:/home/nacos/logs
# 建立宿主和容器配置映射
- /app/cloud/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties
ports:
- "8848:8848"
depends_on:
- mysql
restart: always
可以看到启动成功了,服务也能正常访问
查看docker
性能开销和内存占用也确实小了许多。
通过top
命令查阅一切都正常
由于笔者当前服务业务比较小,后续可能随着功能扩展对象会不断增多,如果我们仍然使用这么小的堆内存的话,可能会导致频繁的GC
进而出现性能瓶颈以及CPU
开销增加,所以后续我们还需不断监控服务器情况以便适时做出调整。
以笔者为例,调整为64M时,在启动之处CPU使用率很高,大概率是因为启动时存在大量GC,后续观察后稳定许多。这一点读者也可以留意一下。
这里笔者就以nacos
容器为例查阅服务器情况,首先使用exec
进入容器
docker exec -it cid bash
使用jps定位进程id,得知为19,然后使用jmap查看堆区使用情况,可以看到老年代已经爆满了
[root@6bf8bccf8a49 nacos]# jmap -heap 19
Attaching to process ID 19, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.272-b10
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 67108864 (64.0MB)
NewSize = 16777216 (16.0MB)
MaxNewSize = 16777216 (16.0MB)
OldSize = 50331648 (48.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 15138816 (14.4375MB)
used = 4554048 (4.34307861328125MB)
free = 10584768 (10.09442138671875MB)
30.081929788961038% used
Eden Space:
capacity = 13500416 (12.875MB)
used = 4554048 (4.34307861328125MB)
free = 8946368 (8.53192138671875MB)
33.73264942354369% used
From Space:
capacity = 1638400 (1.5625MB)
used = 0 (0.0MB)
free = 1638400 (1.5625MB)
0.0% used
To Space:
capacity = 1638400 (1.5625MB)
used = 0 (0.0MB)
free = 1638400 (1.5625MB)
0.0% used
tenured generation:
capacity = 50331648 (48.0MB)
used = 50331640 (47.99999237060547MB)
free = 8 (7.62939453125E-6MB)
99.99998410542806% used
27547 interned Strings occupying 3052848 bytes.
我们再查看gc情况,可以看到尽管堆区占用很大,但是gc情况还算稳定,所以暂时不用调整堆区内存
[root@6bf8bccf8a49 nacos]# jstat -gc 19 10000 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1600.0 1600.0 102.1 0.0 13184.0 13184.0 49152.0 49152.0 81192.0 77804.7 10024.0 9419.2 213 1.184 36 5.830 7.014
1600.0 1600.0 0.0 0.0 13184.0 4324.9 49152.0 49152.0 81448.0 77897.3 10024.0 9419.2 213 1.184 37 5.975 7.159
1600.0 1600.0 0.0 0.0 13184.0 6717.5 49152.0 49152.0 81448.0 77897.3 10024.0 9419.2 213 1.184 37 5.975 7.159
1600.0 1600.0 0.0 0.0 13184.0 9204.0 49152.0 49152.0 81448.0 77897.3 10024.0 9419.2 213 1.184 37 5.975 7.159
1600.0 1600.0 0.0 0.0 13184.0 11435.6 49152.0 49152.0 81448.0 77897.3 10024.0 9419.2 213 1.184 37 5.975 7.159
使用curl查看服务可用性,莫得问题,收工!!!
curl ip:8090/account/getByCode/zsy
# 服务正常响应
{"status":100,"message":"操作成功","data":{"id":1,"accountCode":"zsy","accountName":"zsy","amount":10000.00},"success":true,"timestamp":1675603315488}
升级过程中,很大概率会和之前版本存在兼容性问题。读者必须仔细研读官方文档设计过程,并在升级过程中结合日志去推测可能存在的问题,去不断尝试搜索引擎中得出的解决方案。
kubernetes集群:nacos搭建
JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结(点赞收藏)
使用docker-compose,调整JVM参数
top命令介绍、实存(RES) 与 虚存(VIRT)区别 ——VIRT持续增长,记一次内存泄漏定位
Nacos 内存参数修改调优
运维(4) nacos启动jvm参数调整解决内存占用过多问题
使用创建的用户注册到nacos时出现403
大白话带你认识JVM