반응형

gradle2 API server

간단하게 더하기 하는 API 서버.

프로젝트 초기화


mkdir addserver
cd addserver
gradle init
    application type
    나머지는 다 default
    source package: com.my.test

VC에서 "Add Folder to Workspace" 로 추가.

-------------
app/src/main/java/com/my/test/App.java 가 자동 생성됨.
필요없으니 삭제한다.

https://user-images.githubusercontent.com/6326475/141603735-225b687e-db86-4e7f-8bfe-7b95bcd744e0.png

웹 프로젝트 설정

  • 패키지명에 맞춰서 변경한다.
## 아래에서 ^Z전까지 복사하고, 컨트롤 Z를 수동으로 입력해 줘야 한다.

mkdir app\src\main\webapp\WEB-INF\views

copy con app\src\main\webapp\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
</web-app>
^Z

mkdir app\src\main\java\com\my\test\controller
copy con app\src\main\java\com\my\test\controller\Add.java
package com.my.test.controller;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/add")
public class Add extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        process(request, response);
  }

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        process(request, response);
  }

  public void process(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        PrintWriter out = response.getWriter();
        out.write("hello");
    }
}
^Z

copy con app\src\main\webapp\WEB-INF\views\add.jsp
<html>
           <body>
               view page
           </body>
</html>
^Z

copy con app\src\main\webapp\index.jsp
<html>
    index page
    <p>
        context path: ${pageContext.request.contextPath}
    </p>
</html>
^Z

https://user-images.githubusercontent.com/6326475/141603860-a691f4b4-2049-4a4e-8261-9899759b6308.png

  • app/build.gradle
    • contextPath를 맞게 변경한다.
plugins {
    id 'war'
    id 'org.gretty' version '3.0.5'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'

    compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
    compileOnly 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'

    // This dependency is used by the application.
    implementation 'org.apache.logging.log4j:log4j-api:2.13.1'
    implementation 'org.apache.logging.log4j:log4j-core:2.13.1'

    annotationProcessor 'org.apache.logging.log4j:log4j-api:2.13.1'
    annotationProcessor 'org.apache.logging.log4j:log4j-core:2.13.1'

    gretty 'org.apache.tomcat:tomcat-dbcp:9.0.13'
}

gretty {
    servletContainer = 'tomcat9'
    httpPort=8080
    contextPath = '/addserver'
    enableNaming = true
}
  • gitignore
    • 디폴트로 .gitignore가 생기는데, 형상관리에서 제외할 것들 설정.
**/.classpath
**/.project
**/.settings
**/.factorypath
.gradle
app/tomcat.8080
app/bin
app/build
*.swp
*.sublime-project
*.sublime-workspace
  • .vscode/tasks.json (task로 검색하여 생성하면 된다.)
    • 쉬프트 컨트롤 P ; task 입력. Tasks: Configure default build task - addserver 라고 있는 항목 선택
    • 아래 내용으로 교체.
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Tomcat Start",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStart",
            "problemMatcher": "$msCompile",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "Tomcat Debug",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStartDebug",
            "problemMatcher": "$msCompile"
        },
        {
            "label": "Tomcat Stop",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStop",
            "isBackground": true,
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        }
    ]
}
  • RUN해서 /addserver/add 주소로 잘 되는지 확인한다.

    • 쉬프트 알트 R - tomcatStart : addserver 를 선택.

    • 단축키 설정은 이전편에서....

      https://user-images.githubusercontent.com/6326475/141604004-3f2c4ed6-cd90-4a5d-9234-06eeb6d9534d.png

https://user-images.githubusercontent.com/6326475/141604017-5bcfb582-55eb-4460-baf8-0ac543938b0b.png

  • 서버 중지는 쉬프트+알트+R 에서 tomcatStop : addserver 를 선택한다.
  • 기본틀은 완성되었다. 이제 기능을 구현하자...

'Develop > Java' 카테고리의 다른 글

gradle4 API server  (0) 2021.11.13
gradle3 API server  (0) 2021.11.13
gradle1 기초  (0) 2021.11.13
이클립스 단축키 이것만.  (0) 2019.11.10
Short URL(단축URL) API  (1) 2019.11.07
반응형

gradle1 기초

빌드 자동화 툴로 요즘은 Maven 보다 gradle이 대세라고 한다... 그래서 어떻게 쓰는지 한 번 알아봤다. 덤으로 이클립스 대신 Visual Studio Code로 java 개발하는 것도 알아봤다.

이클립스는 너무 느려서 답답하다.

VC는 대신 초반에 설정해 줘야 할 것들이 많아 귀찮긴 하다.

gradle 설치

  1. gradle을 다운로드 받아 설치 (압축해제)
  2. 환경변수 PATH에 bin 폴더를 걸어둔다.
  3. gradle -v ; 버전 확인. 잘 실행되는지 확인.

HelloWorld

프로젝트 폴더를 생성한다.

-프로젝트 폴더 생성
mkdir hello
cd hello

-프로젝트 초기화
gradle init --type java-application

폴더들이 생성된다. (.gradle, app, gradle 등등)

-빌드
gradle compilejava

-실행
gradle run
실행관련 정보와 결과가 출력됨.

gradle run -q
quiet 모드. 실행 결과만 출력됨.

-라이브러리로 만들기
gradle jar

