问题背景
从V1.16升级到V1.20.23,调试接口自动化场景,Case执行异常
现象一:断言-文本-不包含,即正则“(?s)^((?!keyword).)*$”,取消此断言,调试正常
现象二:ms-node-controller容器日志报:Exception in thread "ThreadGroup 1-1" java.lang.StackOverflowError
现象
接口自动化场景,点调试,运行到某个case,就会卡在“测试中”
单独运行case,无结果返回
问题定位
查看日志,ms-node-controller容器返回:Exception in thread "ThreadGroup 1-1" java.lang.StackOverflowError
同一个场景下,部分case异常,部分正常,比对正常和异常的,找到断言部分差异
定位到是【文本-不包含】的断言不启用,则case能成功;
排查正则不包含语句:(?s)^((?!keyword).)*$,发现正则没问题
综合来看:StackOverflowError有一个原因是线程内存溢出,而不启用能成功,启用就失败,有可能是因为启用后内存占用超限
问题结论
加大ms-node-controller容器的JVM线程堆栈内存上限
解决方案
进入ms-node-controller容器内,执行top,能看到当前的Java运行配置
进入/opt/metersphere/,可以看到有很多docker-compose*.yml文件,包含node-controller
进入Portainer,在Container details看到Env里有JAVA_OPTIONS配置,复制现有的,并增加【 -Xmx1024m -Xms1024m -Xmn256m -Xss20m】
编辑docker-compose-node-controller.yml,在environment下,新增JAVA_OPTIONS配置,写入上面的配置,完整配置如下:
version: "2.1"
services:
ms-node-controller:
image: ${MS_IMAGE_PREFIX}/ms-node-controller:${MS_IMAGE_TAG}
container_name: ms-node-controller
environment:
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS: 'true'
RUN_AS_NON_ROOT_USER: 'true'
JAVA_OPTIONS: '-Dfile.encoding=utf-8 -Djava.awt.headless=true --add-opens java.base/jdk.internal.loader=ALL-UNNAMED -Xmx1024m -Xms1024m -Xmn256m -Xss20m'
command: sh -c 'sed -i "s/:101:/:${MS_DOCKER_GID:-101}:/g" /etc/group; /deployments/run-java.sh'
ports:
- ${MS_NODE_CONTROLLER_PORT}:8082
- ${MS_NODEEXPORTER_PORT}:9100
healthcheck:
test: ["CMD", "nc", "-zv", "localhost", "8082"]
interval: 6s
timeout: 5s
retries: 10
volumes:
- ms-conf:/opt/metersphere/conf
- ms-data:/opt/metersphere/data
- ms-logs:/opt/metersphere/logs
- /var/run/docker.sock:/var/run/docker.sock
mem_limit: 2048m
restart: always
networks:
- ms-network
注:按需配置内存上限
重新创建docker容器:
docker-compose -f docker-compose-base.yml -f docker-compose-node-controller.yml up -d
注:要连着base.yml文件
验收
进入ms-node-controller容器内,执行top,能看到新配置是否生效
-Xss配置为2m,还是失败,考虑到服务器内存比较大,直接改到20m,这回自动化场景的调试就一路顺畅了