2021-11-17

1117 implements 한 클래스가 많은경우 어떻게 빈으로 등록할지

  프록시 빈을 받을 때 이 문제가 발생 

-> 인터페이스 기반의 프록시

구현한 객체가 많아서. @Autowired로 해서는 충돌하게 된다

-> 해결방법

1. @Configuration 파일을 직접작성 

2. 이름으로 받을 수 있다. @Qualifier 혹은 변수명에 직접 해당 @Autowired 할 객체의 이름을 쓴다 (클래스명의 소문자)

3. 아예 그냥 List 등의 자료구조로 전부 받아버린 다음에 - 조건에 따라서 분기한 뒤 돌려준다



// 아니면  extends클래스 해서 상속으로 해결한다는 방법도 있다..얘는 아예 다른 방식. 좋은지는~? 잘 모르겠다. 왜냐면 - 자식타입이 어떤식으로 동작할지 클라이언트 쪽에서 다 알아야 대자나. ㅜㅜ extends 에 대한.. 이 불안함~~~

2021-11-09

1109 thread 실습하기!




대기큐 사이즈를 0로, 스레드풀사이즈를 100으로 한정해놓고 스레드 1000개를 동시에 보냈다.!!

그랬더니 - 더이상 요청을 받아들일수없다는 에러 메시지 출력!!오오오.



1109 리눅스 os 실습하기~!!

 

ulimit -a 로 open 할수있는 파일수를 확인해본다. !

 65535개. max-user thread는 unlimited다. 이럴수가..




음? 근데 커널레벨 max-thread를 확인해보니 7702개다. 음~~왜 다르지?

리눅스는 스레드=프로세스일테니까 그건 상관없을테고... 흠. 일단 실험해보자!!


sudo vi /etc/security/limits.conf

nofile : 열수있는 파일수를 100으로 수정한뒤에 !! 다시 재로그인해보았다!



100으로 바뀌어있는것을 확인해볼수있당!!^@^ 끼얏호~~~


마찬가지로 max user process 도 100으로 수정한다 ^^후후후.

2021-11-07

1107 JUnit 테스트시의 의문점 해결

 JUnit으로 스레드풀테스트를 돌렸을때. join()을 걸어주지않았더니 바로 테스트가 종료되는 점 이 이상하다고 생각했다.

메인스레드가 종료되어도 다른작업스레드가 남아있으면 JVM이 종료되지 않는것이 보통아닌가? 그런데 왜 메인스레드가 이걸 기다려줘야 하지? 하고 의문이 들었다.

->실험1) 스프링이 만들어주는 생명주기와 관련이있다?

이를테면스프링빈에 의존하고있어서?? HelloService의 생명주기와 관련한것인가?

하지만 그렇다면 스레드 자체가 종료되는게 아니고 에러가 떴을거다. 

applicationRunner클래스를 이용하여 즉시실행으로 확인해본결과 역시 스프링 빈 문제는 아니었다.
join()메소드를 걸지 않아도 메소드는 잘 동작했고 예상했던 바와 같이 동시성문제도 발생하는 것을 확인할 수 있었다.


-> 실험2) JUnit프레임워크의 생명주기와 관련이있다?


마찬가지로 일반 main메소드로 돌렸을때도 join()걸지않아도 예상했던대로 출력되었다.


메인 스택이 종료되어도 남은 스레드가 있기때문에 jvm이 종료되지않고 출력되고있음을 확인할수있다.

이로서 JUnit의 생명주기와 join()메소드가 관련있음을 알게되었다!!

아마 JUnit은 테스트종료후에도 남은 스레드로 인해 메모리 누수가 생기는 것을 방지하기 위해 하위스레드들을 자동으로 데몬으로 셋팅하는.. 그런 작업이 있지않나 싶다.

1107 threadPoolExecutor

 

for 문안에 execute를 열번. 제각각의 스레드가 형성되며

동시성문제 및 결과순서도 뒤죽박죽이 되는 것을 확인할수있다. ID값이 중복되어서 나타나고있음.

또한 sysout으로 찍을때 서로 화면을 빼앗으려는 경합이 발생한다.

메소드 수행도중에 화면에 찍고 싶은데 - 다른 스레드가 치고 들어와서 순서빼앗고 지가 먼저 찍고 계속 반복. System.out.println 메소드가 경합에서 밀려서 나중에서야 찍힌다. 

(근데 희한하다. service안에서 부르는 메소드도 똑같은 Syso를 사용하는데 다 먼저찍히네? ) 


execute 안에서 열번 같은 메소드 호출.

하나의 스레드가 수행하므로 id값과 순서가 순차적으로 나타난다. 동시성문제x

2021-11-02

1102 리눅스 명령어 : ip, netstat, ping, tcpdump

# 리눅스 명령어

## ip

- 아이피 주소 확인 명령어.

- ip addr | grep 'inet'

- ifconfig , hostname으로도 동일한 결과를 출력할 수 있음. 