-build 폴더 삭제
gradle clean
  • DOS에서 디렉터리 구조를 보려면 tree 를 사용하면 된다. /f 옵션을 주면 파일목록도 나옴.
  • 초반에 빠르게 구조 파악에 도움이 된다.

프로젝트 초기화

gradle init --type java-application
  • init type
    • basic (디폴트임)
    • java-application
      • App.java 가 기본 main 클래스.
    • java-library
      • jar 파일 생성용.
      • main 클래스가 없음.
    • groovy-application
    • pom
      • 기존 Maven 프로젝트를 마이그레이션한다

Tasks

gradle tasks

gradle 커맨드 목록, 도움말이 나옴.

init, jar, clean, run, 등등 모두가 Task임.

  • 태스크는 사용자 정의로 추가가 가능하다.
  • app 폴더 안의 build.gradle 파일에 정의하면 된다.
task hello {
    println 'hello gradle'
    doLast {
        println 'bye~'
    }
    doFirst {
        println 'first line.'
    }
}
gradle tasks --all
app:hello 가 생겼다.

gradle -q hello  ; 실행
  • 자세한건 groovy 문법을 알아야 한다.

Authoring Tasks

웹 어플리케이션

mkdir helloweb
cd helloweb
gradle init --type java-application

(중간 경로를 자동으로 만들어줌.)
mkdir app\src\main\webapp\WEB-INF\views

copy con app\src\main\webapp\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

</web-app>
^Z

mkdir app\src\main\java\test
copy con app\src\main\java\test\TestServlet.java
package test;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/test")
public class TestServlet extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        process(request, response);
  }

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        process(request, response);
  }

  public void process(HttpServletRequest request, HttpServletResponse response)
  throws IOException,ServletException {
        PrintWriter out = response.getWriter();
        request.getRequestDispatcher("/WEB-INF/views/test.jsp").forward(request, response);
    }
}
^Z

copy con app\src\main\webapp\WEB-INF\views\test.jsp
<html>
           <body>
                     <h1>Hello Gradle!!</h1>
           </body>
</html>
^Z

copy con app\src\main\webapp\index.jsp
<html>
    hello world.... index.
    <p>
        context path: ${pageContext.request.contextPath}
    </p>
</html>
^Z
  • 이제 빌드 설정
    • war 기능 추가. gretty는 경량웹서버 기능의 플러그인.
notepad app\build.gradle

build.gradle 파일을 열고 아래와 같이 작성.

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'gretty'

buildscript {
           repositories {
                     jcenter()
           }
           dependencies {
                     classpath group:'org.akhikhl.gretty', name:'gretty-plugin', version:'+'
           }
}

repositories {
           jcenter()
}

dependencies {
           testCompile group:'junit', name:'junit', version:'4.12'
}

==> deprecated.... 너무 옛날거라 이 방식이 안 돌아간다... 
수정 필요...!!
  • 배포
gradle war

VS Code 로 개발하기

위 작업한 폴더를 연다.

java 파일을 열면, java 확장을 설치하라고 뜬다. 설치.

확장프로그램 설치

Code Runner

Ant Target Runner

Log Viewer

Sort lines

Rainbow

VC 설정

settings.json (^+, 단축키. 오른쪽에 json으로 보기.)

java 경로는 환경에 맞게 설정

{
    "editor.fontFamily": "D2Coding, Consolas, 'Courier New', monospace",
    "editor.renderWhitespace": "all",
    "editor.insertSpaces": false,
    "workbench.colorTheme": "Default Dark+",
    "editor.suggestSelection": "first",
    "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
    "files.exclude": {
        "**/.classpath": true,
        "**/.project": true,
        "**/.settings": true,
        "**/.factorypath": true,
        ".gradle":true,
        "app/tomcat.8080":true
    },
    "search.exclude": {
        "**/node_modules": true,
        "**/bower_components": true,
        "**/*.code-search": true,
        "**/.classpath": true,
        "**/.project": true,
        "**/.settings": true,
        "**/.factorypath": true,
        ".gradle":true,
        "app/tomcat.8080":true
    },
    "window.titleBarStyle": "custom",
    "window.title": "${dirty}${activeEditorMedium}${separator}${rootName}",
        "java.home":"C:\\Program Files\\Java\\jdk-14.0.2"
}

.gitignore 설정

**/.classpath
**/.project
**/.settings
**/.factorypath
.gradle
app/tomcat.8080
app/bin
app/build
*.swp
*.sublime-project
*.sublime-workspace

Save As WorkSpace로 workspace를 저장하고 VC 재시작.

Add Folder to Workspace로 워크스페이스에 다른 프로젝트 들을 추가할 수 있다.

주의!

첫 번째 프로젝트로 위치해야 좋다?

프로젝트명을 선택하여 가장 위에 WORKSPACE 왼쪽 아래화살표 밑으로 드래그하면 첫번째로 이동된다.

