记一次Nacos容器升级调优
# 前言
笔者在本系列文章基于docker容器化部署微服务 (opens new window)完成了服务的容器化部署,在运维过程中发现服务占用内存过大,于是希望通过调整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
2
3
4
5
6
完成后我们键入下面这条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文件
根据官网文档,笔者将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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
完成后重启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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
完成后在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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 启动并测试
可以看到启动成功了,服务也能正常访问

查看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.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
我们再查看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
2
3
4
5
6
7
使用curl查看服务可用性,莫得问题,收工!!!
curl ip:8090/account/getByCode/zsy
# 服务正常响应
{"status":100,"message":"操作成功","data":{"id":1,"accountCode":"zsy","accountName":"zsy","amount":10000.00},"success":true,"timestamp":1675603315488}
2
3
4
# 小结
升级过程中,很大概率会和之前版本存在兼容性问题。读者必须仔细研读官方文档设计过程,并在升级过程中结合日志去推测可能存在的问题,去不断尝试搜索引擎中得出的解决方案。
# 参考文献
kubernetes集群:nacos搭建 (opens new window)
JVM 参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结(点赞收藏) (opens new window)
使用docker-compose,调整JVM参数 (opens new window)
top命令介绍、实存(RES) 与 虚存(VIRT)区别 ——VIRT持续增长,记一次内存泄漏定位 (opens new window)
Nacos 内存参数修改调优 (opens new window)
运维(4) nacos启动jvm参数调整解决内存占用过多问题 (opens new window)