在ToB场景中,常常需要写一些demo,来完成某些测试或者说调试工作。
为了简化大家输出demo应用程序包的成本,我们在这里简单总结了一个Demo应用程序。
在我们需要的时候,只需要替换某些参数即可使用。
1.Demo结构
Demo结构如下图所示:
有五个部分:
(1)bin目录下的启动和停止脚本
(2)assemblies中定义assembly插件对tar包配置
(3)java目录下的业务逻辑源码
(4)resources目录下的配置文件,比如日志配置文件。
(5)pom.xml中定义的依赖项。
2.pom.xml文件定义
我们这里使用maven构建工具。
pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>hdfs-client-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<hadoop.version>2.3.0</hadoop.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<assembly.path>src/main/assemblies/hdfs-client-demo-assembly.xml</assembly.path>
<slf4j.version>1.7.36</slf4j.version>
<logback.version>1.2.11</logback.version>
</properties>
<dependencies>
<!-- 业务依赖项,可随意替换 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>mvn-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/dependency</outputDirectory>
<overWriteSnapshots>true</overWriteSnapshots>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<skipAssembly>false</skipAssembly>
<descriptors>
<descriptor>${assembly.path}</descriptor>
</descriptors>
<finalName>hdfs-client-demo-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>./target</outputDirectory>
<!--macOS: posix, linux: gnu-->
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<excludes>
<exclude>*.yml</exclude>
<exclude>*.properties</exclude>
<exclude>*.txt</exclude>
<exclude>*.xml</exclude>
<exclude>*.json</exclude>
<exclude>*.dtd</exclude>
<exclude>*.sh</exclude>
<exclude>conf/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<!--使用plugin生成的jar包-->
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>assembly</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
这里包名为hdfs-client-demo,需根据自己应用名称替换。
3.java目录下的源码
这里可随意创建自己的demo类。
4.resources配置文件目录
我们把配置文件放到resources目录下,最简单的就是一个logback.xml文件,内容如下:
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="log_dir" value="logs"/>
<property name="log_pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %p %C.%M [%t] [line:%L]- %m%n"/>
<property name="maxHistory" value="7"/>
<timestamp key="bySecond" datePattern="yyyyMMddHHmmss"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<pattern>${log_pattern}</pattern>
</encoder>
</appender>
<appender name="DEBUG-APPENDER" class="ch.qos.logback.core.FileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<file>${log_dir}/debug-log.${bySecond}.log</file>
<encoder>
<pattern>${log_pattern}</pattern>
</encoder>
<append>false</append>
</appender>
<!-- <logger name="org.apache.kafka.clients" level="OFF"></logger>-->
<root>
<level value="DEBUG"/>
<appender-ref ref="STDOUT"/>
<appender-ref ref="DEBUG-APPENDER"/>
</root>
</configuration>
如果要禁止某种日志的输出,将对应logger的level置为OFF即可。
5.bin目录下的运维脚本
主要包括start.sh和stop.sh,用于启动和停止demo应用。
start.sh脚本内容如下:
#!/bin/bash
source /etc/profile >/dev/null 2>&1
BIN_DIR=$(cd "$(dirname "$0")" && pwd)
cd "${BIN_DIR}" && cd ..
WORKSPACE=$(pwd)
if [ -z "${MAIN_CLASS}" ]; then
MAIN_CLASS=example.hadoop.HDFSClientDemo
fi
pid=$(ps aux | grep "${MAIN_CLASS}" | grep -v grep | awk '{print $2}')
if [[ "$pid" != "" ]]; then
echo "Process (PID = $pid) is already running."
exit 0
fi
if [ -n "${JAVA_HOME}" ]; then
if [[ "${JAVA_HOME}" =~ /$ ]]; then
JAVA=${JAVA_HOME}bin/java
else
JAVA=${JAVA_HOME}/bin/java
fi
elif [ -n "$(which java)" ]; then
JAVA=$(which java)
fi
if [ -z "${JAVA}" ]; then
echo "ERROR: could found java"
exit 1
fi
if [ -z "${CONFIG_DIR}" ]; then
CONFIG_DIR="${WORKSPACE}/conf"
fi
CLASSPATH=${WORKSPACE}/lib/*:${WORKSPACE}/conf/:/etc/hadoop/conf/
if [ -z "${MEM_SIZE}" ]; then
MEM_SIZE=4G
fi
MEMORY_OPTS="-Xms${MEM_SIZE} -Xmx${MEM_SIZE}"
if [ -z "${GC_OPTS}" ]; then
GC_OPTS="-XX:+UseG1GC"
fi
LOG_DIR=${WORKSPACE}/logs
GC_LOG_DIR=${WORKSPACE}/logs/gc
mkdir -p ${LOG_DIR} ${GC_LOG_DIR}
export JAVA_OPTS="${MEMORY_OPTS} ${GC_OPTS} ${JMX_OPTS}"
echo "Starting Server..."
${JAVA} \
${JAVA_OPTS} \
-Dlogback.configuration=${CONFIG_DIR}/logback.xml \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=${WORKSPACE}/heap-dump.hprof \
-XX:OnOutOfMemoryError="\"kill -9 %p\"" \
-XX:NumberOfGCLogFiles=10 \
-XX:GCLogFileSize=50M \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:${GC_LOG_DIR}/gc-%t.log \
-cp ${CLASSPATH} \
${MAIN_CLASS} "$@" >/dev/null 2>&1 &
server_pid=$!
echo "start hdfs-client-demo successfully, pid is ${server_pid}"
stop.sh脚本比较简单,找到PID,直接kill即可。
6.打包配置文件
这里指的是maven-assembly-plugin插件需要用到的assembly配置文件。如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>assembly</id>
<formats>
<format>tar.gz</format>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>bin</directory>
<outputDirectory>/bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/resources/</directory>
<outputDirectory>/conf</outputDirectory>
</fileSet>
<fileSet>
<directory>target/dependency</directory>
<outputDirectory>/lib</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>target/hdfs-client-demo-${project.version}.jar</source>
<outputDirectory>/lib</outputDirectory>
</file>
</files>
</assembly>
这里定义了tar包中所包含的内容。
7.打包和运行
当以上都开发完成后,需执行以下命令进行打包。
mvn clean package -Passembly -DskipTests
打包完成后,直接解压,执行start.sh脚本即可启动demo应用。
最好编写README.md文件,详细描述demo应用的功能、设计和使用方式,以便后续可能的交接。