build.gradle

  • 설정이 까다롭다....
  • 버전이 틀리면 실패.. 예전 버전으로 설정하니 에러가 발생해서 버전을 올리니까 돌아감.. :-(
plugins {
    id 'war'
    id 'org.gretty' version '3.0.5'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'

    compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
    compileOnly 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'

    // This dependency is used by the application.
    implementation 'org.apache.logging.log4j:log4j-api:2.13.1'
    implementation 'org.apache.logging.log4j:log4j-core:2.13.1'

    annotationProcessor 'org.apache.logging.log4j:log4j-api:2.13.1'
    annotationProcessor 'org.apache.logging.log4j:log4j-core:2.13.1'

    gretty 'org.apache.tomcat:tomcat-dbcp:9.0.13'
}

gretty {
    servletContainer = 'tomcat9'
    httpPort=8080
    contextPath = '/helloweb'
    enableNaming = true
}

https://mvnrepository.com

라이브러리 의존성 확인시 위 사이트에서 검색하여 버전을 맞춘다.

gradlew tasks
tomcat관련 명령어들이 추가된 것을 알 수 있다.

gradlew tomcatrun
에러가 없어야 하는데.... 잘 되네요. 

http://localhost:8080/helloweb
index.jsp 가 구동됨.

http://localhost:8080/helloweb/test
서블릿 구동됨. (TestServlet.java → views/test.jsp )

VC 작업 만들기

Terminal - configure task - tasks.json을 생성한다.

템플릿은 MSBuild 기본형으로 선택.

create tasks.json 메뉴가 안보이면, 이미 있어서 그렇다. .vscode 폴더에 tasks.json. (삭제하고 다시 만들면 된다.)

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Tomcat Start",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStart",
            "problemMatcher": "$msCompile",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "Tomcat Debug",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStartDebug",
            "problemMatcher": "$msCompile"
        },
        {
            "label": "Tomcat Stop",
            "type": "shell",
            "command": "${workspaceRoot}/gradlew tomcatStop",
            "isBackground": true,
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        }
    ]
}

preference - keyboard shortcut (^+shfit+p 로 short로 검색)

keybindings.json

// Place your key bindings in this file to override the defaults
[
    {
        "key":"shift+alt+r",
        "command":"workbench.action.tasks.runTask"
    },
    {
        "key": "ctrl+shift+alt+s",
        "command":"workbench.action.files.saveAll"
    },
    {
        "key": "ctrl+alt+u",
        "command":"editor.action.transformToUppercase"
    },
    {
        "key": "ctrl+alt+l",
        "command":"editor.action.transformToLowercase"
    }
]

shift+alt+r 을 누르면 tasks 3개가 뜬다. tomcat run , run debug, stop.

디버깅시에는 tomcat debug를 실행하면, 디버깅 별도 포트를 알려준다.

5005로 나옴.

VC의 디버깅창에서 디버깅 configuration을 만들어준다.

launch.json

{
    "version": "0.2.0",
    "configurations": [

        {
            "type": "java",
            "name": "Tomcat Debug",
            "request": "attach",
            "hostName": "localhost",
            "port": 5005
        }

    ]
}

이제 디버그 메뉴에서 Tomcat Debug로 실행하면 디버그 포트로 연결되면서 콜스택에

쓰레드 정보가 나올 것이다.

bp 설정하여 디버깅 가능.

'Develop > Java' 카테고리의 다른 글

gradle3 API server  (0) 2021.11.13
gradle2 API server  (0) 2021.11.13
이클립스 단축키 이것만.  (0) 2019.11.10
Short URL(단축URL) API  (1) 2019.11.07
[JavaScript] 스탑와치 밀리초/StopWatch milliseconds  (0) 2019.08.27
반응형

Docker tomcat mysql mongo

tomcat 서버에서 mysql과 mongodb를 동시에 사용할 일이 있어서 도커 환경으로 만들어봤다.

clean.sh

#!/bin/sh
/usr/bin/sudo rm -rf ./db ./webapps ./mongo
mkdir db
mkdir mongo
mkdir -p webapps
mkdir initdb
cd initdb
initdb.sql : 테이블 스키마. 초기 데이터 쿼리
mkdir initmongo
cd initmongo
cat > initdb.js
db.createUser(
    {
        user: "myhome",
        pwd: "myhome00.",
        roles:[
            {
                role: "readWrite",
                db:   "DB_ANALYZE"
            }
        ]
    }
);
mkdir locallib
cd locallib
*.so 파일 복사. (/usr/local/lib 으로 연결)
mkdir myhome
cd myhome
was에서 사용하는 설정 파일들

docker-compose.yml

version: '2'
services:
        db:
                image: mysql:5.7
                environment:
                        MYSQL_ROOT_PASSWORD: myhome00.
                        MYSQL_DATABASE: DB_ANALYZE
                        MYSQL_USER: myhome
                        MYSQL_PASSWORD: myhome00.
                ports:
                        - "3306:3306"
                volumes:
                        - ./mycustom.cnf:/etc/mysql/conf.d/custom.cnf
                        - ./db:/var/lib/mysql
                        - ./initdb:/docker-entrypoint-initdb.d
                restart: always
        mongo:
                image: mongo
                environment:
                        MONGO_INITDB_ROOT_USERNAME: myhome
                        MONGO_INITDB_ROOT_PASSWORD: myhome00.
                        MONGO_INITDB_DATABASE: DB_ANALYZE
                ports:
                        - "27018:27017"
                volumes:
                        - ./mongo:/data/db
                        - ./initmongo:/docker-entrypoint-initdb.d
                restart: always

        web:
                image: crazyj7/ubuntu16.04-tomcat8-jre8
                depends_on:
                        - db
                        - mongo
                environment:
                        JDBC_URL: jdbc:mysql://db:3306/DB_ANALYZE?connectTimeout=0&amp;socketTimeout=0&amp;autoReconnect=true
                        JDBC_USER: myhome
                        JDBC_PASS: myhome00.
                ports:
                        - "9090:8080"
                mac_address: 02:42:ac:15:00:03
                volumes:
                        - ./webapps:/usr/local/tomcat/webapps
                        - ./myhome:/myhome
                        - ./locallib:/usr/local/lib
                links:
                        - db
                        - mongo
                restart: always

