Fedora Linux 에서 동영상 캡쳐 시 별도의 소프트웨어를 설치 하지 않고도, 캡쳐 가능
Ctrl + Alt + Shift + R
Fedora Linux 에서 동영상 캡쳐 시 별도의 소프트웨어를 설치 하지 않고도, 캡쳐 가능
Ctrl + Alt + Shift + R
Gradle 3.2.1
위 "test-ear-dir" 디렉토리와 같이 ear 구조로 배치되어 있는 상태에서 gradle + ant 를 활용해 패키징 한다.
task dirEar {
doLast {
println 'aa'
ant.ear(destfile: 'build/test.ear',
appxml: 'build/test-ear-dir/META-INF/application.xml') {
fileset (dir: 'build/test-ear-dir')
}
}
}
VirtualBox 5.0.30
Fedora 23/24/25 모두 해봄 (VirtualBox 4 버전에서 Fedora 25 버전은 잘 안되서 VirtualBox 5 버전으로 업그레이드 함)
yum update yum install kernel-devel-$(uname -r) yum install gcc make shutdown -r now cd /var/run/media/root/VBOXADDITIONS_4.3.40_110317/ ./VBoxLinuxAdditions.run shutdown -r now
Plugin
Live Templates 설정
addlog - Applicable in Java: declaration
Edit Template Variables - Name=CLASSNAME, Expression=className()
private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger($CLASSNAME$.class);
dlog - Applicable in Java: expression
Edit Template Variables - Name=VAR, Expression=completeSmart()
logger.debug("===== $END$: {}", $VAR$);
addtest - use static import if posible 체크
@org.junit.Test
public void test$EXPR$() {
$END$
org.junit.Assert.assertThat("업무", 1, org.hamcrest.Matchers.is(1));
}
Windows Batch Script 심오하군...
특정 Tomcat Instance 찾아 KILL
@echo off setlocal enableDelayedExpansion # Command 에서는... wmic process where "Name='java.exe' AND commandLine like '%test-app%'" delete # Batch Script 에서는 "%" 변수에대한 접두사라서 LIKE 검색이 안되니 두개로... 그 안에 변수라면 아래와 같이 wmic process where "Name='java.exe' AND commandLine like '%%%HTTPD_WORKER_NM%%%'" delete
Tomcat 기동여부 확인 - 해당 포트가 떠 있나 확인 후 있으면 PID 및 실행 문자열 출력
@echo off setlocal enableDelayedExpansion netstat -na | find "LISTENING" | find /C ":%AJP_PORT%" > tmpFile set /P result=<tmpFile del tmpFile REM echo !result! if !result!==0 ( echo ===== TOMCAT IS STOPED ===== ) else ( echo ===== TOMCAT IS RUNNING ===== wmic process where "Name='java.exe' AND commandLine like '%%%HTTPD_WORKER_NM%%%'" get commandLine, processid )
빌드가 끝난 후 Finished: "SUCCESS" 나 "FAILURE" 둘 중 하나만 받을 수 있었다.
빌드 스크립트 상에서 System.exit(1) 을 만나거나 Exception을 만나게 되면 무조건 "FAILURE" 메시지가 떨어진다.
하지만 상황에 따라 경고성 메시지가 필요했다.
예를 들어 빌드/배포 실패 시 롤백 JOB를 호출 해야 하는 상황인데 빌드/배포 시
유효성 검사 및 기타 작업 시점에 Exception이 발생하면 "경고",
원격지 배포 중간이라면 "에러" 발생 후 롤백 JOB을 호출 해야 했다.
유효성 검사 시점에 Exception이라도 "SUCCESS" 를 떨어뜨려 해결 했더니 배포 History 가 뭔가 깔끔치 않아 "경고" 성 메시지가 필요 했다.
빌드 후 조치 에 "Trigger parameterized build on ohter projects" 에 "Trigger when build is" 옵션에 "Failed" 이외에 값들이 있는데 어떻게 이용하는지 방법을 못 찾았다.
경고 성일때는 "Unstable" 떨어 뜨리면 OK 일텐데..
새롭게 찾은 방법은 https://wiki.jenkins-ci.org/display/JENKINS/Text-finder+Plugin 을 이용한다.
스크립트 상에서 "Failed" 이외 "Unstable" 로 떨어뜨러야 할 경우
System.exit(1) 하지 말고 정상 종료 시키고, println "UNSTABLE" 출력한다.
"UNSTABLE" 의 경우 스크립트 상과 Jenkins Text-finder Plugin 과 약속이다.(다른 문자열로 해도 된다.)
그런 후 Jenkins 에서 아래와 같이 셋팅한다.
그럼 에러와 경로를 나울 수 있고, 각각의 상황에 따라 분기 하면 될듯하다.
간단한 방법이 있는데 어렵게 돌아가는게 아닌가 싶다..ㅡㅡ;;
Gradle 이용한 간단한 원격 배포 셈플링
그룹별 병렬? 배포 - WAS Instance 가 늘더라도 배포 시간 절약
빌드 파일과 별도 분리 해도 되고...(분리된 파일을 Jenkins에서 실행)
clean build remoteDeploy
.. .. apply plugin: 'org.hidetake.ssh' .. .. buildscript { repositories { jcenter() } dependencies { classpath 'org.hidetake:gradle-ssh-plugin:2.4.2' } } task remoteDeploy << { def startTime = System.currentTimeMillis() println "project: [$project]" def PROJECT_NM = project.name def DEPLOY_SERVERS = [] if( "$targetServer" == "dev" ){ DEPLOY_SERVERS = [ group1: [ ], ] } else if( "$targetServer" == "stage" ){ DEPLOY_SERVERS = [ group1: [ ], ] } else if( "$targetServer" == "real" ){ DEPLOY_SERVERS = [ group1: [ [host: "dkwas01", user: "tomcat", wasHome: "/usr/local/tomcat/domains/test11", wasDomain: "test11", webRoot: "/data/webroot/app-test", isWait: true,], [host: "dkwas02", user: "tomcat", wasHome: "/usr/local/tomcat/domains/test21", wasDomain: "test21", webRoot: "/data/webroot/app-test", isWait: true,], ], group2: [ [host: "dkwas03", user: "tomcat", wasHome: "/usr/local/tomcat/domains/test31", wasDomain: "test31", webRoot: "/data/webroot/app-test", isWait: true,], [host: "dkwas04", user: "tomcat", wasHome: "/usr/local/tomcat/domains/test41", wasDomain: "test41", webRoot: "/data/webroot/app-test", isWait: true,], ], ] } DEPLOY_SERVERS.eachWithIndex { gItem, gIdx ---> logInfo(DEPLOY_SERVERS, gItem, gIdx, null, null, "START") gItem.value.eachWithIndex() { hItem, hIdx -> def remoteUser = hItem.user def remoteHost = hItem.host def isWait = hItem.isWait def catalinaBase = hItem.wasHome def wasDomain = hItem.wasDomain def webRoot = hItem.webRoot def warPath = webRoot + "/../" + PROJECT_NM def remoteServer = [host: remoteHost, user: remoteUser, identity: file("${System.properties['user.home']}/.ssh/id_rsa")] ssh.run { session(remoteServer) { logInfo(DEPLOY_SERVERS, gItem, gIdx, hItem, hIdx, "HTTPD(JK_MOD) BLOCK -> WAS SHUTDOWN") // 고객유입 차단 -> WAS 중지 execute "cd $catalinaBase; ./shutdown.sh " + (isWait?'wait update 5':'') logInfo(DEPLOY_SERVERS, gItem, gIdx, hItem, hIdx, "WAR REMOTE COPY") put from: war.archivePath.path, into: warPath execute "rm -Rf " + webRoot + "/*" execute "cd " + webRoot + "; jar xf " + warPath execute "chmod -Rf 755 " + webRoot + "/*" logInfo(DEPLOY_SERVERS, gItem, gIdx, hItem, hIdx, "WAR START (HTTPD(JK_MOD) BLOCKING)") // WAS 기동 (고객 유입은 차단상태) execute "cd $catalinaBase; ./start.sh" } } } gItem.value.eachWithIndex() { hItem, hIdx -> def remoteUser = hItem.user def remoteHost = hItem.host def catalinaBase = hItem.wasHome def isWait = hItem.isWait def wasDomain = hItem.wasDomain def remoteServer = [host: remoteHost, user: remoteUser, identity: file("${System.properties['user.home']}/.ssh/id_rsa")] ssh.run { session(remoteServer) { logInfo(DEPLOY_SERVERS, gItem, gIdx, hItem, hIdx, "CHECK SERVICE") while (true) { sleep(2000) def resultStr = execute "cd $catalinaBase; ./checkService.sh" if (resultStr.contains(wasDomain) && resultStr.contains("SERVICE CHECK ERROR") == false) { break } print "." } logInfo(DEPLOY_SERVERS, gItem, gIdx, hItem, hIdx, "HTTPD(JK_MOD) FLOW") // 고객 유입 execute "cd $catalinaBase; ./httpd.sh start" } } } logInfo(DEPLOY_SERVERS, gItem, gIdx, null, null, "END") } def totalExecTime = (System.currentTimeMillis() - startTime) / 1000 println "==================== TOTAL EXEC TIME: " + (totalExecTime) + "s ====================" } static logInfo(deployServers, gItem, gIdx, hItem, hIdx, msg) { println("==================== [GROUP $gItem.key " + (gIdx + 1) + "/" + deployServers.size() + (hItem?" " + (hIdx + 1) + "/" + gItem.value.size() + " $hItem.host:$hItem.wasDomain] ":" ") + msg + " ====================" ) }
일반적으로 Jenkins나 SSH(SCP) 등을 이용해서 원격지 배포 시 순차 배포 하게 된다.
하지만 원격지 서버의 수가 많으면 (1대 배포 시간 * 배포 서버 수)가 되어 배포 시간이 증가하게 된다.
급하게 배포하거나, 롤백 하는 상황에서 배포 시간이 증가하게 되면 빠른 복구가 힘들어 진다.
그에 따라서 약 2그룹으로 나누고, 각 그굽을 병렬로 처리 할 수 있도록 해보자.
하지만 이 방법은 2그룹 중 1그룹으로도 고객 서비스가 원할 해야 한다는 보장이 있어야 하며, 결국 오버스펙으로 운영 해야 한다는 말..
(war 배포아닌 파일 묶음 배포 방식)
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; public class TextTest { public static void main(String[] args) { Path path1 = Paths.get("test.log"); Path path2 = Paths.get("test.log-2"); try (Streamstream = Files.lines(path1)) { Files.write(path2, (Iterable )stream.filter(s->s.trim().startsWith("{")).filter(s->s.trim().endsWith("}"))::iterator); } catch (IOException e) { e.printStackTrace(); } } }