[펌,수정]기업이 좋은 직원을 잃는 과정… ㄷㄷㄷㄷㄷㄷ

사원 A 입사 (9월)

사원 B 입사 (12월)

3개월 정도 차이지만 A 는 코딩자체에 흥미도 없고 프로젝트 이해력도 떨어지고 심지어 노력도 안함.

문서 제한일이 다가와서 다들 야근 할 때도 자기가 할 일은 다 하지도 않은 채 자기는 칼퇴주의라며 칼퇴.

결국 그 사람 일 다른 사람이 맡아서 하고 그러다보니 또 다른 팀원은 야근 ㅋ

B 는 코딩을 좋아하고 이해력이 좋음. 빨리 적응했고 그러다보니 출장 관련 업무도 다 함.

잦은 출장을 가게되고 조그마한 파트도 맡아서 진행. 팀장은 믿는다면서 여러 일을 더 맡김ㅋ 일이 나날이 많아짐.

이 친구도 정시퇴근을 초반에 계속 하다가 업무량이 많아지니 야근을 할 수밖에 없게됨..

2년 지났는데 A 는 여전히 일 못하지만 팀장은 그냥 쟤는 원래 못하니까 라고 놔둠.

B 는 업무량 다 못채우면 믿었는데 어떻게 그럴수 있냐며 서운함을 표함 ㅋㅋㅋㅋㅋㅋ

B 에게 조기진급으로 대리를 달아주겠다고 호언장담 하더니 윗선(임원)에서 아직 이르다고 거절먹음ㅋㅋ

연봉자체를 공개하면 안되는데 회사에서 올해는 공평하게도 연봉을 모두 5% 씩 올려주겠다고 공표함ㅋㅋ

B 는 좆같네 하면서 기업 퇴사하고 카카오 감…

A 는 5% 좆같네 하면서 다른 기업 갔다가 적응 못하고 (거긴 못한다고 안봐주나보지 ㅋ) 거기도 퇴사하고 돌아오겠다지만

받아주지 않음 절대 ㅋ

실화입니다. 기업이 좆같은 이유는 인재관리도 좆같이해서 그렇습니다.

http://www.ddanzi.com/free/539055230


실제로 내가 사회생활을 시작하면서 지금까지 거의 한평생을 겪었던 일이다. 나는 컴퓨터를 다루는걸 좋아한다. 다른게 있다면 엔지니어가 됐다는 것 뿐이다.

대학때부터도 그랬고 지금도 그렇지만 Linux 를 다루는걸 좋아라했고 자연스럽게 OpenSource 프로그램들을 주로 다루게 되었다. 그리고 인터넷을 움직이게하는 필수 프로그램들에 대해서도 경험을 쌓게됐다. 심지여 DB 까지 어느정도 다뤘으니까.

이력서를 내놓으면 여기저기서 연락이 온다. 그것도 그냥 오는게 아니라 자주 온다. 그러면서 다음과 같이 말한다.

꼭 찾던 인물이다. 함게 했으면 좋겠다.

그리고 입사를 하면 혼자서 Web Server, Was Server, System Monitoring 까지 하는건 좋다. 그런데 DB 작업(설치, Replica, 업그레이드), WAS Memory leak 분석, 프로그램상의 오류를 디버깅하라고 한다. 서버에서 오류가 났으니 그걸 분석하다보면 결국에는 Java 프로그램상의 오류가 대부분이다.

이렇게 일하면서 연봉을 많이 받느냐? DBA 가 있음에도 그 사람은 다음과 같이 당당하게 말한다.

MySQL 설치, Replica, 업그레이드를 해본적이 없어요. Toad 열고 쿼리 작업만 해봤습니다.

한국 SI 산업의 가장큰 병폐가 이런것이다. 경력 13년차를 뽑아놓고 보면 ‘안해봐서 모른다’ 라는 답변하는 하는 사람들이 많다. 하지만 정작 ‘안해봤지만 MySQL 도 DB 니까 대충 이론은 같을 거고 사용법을 익히면 될거 같다’ 라는 말을 하는 인간은 못봤다.

의지를 안가지는 자들 vs 해보겠다는 의지를 보이는 자들

정확하게 저렇게 나뉜다. 많은 프로젝트를 돌아다니다보면 저런 인간들로 다 분류 된다. 자신이 하는 일 외에는 안한다고 하지만 앞서말한 DBA 처럼 자신이 하는 일조차도 자기 스스로가 결정한 영역일 뿐이다.