mycustom.cnf

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
skip-name-resolve

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

! 중요!! skip-name-resolve를 위에 지정하지 않으면 DB 접속시 1분정도??? Delay가 발생하는 현상이 생길수 있다!

실행

docker-compose up

다른 쉘에서 war를 webapps에 복사한다.

9090 포트로 접속하여 테스트

반응형

윈도우 cmd 창에서 폴더(디렉터리) 복사를 하려고 할 때 막상 해보면 잘 되지 않는다...

리눅스 처럼 간단하게 cp -rf 같은 게 있으면 될 텐데, 이러저리 해봐도 쉽지 않았다.

팁!

xcopy /hickey [소스] [목적지]

xcopy의 옵션이 워낙 많아서 읽어보려면 시간이 많이 걸린다. 

한 번 정리해본 결과. 최종 옵션은 hickey 다.

hickey ;  어떻게 쉽게 외울까 하다가 옵션 순서를 영어 단어가 있는 것으로 배열해 봤다.

히키로 외우자. (영어 단어 뜻은 여드름. 흠집. 키스마크.^^ 이다.)

옵션 정리

a ; 보관특성만 복사. 보관특성 유지
m ; 상동. 단, 보관특성 삭제.
d:m-d-y ; 지정날짜 이후 수정파일만 복사. 미지정시, 대상 파일보다 최신인 것만 복사.
p ; 사용자에게 물어보기. 
s ; sub 포함. 단, empty dir 제외.
e ; sub 포함. 단, empty dir 포함.
q ; 조용히
c ; 에러무시하고 진행
h ; hidden 포함
l ; 파일 목록 표시 list
t ; tree 구조만 복사.
u ; update
k ; 특성도 복사
o ; 파일소유권 owner 복사
y ; overwrite할때 묻지 않음. yes
i ; directory 자동인식

 

 

 

반응형

도커 환경에서 tomcat, mariadb 컨테이너 구성하여 테스트하는 중.

이상한 증상이 있었음.

war를 올려서 구동하는데, 너무 늦게 구동됨. 1분 정도?? 딜레이가 발생하였다...

tomcat 로그를 봐도 알수가 없었음. WAR가 풀리고 중간에 1분 정도 멈췄다가 다시 진행되어 WAS가 구동되는 현상.

원인은??? DB의 name resolve 문제였음. DBMS가 외부에서 온 접속을 IP 주소에서 호스트명으로 변환을 시도하다 호스트명 resolve를 못하고 타임아웃까지 기다리는 현상이 원인이었던 것으로 추정된다. (어디서는 이런 현상이 없었는데, 어디서는 이런 현상이 발생하고 그랬다. 어떤 환경차이인지는 모르겠다.)

해결방안 my.cnf 파일을 만들어 DB 컨테이너 만들때 config에 넣어준다. 아래에서 보면 skip-name-resolve  한 줄을 추가했더니, 위에 1분간 딜레이되던 현상이 없어졌다. 바로 war가 풀리고 정상 가동되었다. 

my.cnf

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
skip-name-resolve
#default-authentication-plugin=mysql_native_password
#sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

(sql_mode가 DBMS에 따라 가끔 지원하지 않는 필드들이 있어서 위에 주석처리한 것들이 있음.)

 

+ tomcat, mariadb 도커 환경 구축

여기서는 식별을 위해서 컨테이너 이름이나 포트번호에 2를(db2, 23306, tomcat2, 28080 등) 붙였다. (이후에 또 만들것들은 3, 4, 등으로 연속해서 추가하는 방식으로 관리하였다.)

1. create_db.sh ; DB 컨테이너 생성하여 실행 또는 있으면 재실행

현재 폴더에 db 폴더가 없으면 최초 실행으로 판단하여 db 설정(my.cnf)를 복사하고 DB를 초기화한다.

#!bin/sh
if [ "$(ls -A db)" ]; then
	echo "db dir is already exist."
else
	echo "created db dir and copied my.cnf."
	mkdir -p db/config
	cp my.cnf db/config
fi

docker rm -f db2
docker run -d --restart always \
--name db2 \
-v /home/storage/2.mysvc/db/config/my.cnf:/etc/mysql/my.cnf \
-v /home/storage/2.mysvc/db/data:/var/lib/mysql \
-v /home/storage/2.mysvc/db/log:/var/log/mysql \
-v /home/storage/2.mysvc/db/temp:/temp \
--privileged \
-p 23306:3306 \
-e TZ=Asia/Seoul \
-e LC_ALL=C.UTF-8 \
-e MYSQL_ROOT_PASSWORD=mysvc00. \
mariadb:latest

위 쉘을 실행하여 mariadb가 떴으면 23306 포트로 접속하여 쿼리로 데이터베이스와 테이블들을 생성해 주면 된다.

 

