어셈블리를 사용하여 SpringBoot MicroServices 프로젝트를 포장하기 전에 현재 SpringBoot 프로젝트를위한 몇 가지 일반적인 배포 방법에 대해 이야기하고 싶습니다.
Docker 컨테이너를 사용하여 배포하고 SpringBoot의 응용 프로그램을 Docker 이미지로 빌드 한 다음 컨테이너를 통해 이미지를 시작하십시오. 이 방법은 대규모 응용 프로그램 및 응용 프로그램 확장이 필요할 때 매우 편리합니다. 현재 산업 수준의 배포 솔루션이지만 Docker Ecosystem 기술을 마스터해야합니다.
Fatjar를 사용하여 배포 및 직접 시작하십시오. 이는 많은 초보자 또는 매우 소규모 상황에 대한 간단한 응용 프로그램 배포 방법입니다.
이 기사는 주로 배포 관리를보다 쉽게 할 수 있도록 두 번째 배포 방법에보다 친숙한 포장 솔루션을 제공합니다. 첫 번째 방법은 나중에 내 블로그에 작성 될 수 있습니다.
1. 왜 SpringBoot가 서비스에 포장되어야합니까?
최근에 프로젝트 팀을 보았습니다. 그들은 SpringBoot를 사용하여 프로젝트를 개발하고 Spring Boot Fatjar 인 Operation and Maintenance Team과의 상호 작용을 구성했습니다. 또한이 원래 패키지는 의심 할 여지없이 전통적인 프로젝트 개발 회사의 운영 및 유지 보수 직원에게 매우 치명적입니다. 프로젝트가 전달되면 전체 구성 파일이 JAR에 숨겨져 있으며 다른 환경에 대한 구성 파일을 수정하는 것이 매우 어려워집니다. 따라서 회사에 새로운 기술을 도입 할 때 서비스 지향 및 엔지니어링 방법을 고려해야합니다. 기술 프레임 워크 만 참조하는 경우 몇 가지 종속성 만 추가하고 API를 읽고 몇 줄의 코드를 작성하면 실행할 수 있습니다.
위의 문제를 해결하기 위해서는 서비스 지향 및 엔지니어링 지향적이어야하며 두 가지 문제를 대략적으로 해결해야합니다.
SpringBoot가 JAR 외부의 구성 파일을로드하도록 활성화하십시오.
일반적으로 Windows 아래의 쉘 또는 박쥐 인 서비스 기반 스타트 업 스크립트를 제공합니다. SpringBoot의 응용 프로그램 서비스 스크립트를 사용하면 SpringBoot 애플리케이션을 컨테이너로 시작하고 중지 할 수 있습니다.
2. 패키지 스프링 부츠 응용 프로그램 구조 다이어그램
여기서는 먼저 어셈블리를 사용하여 SpringBoot 서비스를 포장 한 후 렌더링을 살펴 봅니다.
3. 서비스 포장을위한 중요한 단계
다음은 SpringBoot를 포장하기위한 자세한 단계입니다.
3.1 어셈블리 패키지 플러그인 추가
<Plugin> <ArtifactID> Maven-Assembly-Plugin </artifactid> <bersion> 3.0.0 </version> <configuration> <descriptor> <crc/main/Assembly/Assembly.xml </descriptor> </descriptors> </configuration> <suceution> <id> make-assembly </id> <id> <Goal> Single </Goal> </Goal> </execution> </executions> </plugin>
위의 코드에서 어셈블리 구성을 기본 디렉토리에 넣었습니다. 이것은 습관이며 여기에 넣을 수 없습니다. 다음은 프로젝트의 일반적인 구조 다이어그램입니다.
3.2 Assembly.xml 구성
어셈블리 구성은 다음 구성과 유사합니다.이 구성은 서비스 스크립트, 항아리, 구성 파일 등을 포장하는 것과 유사합니다. 다음 코드에서 어셈블리가 구성 파일을 입력했음을 알 수 있습니다.
<Assolly> <id> 1.0 </id> <formats> <format> tar.gz </format> </format> </formats> <fileset> <fileset> <firedet> <criptory> src/main/어셈블리/bin </directory> <outputdirectory> bin </outputdirectory> <filemode> 0755 </fileset> </fileset> </fileset> <Directory> SRC/Main/Assembly/Config </directory> <outputDirectory> config </outputDirectory> <fileMode> 0644 </fileMode> </fileset> <Firectory> target </directory> <outputdirectory> lib </outputDirectory> <allener> </concert> </concert> include>. <Directory> src/main/resources </directory> <outputDirectory> logs </outputDirectory> <fileMode> 0755 </fileMode> <excludes> <excludes> **/*</exclud> </filest> </filesetsets> </Assembly>
3.3 서비스 스크립트 작성
이제 Linux 환경에 대한 스크립트를 작성하십시오.
첫 번째 : start.sh startup 스크립트
#!/bin/bashserver_name = 'spring-vue'# jar 이름 jar_name = 'springboot-vue.jar'cd` dirname $ 0`Bin_Dir =`pwd`cd ..deploy_dir =`pwd`conf_dir = $ doploy_dir/rever_port ='sed '/server.port/ !d ;s/.*=//'config/application.properties | tr -d '/r'`# 응용 프로그램의 포트 번호를 가져옵니다 _port =`sed -nr'/port : [0-9]+/s /.* 포트 :+([0-9]+).*// 1/p 'config/application.yml`spids =`ps -f | grep java | "$ conf_dir"| awk '{print $ 2}'`if [ "$ 1"= "상태"]; 그런 다음 [-n "$ pids"]; 그런 다음 "$ server_name이 실행 중입니다 ...!" echo "pid : $ pids"exit 0 else echo "$ server_name이 중지됩니다."exit 0 fifiif [-n "$ pids"]; 그런 다음 echo "오류 : $ server_name이 이미 시작되었습니다!" echo "pid : $ pids"종료 1fiif [-n "$ server_port"]; 그런 다음 server_port_count =`netstat -tln | grep $ server_port | WC -L` if [$ server_port_count -gt 0]; 그런 다음 echo "오류 : $ server_name port $ server_port가 이미 사용되었습니다!" 종료 1 FIFILOGS_DIR = $ deploy_dir/logsif [! -d $ logs_dir]; 그런 다음 mkdir $ logs_dirfistdout_file = $ logs_dir/stdout.logjava_opts = "-djava.awt.headless = true -djava.net.preferipv4stack = true"java_debug_opts = "" "" "$ 1" "debug"; 그런 다음 java_debug_opts = "-xdebug -xnoagent -djava.compiler = none -xrunjdwp : ranfort = dt_socket, address = 8000, server = y, sustend = n"fijava_jmx_opts = ""if [ "$ 1"= "jmx"]; 그런 다음 java_jmx_opts = "-dcom.sun.management.jmxremote.port = 1099 -dcom.sun.management.jmxremote.ssl = false -dcom.sun.management.jmxremote.authenticate = false"fijava_mem_opts = "bits =`bits =`bits = grep -i 64 비트`if [-n "$ bits"]; 그런 다음 java_mem_opts = "-server -server -xmx512m -xms512m -xmn256m -xx : permsize = 128m -xss256k -xx :+disable -xplicitgc -xx :+useconcmarksweepgc -xx :+cmsparallelremarkenabled :+usecmcmscompatfullcollections. -xx : margepagesizeinbytes = 128m -xx :+usefastaccessormethods -xx :+usecmsinitiationoccupanconly -xx : cmsinitiationoccupincuctionfraction = 70 "else java_mem_opts ="-server -xms512m -xmx512m -permsize = 128m. -xx : survivorratio = 2 -xx :+useparallelgc "ficonfig_files ="-dlogging.path = $ logs_dir-dlogging.config = $ conf_dir/log4j2.xml -dspring.config.location = $ conf_dir/application.properties "eva"eva "" $ java_opts $ java_mem_opts $ java_debug_opts $ java_jmx_opts $ config_files -jar $ deploy_dir/lib/$ jar_name> $ stdout_file 2> & 1 & count = 0 shile [$ count -lt 1]; echo -e "./c"sleep 1 [-n "$ server_port"]; 그런 다음 count =`netstat -an | grep $ server_port | wc -l` else count =`ps -f | grep java | grep "$ deploy_dir"| awk '{print $ 2}'| [$ count -gt 0] 인 경우 wc -l` fi; 그런 다음 Fidoneecho "Ok!"Pids =`ps -f |를 깨십시오 grep java | grep "$ deploy_dir"| awk '{print $ 2}'`echo "pid : $ pids"echo "stdout : $ stdout_file"스크립트 사용 사례 :# application./start.sh# debug 모드에서 시작하십시오 ./start 디버그# 작업 시작 및 JMX 상태를 시작하고 현재 실행 상태를 시작합니다. `dirname $ 0`bin_dir =`pwd`cd ..deploy_dir =`pwd`conf_dir = $ deploy_dir/configserver_name = $ deploy_dirpids = 'ps -ef | grep java | grep "$ conf_dir"| awk '{print $ 2}'`if [-z "$ pids"]; 그런 다음 echo "오류 : $ server_name이 시작되지 않았습니다!" 종료 1fiif [ "$ 1"! = "skip"]; 그런 다음 $ bin_dir/dump.shfiecho -e "$ pids in $ pids의 경우 $ server_name .../c"를 중지합니다. $ pid> /dev /null 2> & 1donecount = 0 while [$ count -lt 1]; echo -e "./c"$ pids의 PID의 경우 수면 1 count = 1; pid_exist =`ps -f -p $ pid |를 수행하십시오 [-n "$ pid_exist"] if grep java`; 그런 다음 count = 0 break fi doneoneecho "ok!" echo "pid : $ pids"Windows 환경을위한 시작 스크립트 :
echo 오프셋 app_name = springboot -vue.jarset config = -dlogging.path = ../logs -dlogging.config = ../config/log4j2.xml -dspring.config.location = .. -xloggc : ../ logs/gc.log -verbose : gc -xx :+printgcdetails -xx :+heapDumpNoutOfMemoryError -XX : heapDumpPath = ../logs goto debug) set jmx_opts = if "" "" ""== ""jmx "(set jmx_opt =" -dcom.sun.management.jmxremote -dcom.sun.management.jmxremote.port = 9888 -dcom.sun.management.jmxremote.ssl = false -dcom.sun.management.jmxremote.authenticate = false goto jmx) echo "java -xms512m 시작 -xmx512m -server%debug_opts%%jmx_opts%config%config%-jar ../lib/%APP_Name%Goto 종료 : debugecho "debug"java -xms512m -xmx512m -server%debug_opts%%config%config -jar ../lib/ renname%Name%Name%Name endo end : jxmx512m -server%debug_opts%%config. -xms512m -xmx512m -server%jmx_opts%config%-jar ../lib/%APP_Name%Goto 종료 : endPause
다른 SpringBoot 프로젝트의 경우 스크립트를 적절하게 수정하면됩니다. 공간을 절약하기 위해 다른 스크립트를 여기에 나열하지는 않습니다. 내가 제출 한 데모를 참조 할 수 있습니다 : https://github.com/shalousun/springboot-vue.git
참고 : 위의 스크립트는 Dubbo Official에서 참조됩니다. 실제로, 그것은 또한 Dubbo 프로젝트의 가벼운 구성과 유사합니다.
4. 포장 후 로그 경로 처리
두 번째 섹션의 그림에서 패키지 된 응용 프로그램 로그가 일반적으로 로그 디렉토리에 출력되는 것을 알 수 있습니다. 그러나 다른 시스템 플랫폼의 경우 구성된 로그 출력 경로가 동일하지만 결국 로그에 출력되는 것은 아닙니다. 테스트 후 Windows 플랫폼에서 상대 로그 경로를 사용하는 것은 문제가되지 않지만 Logs, Linux 시스템에서 상대 경로를 사용하기 위해서는 로그에 출력 할 수 없습니다. 따라서 Linux 플랫폼에 절대 경로를 작성하는 것이 좋습니다. 그러나 내가 제공 한 스크립트에서 출력 로그로의 경로를 설정하십시오.
-dlogging.path = ../로그
따라서 Log4J2의 강력한 구문 분석 기능을 결합하면 Log42의 로그 경로를 설정할 수 있습니다.
<property name = "log_home"> $ {sys : logging.path} </property>그러나 SpringBoot 응용 프로그램의 액세스 로그는 Linux에서 절대 경로 만 사용하는 것으로 보입니다.
# Server Configserver : Port : 8080 Undertow : AccessLog : enabled : true dir :/usr/xxx/logslogging : path :/usr/xxx/logs
물론, 나중에 문제를 해결하기 위해 구성을 사용하는 학생들은 문제를 해결하도록 상기시킬 수 있습니다.
요약 :
이 계획 자체는 새로운 것을 가져 오지 않으며 대부분의 스크립트는 Dubbo의 공식 스크립트를 참조하지만, 개선을 수행했습니다. 그러나 중요한 점은 실제 기술 응용 시나리오를 기반 으로이 기술을 사용하는 데 필요한 서비스 및 엔지니어링에 대해 생각하는 방법입니다.
위의 것은 편집기가 소개 한 Springboot Assembly 기반 서비스 포장 솔루션입니다. 모든 사람에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 모든 사람에게 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!