하지만 해보겠다고 의지를 보이는 자들은 자신이 하는 일에 대한 영역이 산업계에서 요구하는 영역과 일치하는 경우가 많다.

문제는 저렇게 두분류의 사람을 함께 일하게하면 기업들은 결국에는 의지를 가지고 있는 사람에게만 일을 준다. 그렇다고 의지를 안가지는 사람을 자르거나 뭐라하거나 하지도 않는다.  그리고 결정적으로는 둘다 필요한 사람들이라고 하고 대우를 똑같이 한다.

오히려 ‘뭔 불만이 그리 많냐’, ‘너는 일 쉽게 할 수 있지 않냐?’ 이런 답변으로 더 일을 시킬려고 든다.

의지를 가지고 일을 하지 않는 자들이 같은일을 반복하는 것에 최적화된 자들이 변화하는 뭔가에 대응하고 아이디어를 내서 오래된 시스템을 바꾸는 일은 없다. 그냥 월급루팡에 최적화된 프로젝트만 남는거지..

 

systemd –user 사용하기

Systemd 는 기존 리눅스 시스템에서 사용해왔던 init script 를 대체한다. 배포판마다 적용된 버전이 다른데, CentOS에 경우에는 7 버전부터 Ubuntu 의 경우에는 16.04 부터 적용되기 시작했다.

Systemd 는 부팅과정에서 최초로 실행되는 프로세스이며 리눅스 시스템 전체를 움직하게 하는 프로세스이다. 이 프로세스는 또 다른 프로세스들을 제어하는데 이를 위해서 systemd 프로그램을 제공한다.

부팅과정에서 자동으로 데몬들을 실행시키는 것도 systemd 가 하는데 이 프로그램은 데몬에 대한 명세서인 unit 파일을 기반으로 실행을 시켜준다. 이러한 파일들은 전역 시스템 영역에 속한다.

전역 systemd 영역

전역 systemd 영역의 파일들은 다음에 디렉토리를 가진다.

  • CentOS: /usr/lib/systemd
  • Ubuntu: /lib/systemd

한가지 특징이 있는데, CentOS 경우에는 전역 systemd 디렉토리가 한가지이지만 Ubuntu 의 경우에는 /lib/systemd외에 /usr/lib/systemd 도 존재하는데 /usr/lib/systemd 는 user 영역을 위한 것이다.

커스터마이징 전역 systemd 영역

앞서 살펴본 디렉토리는 배포판의 패키지를 설치할 경우에 사용되어진다. 하지만 이것외에 별도에 설치한 데몬 프로그램을 전역 systemd 에 등록하고 싶다면 다음의 디렉토리를 사용한다.

  • /etc/systemd

예를들어 컴파일 설치한 프로그램, 자바 프로그램의 경우에 systemd 에 등록해서 사용하자 한다면 위 디렉토리에 unit 파일을 작성하면 된다.

사용자 systemd 영역

systemd 는 자동으로 데몬으로 실행시켜 준다. 그런데, 이러한 실행은 systemd 라는 전역적인 권한을 가진 상태에서 이루어진다. 그렇다면 사용자가 자신만의 systemd 를 운영할 수 없지않을까 하는 아이디어로 나온것이 사용자 systemd 영역이다.

동작방법은 두가지로 나뉜다.

  • 사용자가 시스템에 로그인을 할때 실행
  • 시스템이 부팅할때에 사용자 systemd 영역도 함께 실행

그리고 사용자 systemd 영역은 사용자 홈디렉토리에 unit 파일을 작성해야 한다. 이 디렉토리는 다음의 위치에 존재한다.

  • ~/.config/systemd/user

사용자 systemd 영역 실행은 다음의 명령어를 사용한다.

  • systemctl –user

사용자 systemd 영역 동작 방법

잠깐 어떻게 이게 가능한지를 설명해 본다. 이 기본적인 동작을 위해서는 PAM 이 실행되어야 하는데 /etc/pam.d/systemd-user 파일이 이 일을 하게 해준다. 이 파일은 대략 다음과 같다.

이 PAM 모듈은 사용자가 로그인을 하게 되면 자동으로 systemd –user 명령을 실행해준다. 그리고 로그아웃을 하게되면 systemd –user 로 실행된 프로세스는 종료된다.

기본 설정