2. create_tomcat.sh ; tomcat 실행 또는 재실행(이미 컨테이너가 떠 있는 경우)

아래의 경우 맥주소를 고정할 필요가 있어서 --mad-address 옵션을 추가한 것이다. (필요시 사용)

webapps 폴더가 생성될 것이고, 여기에 war를 올리면 구동될 것이다.

myconfig라고 폴더를 지정한 것은 war에서 사용할 설정 파일들을 특정 위치에 고정시키려고 한 것이다. (필요시 사용)

locallib 폴더는 native library (*.so)를 JVM에서 사용하려고 올려 넣은 것이다. (필요시 사용)

link로 위에서 만든 컨테이너 db2를 사용할수 있도록 지정함.

#!/bin/sh
docker rm -f tomcat2
docker run -d --restart always \
--mac-address=12:33:44:55:66 \
--name tomcat2 \
-v /home/storage2/2.mysvc/myconfig:/myconfig \
-v /home/storage2/2.mysvc/webapps:/usr/local/tomcat/webapps \
-v /home/storage2/2.mysvc/locallib:/usr/local/lib \
--privileged \
--link db2:db2 \
-p 28080:8080 \
-e TZ=Asia/Seoul \
-e LC_ALL=C.UTF-8 \
-e JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Duser.timezone=GMT+9:00 -Djava.library.path=/usr/local/lib" \
tomcat:8

war 설정 파일들(/myconfig)과 war 파일을 다 올렸으면, 로그를 확인함.

3. log.sh  ; 톰캣 최근 1분 로그부터 보기

#!/bin/sh
docker logs -f --since 1m tomcat2

4. stop.sh ; 컨테이너 종료.

#!/bin/sh
docker rm -f db2
docker rm -f tomcat2

 

이제 간단하게 shell script 만 실행하면서 쉽게 개발 테스트를 할 수 있다.

 

반응형
bash_Tip_작업속도

Bash Tip 작업속도를 빠르게

다음 방법을 알게 되면 bash 쉘 상에서 커맨드 입력 속도가 아주 빨라진다.

이전 명령어 실행

보통은 쉘상에서 위아래로 이동하여 전에 실행한 명령어를 찾아 실행하면 된다.
하지만 아래와 같이 하는 것이 더 편리할 때가 있다.

!! ; 바로 전 명령어
!스트링 ; 해당 스트링으로 시작하는 최근 커맨드.
!번호 ; history 번호

$ gcc a.c 
$ ls -al C*
...
$ ping 8.8.8.8

$ !!
 이전 명령어 ping 8.8.8.8 가 실행된다.
$ !l
  이전 명령어 중 l로 시작하는 최근 명령어를 실행한다.
  즉, 위에 ls -al C*
$ !gc
  이전 명령어 중 gc로 시작하는 것을 실행.
  즉, gcc a.c

또는 명령어 히스토리를 보고 번호로 실행할 수 있다.

$ history
50 netstat -ant
51 ls -al
52 gcc a.c

$ !50
	히스토리에서 50번 명령어를 실행한다.
	즉, netstat -ant 를 실행.

터미널 종료

^+C ; 현재 실행 중인 프로그램 종료. interrupt
^+D ; 터미널 종료. (logoff)

화면 지우기

clear 를 실행하면 터미널 화면을 지운다.
더 간편한 방법으로 단축키가 있다.
^+L ; clear 커맨드와 같다.

TAB 자동 완성

파일명을 모두 입력할 필요가 없다. 간단히 TAB키를 활용.
탭. 또는 탭탭.

$ ls a ; 여기서 TAB키를 누르면 a로 시작하는 파일이 자동으로 나타난다.
$ ls abc

위 경우 나타나지 않으면 없거나 여러 개라서 그렇다.

$ ls a ; 여러 개인 경우 TAB키를 한 번 더 누르면 모두 출력된다.
a1
a2
a3
...

커서위치 뒤로 삭제

이전 커맨드를 커서로 찾다가 뒷 부분을 다 수정해야 하는 경우.
^+K ; 커서위치 포함하여 뒤로 나온 텍스트 삭제 (cut)
^+U ; 커서 전에 나온 앞의 텍스트를 삭제 (cut)
^+Y ; 삭제된 텍스트를 붙여넣기
^+W ; 현재 입력한 커맨드 삭제.

$ ping 1.2.3.4
위 커맨드에서 커서를 3 위치로 이동하고 ^+K  (3.4가 삭제)
$ ping 1.2.   이후에 수정하면 된다.

$ ping 9.9. 여기서 ^+Y를 누르면 삭제됐던 텍스트가 붙여넣기가 됨
$ ping 9.9.3.4

커서 위치 이동

^+A ; 맨 앞으로 이동
^+E ; 맨 뒤로 이동

명령어 편집

먼저 환경변수에 기본 EDITOR를 vi로 설정해 둔다.
.bashrc 에 추가.

export EDITOR=vi

^+X+E ; 현재 입력한 커맨드를 편집기로 편집. (vi) 저장하고 빠져나오면 바로 편집한 명령어를 실행한다.

로그 보기 커맨드

대부분 로그 파일을 실시간으로 볼 때 tail을 많이 쓸 것이다.

tail -f catalina.out

이거 대신 아래 커맨드를 써라. (기본으로 Shift+F 효과가 들어감. 쓰다 보면 훨씬 편리하다.)

