POM.xml配置
</dependencies>
<!--skywalking日志监控依赖-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.5.0</version>
</dependency>
</dependencies>
<build>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<!--生成的镜像名称,需要替换的地方-->
<imageName>creatar</imageName>
<!--覆盖旧镜像-->
<forceTags>true</forceTags>
<!--指定dockerfile文件所在目录,跟pom平级-->
<dockerDirectory>${basedir}</dockerDirectory>
<buildArgs>
<!--指定需要复制的jar的名称,在dockerfile中会根据这个参数来将jar复制到容器中-->
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
logback日志配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty scope="context" name="log.path" source="logging.file.path"/>
<!-- 日志输出格式 -->
<property name="log.pattern"
value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - [methodName:%method,line:%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/%d{yyyy-MM-dd}/%d{HH}/sys-info.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 只会打印info不会有info日志-->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/%d{yyyy-MM-dd}/%d{HH}/sys-error.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--发送日志skywalking-->
<appender name="SKYWALKING" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<!-- 日志输出编码 -->
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.example" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="SKYWALKING"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
<appender-ref ref="SKYWALKING"/>
</root>
</configuration>
Dockerfile
Dockerfile文件跟pom文件平级
FROM eclipse-temurin:21
RUN mkdir /opt/app
ARG JAR_FILE
#看情况,自己要改复制到镜像中的名称也行,但是注意在ENTRYPOINT处启动的jar名称也要换
ADD target/${JAR_FILE} /opt/app/creatar.jar
#跟项目src文件平级的文件夹,后续会有截图
ADD base-app/skywalking/apache-skywalking-java-agent-9.1.0.tgz /opt/app/
#配置日志监控平台,跟后续的docker-compose呼应
ENV SW_AGENT_NAME=creatar
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=creatar-skywalking-oap:11800
ENTRYPOINT ["java","-javaagent:/opt/app/skywalking-agent/skywalking-agent.jar","-jar","-Xms512m","-Xmx512m","/opt/app/creatar.jar"]
docker-compose
version: "1.0.0"
#创建Docker网络,用于容器间通信,通过容器名称访问
networks:
#容器名称,默认就是使用bridge模式,如果替换了名称,那本文件中后续所有关于networks节点的配置都要换名称
creatar-networks:
services:
#应用镜像,镜像名称,在pom的imageName节点配置的是什么这里就写什么
creatar:
image: creatar:latest
#应用容器名称,可换可不换
container_name: creatar
#限制容器内存大小
deploy:
resources:
limits:
memory: 1024MB
networks:
- creatar-networks
#配置日志监控环境变量,用于初次运行时
environment:
- "SW_AGENT_NAME=creatar"
- "SW_AGENT_COLLECTOR_BACKEND_SERVICES=creatar-skywalking-oap:11800"
ports:
- "9436:9436"
restart: always
#启动应用之前先启动redis、mysql、es
depends_on:
- "creatar-redis"
- "creatar-mysql"
- "creatar-elasticsearch"
volumes:
- ./base-app/creatar/logs:/opt/app/logs
#Redis容器
creatar-redis:
image: redis:7.2.4
container_name: creatar-redis
cap_add:
- ALL
command: redis-server /etc/redis/redis.conf
networks:
- creatar-networks
ports:
- 9437:6379
restart: always
volumes:
- ./base-app/redis/data:/data:rw
- ./base-app/redis/conf/redis.conf:/etc/redis/redis.conf:rw
- ./base-app/redis/logs:/logs:rw
#mysql容器
creatar-mysql:
image: mysql:8.2.0
container_name: creatar-mysql
cap_add:
- ALL
command:
- "--default-authentication-plugin=caching_sha2_password"
environment:
#配置mysql的root用户密码
- "MYSQL_ROOT_PASSWORD=creatar_mysql@yyds"
#创建数据库
- "MYSQL_DATABASE=creatar"
#创建用户,该用户对MYSQL_DATABASE创建的数据库拥有所有权限
- "MYSQL_USER=creatar"
#新用户的密码
- "MYSQL_PASSWORD=creatar9436"
- "TZ=Asia/Shanghai"
networks:
- creatar-networks
ports:
- 9438:3306
restart: always
volumes:
- ./base-app/mysql/data/:/var/lib/mysql:rw
- ./base-app/mysql/log:/var/log/mysql:rw
#ES容器
creatar-elasticsearch:
image: elasticsearch:7.17.16
container_name: creatar-elasticSearch
deploy:
resources:
limits:
memory: 3072MB
cap_add:
- ALL
environment:
- discovery.type=single-node
#设置Es访问密码,用户名默认就是:elastic
- ELASTIC_PASSWORD=creatar9436
- xpack.security.enabled=true
- ES_JAVA_OPTS=-Xlog:disable -Xlog:gc=debug:stderr -Xms2048m -Xmx3072m
- PATH=/usr/share/elasticsearch/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- ELASTIC_CONTAINER=true
networks:
- creatar-networks
ports:
- 9439:9200
- 9440:9300
restart: always
ulimits:
memlock:
hard: -1
soft: -1
nofile:
hard: 65536
soft: 65536
volumes:
- ./base-app/elasticSearch/data/data:/usr/share/elasticsearch/data:rw
- ./base-app/elasticSearch/data/backup:/usr/share/elasticsearch/backup:rw
- ./base-app/elasticSearch/data/conf/jvm.options:/usr/share/elasticsearch/config/jvm.options:rw
#创建日志监控收集工具,oap
creatar-skywalking-oap:
image: apache/skywalking-oap-server:9.0.0
container_name: creatar-skywalking-oap
cap_add:
- ALL
environment:
#使用Es存储日志
- "SW_STORAGE=elasticsearch"
#ES地址,由于是同一网络所以就使用容器名称即可
- "SW_STORAGE_ES_CLUSTER_NODES=creatar-elasticsearch:9200"
#ES地址
- "SW_ES_USER=elastic"
#ES密码,就是在ES容器配置项目中设置的密码
- "SW_ES_PASSWORD=creatar9436"
- "TZ=Asia/Shanghai"
networks:
- creatar-networks
ports:
#端口暴露,skywalking需要暴露11800和12800
- 9441:11800
- 9442:12800
restart: always
#依赖于ES,需要等ES启动之后在启动
depends_on:
- "creatar-elasticsearch"
#日志监控界面容器
creatar-skywalking-ui:
image: apache/skywalking-ui:9.0.0
container_name: creatar-skywalking-ui
cap_add:
- ALL
environment:
#skywalking-oap服务地址,使用容器名访问
- "SW_OAP_ADDRESS=http://creatar-skywalking-oap:12800"
- "TZ=Asia/Shanghai"
networks:
- creatar-networks
ports:
#UI界面需要暴露8080端口
- 9443:8080
restart: always
depends_on:
#依赖于Skywalking-oap服务
- "creatar-skywalking-oap"
初次部署运行脚本
echo "开始构建应用镜像----------------"
#删除旧镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#打包并使用dockerfile构建应用镜像
mvn clean package
mvn docker:build
#后续会有该目录的讲解
chmod -R 777 ./base-app
echo "开始构建基础应用---------------"
docker-compose up -d
#赋予权限
chmod 777 deploy.sh
#执行脚本
sh deploy.sh
卸载脚本
会将应用的Docker镜像删除,以及本次部署所用到的,应用容器,基础设施容器全部删除
#停止creatar容器
docker stop $(docker ps -a | grep creatar | awk '{print $1}')
#停止mysql容器
docker stop $(docker ps -a | grep creatar-mysql | awk '{print $1}')
#停止Redis容器
docker stop $(docker ps -a | grep creatar-redis | awk '{print $1}')
#停止skywalking-ui容器
docker stop $(docker ps -a | grep creatar-skywalking-ui | awk '{print $1}')
#停止skywalking-oap容器
docker stop $(docker ps -a | grep creatar-skywalking-oap | awk '{print $1}')
#停止ES容器
docker stop $(docker ps -a | grep creatar-elasticSearch | awk '{print $1}')
#删除creatar容器
docker rm $(docker ps -a | grep creatar | awk '{print $1}')
#删除creatar镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#删除mysql容器
docker rm $(docker ps -a | grep creatar-mysql | awk '{print $1}')
#删除redis容器
docker rm $(docker ps -a | grep creatar-redis | awk '{print $1}')
#删除skywalking-ui容器
docker rm $(docker ps -a | grep creatar-skywalking-ui | awk '{print $1}')
#删除skywalking-oap容器
docker rm $(docker ps -a | grep creatar-skywalking-oap | awk '{print $1}')
#删除es容器
docker rm $(docker ps -a | grep creatar-elasticSearch | awk '{print $1}')
#删除Docker网络
docker network rm creatar_creatar-networks
#删除creatar应用数据
rm -rf ./base-app/creatar/logs/*
#清空mysql数据
rm -rf ./base-app/mysql/data/*
rm -rf ./base-app/mysql/log/*
#删除Redis数据
rm -rf ./base-app/redis/data/*
rm -rf ./base-app/redis/conf/redis.conf
#赋予权限
chmod 777 undeploy.sh
#执行脚本
sh undeploy.sh
应用更新
当jar报需要更新时使用
#拉取最新代码
git pull origin main
#停止容器
docker stop $(docker ps -a | grep creatar | awk '{print $1}')
#删除容器
docker rm $(docker ps -a | grep creatar | awk '{print $1}')
#删除旧镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#构建镜像
mvn clean package
mvn docker:build
docker run -dit --restart=always -p 9436:9436 -m 512m --name creatar --network=creatar_creatar-networks $(docker images | grep creatar | awk '{print $3}') /bin/bash
chmod 777 build.sh
sh build.sh
base-app目录详解
该目录是和项目中的src文件夹平级的,当本项目所用到的所有容器启动之后,他们的数据卷都是挂载在这个目录的,里面包含了一些容器启动时的配置文件,以及第三方的一些包(例如Skywalking的插件tar包)
在项目中按照这个结构创建即可,其中的**.gitkeep**文件只是为了占位而已,避免文件夹是空的提交不到Git上.
jvm.options
该文件是es启动时需要的,如果没有会报错,这个文件是本人在不使用数据卷挂载时启动ES之后复制出来的官方配置
################################################################
##
## JVM configuration
##
################################################################
##
## WARNING: DO NOT EDIT THIS FILE. If you want to override the
## JVM options in this file, or set any additional options, you
## should create one or more files in the jvm.options.d
## directory containing your adjustments.
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/jvm-options.html
## for more information.
##
################################################################
################################################################
## IMPORTANT: JVM heap size
################################################################
##
## The heap size is automatically configured by Elasticsearch
## based on the available memory in your system and the roles
## each node is configured to fulfill. If specifying heap is
## required, it should be done through a file in jvm.options.d,
## and the min and max should be set to the same value. For
## example, to set the heap to 4 GB, create a new file in the
## jvm.options.d directory containing these lines:
##
## -Xms4g
## -Xmx4g
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/heap-size.html
## for more information
##
################################################################
################################################################
## Expert settings
################################################################
##
## All settings below here are considered expert settings. Do
## not adjust them unless you understand what you are doing. Do
## not edit them in this file; instead, create a new file in the
## jvm.options.d directory containing your adjustments.
##
################################################################
## GC configuration
8-13:-XX:+UseConcMarkSweepGC
8-13:-XX:CMSInitiatingOccupancyFraction=75
8-13:-XX:+UseCMSInitiatingOccupancyOnly
## G1GC Configuration
# NOTE: G1 GC is only supported on JDK version 10 or later
# to use G1GC, uncomment the next two lines and update the version on the
# following three lines to your version of the JDK
# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
## JVM temporary directory
-Djava.io.tmpdir=${ES_TMPDIR}
## heap dumps
# generate a heap dump when an allocation from the Java heap fails; heap dumps
# are created in the working directory of the JVM unless an alternative path is
# specified
-XX:+HeapDumpOnOutOfMemoryError
# exit right after heap dump on out of memory error. Recommended to also use
# on java 8 for supported versions (8u92+).
9-:-XX:+ExitOnOutOfMemoryError
# specify an alternative path for heap dumps; ensure the directory exists and
# has sufficient space
-XX:HeapDumpPath=data
# specify an alternative path for JVM fatal error logs
-XX:ErrorFile=logs/hs_err_pid%p.log
## JDK 8 GC logging
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
# JDK 9+ GC logging
9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m
redis.conf
Redis容器的配置文件,其中也是配置了一些我个人的东西,例如连接密码呀等等,可以自己复制一份官方的配置文件进行修改即可,篇幅过长这里不做粘贴了
项目整体结构
配置文件中的连接信息
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
#mysql地址,注意,这里因为应用和mysql容器是在一个网络内的,所以可以直接使用mysql的容器名称访问,并且端口号使用的是容器内部的端口号并不是暴露出来的端口号
url: jdbc:mysql://creatar-mysql:3306/creatar?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: creatar
password: creatar9436
data:
redis:
#同理也是使用的容器名称,我这里是由于使用了SpringBoot3.3.0版本是这么配置的,具体的各位可以参考自己的配置
url: redis://creatar9436@creatar-redis:6379
lettuce:
pool:
max-wait: 3000ms
#这里由于项目中使用了Easy-es依赖操作ES,所以我这里是这么配置的
easy-es:
enable:
address: creatar-elasticsearch:9200
username: elastic
password: creatar9436
logging:
#指定日志配置文件
config: classpath:logback-spring.xml
level:
web: error
sql: debug
com:
baomidou:
mybatisplus: debug
file:
path: ./logs/
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler