반응형

Solution

$ yum -y install gcc-c++

 

반응형
반응형

Solution

$ yum -y install gcc 
반응형
반응형

Docker기반의 Superset을 사용중인데 yum update이후 docker관련 라이브러리들이 업데이트 되었다.

이로 인해 잘돌아가던 Superset UI에 접속할 수 가 없었다.

계속해서 페이지에 접속되지 않고 ERR_CONNECTION_TIMED_OUT 메세지가 떴다.

이에 Docker, Superset 재시작을 해보았지만 여전히 동일한 상황....문제는 둘 다 재시작되면서 별다른 에러메세지도 없었고 잘 구동되었다.

뭔가 네트워크적인 이슈가 있다고 판단 구글링을 해서 본 docker 디렉토리 밑의 network/files를 날려보기로 결심...(너무 무서워서 알파 환경에서 먼저 시도해보았다. 이래서 리얼환경과 동일한 알파환경은 꼭 필요하다.)

ref : https://github.com/moby/moby/issues/25981

 

알파환경에서 sudo systemctl stop docker 실행 후 /var/lib/docker/network/files를 날리고 기존 Docker container, image들을 모두 제거 해준 뒤 재시작해보았다.

sudo systemctl stop docker
sudo rm -rf /var/lib/docker/network/files  => 네트워크 파일 제거

incubator-superset/docker 폴더 밑에서
docker stop $(docker ps -a -q)     => 도커 모든 프로세스 중단
docker rm $(docker ps -a -q)        => 도커 모든 컨테이너 제거
docker rmi $(docker images -q)   => 도커 모든 이미지 제거

위와 같이 수행하였고 docker-compose up 명령어를 통해 다시 superset을 띄워보았다. 

문제없이 Superset내부의 데이터들이 그대로 남아있는 것을 확인(제일 중요)하고 리얼에 적용해 보았다.

동일하게 sudo rm -rf /var/lib/docker/network/files 제거 하고 docker stop $(docker ps -a -q)     => 도커 모든 프로세스 중단명령을 날리는데 다음과 같은 에러메세지가 떴다.

$ docker stop $(docker ps -a -q)
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
"docker stop" requires at least 1 argument.
See 'docker stop --help'.

Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop one or more running containers

해결은 아래의 명령어로 처리

$ sudo dockerd

dockerd is the daemon service for docker containers, because it is not running in background we're not able to take any actions related to the service, which needs be restarted.

참조 : https://stackoverflow.com/questions/44678725/cannot-connect-to-the-docker-daemon-at-unix-var-run-docker-sock-is-the-docker

 

Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running?

I have applied every solution available on internet but still I cannot run Docker. I want to use Scrapy Splash on my server. Here is history of commands I ran. docker run -p 8050:8050 scrapinghub/

stackoverflow.com

이렇게 문제를 해결해주고 알파환경과 동일하게 Docker Container, image 파일들을 제거하고 Docker, Superset을 재시작해주었더니...

문제가 말끔히 해결되어 Superset UI에 잘 접근하는 것을 확인 할 수 있었다.

뭔가 docker network 파일들이 꼬여있었던 것 같다.

docker network아래의 파일들을 지워주기 전에 시스템 로그(/var/log/messages)에서 아래와 같은 메세지가 계속해서 떴었다.

IPv6: ADDRCONF(NETDEV_UP): veth8155173: link is not ready
br-72dc763038be: port 4(veth8155173) entered blocking state
br-72dc763038be: port 4(veth8155173) entered forwarding state
br-72dc763038be: port 5(veth8f6205c) entered blocking state
br-72dc763038be: port 5(veth8f6205c) entered disabled state
device veth8f6205c entered promiscuous mode

하지만 Docker network 디렉토리 밑의 file들을 삭제해주고 Docker를 재부팅한 이부에는 시스템 로그에 위의 로그들이 나타나지 않음을 확인하였다. 어떠한 이유에서 위와 같은 문제가 발생했는지에 대한 정확한 원인은 파악하지 못했다.....찾게 되면 포스팅하도록 하겠다.

감사합니다.

반응형
반응형