less +F catalina.out

less에는 유용한 다른 기능들이 많이 있다.

Shift+F ; 마지막으로 실시간 이동. (tail -f 처럼 실시간으로 추가되는 로그를 볼 수 있다.) less에 +F 옵션을 주면 바로 이 모드로 작동한다.
이 모드에서 ^+C를 tail -f 모드에서 빠져나온다.

위 모드에서 빠져나오면 기본으로 vi 편집기처럼 이동이 가능함. (^+B, ^+F 페이지 이동, j, k 위 아래 스크롤). 이전 데이터를 쉽게 볼 수 있고, 언제는 tail 모드로 진입했다 빠져나왔다 할 수 있다.

종료는 q

Author: crazyj7@gmail.com

'Develop > Linux_Unix' 카테고리의 다른 글

[도커] tomcat mysql mongodb  (0) 2021.10.31
[도커] tomcat, mariadb 환경 war hang/slow  (0) 2021.04.28
리눅스 백그라운드 실행(터미널종료에도)  (1) 2021.02.23
Git 사용법_요약  (0) 2019.12.16
Ubuntu18/tomcat8 setup  (0) 2019.11.08
반응형
port

windows port

로컬에서 쓸데없이 리스닝하는 포트를 찾아 프로세스 종료시키기

netstat 옵션

-a ; 모든 상태 표시.
-n ; 번호로 표시. (hostname, 서비스명 대신 다 숫자로…)
-o ; owner process ID
-r ; 라이팅 테이블

리스닝 포트 확인

netstat -an | findstr "LISTEN"

image

port 누가 쓰지?? PID를 먼저 찾는다.

netstat -ano | grep "포트번호"
netstat -ano | findstr /i "검색어"

findstr.exe 는 옵션 /i=caseinsensitive. /v=inverse.

C:\WINDOWS\system32>netstat -ano | findstr 8080
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       1236
  TCP    [::]:8080              [::]:0                 LISTENING       1236
  UDP    0.0.0.0:8080           *:*                                    1236
  UDP    [::]:8080              *:*                                    1236

8080 포트를 1236 PID가 쓰고 있음을 알 수 있다.

PID 로 프로세스 확인

C:\>tasklist -fi "pid eq 1236"

이미지 이름      PID       세션 이름     세션#  메모리 사용
======================== ======== =============== =========== 
svchost.exe    1236       Services       0        17,080 K

tasklist.exe /fi=filter,

작업관리자에서 확인하거나 processexplorer, processhaker 등을 사용하여 상세 정보 확인.

프로세스 강제종료

  • PID로 프로세스 강제 종료
taskkill /f /pid 1236

권한이 부족해서 실패한다면 관리자 권한으로 cmd창을 실행해서 해야 한다.

  • 프로세스명으로 강제종료
taskkill /F /T /IM notepad.exe
taskkill /f /fi "imagename eq note*"

[참고] /F ; 강제 종료, /T; 하위프로세스포함. /IM; 이미지명. /FI ; 필터
이미지명과 필터는 와일드카드 (*)를 사용 가능.

Author: crazyj7@gmail.com

반응형
screen_백그라운드

리눅스 백그라운드 실행 (터미널종료에도)

터미널종료해도 백그라운드 실행유지. 요약.

  • 방법1 (nohup)
$ nohup [커맨드] &
  • 방법2 (disown)
$ 커맨드 &
$ disown 
  • 방법3 (screen)
$ screen -S [작업명] ; 작업명은 임의의 스트링...
$ [커맨드]
^A, d ; (컨트롤+A 누르고 d키를 누름) detach되면서 백그라운드로 돌아감. 
  • 로그아웃했다가 다시 로그인하여 프로세스 확인
ps -ef | grep [검색어] ; 프로세스가 잘 떠 있는지 확인

screen 백그라운드 실행

스크린 - 윈도우 개념.
스크린들을 여러 개 만들수 있고, 스크린 내부에 윈도우를 여러 개 만들 수 있다. (처음 스크린을 만들면 0번 윈도우가 자동으로 만들어짐)

스크린 만들기

screen -S [세션명]
ex)
screen -S edit
screen -S build

스크린 목록

screen -ls
여기에 Attached라고 되어 있는 것이 현재 screen.
전부 detached라고 나오면 스크린 상태가 아님.

스크린 나오기

^+A, d ; detach. 작업중인 것은 백그라운드로 계속 돌아간다.

스크린 재접속

screen -r [세션명]

스크린 내에서 윈도우 만들기

  • ^+A 누른 후에 C (create) 를 누름.

윈도우 종료는 exit

윈도우 목록. 몇 번 까지 있는지 하단에 나옴.
^+A, W ; window

윈도우 이동

^+A, a ; 바로 전
^+A, 0 ; 0번창
^+A, 1 ; 1번창.

screen 상태에서 화면 스크롤

스크린 상태에서는 쉬프트+PageUp (스크롤)이 먹히지 않는다. 화면이 깜빡이고 만다.
^+A, ESC ; vi모드로 이동 및 페이지 업 , 다운에 vi커맨드로 하면 된다. ^B, ^F
ESC를 누르면 스크롤 모드 해제.

nohup

nohup [커맨드] &
터미널 종료 후에도 계속 작업이 유지됨

&, bg, fg

