记一次Nacos容器升级调优

前言

笔者在本系列文章基于docker容器化部署微服务完成了服务的容器化部署,在运维过程中发现服务占用内存过大,于是希望通过调整JVM参数的方式调整进程大小,尽可能减小对服务器内存的占用。

可以看到笔者的上方的文章,笔者对每一个服务都调整的JVM参数,就以account-serviceDockerfile为例,如下所示,可以看到笔者调整了初始化堆大小和最大堆大小:

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和内存占用情况。发现第一行有个内存占用很大的进程。

记一次Nacos容器升级调优_第1张图片

我们通过cd /proc/pid定位具体进程

cd /proc/27899

经过确认还真的是nacos,所以我们需要对nacos进行调整。

记一次Nacos容器升级调优_第2张图片

我们输入htop命令间隔2min来看看nacos启动的参数

htop -d 120000

如下图所示,可以看到nacos启动的jvm参数指定的堆区大小默认为512m,所以我们需要对其进行调整。

记一次Nacos容器升级调优_第3张图片

笔者一开始也尝试在docker-compose.yml用environment设置JVM参数,但是查看htop似乎没有生效,经过查阅网上资料得知,nacos只有1.40+才支持调整JVM参数,所以我们需要对nacos进行一次升级。

升级步骤

调整docker-compose文件

根据官网文档,笔者将docker-compose调整成下面这个模样,可以看到JVM参数采用JVM_XMSJVM_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参数未知。

记一次Nacos容器升级调优_第4张图片

调整配置文件

可是笔者的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



启动并测试

可以看到启动成功了,服务也能正常访问

记一次Nacos容器升级调优_第5张图片

查看docker性能开销和内存占用也确实小了许多。

记一次Nacos容器升级调优_第6张图片

通过top命令查阅一切都正常

记一次Nacos容器升级调优_第7张图片

补充说明

由于笔者当前服务业务比较小,后续可能随着功能扩展对象会不断增多,如果我们仍然使用这么小的堆内存的话,可能会导致频繁的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

你可能感兴趣的:(微服务,操作系统,docker,运维,jvm,容器)