이전에 어디선가 질문 받은게 갑자기 생각나 String.format을 사용하지 않고 메서드를 구현해보았다.

    @Test
    public void convertStringToNumberStyle(String money) {
        String[] strSplit = money.split("");
        String convertedNumberStyle = "";

        int size = strSplit.length - 1;

        int count = 1;
        for (int i = size; i >= 0; i--) {

            if (count == 1) {
                convertedNumberStyle += strSplit[i];
            } else if (((count % 3) == 0) && (i != 0)) {
                convertedNumberStyle = "," + strSplit[i] + convertedNumberStyle;
            } else {
                convertedNumberStyle = strSplit[i] + convertedNumberStyle;
            }

            count++;
        }

        System.out.println(convertedNumberStyle); // money : 5000000 => output : 5,000,000
    }

하지만 String.format을 쓰면 1줄이면 끝난다는거 ㅎㅎ

String.format("%,d", Integer.parseInt(money))

심심해서 구현해보았는데 보통 라이브러리들에 의존해서 이런 부분을 처리하다 보니 막상 코드로 옮기기가 쉽지 않았다.

방식도 다양하고 여러 방법이 있겠지만 나는 한글자씩 쪼개어서 string을 다시 합쳐가며 3자리 지점마다 ","를 붙여주는 방식을 택했다.

가끔 자바 관련 면접에도 나올 수 있기에 다양한 방법으로 직접 구현해 보면 좋을 것 같다.

반응형
반응형

간혹 intellij에서 서비스 실행시  java.net.BindException: Address already in use 가 뜨곤 한다.

서비스를 실행시키려는 PORT가 이미 사용중이라서 그렇다.

다음과 같이 명령어를 주어서 프로세스 ID를 알아내 Kill 하자.

$ lsof -i :포트번호

PID의 번호 31056을 KILL 시켜주면 된다.

$ kill -9 31056

 

반응형
반응형

자바 어플리케이션을 개발하다 보면 외부 프로세스를 실행해야 할 경우가 있다.

예를 들어 자바 어플리케이션 내에서 서버의 특정 스크립트를 실행한다거나 다른 시스템 (spark, hadoop etc)에 명령을 내리는 경우다.

이번에 포스팅 할 내용은 JAVA process exec()명령을 실행하고 process.waitFor()를 실행함으로써 시스템이 행이 걸려 한참을 헤맨 내용이다.......정확히는 자바 어플리케이션 내부에서 Spark 어플리케이션을 실행하고 waitFor로 작업이 마무리 되었을 때 그 다음 작업을 진행시키는 배치가 맛이 가버린 내용이다.

자바내에서 특정 입력값을 사용자로 부터 받아 스파크(SPARK)의 특정 작업을 여러번 호출시키도록 설계되어 있다. admin시스템으로써 외부 부서에서 보통 3개의 입력값만 사용한다고 하셨었고 당연히 기능 개발후 테스트까지 마친 상태였다.

하지만 문제는 사용자가 5개의 입력값을 입력함으로써 시작되었다.....처음에는 Spark작업을 의심했었다. 다량의 Input값으로 메모리문제가 발생해 정상적인 아웃풋을 자바 어플리케이션에 전달하지 못하여 배치가 hang에 걸린 줄 알았었으나....그 문제는 아니였다.

[ 문제가 발생한 기존 코드 ] 

Process process = Runtime.getRuntime().exec(command);
process.waitFor();

보통 이렇게만 해도 큰 문제가 되지 않는다. 왜냐하면 보통 Command라고 해봤자 정말 단순한 명령어(grep, kill과 같은 단순한 리눅스 명령어)일 확률이 높기 때문이다.

하지만 이번 경우에는 달랐다.

문제는 명령어의 입력값이 커지면서 스파크(Spark) 작업이 여러번 돌게 되었고 작업이 끝나는 동안 outputstream을 한 번도 읽어주지 않음으로써 해당 버퍼가 꽉 차버리면서 정상적인 결과값을 읽지 읽어들이지 못하게 되면서 waitFor가 계속해서 끝나지 않는 상태가 되어 hang이 걸리게 되는 것이다.

 

[ 문제를 해결 코드 ] 

가장 간단하게는 process의 outputstrem을 받아 close해주는 방식이다.

process.getOutputStream().close();