백그라운드 실행을 하면, 쉘은 그대로 쓸 수 있는데, 백그라운드에서 터미널로 출력되는 메시지도 화면에 출력된다.

  • 백그라운드 실행
    ./a.sh &
    그러나 터미널 종료시 종료됨… (종료 방지를 하려면 screen이나 nohup을 사용)

  • 현재 실행중인 프로그램을 백그라운드로.

^+Z ; 일시 중단하고 shell로 빠져나옴.
jobs ; 백그라운드 조회. 번호와 커맨드가 나옴.
bg %1  ; %잡번호를 입력하여 백그라운드로 재개시킴.

기타

fg %1 ; 포그라운드로 재개됨.
kill %1 ; 잡1번 강제종료.

disown

그러나, 위 백그라운드는 터미널이 종료되면 프로세스도 종료된다.
이것을 방지하려면,

disown

disown을 하게 되면 현재 세션 job list에서 job 들이 빠져나가게 된다. (jobs 커맨드로 확인 가능. 프로세스 전체 보기로 보면 프로세스는 남아있음.)
따라서 터미널이 종료되어도 SIGHUP이 전달되지 않아서 계속 돌아가게 된다.

Author: crazyj7@gmail.com

'Develop > Linux_Unix' 카테고리의 다른 글

[도커] tomcat, mariadb 환경 war hang/slow  (0) 2021.04.28
Bash Tip 작업속도를 빠르게  (0) 2021.03.03
Git 사용법_요약  (0) 2019.12.16
Ubuntu18/tomcat8 setup  (0) 2019.11.08
VI 사용법  (0) 2015.06.02
반응형
mariadb_10.4_setup

MariaDB 10.4 install / CentOS 7

CentOS 7.9에서 mariaDB 10.4 설치하다 디스크 공간 문제를 고려하여 경로 변경하는 중 계속된 실패로 삽질을 한 참 하였다.

  • 일단 전에 설치된 DB를 지우고 시작.
// 서비스 중지
$systemctl stop mariadb

[패키지 삭제]
$yum remove Maria*

// 전에 설치한 디폴트 경로
$rm -rf /var/lib/mysql

패키지 다운로드 및 기본 설치

yum으로 설치

// MariaDB yum repo 등록
$ vi /etc/yum.repos.d/MariaDB.repo

아래의 내용을 작성한다.

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
// MariaDB 설치
$ yum install MariaDB

// 설치된 버전 확인
$ rpm -qa | grep MariaDB
MariaDB-compat-10.4.17-1.el7.centos.x86_64
MariaDB-common-10.4.17-1.el7.centos.x86_64
MariaDB-server-10.4.17-1.el7.centos.x86_64
MariaDB-client-10.4.17-1.el7.centos.x86_64
또는
$ yum list installed Maria*
Installed Packages
MariaDB-client.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-common.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-compat.x86_64                                10.4.17-1.el7.centos                                @mariadb
MariaDB-server.x86_64                                10.4.17-1.el7.centos                                @mariadb

// 버전 확인
$ mariadb --version
mariadb  Ver 15.1 Distrib 10.4.17-MariaDB, for Linux (x86_64) using readline 5.1

기본적으로 /var/lib/mysql에 설치된다.

  • 서비스 실행 및 암호 설정
// mariadb 실행
$ systemctl start mariadb

// 패스워드 설정
$ /usr/bin/mysqladmin -u root password '패스워드'

// 포트 확인
$ netstat -anp | grep 3306
tcp6       0      0 :::3306                 :::*                    LISTEN      102252/mysqld
  • DB 생성 및 초기화 / 사용자 생성
$ mysql -u root -p
> use mysql ;

[사용자 추가]
create user 'crazyj'@'%' identified by 'crazyj00.';
create user 'crazyj'@'localhost' identified by 'crazyj00.';
flush privileges ;

[DB생성]
create database CRAZYJ_DB ;
grant all privileges on CRAZYJ_DB.* to 'crazyj'@'%';
grant all privileges on CRAZYJ_DB.* to 'crazyj'@'localhost';
flush privileges ;


[사용자 패스워드 변경]
ALTER user 'crazyj'@'localhost' IDENTIFIED WITH mysql_native_password BY '새패스워드';
또는 아래와 같이 설정
ALTER user 'crazyj'@'localhost' IDENTIFIED BY '새패스워드';
ALTER user 'crazyj'@'%' IDENTIFIED BY '새패스워드';
flush privileges ;

여기서 기본 경로가 /var/lib/mysql 인데 추후 디스크 공간을 고려하면 다른 파티션으로 옮기고 싶어졌다.
여기서 문제가 시작됨…

데이터 경로 위치 변경

쉽게 생각하면… DB 서비스 중지하고,
/var/lib/mysql 폴더를 용량큰 파티션으로 이동하고
기존 경로를 링크를 걸어주면 끝.
이라고 생각하지만, 여러가지 원인으로 실패할 수 있다.

결론부터 말하면

  1. selinux (접근통제)도 off 해줘야 한다.
  2. mariadb 기본설정에서 /root 나 /home 경로로 이동을 막고 있다.
    설정을 바꾸면 해결됨.
  • selinux off
# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
#
#vi /etc/selinux/config
--------------
#SELINUX=enforcing
SELINUX=disabled
------------
  • mariadb 서비스 설정 변경