모든 사용자 systemd 영역 파일들은 ~/.config/systemd/user 에 존재하게 된다. 처음 로그인을 할때에 서비스가 실행되길 원한다면 다음과 같이 서비스를 활성화 할 수 있다.

한가지 팁(Tip) 으로, 만일 root 사용자라면 모든 시스템 사용자의 사용자 systemd 영역 서비스를 다음과 같이 할 수 있다.

환경 변수

서비스 데몬들이 실행될때에도 환경 변수들이 필요하다. 예를들어, PATH 같은 것이 대표적이다. 문제는 사용자 systemd 영역 서비스 데몬들은 .bashrc 파일에 정의된 환경변수들을 계승하지 않는다.  이것은 environment.d 디렉토리에 정의하는데 위치는 ~/.config/environment.d/ 이며 여기에 .conf 확장자를 가지는 파일을 작성하는데 INI 형식인 NAME=VAL 식으로 작성한다.

전역적인 환경변수 파일은 다음에 위치한다. 이 파일들은 모든 사용자 unit 파일에 영향을 준다.

  • /etc/environment.d/*.conf
  • /usr/lib/environment.d/*.conf
  • /etc/environment

모든 사용자 unit 에 영향을 주는 기본 환경변수인 DefaultEnvironment 는 /etc/systemd/user.conf 도 있다.

기존의 환경 변수들을 추가할 수도 있다. 예를들어, PATH 라는 환경변수는 사용자마다 가장 많이 커스터마이징되는 변수다. 이러한 변수를 systemd 에서 환경변수로 등록하고자 한다면 다음과 같이 해준다.

사용자 systemd 영역에 설정된 변수들을 보고 싶다면 다음과 같이 하면 된다.

사용자 systemd 자동 실행

systemctl –user 사용은 사용자가 로그인을 해야만 실행이되며 사용자 세션이 닫히면, 사용자가 로그아웃을 하면 자동으로 종료 된다. 하지만 사용자의 로그인/로그아웃에 상관없이 서버가 부팅되면 자동으로 실행되고 서버가 종료되어야만 중지되게 하고 싶다면 어떻게 할가?

이것은 로그인 관련된 내용으로 링거링(Lingering) 설정에 영향을 받는다.

multi-user.target 문제

systemd unit 파일 작성할때에 어떤 환경에서 실행될 것인지를 명시하기 위해서 다음과 같이 작성한다.

그런데, ‘systemctl –user’ 를 사용할때에는 multi-user.target 사용해서는 안된다. 이는 –user 에서 사용할 수 있는 타켓이 제한되어 있기 때문인데, 다음과 같이 확인이 가능하다.

위에 리스트를 보면 multi-user.target 은 존재하지 않는다. 따라서 ‘systemd –user’ 사용을 위한 systemd 유닛 파일을 작성할때에는 default.target 을 사용하는 것이 적절하다.

ElasticSearch 에 대한 systemd unit 파일 예제.

이제 간단하게 예제하나를 작성해 보자.

전문 검색 엔진인 ElasticSearch 는 자바를 기반으로 작동한다. 그러다보니 반드시 root 로 실행할 필요가 없다. 실제로 대부분 자바기반의 서비스들은 일반 계정으로 실행하는게 대부분이다.

unit 파일에 대해서 먼저 알아둘 필요가 있다. 이 파일들은 대체로 다음에 위치한다.

  • /usr/lib/systemd/systemd: 설치된 패키지에 의해서 제공된 units
  • /etc/systemd/systemd: 시스템 관리자에 의해서 제공된 units

하지만 사용자 systemd 영역을 사용할 것임으로 앞에서 언급한 대로 사용자 홈디렉토리에 관련 디렉토리를 생성해 준다.

자바 프로그램은 자바를 필요로하는데, 설치가 되어 있다고 하더라도 PATH, JAVA_HOME 등의 환경변수를 설정해 줘야 한다. systemd 가 알아차릴 환경변수는 environment.d 에서 작성해야 함으로 java.conf 파일을 다음과 같이 작성해 준다.

이제 elasticsearch.service 를 다음과 같이 작성한다. 이 파일은 ElasticSearch 의 소스가 공개된 GitHub 에서 찾을 수 있다.

Ubuntu 1.604 에서 문제

한가지 문제가 있다. elasticsearch.service 파일을 보면 중간에 리소스를 조정해주는 내용이 나온다.

  • LimitNOFILE=65536
  • LimitNPROC=4096

그런데, 이 설정은 적용되지 않는다. Systemd 에서 시스템 자원 조정을 위한 파일들이 여럿 존재한다.

  1. /etc/systemd/system.conf
  2. /etc/systemd/system/user@1000.service.d/limit.conf – 1000 은 userid 값이다.
  3. .config/systemd/user/elasticsearch.service.d/limits.conf

여기서 3번째는 작동되지 않는다. 1번의 경우에는 전역적으로 모든 사용자에게 적용이 된다.    2번째 경우에는 사용자에게만 적용이 된다.

보통 시스템 리소스는 /etc/security/limits.conf 파일에서 조정하는게 보편적이지만 systemd 는 이처럼 자체적으로 리소스를 제어할 수 있도록 해준다.

systemctl –user 사용법

이제 elasticsearch.service 를 활성화하고 사용법을 익혀보자.

먼저 elasticsearch.service 를 다음과 같이 활성화 해준다.

그리고 서비스 시작/중지는 사용자 계정으로 로그인을 하면 자동으로 시작되며 로그아웃을 하면 중지된다. 하지만 수동으로 시작,중지를 하고 싶다면 다음과 같이 하면 된다.

ElasticSearch 6.4.x 노리(Nori) 형태소 분석기

ElasticSearch 는 루신을 기반으로 하는 전문 텍스트 검색 엔진이다. ElasticSearch 는 어떤 문장에 대해서 이를 분해한다. 문제는 ElasticSearch 가 외국에서 만든거라서 영어를 기반으로한 문장에 대해서는 분해하고 분석해준다. 하지만 그외에 대해서는 공백을 기반으로 문장을 분석한다.

여기서 문장에 대해서 좀 더 생각을 해봐야 한다. 문장을 분석할때에는 약간의 지식이 필요하다. 예를들어 다음과 같은게 있다고 하자.

고양이는 귀엽다

ElasticSearch 가 이 문장을 분석하면 ‘고양이는’, ‘귀엽다’ 로 분해한다. 하지만 이 문장에는 ‘고양이’ 라는 명사가 있고 ‘는’ 이라는 조사, ‘귀엽다’ 라는 동사가 존재한다. (정확한지는 나도 잘 모르겠다.)

이렇게 ElasticSearch 가 한글을 분석할 수 있도록하기 위해서는 한글이 이해시킬 수 있는 일종의 분석엔진 같은 것이 필요하게 되는데 이것이 바로 ‘한글 형태소 분석기’ 라고 한다. 몇가지 한글 형태소 분석기 엔진이 존재한다.

  • 아리랑
  • 은전한잎
  • 노리(nori)

ElasticSearch 를 제작하는 Elastic 사에서는 한글 형태소 분석기 Nori(노리) 를 내놓았다. 최신버전에 잘 설치되며 잘 동작한다.

설치

설치는 플러그인 설치로 끝난다.

설치할때는 마스터 노드, 데이터 노드에 설치를 해야 한다.

인덱스 분석에 노리 추가

ElasticSearch 는 알고 있겠지만 Index 단위로 데이터를 다룬다. Index 에는 데이터를 담기위한 그릇을 정의해야 하는데, 이것이 바로 Mapping 이다. 이 매핑에는 각 필드(Field)에 대한 데이터 타입을 정의하는데, 여기서 Index 에 대한 형태소 분석기로서 노리(Nori) 를 지정해줘야 한다. 기사를 인데싱하는 매핑에 예를 들면 다음과 같다.

analysis 에서 tokenizer 에 nori_tokenizer 를 지정하고 analyzer 에 이것을 korean 으로 지정한다.

이렇게 매핑(Mapping) 을 정의하고 다음과 같이 한글 데이터를 입력해준다.

 

테스트

먼저 인덱스 검색대신 문장에 대한 분석을 어떻게 하는지에 대해서 살펴보자.

위 내용을 보면 기본 형태소 분석기를 이용해 ‘고양이 냐옹냐옹’ 을 분석한 결과다. 공백을 기준으로만 한글을 분석했음을 알 수 있다. 그렇다면 설치한 노리 한글 형태소 분석기는 어떤 결과를 보여줄까?

기본 형태소 분석기와는 다르게 한글에 대한 형태소 분석의 결과를 보여준다. ‘고양이’가 명사임을 인식하고 있다.

한글 형태소 분석은 이런것이다. 조사와 합쳐진 명사만을 검색어로 입력하더라도 검색 결과를 보여준다.

ElasticSearch Nodes

ElasticSearch 는 노드(node) 로 불리운다. Node 는 ElasticSearch 의 독립된 인스턴스다. 그런데, 이 Node 에는 역할이 있으며 어떻게 Node 에 역할을 부여하는지에 해서 알아본다.

Node Type

Master Node

마스터 노드(Master Node) 는 ElasticSearch 의 클러스터(Cluster) 전체를 총괄하는 역할을 맡는다. ElasticSearch 는 분산검색엔진이며 각 노드들은 특정한 일을 하기 위한 하나의 그룹내의 멤버들로 관리되는데 이렇게 ‘하나의 그룹’ 을 클러스터라고 한다.

클러스터내에 노드들의 상태를 점검하고 이들의 유기적인 통제를 해야할 필요가 있는데, 이러한 역할을 하는 것이 바로 마스터 노드이다.

ElasticSearch 의 공식 문서에 보면 ‘Master Eligible Node’ 라는 말이 나온다. ‘마스터를 수행할만한 노드’ 정도로 해석되는데, 쉽게말하면 ‘마스터 후보군’ 이다. 이는 마스터 후보군이 존재하며 여기서 단 하나의 마스터가 선출되어 동장하고 만일 선출된 마스터가 장애를 겪는다면 마스터 후보군중에서 다른 마스터를 선출하게 된다.

Data Node

ElasticSearch 클러스터에서 실질적인 데이터를 저장하고 데이터 관련 연산을(Search, Aggregation 등) 수행하는 노드다.

샤드(Shard) 라는 개념이 바로 이 노드에 존재한다.

Ingest Node

파이프라인 스트림(Pipeline Stream) 이라고 한다. 문서를 인덱싱하기 전에 문서를 변형하는 역할을 수행 한다. 만일 각 노드에 대한 모니터링 기능을 켜게되면 반드시 Ingest Node 가 필요하게 된다.

Coordinating Node

코디네이팅 노드는 외부의 요청을 받아서 내부의 마스터 노드에 전달해준다. 벌크 인덱싱, 검색단계 줄이기등의 역할을 수행하기도 한다.

하나의 노드가 여러개의 역할을 중복해서 수행 가능하다. 그래서 개발을 위한 ElasticSearch 는 오직 하나의 노드만으로 모든 것을 할 수 있다.

 

Communication with Nodes

ElasticSearch 내에 노드들끼리는 TCP 통신을 기반으로 한다. 외부에 검색 쿼리(Query) 요청은 Http 통신을 기반으로 한다.

이제 여기서 생각을 해보자. 코디네이텅 노드의 역할을 분리해서 별도로 운영해야하느냐 하는 문제이다. 만일 코디네이텅 노드가 없을 경우에는 마스터 노드가 검색쿼리 요청을 받아야 하는 상황이 된다.

ElasticSearch 아키텍쳐1
ElasticSearch 아키텍쳐1

하지만 만일 코디네이팅 노드가 추가 된다면 다음과 같다.

ElasticSearch 아키텍쳐2
ElasticSearch 아키텍쳐2

뭘 하던간에 동작하는데에는 아무런 문제가 없지만 첫번재 아키텍쳐에서는 ELB 가 마스터 노드의 상태를 체크하고 잘못된 마스터 노드에 대해 제외를 시켜줘야 한다.

두번째 아키텍쳐에서는 ELB가 마스터 노드를 직접 제어하는 대신에 코디네이팅 노드를 제어한다.

유연성 측면에서 봤을때는 두번째 아키텍쳐가 더 좋아보이지만 그렇다고 딱히 아키텍쳐1번도 유연성에 문제가 있어보이지는 않는다.

Kibana 를 포함한 전체 아키텍쳐

Kibana 를 포함한 전체 아키텍쳐
Kibana 를 포함한 전체 아키텍쳐

Kibana 를 운영하기 위해서는 Ingest 노드가 필요하게 된다. 코디네이팅 노드를 포함하면 적어도 8개, Kibana 를 포함하면 9개 노드가 필요하게 된다.

ElasticSearch 시스템 설정

ElasticSearch 를 실행하기 위해서는 기본적으로 리눅스 시스템의 설정을 변경해줄 필요가 있다. 이는 ElasticSearch 문서에도 아주 잘 나와 있다.

Max Open File

리눅스 시스템은 사용자별로 최대 파일 오픈 개수를 제한 하고 있다. 이를 늘려주기 위해서는 /etc/security/limits.conf 파일에서 늘려줄 수 있다.

맨 앞에 문자열은 시스템 계정이며 맨 뒤에 숫자는 오픈가능한 최대치 값이다. ElasticSearch 에서는 65536 값을 권장하고 있다.

파일에 저장하고 계정을 재로그인하면 바로 적용된다.

Memlock 해제.

Memory Lock 에 대해서 무제한으로 해제를 해줘야 한다.

이것 역시 /etc/security/limits.conf 파일에 다음과 같이 설정하면 된다.

Virtual Memory

ElasticSearch 를 문제 없이 운영하기 위해서는 이를 조정해 줄 필요가 있다. 이는 리눅스 커널 파라메터값으로 재부팅 없이 조정이 가능하다.

시스템이 재부팅 되면 이 값을 다시 설정해줘야 함으로 이를 /etc/sysctl.conf 파일에 저장한다.

이렇게 파일에 저장한 후에 다음과 같이 하면 적용된다.

적용하기 위해서는 root 계정이 있어야 한다.

Error – The server time zone value ‘KST’ is unrecognized

Java 와 MySQL 을 연동하는 상황에서 다음과 같은 오류를 만나기도 한다.

자세히 보면 java.sql.SQLException 이 보인다. 이 경우는 결국에는 데이터베이스쪽에 문제가 있다는 것이며, MySQL을 사용할 경우에 보이게 된다. 이는 MySQL의 시간을 나타내는 타임존 설정이 맞지 않아 생기는 오류다.

MySQL 5.7, MariaDB 10

MySQL 5.7 과 MariaDB 10 을 사용한다면 my.cnf 에서 다음과 같이 설정함으로써 문제 해결이 가능하다.

설정할 수 있는 타임존 리스트는 MySQL 메뉴얼을 참조하기 바란다. 이렇게 했는데도 다음과 같은 오류를 만날 가능성도 있다.

이럴때는 다음과 같이 해준다.

다얼유 LK158 블루투스 겸용 LED 기계식 키보드

USB와 블루투스를 함께 지원하는 텐키리스 기계식 키보드가 필요했는데, 다얼유 에서 출시해서 구매하게 되었다.

다얼유 LK158 블루투스 겸용 LED 기계식 키보드

이 키보드는 맥(Mac) 도 지원한다. 맥을 지원한다는 것은 맥에서 사용가능한 펑션키가 있다는 것이며 이는 편리성을 제공한다는 것이다.

내가 구매한 모델은 적축 모델이다. 다음은 블루투스 설정방법을 스크랩한 것이다.

블루투스모드, 유선모드 전환

다얼유 블루투스-USB 전환

블루투스 멀티페어링 전환

다얼유 멀티 페어링

 

블루투스 페어링 방법

다얼유 페어링 방법

LED 효과

다얼유 LED 효과
사용 후기

집에서 아주 만족해 하면서 사용하고 있다.  집에서는 Windows 10 에는 USB 로 연결하고 Mac Mini 를 블루투스로 연결해서 사용하고 있다. 하나의 키보드로 두개의 OS를 번갈아가면서 사용할 수 있어 너무 편하다. 특히나 맥용 키보드 맵핑이 되어 있어서 별도의 노력없이 바로 사용이 가능하다.

거기다 적축이라서 키압도 그리 높지도 않고 사무실에서 사용도 가능할 정도로 소리가 없다.

 

Tomcat 설치 디렉토리 구성

과거에 Tomcat Multi Instance 설치에 관해서 쓴 글이 있다. Multi Instance 설치에서 핵심은 CATANINA_HOME과 CATALINA_BASE 를 분리하는데 있다.

오늘은 한발 더 들어가서 배포를 위한 설정과 시작, 종료 스크립트의 변경등에 대해서 이야기해보고자 한다.

Multi Instance 구성

Tomcat 을 다운로드 받아 압축을 풀면 그것이 곧 CATALINA_HOME 이 된다. 그리고 CATALINA_BASE 를 위해서 conf 디렉토리를 복사해주고 bin, lib, logs, temp, webapps, work 디렉토리를 생성해준다. 그리고 더블어서 war 파일을 배포를 위한 디렉토리를 Deployments 를 생성해주고 PID 저장을 위한 run 디렉토리도 생성해준다.

CATALINA_HOME 에서 복사해주는 디렉토리는 conf 밖에 없다는걸 상기해야 한다.

setenv.sh 작성

catalina.sh 스크립트를 보면 Tomcat 를 위한 설정등은 setenv.sh 를 읽어오도록 되어 있다.

CATALINA_BASE/bin/setsenv.sh 를 먼저 확인하고 없으면 CATALINA_HOME/bin/setenv.sh 를 찾도록 되어 있다.

setenv.sh 에는 CATALINA_OPTS, JAVA_OPTS 등의 환경변수등을 설정할 수 있다.  환경변수에 대해서는 catalina.sh 파일을 열어보면 자세히 나온다.

‘-Dport.http’ 와 같은 변수 선언은 server.xml 에 다음과 같이 활용할 수 있다.

그리고 이제 start.sh 와 shutdown.sh 는 다음과 같이 아주 간단하게 작성하면 된다.

CATALINA_HOME, CATALINA_BASE 디렉토리를 함께 정의해 준다.

기본적은 환경 변수를 start.sh, shutdown.sh 에 넣어주거나 하니면 별도로 빼서 소스해줘도 된다.

배포

Tomcat 에는 appBase, docBase 와 같은 지시자가 존재한다. 이것을 별도로 지정하지 않으면 webapps 디렉토리가 appBase, docBase 가 된다. 이를 분리하면 war 파일 배포와 app 실행 디렉토리를 분리할 수 있게 된다.

이를 위해서 먼저 server.xml 에서 다음과 같이 설정을 변경한다.

위와같이 Context 에서 docBase 로 war 파일을 지정하면 된다. 이렇게하면 war 파일을 읽어서 webapps 디렉토리에 압축을 해제하게 된다.

이렇게해야 하는 이유가 있는데, war 파일을 배포하는 디렉토리의 소유권을 배포계정으로 하고 others 에 읽기(read) 퍼미션만 준다. 즉, 운영계정과 배포 계정을 분리해서 운영할 수 있게 된다는 것이다.

배포는 conf/CATALINA/${virtualhost}/ 디렉토리에 context 이름으로 xml 파일을 작성해도 배포가 된다. Multi Instance 를 구성하게 되면 Manager 가 없게 된다. 그런데, 많은 사람들은 이를 CATALINA_HOME/webapps/manager 디렉토리를 CATALINA_BASE/webapps 디렉토리에 복사해 넣는다. 하지만 그렇게 하지 않아도 된다.

이를 ${catalina.base}/conf/Catalina/localhost/manager.xml 파일로 작성한다.

그러면 Tomcat 은 이를 읽어서 manager context 를 실행 준다.

왜 이렇게 하나?

CATALINA_HOME 과 CATALINA_BASE 를 분리하면 좋은 점이 업그레이드를 해야할 경우 나타난다.

몇몇 프로젝트하는 곳에서 Tomcat 설치된 것을 보면 CATALINA_HOME 에 startup.sh 파일이나 catalina.sh 파일을 직접 수정하는 경우를 볼 수 있다. 만일 보안 업데이트가 발생해 이를 Tomcat 업데이트를 해야한 경우라면 startup.sh, catalina.sh 파일을 새롭게 수정해줘야 한다.

하지만 CATALINA_HOME 과 CATALINA_BASE 를 분리하면 CATALINA_HOME 은 건드린게 없기 때문에 그냥 새로운 버전의 Tomcat 으로 바꿔치기하면 그만이다.

이는 휴먼 에러를 줄이는 확실한 방법이며 보안 업데이트 시간을 단축시켜준다.

 

Spring5 requirements

Spring5 를위한 필요사항들을 정리.

  1. java 8. 원래 Spring5 는 Java 9를 기반으로 하려고 했지만 변경됐다. 이로 인해서 Reactive Programming을 하기 위해서는 의존성 라이브러리를 필요로 한다. 현재Java 9 은 지원이 중단된 상태다. Java 10 을 사용해도 된다.
  2. Java EE 8 호환. Servlet 4.0, Bean Validation 2.0 등을 지원한다.
  3. HTTP/2 지원한다.
  4. Jackson 2.9, Protobuf 3.0 지원.

 

컴퓨터 영역이 너무 어려워 지고 있다.

컴퓨터 영역이 너무 어려워 지고 있다. 어찌보면 그런 수순으로 가고 있는게 당연한건지도 모르겠다. 과거에 등안시 했던 것들, 대표적으로 알고리즘 같은 것들을 요즘에는 중요하게 여기는 걸 보면 말이다.

과거나 지금이나 알고리즘은 중요하다. 하지만 유독 그것이 부각되고 나머지는 좀 덜한 중요도를 갖는것처럼 왜곡되고 있는게 문제가 되지 않을까 싶다. 그동안에 개인의 역량이란게 무엇으로 평가 되었는지는 모르겠지만, 요즘에는 코딩 알고리즘 문제가 기본이 되다보니 책방에 가서 보면 알고리즘 관련 서적들이 아주 많다.

거의 15년정도를 컴퓨터 분야에 있다보니, 요즘들어 그런 생각이 더 깊어지는 것 같다.  코딩으로 알고리즘을 구현하는 것도 중요하지만 그것보다 더 중요한 것이 ‘상황인식’ 그리고 ‘아이디어’가 아닐까 싶은데 나보다 어린 사람들을 보면 알고리즘은 잘 아는데 나머지는 모두 부족함으로 다가온다.

개인적으로 어떤 사람이 경력을 봤을때에 다음과 같은 질문을 먼저한다.

  • 문서 작성은 잘하는가? 그렇다면 어떻게 작성하나?
  • 협업을 할때에 주로 어떤걸로 하나? 메신저? E-메일?
  • Java 를 쓴다고 하는데 객체지향 프로그래밍이 뭔가?
  • 디자인 패턴을 잘 사용하나?
  • 코드 재사용성 고려에는 어떤게 있나?
  • 뭔가 관심을 넓히려고 하는가?

나는 문서 작성을 중요시 한다. 어느 회사에 잠깐 있었을때에 어떤 개발자는 ‘소스코드에 다 있다’ 라고 말했던게 기억난다. Jira 와 소스코드를 보라는 말만 되풀이했던 곳이 였다.

정작 소스코드를 보고 있자면 커다란 배치 프로그램을 보는 느낌이 들곤 한다. 하나의 메소드에서 여러가지 조건들을 처리하기 위해서 if 문이 수십게 있었던 기억들… 클래스 하나에 조건마다 메소드를 작성하다보니 1000 라인이 넘었던 클래스…..

알고리즘으로 뭘썻네 하기전에 객체지향 프로그래밍이라도 먼저 해줬으면 하는 바람이 요새는 더 크게 다가온다.

알고리즘은 대략 이런게 있다정도의 내용을 인지하고 있고 상황에 맞게 활용할수 있도록 떠올리는 정도면 그만이다. 현업에서 알고리즘을 온전히 내 머리속에서 생각해서 구현해보적은 별로 없었던게 이유이기도 했지만, 혼자 일하고 있다면 알고리즘만 생각하겠지만, 협업을 하는 경우에는 알고리즘 만큼이나 중요한 여러가지가 존재한다는 사실도 잊지 않았으면 좋으련만…  (사실 많은 사람들이 사용하는 킬러 애플리케이션들에서는 독창적인 알고리즘이 중요하다. OS를 제작한다던가, Office 와 같은 것들… 거대하기도 하지만 내부적인 기능들이 정교하면서도 깊이가 있는 것들은 알고리즘을 속속들이 알고 응용하고 독창적으로 개발하기도 해야한다.  하지만 지금 경력을 뒤돌아볼때에 그러한 정교한 것들을 만들어보긴 했지만 깊이가 있는 것들을 작성해본적은 거의 없다. 웹, 서버개발들을 했었지만 사실 주어진 알고리즘 라이브러리를 잘 활용해도 왠만한 안전한 프로그램은 나온다)

어떤 일을 하던간에 많은 고민을 하면서 했으면 하는 바람이 있다. 자바 프로그래밍을 할 경우에 java 8 로 프로젝트를 한다고 하더라도 미래에는 바꿀 수밖에 없는 운명일 거다. 그렇다면 호환성을 고려해 제작해야하는건 개발자라면 당연한 역량인데도 나중에 생각하자는 식..

지금은 모로가던 서울로 가기만 하자라는 식의 사고방식의 개발자들이 너무나 많아 보인다. 그런 사고방식을 하면서 결국에는 남탓, 환경탓을 하고 있는 사람들이 너무나 많아 보인다.