행에 걸린 경우는 별도의 에러코드도 내뱉지 않게 된다. 문제 발생시 에러에 대한 내용 파악이 필요하다면  process.getErrorStream() 을 받아 처리하는 부분의 구현이 필요하다.

관련해서 java.lang.Process 클래스의 API 문서에 다음과 같이 나와있다.

Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

간단히 말해 표준입력과 출력에 대한 버퍼 사이즈가 제한이 되어 있고, subprocess의 input stream과 또는 output stream을 즉시 읽지 못한다면 subprocess가 block되거나 심지어 deadlock에 빠질 수 있다는 것이다.

이렇게 나는 이런 버퍼관련 이슈와 관련 신경쓰지 않고 싶을 경우에는 Apache Commons Exec를 쓰면 된다.

좀 더 자세한 내용이 궁금하다면 아래의 참고문헌을 참고 바란다.

[ 참고 문헌 ]

https://d2.naver.com/helloworld/1113548

https://pasudo123.tistory.com/250

https://stackoverflow.com/questions/5483830/process-waitfor-never-returns

반응형
반응형

JPA사용시 native query로 @Param 애노테이션을 통해 Model을 사용하는 방법과 발생할 수 있는 에러에 대해서 알아보자.

작업중 다음과 같은 에러가 발생

[ 작업 코드 ] 

문제가 된 부분

[ 에러 1 ]

org.hibernate.QueryException: Named parameter not bound : range.leftBottomLatitude
org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:210) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
.
.

[ 에러 2]

org.hibernate.QueryException: Named parameter not bound : __$synthetic$__1and
.
.

[ 해결책 ]

마지막 줄 이외의 쿼리문 끝에 한 칸을 띄워준다!!!

쿼리문 끝에 한 칸을 띄워준다!!!

 

포스팅 마무리하도록 하겠습니다.

반응형
반응형

보통 git + sourcetree로 작업을 할 때 기능별 featrue를 생성해 작업한다.

해당 작업이 완료되면 '깃 플로우'기능을 사용해 기능마무리 및 자동 develop브랜치에 머지하면서 삭제하는데 해당 작업을 할 때 다음과 같은 에러가 발생하였다.

Fatal: could not read username for 'https //github.com' device not configured

sourcetree Fatal: Could not fetch feature/#8 from origin.

해결책

소스트리에서 아래의 터미널을 클릭

터미널에서 다음 순서대로 입력한다

입력 > git config credential.helper 

osxkeychain

입력 > git config credential.helper sourcetree

입력 > git config credential.helper

sourcetree

그러면 마지막으로 'sourcetree'를 볼 수 있다. 

그리고 다시 터미널 종료하고 깃플로우의 기능 마무리 작업을 하면 정상적으로 처리 되는 것을 볼 수 있다~!

감사합니다~

 

반응형
반응형

스프링부트에서 JavamailSender사용시 sendMail부분에서 다음과 같은 에러가 발생

org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.NoSuchProviderException: No provider for SMTP. Failed messages: javax.mail.NoSuchProviderException: No provider for SMTP at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:446) ~[spring-context-support-5.1.2.RELEASE.jar!/:5.1.2.RELEASE] at
.
.
.
Caused by: javax.mail.NoSuchProviderException: No provider for SMTP
at javax.mail.Session.getProvider(Session.java:545) ~[javax.mail-1.6.2.jar!/:1.6.2] at 
.
.

 

소스코드

    @Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setProtocol("SMTP");
        javaMailSender.setHost("127.0.0.1");
        javaMailSender.setPort(25);

        return javaMailSender;
    }

문제의 원인은 javaMailSender.setProtocol("SMTP"); 이부분이였다.

setProtocol의 "SMTP"를 "smtp" 소문자로 변경해주면 해결된다.

해결책

"SMTP" => "smtp"

이유

JavaMailSenderImpl 파일을 들어가보면 알 수 있다. 내부에 DEFAULT_PROTOCOL 이 소문자로 할당되어있다.

public class JavaMailSenderImpl implements JavaMailSender {
    public static final String DEFAULT_PROTOCOL = "smtp";
    

항상 문제가 발생했을 때 문제 해결에 그치지 말고 이유에 대해서도 꼭 짚고 넘어가도록 하자!!!!

문제 해결보다 중요한게 원인 파악 이라고 생각한다.

반응형

+ Recent posts