$ systemctl stop mariadb
$ vi /usr/lib/systemd/system/mariadb.service
--------------------
# Prevent accessing /home, /root and /run/user
#ProtectHome=true
ProtectHome=false
------------------------
  • DB 링크 설정하고 서비스 시작.
$ mv /var/lib/mysql /home/mysql
$ ln -s /home/mysql /var/lib/mysql

$ systemctl start mariadb

끝.

참고) 아래는 시도 과정…

아예 처음부터 새로 만들자. 디폴트 경로 변경
$ vi /etc/my.cnf.d/server.cnf
아래 섹션에 추가
------------------------
[mysqld]
datadir=/home/data/mysql
socket=/home/data/mysql/mysql.sock
-----------------

$ vi /etc/my.cnf.d/mysql-clients.cnf
아래를 추가 (client 섹션이 없어서 추가)
-----------------
[client]
socket=/home/data/mysql/mysql.sock
----------------

$ cd /bin
$ mariadb-install-db --user=mysql
위 설정파일에서 지정된 경로에서 초기화됨!!!! 
(--user 옵션을 생략하면 root 계정으로 생성됨)

위와 같이 하면 되야 되는데… 서비스 실행시 그래도 에러발생???

  • centOS7의 selinux 기본 정책으로 실패???

  • selinux 관련 설정 변경

$ yum install policycoreutils-python
  
$ ls -lZ /var/lib/mysql
$ cp -rf /var/lib/mysql /home/data/mysql
$ chown -R mysql:mysql /home/data/mysql
$ ls -lZ /home/data/mysql

$ vi my.cnf
datadir=/home/data/mysql

$ semanage fcontext -a -t mysqld_db_t "/home/data/mysql(/.*)?"

$ grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local

$ restorecon -R -v /home/data/mysql

$ ls -lZ /home/data/mysql
-----------------------------------
위와 같이 했는데도 결국 안되서 selinux 옵션을 끄기로...

# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
#
#vi /etc/selinux/config
--------------
#SELINUX=enforcing
SELINUX=disabled
------------

위와 같이 해도 selinux를 off했음에도 실패했음.

원인은… 기본적으로 centos에서 mariadb는 /home, /root 경로를 사용할 수 없다나…
아니, 이런 설정도 있었나??? 헐… 삽질만…

데이터 폴더 이동 방법 찾던 중 발견.

$ systemctl stop mysql
$ mkdir -p /home/data/mysql

$ cp -rf /var/lib/mysql /home/data/mysql
$ chown -R mysql:mysql /home/data/mysql
(나중에 정상작동 확인후, 기존data인 /var/lib/mysql은 삭제)

==================> 이 문제였음. <===================
$ vi /usr/lib/systemd/system/mariadb.service
# Prevent accessing /home, /root and /run/user
#ProtectHome=true
ProtectHome=false
==================> 이 문제였음. <===================

서비스 시작
$ systemctl start mysql

Author: crazyj7@gmail.com

반응형
자모병합

자모병합 / 한타영타 변환기

필요해서 만들어봤습니다. 필요하시면 사용하세요. ^^
맥사용자가 한글이 포함된 파일명의 파일을 보내면 파일명에 들어간 한글의 자모분리 현상이 발생합니다!!! ( 한 -> ㅎ ㅏ ㄴ )
(맥와 윈도우의 한글호환이 안 되는 문제로 어쩔 수 없음.)
깨진 한글 파일명을 복원할 방법이 없을까??? 해서… 만들었습니다.

본 프로그램은 자모분리된 파일명을 복원(병합)해주는 기능을 함. (윈도우나 맥에서 분리된 한글 지원)

  1. 탐색기에서 파일명이 깨진 파일을 드래그하여 가장 위에 에디트 창에 넣는다. (직접 스트링을 입력해도 됨.)

  2. File Rename 버튼을 누르면 복원된 이름으로 이름 변경됨.

부가 기능으로 화면 아래에 한글의 한타와 영타를 전환해주는 기능도 있음. 이건 한글이 안나오는 사람들을 위해…

image

직접 만든 바이너리 해시값도 첨부합니다. (무결성 확인용)
아래 해시값이 원본입니다.

다운로드 경로
https://www.mediafire.com/file/maydhuaqacpdg63/hantaui_Release.zip/file

c:\>certutil -hashfile hantaui_Release.zip
SHA1 해시(hantaui_Release.zip 파일):
7d 3d df bb bd 3c 53 ad 00 f8 2e a0 79 47 c4 cd 87 50 11 4b
CertUtil: -hashfile 명령이 성공적으로 완료되었습니다.

c:\>certutil -hashfile hantaui.exe
SHA1 해시(hantaui.exe 파일):
27 e2 b2 ea e3 66 44 5e 2e bb d1 3f af 1f 34 e5 07 15 e6 32
CertUtil: -hashfile 명령이 성공적으로 완료되었습니다.

참고: 윈도우에서 간단하게 파일 해시값 확인

certutil -hashfile 검사할파일명

기본적으로 SHA1 해시값을 출력한다.
다른 해시 알고리즘을 사용하려면 뒤에 알고리즘명을 추가한다.
예를 들면 MD5, SHA1, SHA256 등을 쓴다.

certutil -hashfile 검사할파일명 SHA256

Author: crazyj7@gmail.com

+ Recent posts