## netstat

- 네트워크 상태값을 확인할수있음.

옵션

- -a : 모든 연결, 및 수신대기 포트 표시

- -n : 주소나 포트형식으로 숫자로 표현

특정포트번호 검색하고 싶을때

- netstat -an | find '포트번호'

## ping

- 대상 컴퓨터에대한 동작여부 및 네트워크 상태를 확인할 수 있다. 

## tcpdump

- 원하는 패킷들의 헤더를 출력해주는 프로그램.

- 와이어샤크 같은 프로그램과 비슷
- 커맨드라인에서 바로 실행새서 볼수도있고, txt로 저장할 수도 있음

- 네트워크 패킷 로그를 출력한다
- destination ip, source ip, port번호, host 주소 기준 등 다양한 기준으로 패킷 뜰수있음
- and 조건 붙여서 검색조건 상세화 가능

1102 jsp, web 기술

 # 1. JSP란

- 서버사이드에서 동적컨텐츠를 생성해주는 랭귀지

- 자바 웹 어플리케이션에서 이용됨

- 서블릿 기술의 확장판이라고 볼 수 있다.

- HTML과 자바언어의 갭을 메꾸기 위하여 탄생

# JSP servlet의 장점?

- 태그라이브러리 등 지원

- HTML과 자바언어를 분리하여 깔끔한 코드 작성에 도움

# JSP 라이프사이클

- 번역 -> 컴파일 -> 메모리에 클래스가 로딩됨 -> 인스턴스 생성 -> 초기화

: 초기화 된 후, 다른 인스턴스들 (servlet request 같은) 이 jsp 인스턴스에 접근할 수 있게[ 된다.  

 -> 사용자 요청 처리 -> 소멸

( 일반적인 클래스 객체의 생성과정과 동일.)

---

# 기타

## 초기화 순서

- 스태틱 변수의 기본 초기화 (이를테면, int 가 0으로 초기화되는것. )

- 명시적 초기화

- static 블록 

### 스태틱 블록이란, 말하자면 클래스의 생성자같은 존재. 

- 인스턴스 변수 기본 초기화

- 인스턴스 변수 명시적 초기화

- 인스턴스 블록

- 생성자 

## 어떻게 하나의 컨트롤러가 여러 요청을 처리할 수 있는가 ?

- 힙영역 / 메소드 영역 별로 메모리에 로딩되기 때문이다. 

## 어떻게 톰캣은 여러 유저의 요청을 동시에 처리할수있는가?

- 현재 톰캣은  NIO기반으로 돌아간다. 

- 사용자 요청이 끝날때까지 대기하는 동기방식(이전방식) 이 아니라, 요청을 다른 워커스레드에게 넘긴다. 즉 메소드 호출하고 return 하기 때문에, 더 많은 사용자 요청을 바로바로 받아들일수있게 된다. 

## 톰캣 스레드와 커넥션 객체의 관계

- 커넥션 객체는 생성 비용이 비싸다. 

- 모든 사용자가 db 커넥션을 사용하는 것은 아니기 때문에, 사용자 요청 스레드 > 커넥션 객체 수 가 된다. 

- maxIdleconnection 과 maxconnection수는 같은 것이 좋다. 만약 maxidle < maxconn 일 경우, idle수보다 커넥션객체를 더 많이 생성해야하면 그만큼 객체를 생성했다가 없앴다가 하는 비용이 들기 때문이다. 

## 로그대신 system.out.println을 사용하면 안 좋은 이유

1) 필수적인 정보들을 얻을 수 없다. 시간 정보, 유저정보, 리퀘스트 ip 정보등.

2) 사용하는 개발자의 성향에 따라 찍히므로 형식이 통일되지 않는다.

3) syso는 시스템콜을 유발하기 때문에, os의 native IO를 사용하고, 따라서 해당 어플리케이션 외의 다른 프로세스에게도 민폐를 끼치게 된다.

4) 성능면에서 10배이상 떨어진다고 한다. (위 3번에서 이어지는 이유. 시스템콜을 하고 다시 유저 모드로 컨텍스트 스위칭하는 비용이 비싸다) 

5) 로그파일로서 따로 수집되지 않는다. 

## 스프링이 유저 웹 요청을 받아들이는 순서

- 유저요청 -> dispatcherServlet -> adaptor -> controller 가 요청을 process하고 뷰네임 반환 -> adaptor -> dispatcherServlet 이 요청 반환

- 스프링은 dispatcherServlet이 일단 모든 요청을 받아들이는. 프론트 기반? 방식을 사용중. 

0328 fdisk, mkfs, mount, fstab

 1. 하드디스크를 붙인다. 2. fdisk -l로 하드디스크를 확인한다.  - interactiive한 커맨드모드 사용하여 (m) 붙인 하드디스크의 파티셔닝을 한다.  - 마지막에 w를 해야 실제로 반영이 된다.  3. mkfs를 하여 어떤 파일시스...