앞으로 입싱하여 내가 걸어온 길을 걸어야 하는 다른 분들을 위해서 기록을 남깁니다.

생각보다 얻기 힘든 정보들이 많았는데 아무쪼록 도움이 많이 되었으면 합니다.

나는 싱가포르 사람과 결혼한 다음 우리의 보금자리를 찾기 위해서 싱가포르의 HDB(이하 아파트) 알아보기 시작했다.  싱가포르의 대부분의 국민들은 일반적으로 HDB(Housing & Development Board)라는 아파트에서 거주하게 된다.  한국과의 가장 큰 차이점이라 한다면, 한국은 집을 개인이 소유하지만 싱가포르는 국가가 소유한다는 차이점이 있다. 정부가 아파트를 소유하는 만큼 아파트의 가격이 날뛰지 않게 가격을 조정하는데, 이로 인하여 한국에 비해 집값이 저렴하다고 느껴질 수도 있겠다. 그럼 집 가격은 얼마나 오르는 것일까? 집 가격이 연 평균 얼마나 오르는지에 대하여 나의 에이전트인 '아이작' 에게 물어봤더니, 연 평균 2%대로 오른다고 생각하면 된다고 하더라. 물론 지하철역이 가깝고, 좋은 초등학교, 중학교, 고등학교, 혹은 대학교가 붙어있으면 상승폭은 더 크다고 한다. 이 말은 즉, 학군이 좋지 않으면 잘 오르지 않거나 가끔은 내릴수도 있다는 뜻으로 보면 되겠다. 싱가포르는 만 35세가 되기 전까지는 자신의 아파트를 소지할 수 없다. 만약 소지하고 있는 사람이 있다면 그 사람은 결혼한 사람일 것이다. 우리는 집 구매 후 남는 방들을 다른 사람들에게 월세를 줄 계획을 갖고 있었다. 그리하여 안방을 포함한 방 3개의 집을 구매할 하고 있었다. 싱가포르는 방이 3개라면 거실도 방으로 카운트해서 4룸이라 부른다.

아파트를 구매하기 위해서는 정말 많은 절차를 거쳐야 한다. 한국과 프로세스를 비교해 보겠다.

집은 어떻게 알아보는가?

한국

한국에서는 직방, 네이버 부동산, 호갱노노 등의 어플을 이용하여 집을 살펴본다. 우리가 직접 가지 않더라도 어플상에서 손품을 푼다면 얼마든지 많은 정보를 얻을 수 있다. 부족한 정보가 있다면 해당 지역의 커뮤니티(네이버 카페 등)을 이용하여 얼마든지 정보를 얻을 수 있다. 방문하기 전까지 내가 모을 수 있는 정보는 모두 모은 다음 마음에 든다면 오프라인 방문을 시작한다.

방문을 하는 목적은 아파트의 노후화 정도, 거주자가 집을 얼마나 깔끔하게 사용하고 있는지, 집에 하자가 없는 지 등을 확인하기 위해서 방문하는 경우가 대부분인 거 같다.

싱가포르

집이 어디에 위치했는지에 대한 정보 말고는 아무런 정보를 제공하지 않는다. 집주인의 프라이버시 때문이라고 한다. 특정한 커뮤니티 문화가 발달되어 있지 않기 때문에 정보를 얻을 수 있는 곳이 제한적이다. 나라가 좁기 때문에 지인의 지인을 통해서 같은 아파트에 사는 사람을 찾아서, 어떤지 물어보는 정도가 할 수 있는 최대한의 행동이라 보면 되겠다. 근처에 버스가 다니는 정보는 'OneMap' 같은 어플을 사용하면 되는데 보통 싱가포르에서 사는 사람들은 이 앱의 존재조차 모를 것이다. 한국과 동일하게 부동산 중개인이 존재하고 있으며 보통은 중개인에게 많이 의지하는 편이다. 중개인에게 '우리가 원하는 조건의 집'을 최대한 자세히 서술하면 해당 조건을 바탕으로 집을 찾아서 리스팅 해준다. 여기서 중요한 점은 '최대한 자세히 서술' 이다. 

해당 부분이 얼마나 중요한지 나의 케이스에서 예시를 들어주겠다. 나의 경우엔 꽤나 까다로운 요구조건을 갖고 있었다.

요구조건 비고
MRT(지하철), LRT MRT - 걸어서 5분 이내여야 할것(500m 이내여야 할 것)
LRT - 걸어서 2분 이내여야 할 것(250m 이내여야 할 것)
층 수 10층 이상이여야 할 것
집 컨디션 햇빛이 잘 들어야 한다. 어두운 집에서는 살기 싫다. 실제로 인디안들이 사는 집의 대부분이 어두운 분위기를 갖고 있었다.
맞바람이 불어야 한다. 바람이 불지 않는다면 습한 기후 때문에 집에 곰팡이가 스는 경우가 많고, 환기가 잘 이루어지지 않아 만성 냄새가 난다.
프라이버시가 존중되는 집이여야 한다. 거실 창문에서 다른 집의 거실을 볼 수 있으면 안 된다.
어느정도 인테리어가 되어있는 집이여야 한다. 싱가포르의 인테리어 비용은 상상을 초월한다.
이미 조금 되어있는 집을 들어가게 된다면 많은 금액을 절약할 수 있을 거 같았다.
학군 1키로 반경에 초/중/고 필수로 한 개씩 있어야 한다. 조카들이 놀러 오거나 학업을 위해 오는 경우, 그리고 내 자녀를 안전한 곳에서 키우고 싶었다.
연식 집은 1995년 이후에 지어졌어야 한다.  싱가포르는 자신보다 나이 많은 아파트를 구매하게 된다면 대출이 많이 나오지 않을 가능성이 크고, 이는 집을 다시 판매할때도 다른 사람들이 구매를 꺼려할 수도 있는 요인이 된다.

나의 요구 조건은 꽤나 정확하고 세세했는데 처음에는 어떻게 말을 해야 할지 몰랐기 때문에 아내의 의견에 따라서 '가장 중요한 요인'을 각자 1-2개씩 정하고 이를 에이전트에게 알리기로 했다. 처음부터 많은 요구 조건을 말하면 집을 찾기 어려울 거라는 이유 때문이었는데 첫 날 4개의 집을 보고 나서 나는 나의 요구조건을 정확하고 세세하게 말을 해야겠다는 생각을 했다. 처음 본 4집 중 3집이 환기가 잘 안 되며, 햇빛이 잘 안 들어서 어둡고, 냄새가 꽤나 나는 경우가 많았기 때문이다. 그리하여 나는 어떤 집을 원하는지 리스트를 작성하여 에이전트에게 전달했고, 그 다음 주부터 집을 보러 다닐때 나의 요구사항이 반영된 집만을 보러 다닐 수 있게 되어 꽤나 만족스러운 집을 보러 다닐 수 있게 되었다.

마음에 드는 집이 있다면?

정확히 기억이 나지 않지만 약 17번째의 집을 봤을 때 나에게 마음에 드는 집을 찾았다. 꽤나 빠르게 찾은 셈이다. 한인 커뮤니티에 물어보니 많이 둘러본 사람은 60번 째의 집에서 자신의 집을 찾았다 하고 아내의 친한 친구 역시 약 50번정도의 방문 후에 원하는 집을 얻을 수 있었다고 한다. 혹시 중개인을 너무 값싼 가격에 부려먹는다 생각하는가? 싱가포르의 중개비는 구매시 집 값의 1.09%(부가세 포함), 판매시에는 2.18%이다. 이 정도의 가격이면 열에 아홉은 나와 비슷하게 행동할 거 같다고 생각한다. 어찌 됬든, 우린 원하는 조건을 꽤나 자세히 이야기 했고 원하는 집을 빠르게 찾을 수 있었다고 생각한다. 

중간에 'Odd Shape'으로 구성되어 있는 집을 보기도 했다. Odd Shape를 제외한다면 모든 조건이 맞았지만, 싱가포리안들은 Odd Shape을 선호하지 않고, 잘 구매하려고 하지 않는다는 한인 분들의 조언을 적극 반영하여 구매하지 않았다. Odd Shape는 집 구조가 사격형이지 않은 구조를 포함한 집을 Odd Shape라 한다. 보통 거실 혹은 방 하나가 삼각형, 오각형, 마름모꼴인 경우가 많다. 이 경우엔 가구를 배치하기로 어려우며 잉여공간을 활용하기가 어려워서 선호하지 않는 거 같다.

A-1. 정말 마음에 들었던 Odd Shape의 집.
A-2. Odd Shape의 안방에서 볼 수 있는 뷰. 싱가포르에선 Unblock View라 부른다.

A-2 사진처럼 먼 곳에서부터 불어오는 바람이 어떠한 사물로부터 방해를 받지 않고 집으로 바로 불어오는 점이 꽤나 마음에 들었었다. 덕분에 집에서 묵은내가 전혀 나지 않았고 선풍기를 틀지 않았음에도 불구하고 꽤나 시원하다고 느껴졌다. 이는 일요일 아침에 잠이 들 깬 채로 거실에 나와서 잠깐 쇼파에서 낮잠을 잔다고 상상해보자. 선풍기, 에어컨, 실링팬을 키지 않아도 행복한 자연의 바람 아래에서 평온한 낮잠을 즐길 수 있을 것이다.

한국

보통 가계약금, 계약금 두 개로 나눠서 생각하는 경향이 강한 거 같다. '가계약금' 경우엔 계약금을 작성하기 전에 내가 이 집을 살 거니까 다른 사람들에게 보여주지 마세요! 하는 정도의 '찜콩' 가격이라고 보면 되겠다. 내 주위의 사람들은 가계약금을 100만원 정도가 적당하다고 생각하는 사람들이 많은 거 같다.

가계약금을 입금한 다음, 집 주인과 부동산에서 만나서 계약서를 작성한다. 보통 '은행에서 대출이 나오지 않는다면 이 계약은 취소된다' 라는 등의 특약을 넣고 계약하는 경우가 많다. 계약을 진행한 다음엔 집 값의 5%이상의 현금을 계약금으로 입금해야 한다. 만약 10억정도 하는 아파트를 구매하는 경우엔 최소 5000만원을 계약금으로 넣어야 한다는 뜻이 되겠다.

계약금을 입금하고 나서 남은 금액도 영혼까지 탈탈탈 털어서 자금을 준비한다. 보통 집을 구매하고 나서 이사를 하겠다는 마음을 갖기도 힘들고, 집값이 오르는 속도가 내 월급이 오르는 속도보다 빠르기 때문에 보통 흔히 말해 '영끌' 하여 집을 구매하는 경향이 있다고 생각한다.

싱가포르

사실 싱가포르는 집을 알아보기 전 부터 내가 얼마만큼의 집을 살 수 있는지 대충 각이 나온다. 싱가포리안(혹은 PR - 이하 영주권자)의 월급을 바탕으로 내가 얼마만큼의 대출을 받을 수 있는지 체크할 수 있다.

여기에서는 최근 1년(혹은 6개월)의 월급(payslips)을 요구하게 된다. 배우자의 월급(payslips)도 넣으라곤 하지만, 결과적으로는 우리가 받을 수 있는 대출의 양은 변경되지 않았다.(왜 넣으라고 한지는 잘 모르겠다. 보통 이런 정보를 이용하여 싱가포르의 정부가 어떤 일을 하는지는 국민들도 잘 모른다.)

우리는 싱가포리안인 아내의 월급과 이름으로 대출을 받을 수 있는 금액은 약 3.55억으로 책정 되었다. 내가 생각했던 부분과는 좀 차이가 있었다. 우리는 약 4-5억을 대출을 받을 수 있을 것이라 생각했는데 생각보다 적은 금액이였다. 이 3.55억은 내가 몇 년동안 대출을 받을지에 대해서도 받을 수 있는 금액이 달라진다. 다음은 정말 '예시' 표이다. 한국과 비슷하게 나이가 많을수록 받을 수 있는 대출의 금액과 기간이 달라진다.

대출 기간(예시) 금액(예시)
20년 2.55억
23년 3억
25년 3.55억

대출 받을 수 있는 금액과 우리가 모아둔 금액을 바탕으로 우리가 살 집의 금액대를 결정했다. 물론 우리의 많은 요구조건을 통과한 집이라 그런지 경쟁자도 있었다. 여러번의 핑퐁을 바탕으로 집을 6.2억에 구매하기로 결정했고 OTP(Option To Purchase - 구매하기 위하여 찜콩하는 제도라 보면 되겠다.)의 금액인 100만원(1000SGD)을 집주인에게 입금 하였다.

싱가포르의 집 구매 프로세스는 다음과 같이 진행된다.

프로세스 소요시간 설명
OTP(Option To Purchase) NULL 집을 구매하기로 결정하면 바로 입금한다.
보통 정부에서 결정한 1000SGD을 현 집주인에게 입금한다. 
입금을 한 다음부터는 현 집주인은 계약을 파기할 수 없다.
보통 이 기간에 집 구매자는 다른 집들도 보러 다닌다.
Exercise 3주 정부에서 정한 4000SGD를 현 집주인에게 입금한다.
법으로 OTP를 받은 후 21일 이내로 행사하게 되어있다. 
Resale Application 60일 집 주인은 HDB에게 재판매 신청서를 제출한다. 싱가포르의 HDB는 정부 소유이기 때문이다.
HDB Accept 업무일 기준 28일 주 당 업무일은 5일이 있기 때문에 통상 5주 + 3일 정도가 소요된다.
Complete 8주 HDB Accept 이후에 인지세를 납부해야 한다.
싱가포르의 인지세는 한국과는 비교할 수 없을 정도로 세다.
표 아래에서 설명하겠다.
Extension 최대 3개월 싱가포르의 문화에서는 집이 내 소유가 되어도 이전 집 주인을 최대 3개월까지 살 수 있게 해준다. 처음에는 '이게 무슨 눈뜨고 코 베어가는 소리람?' 했지만, 통용되는 문화라고 한다......

싱가포르에서 납부 해야하는 인지세는 총 2개로 나누어진다. 이해하기 편하게 표로 정리해 보겠다.

일반 인지세(BSD, 5억 기준 - 9600 SGD, 약 960만원)

금액(SGD) 인지세 금액
 첫 180,000(0~180,000) 1% 1800 SGD
다음 180,000(180,001 ~ 360,000) 2% 3600 SGD
다음 640,000(360,001 ~) 3% 4200 SGD

더 자세한 정보는 정부에서 제공하고 있는 사이트(클릭) 를 참고하면 된다.

추가 구매자 인지세(ABSD)

추가 구매자 인지세(이하 ABSD)는 싱가포르 시민권자, 영주권자 및 외국인에게 각각 다른 세율로 적용된다. ABSD는 추가 주택 구매 시 적용되며 첫 번째 주택에 대해서는 적용되지 않는다. 기존 집을 판매하든 안 하든 다음 새로운 집을 구매하면 영구적으로 다음 ABSD를 납부해야 한다.

국적 구매 횟수(영구적 카운트) 퍼센트
싱가포리안 첫 주택 0%
두 번째 주택 20%
세 번째 이상 주택 30%
영주권자 첫 주택 5%
두 번째 30%
두 번째 이상 주택 35%
외국인 모든 주택 60%

아내의 이름으로 집을 구매했기 때문에 우리는 ABSD에 대한 금액은 내지 않아도 됬었다. 

OTP까지 완료한 시점에 나의 생각

OTP까지 완료한 이후 주말마다 집을 보러 다니고 있긴 하지만 정말 지금 집을 계약한 것을 잘 했다고 생각한다. 집을 구매하고 싶어하는 다른 구매자랑 경쟁이 붙어서 비록 처음 생각했던 5.88억 보다는 훨씬 비싼 6.2억에 구매를 했을 지라도 후회하지 않는다.

집을 구매하기로 결정 했을 때 나에게 도움을 많이 준 SRX라는 사이트가 있다.

선택을 하기 어려울때 데이터를 기반으로 많은 정보를 얻을 수 있어서 좋았다. 해당 사이트에서는 우리가 구매한 집은 우리가 구매하기 전까지 5.88억 정도로 책정하고 있었다. 오른쪽의 그래프를 보면 알 수 있겠지만, 싱가포르의 집이 아직까진 저렴하다고 생각될 수 있을 만큼, 다른 홍콩과 한국, 샌프란시스코와 뉴욕의 집값을 따라 잡으려는 듯이 그래프가 가파르게 상승하고 있었다. 20년 이후 분기마다 1000만원씩, 즉 달에 333만원 가량 상승하고 있었다. 이러한 정보들 덕분에 조금 더 프리미엄을 주더라도 집을 빠르게 구매하게 된 계기가 되기도 했다. 이 그래프가 내년까지 갈지, 언제까지 이어질지는 모르겠지만 우린 법(MOP 에서 정해준 기준)을 바탕으로 5년이상 거주할 예정이다. 나랑 아내는 최소 10년을 생각하고 있다. 앞으로 들어가서 살 집이기도 하니 900만원 더 준것에 대해서 비싸게 샀다고 전혀 생각하지 않고 있다. 오히려 이렇게 저렴한 금액으로 집을 구매할 수 있게 되어서 감사할 따름이다. 

 

추가적으로 진행되는 부분이 있다면 해당 글을 수정하거나, 새로운 글로 발행하도록 하겠습니다.

긴 글 읽어주셔서 감사하며 도움이 될 만한 정보들은 댓글로 남겨주세요.

 

다음 키워드를 이용하여 epel-release를 설치합니다.
yum install -y epel-release

다음과 같이 뜰겁니다.

$ yum install -y epel-release
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                                     | 8.5 kB     00:00
 * base: mirror.kakao.com
 * epel: epel.01link.hk
 * extras: mirror.kakao.com
 * updates: mirror.kakao.com
base                                                     | 3.6 kB     00:00
epel                                                     | 4.7 kB     00:00
extras                                                   | 2.9 kB     00:00
mysql-connectors-community                               | 2.6 kB     00:00
mysql-tools-community                                    | 2.6 kB     00:00
mysql57-community                                        | 2.6 kB     00:00
updates                                                  | 2.9 kB     00:00
(1/2): epel/x86_64/updateinfo                              | 1.0 MB   00:00
(2/2): epel/x86_64/primary_db                              | 6.9 MB   00:04
Resolving Dependencies
--> Running transaction check
---> Package epel-release.noarch 0:7-11 will be updated
---> Package epel-release.noarch 0:7-13 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                Arch             Version           Repository      Size
================================================================================
Updating:
 epel-release           noarch           7-13              epel            15 k

Transaction Summary
================================================================================
Upgrade  1 Package

Total download size: 15 k
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
epel-release-7-13.noarch.rpm                               |  15 kB   00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : epel-release-7-13.noarch                                     1/2
  Cleanup    : epel-release-7-11.noarch                                     2/2
  Verifying  : epel-release-7-13.noarch                                     1/2
  Verifying  : epel-release-7-11.noarch                                     2/2

Updated:
  epel-release.noarch 0:7-13

Complete!

certbot을 설치해줍니다.
$ yum install -y certbot

$ yum install -y certbot
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.kakao.com
 * epel: ftp.iij.ad.jp
 * extras: mirror.kakao.com
 * updates: mirror.kakao.com
Resolving Dependencies
--> Running transaction check
---> Package certbot.noarch 0:1.11.0-1.el7 will be installed
--> Processing Dependency: python2-certbot = 1.11.0-1.el7 for package: certbot-1.11.0-1.el7.noarch
--> Running transaction check
---> Package python2-certbot.noarch 0:1.11.0-1.el7 will be installed
--> Processing Dependency: python-parsedatetime >= 1.3 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-acme >= 1.8.0 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-configargparse >= 0.9.3 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-cryptography >= 1.2.3 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-distro >= 1.0.1 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-josepy >= 1.1.0 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python-setuptools for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python-zope-component for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python-zope-interface for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-mock for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: python2-pyrfc3339 for package: python2-certbot-1.11.0-1.el7.noarch
--> Processing Dependency: pytz for package: python2-certbot-1.11.0-1.el7.noarch
--> Running transaction check
---> Package python-setuptools.noarch 0:0.9.8-7.el7 will be installed
--> Processing Dependency: python-backports-ssl_match_hostname for package: python-setuptools-0.9.8-7.el7.noarch
---> Package python-zope-component.noarch 1:4.1.0-5.el7 will be installed
--> Processing Dependency: python-zope-event for package: 1:python-zope-component-4.1.0-5.el7.noarch
---> Package python-zope-interface.x86_64 0:4.0.5-4.el7 will be installed
---> Package python2-acme.noarch 0:1.11.0-1.el7 will be installed
--> Processing Dependency: pyOpenSSL >= 0.13.1 for package: python2-acme-1.11.0-1.el7.noarch
--> Processing Dependency: python2-requests >= 2.6.0 for package: python2-acme-1.11.0-1.el7.noarch
--> Processing Dependency: python-ndg_httpsclient for package: python2-acme-1.11.0-1.el7.noarch
--> Processing Dependency: python-requests-toolbelt for package: python2-acme-1.11.0-1.el7.noarch
--> Processing Dependency: python2-pyasn1 for package: python2-acme-1.11.0-1.el7.noarch
--> Processing Dependency: python2-six for package: python2-acme-1.11.0-1.el7.noarch
---> Package python2-configargparse.noarch 0:0.11.0-2.el7 will be installed
---> Package python2-cryptography.x86_64 0:1.7.2-2.el7 will be installed
--> Processing Dependency: python-six >= 1.4.1 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-idna >= 2.0 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-cffi >= 1.4.1 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-ipaddress for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-enum34 for package: python2-cryptography-1.7.2-2.el7.x86_64
---> Package python2-distro.noarch 0:1.2.0-3.el7 will be installed
---> Package python2-josepy.noarch 0:1.3.0-2.el7 will be installed
---> Package python2-mock.noarch 0:1.0.1-10.el7 will be installed
---> Package python2-parsedatetime.noarch 0:2.4-6.el7 will be installed
--> Processing Dependency: python2-future for package: python2-parsedatetime-2.4-6.el7.noarch
---> Package python2-pyrfc3339.noarch 0:1.1-3.el7 will be installed
---> Package pytz.noarch 0:2016.10-2.el7 will be installed
--> Running transaction check
---> Package pyOpenSSL.x86_64 0:0.13.1-4.el7 will be installed
---> Package python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.el7 will be installed
--> Processing Dependency: python-backports for package: python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch
---> Package python-cffi.x86_64 0:1.6.0-5.el7 will be installed
--> Processing Dependency: python-pycparser for package: python-cffi-1.6.0-5.el7.x86_64
---> Package python-enum34.noarch 0:1.0.4-1.el7 will be installed
---> Package python-idna.noarch 0:2.4-1.el7 will be installed
---> Package python-ipaddress.noarch 0:1.0.16-2.el7 will be installed
---> Package python-ndg_httpsclient.noarch 0:0.3.2-1.el7 will be installed
---> Package python-requests.noarch 0:2.6.0-10.el7 will be installed
--> Processing Dependency: python-urllib3 >= 1.10.2-1 for package: python-requests-2.6.0-10.el7.noarch
--> Processing Dependency: python-chardet >= 2.2.1-1 for package: python-requests-2.6.0-10.el7.noarch
---> Package python-requests-toolbelt.noarch 0:0.8.0-3.el7 will be installed
---> Package python-six.noarch 0:1.9.0-2.el7 will be installed
---> Package python-zope-event.noarch 0:4.0.3-2.el7 will be installed
---> Package python2-future.noarch 0:0.18.2-2.el7 will be installed
---> Package python2-pyasn1.noarch 0:0.1.9-7.el7 will be installed
---> Package python2-six.noarch 0:1.9.0-0.el7 will be installed
--> Running transaction check
---> Package python-backports.x86_64 0:1.0-8.el7 will be installed
---> Package python-chardet.noarch 0:2.2.1-3.el7 will be installed
---> Package python-pycparser.noarch 0:2.14-1.el7 will be installed
---> Package python-urllib3.noarch 0:1.10.2-7.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================
 Package                                         Arch               Version                      Repository        Size
========================================================================================================================
Installing:
 certbot                                         noarch             1.11.0-1.el7                 epel              46 k
Installing for dependencies:
 pyOpenSSL                                       x86_64             0.13.1-4.el7                 base             135 k
 python-backports                                x86_64             1.0-8.el7                    base             5.8 k
 python-backports-ssl_match_hostname             noarch             3.5.0.1-1.el7                base              13 k
 python-cffi                                     x86_64             1.6.0-5.el7                  base             218 k
 python-chardet                                  noarch             2.2.1-3.el7                  base             227 k
 python-enum34                                   noarch             1.0.4-1.el7                  base              52 k
 python-idna                                     noarch             2.4-1.el7                    base              94 k
 python-ipaddress                                noarch             1.0.16-2.el7                 base              34 k
 python-ndg_httpsclient                          noarch             0.3.2-1.el7                  epel              43 k
 python-pycparser                                noarch             2.14-1.el7                   base             104 k
 python-requests                                 noarch             2.6.0-10.el7                 base              95 k
 python-requests-toolbelt                        noarch             0.8.0-3.el7                  epel              78 k
 python-setuptools                               noarch             0.9.8-7.el7                  base             397 k
 python-six                                      noarch             1.9.0-2.el7                  base              29 k
 python-urllib3                                  noarch             1.10.2-7.el7                 base             103 k
 python-zope-component                           noarch             1:4.1.0-5.el7                epel             228 k
 python-zope-event                               noarch             4.0.3-2.el7                  epel              79 k
 python-zope-interface                           x86_64             4.0.5-4.el7                  base             138 k
 python2-acme                                    noarch             1.11.0-1.el7                 epel              83 k
 python2-certbot                                 noarch             1.11.0-1.el7                 epel             386 k
 python2-configargparse                          noarch             0.11.0-2.el7                 epel              31 k
 python2-cryptography                            x86_64             1.7.2-2.el7                  base             502 k
 python2-distro                                  noarch             1.2.0-3.el7                  epel              29 k
 python2-future                                  noarch             0.18.2-2.el7                 epel             806 k
 python2-josepy                                  noarch             1.3.0-2.el7                  epel              89 k
 python2-mock                                    noarch             1.0.1-10.el7                 epel              92 k
 python2-parsedatetime                           noarch             2.4-6.el7                    epel              78 k
 python2-pyasn1                                  noarch             0.1.9-7.el7                  base             100 k
 python2-pyrfc3339                               noarch             1.1-3.el7                    epel              16 k
 python2-six                                     noarch             1.9.0-0.el7                  epel             2.9 k
 pytz                                            noarch             2016.10-2.el7                base              46 k

Transaction Summary
========================================================================================================================
Install  1 Package (+31 Dependent packages)

Total download size: 4.3 M
Installed size: 20 M
Downloading packages:
(1/32): python-backports-1.0-8.el7.x86_64.rpm                                                    | 5.8 kB  00:00:00
(2/32): pyOpenSSL-0.13.1-4.el7.x86_64.rpm                                                        | 135 kB  00:00:00
(3/32): python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch.rpm                             |  13 kB  00:00:00
(4/32): python-chardet-2.2.1-3.el7.noarch.rpm                                                    | 227 kB  00:00:00
(5/32): python-cffi-1.6.0-5.el7.x86_64.rpm                                                       | 218 kB  00:00:00
(6/32): python-enum34-1.0.4-1.el7.noarch.rpm                                                     |  52 kB  00:00:00
(7/32): python-ipaddress-1.0.16-2.el7.noarch.rpm                                                 |  34 kB  00:00:00
(8/32): python-pycparser-2.14-1.el7.noarch.rpm                                                   | 104 kB  00:00:00
(9/32): python-idna-2.4-1.el7.noarch.rpm                                                         |  94 kB  00:00:00
(10/32): python-requests-2.6.0-10.el7.noarch.rpm                                                 |  95 kB  00:00:00
(11/32): certbot-1.11.0-1.el7.noarch.rpm                                                         |  46 kB  00:00:00
(12/32): python-setuptools-0.9.8-7.el7.noarch.rpm                                                | 397 kB  00:00:00
(13/32): python-urllib3-1.10.2-7.el7.noarch.rpm                                                  | 103 kB  00:00:00
(14/32): python-six-1.9.0-2.el7.noarch.rpm                                                       |  29 kB  00:00:00
(15/32): python-requests-toolbelt-0.8.0-3.el7.noarch.rpm                                         |  78 kB  00:00:00
(16/32): python-zope-component-4.1.0-5.el7.noarch.rpm                                            | 228 kB  00:00:00
(17/32): python-zope-interface-4.0.5-4.el7.x86_64.rpm                                            | 138 kB  00:00:00
(18/32): python-zope-event-4.0.3-2.el7.noarch.rpm                                                |  79 kB  00:00:00
(19/32): python2-acme-1.11.0-1.el7.noarch.rpm                                                    |  83 kB  00:00:00
(20/32): python2-certbot-1.11.0-1.el7.noarch.rpm                                                 | 386 kB  00:00:00
(21/32): python2-cryptography-1.7.2-2.el7.x86_64.rpm                                             | 502 kB  00:00:00
(22/32): python2-configargparse-0.11.0-2.el7.noarch.rpm                                          |  31 kB  00:00:00
(23/32): python2-distro-1.2.0-3.el7.noarch.rpm                                                   |  29 kB  00:00:00
(24/32): python2-future-0.18.2-2.el7.noarch.rpm                                                  | 806 kB  00:00:00
(25/32): python2-josepy-1.3.0-2.el7.noarch.rpm                                                   |  89 kB  00:00:00
(26/32): python2-mock-1.0.1-10.el7.noarch.rpm                                                    |  92 kB  00:00:00
(27/32): python2-pyasn1-0.1.9-7.el7.noarch.rpm                                                   | 100 kB  00:00:00
(28/32): python2-parsedatetime-2.4-6.el7.noarch.rpm                                              |  78 kB  00:00:00
(29/32): python2-pyrfc3339-1.1-3.el7.noarch.rpm                                                  |  16 kB  00:00:00
(30/32): pytz-2016.10-2.el7.noarch.rpm                                                           |  46 kB  00:00:00
(31/32): python2-six-1.9.0-0.el7.noarch.rpm                                                      | 2.9 kB  00:00:00
(32/32): python-ndg_httpsclient-0.3.2-1.el7.noarch.rpm                                           |  43 kB  00:00:01
------------------------------------------------------------------------------------------------------------------------
Total                                                                                   2.3 MB/s | 4.3 MB  00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python2-pyasn1-0.1.9-7.el7.noarch                                                                   1/32
  Installing : pyOpenSSL-0.13.1-4.el7.x86_64                                                                       2/32
  Installing : python-six-1.9.0-2.el7.noarch                                                                       3/32
  Installing : python-ipaddress-1.0.16-2.el7.noarch                                                                4/32
  Installing : python2-six-1.9.0-0.el7.noarch                                                                      5/32
  Installing : python2-pyrfc3339-1.1-3.el7.noarch                                                                  6/32
  Installing : python-zope-interface-4.0.5-4.el7.x86_64                                                            7/32
  Installing : pytz-2016.10-2.el7.noarch                                                                           8/32
  Installing : python-zope-event-4.0.3-2.el7.noarch                                                                9/32
  Installing : 1:python-zope-component-4.1.0-5.el7.noarch                                                         10/32
  Installing : python-pycparser-2.14-1.el7.noarch                                                                 11/32
  Installing : python-cffi-1.6.0-5.el7.x86_64                                                                     12/32
  Installing : python-chardet-2.2.1-3.el7.noarch                                                                  13/32
  Installing : python2-mock-1.0.1-10.el7.noarch                                                                   14/32
  Installing : python-backports-1.0-8.el7.x86_64                                                                  15/32
  Installing : python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch                                           16/32
  Installing : python-setuptools-0.9.8-7.el7.noarch                                                               17/32
  Installing : python-ndg_httpsclient-0.3.2-1.el7.noarch                                                          18/32
  Installing : python-urllib3-1.10.2-7.el7.noarch                                                                 19/32
  Installing : python-requests-2.6.0-10.el7.noarch                                                                20/32
  Installing : python-requests-toolbelt-0.8.0-3.el7.noarch                                                        21/32
  Installing : python2-distro-1.2.0-3.el7.noarch                                                                  22/32
  Installing : python2-future-0.18.2-2.el7.noarch                                                                 23/32
  Installing : python2-parsedatetime-2.4-6.el7.noarch                                                             24/32
  Installing : python2-configargparse-0.11.0-2.el7.noarch                                                         25/32
  Installing : python-enum34-1.0.4-1.el7.noarch                                                                   26/32
  Installing : python-idna-2.4-1.el7.noarch                                                                       27/32
  Installing : python2-cryptography-1.7.2-2.el7.x86_64                                                            28/32
  Installing : python2-josepy-1.3.0-2.el7.noarch                                                                  29/32
  Installing : python2-acme-1.11.0-1.el7.noarch                                                                   30/32
  Installing : python2-certbot-1.11.0-1.el7.noarch                                                                31/32
  Installing : certbot-1.11.0-1.el7.noarch                                                                        32/32
  Verifying  : python-idna-2.4-1.el7.noarch                                                                        1/32
  Verifying  : python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch                                            2/32
  Verifying  : python2-six-1.9.0-0.el7.noarch                                                                      3/32
  Verifying  : pytz-2016.10-2.el7.noarch                                                                           4/32
  Verifying  : python-ndg_httpsclient-0.3.2-1.el7.noarch                                                           5/32
  Verifying  : python-enum34-1.0.4-1.el7.noarch                                                                    6/32
  Verifying  : 1:python-zope-component-4.1.0-5.el7.noarch                                                          7/32
  Verifying  : python-setuptools-0.9.8-7.el7.noarch                                                                8/32
  Verifying  : python-ipaddress-1.0.16-2.el7.noarch                                                                9/32
  Verifying  : certbot-1.11.0-1.el7.noarch                                                                        10/32
  Verifying  : python-requests-toolbelt-0.8.0-3.el7.noarch                                                        11/32
  Verifying  : python2-configargparse-0.11.0-2.el7.noarch                                                         12/32
  Verifying  : python2-future-0.18.2-2.el7.noarch                                                                 13/32
  Verifying  : python-zope-interface-4.0.5-4.el7.x86_64                                                           14/32
  Verifying  : python-six-1.9.0-2.el7.noarch                                                                      15/32
  Verifying  : python2-distro-1.2.0-3.el7.noarch                                                                  16/32
  Verifying  : python2-josepy-1.3.0-2.el7.noarch                                                                  17/32
  Verifying  : python-urllib3-1.10.2-7.el7.noarch                                                                 18/32
  Verifying  : python-backports-1.0-8.el7.x86_64                                                                  19/32
  Verifying  : python2-acme-1.11.0-1.el7.noarch                                                                   20/32
  Verifying  : pyOpenSSL-0.13.1-4.el7.x86_64                                                                      21/32
  Verifying  : python-cffi-1.6.0-5.el7.x86_64                                                                     22/32
  Verifying  : python2-mock-1.0.1-10.el7.noarch                                                                   23/32
  Verifying  : python-chardet-2.2.1-3.el7.noarch                                                                  24/32
  Verifying  : python-pycparser-2.14-1.el7.noarch                                                                 25/32
  Verifying  : python-requests-2.6.0-10.el7.noarch                                                                26/32
  Verifying  : python-zope-event-4.0.3-2.el7.noarch                                                               27/32
  Verifying  : python2-pyrfc3339-1.1-3.el7.noarch                                                                 28/32
  Verifying  : python2-pyasn1-0.1.9-7.el7.noarch                                                                  29/32
  Verifying  : python2-parsedatetime-2.4-6.el7.noarch                                                             30/32
  Verifying  : python2-cryptography-1.7.2-2.el7.x86_64                                                            31/32
  Verifying  : python2-certbot-1.11.0-1.el7.noarch                                                                32/32

Installed:
  certbot.noarch 0:1.11.0-1.el7

Dependency Installed:
  pyOpenSSL.x86_64 0:0.13.1-4.el7                                   python-backports.x86_64 0:1.0-8.el7
  python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.el7        python-cffi.x86_64 0:1.6.0-5.el7
  python-chardet.noarch 0:2.2.1-3.el7                               python-enum34.noarch 0:1.0.4-1.el7
  python-idna.noarch 0:2.4-1.el7                                    python-ipaddress.noarch 0:1.0.16-2.el7
  python-ndg_httpsclient.noarch 0:0.3.2-1.el7                       python-pycparser.noarch 0:2.14-1.el7
  python-requests.noarch 0:2.6.0-10.el7                             python-requests-toolbelt.noarch 0:0.8.0-3.el7
  python-setuptools.noarch 0:0.9.8-7.el7                            python-six.noarch 0:1.9.0-2.el7
  python-urllib3.noarch 0:1.10.2-7.el7                              python-zope-component.noarch 1:4.1.0-5.el7
  python-zope-event.noarch 0:4.0.3-2.el7                            python-zope-interface.x86_64 0:4.0.5-4.el7
  python2-acme.noarch 0:1.11.0-1.el7                                python2-certbot.noarch 0:1.11.0-1.el7
  python2-configargparse.noarch 0:0.11.0-2.el7                      python2-cryptography.x86_64 0:1.7.2-2.el7
  python2-distro.noarch 0:1.2.0-3.el7                               python2-future.noarch 0:0.18.2-2.el7
  python2-josepy.noarch 0:1.3.0-2.el7                               python2-mock.noarch 0:1.0.1-10.el7
  python2-parsedatetime.noarch 0:2.4-6.el7                          python2-pyasn1.noarch 0:0.1.9-7.el7
  python2-pyrfc3339.noarch 0:1.1-3.el7                              python2-six.noarch 0:1.9.0-0.el7
  pytz.noarch 0:2016.10-2.el7

Complete!

python2-certbot-nginx 을 설치해줍니다.

yum install -y python2-certbot-nginx

$ yum install -y python2-certbot-nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.kakao.com
 * epel: epel.01link.hk
 * extras: mirror.kakao.com
 * updates: mirror.kakao.com
Resolving Dependencies
--> Running transaction check
---> Package python2-certbot-nginx.noarch 0:1.11.0-1.el7 will be installed
--> Processing Dependency: pyparsing >= 1.5.5 for package: python2-certbot-nginx-1.11.0-1.el7.noarch
--> Running transaction check
---> Package pyparsing.noarch 0:1.5.6-9.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================
 Package                               Arch                   Version                        Repository            Size
========================================================================================================================
Installing:
 python2-certbot-nginx                 noarch                 1.11.0-1.el7                   epel                  78 k
Installing for dependencies:
 pyparsing                             noarch                 1.5.6-9.el7                    base                  94 k

Transaction Summary
========================================================================================================================
Install  1 Package (+1 Dependent package)

Total download size: 172 k
Installed size: 633 k
Downloading packages:
(1/2): pyparsing-1.5.6-9.el7.noarch.rpm                                                          |  94 kB  00:00:00
(2/2): python2-certbot-nginx-1.11.0-1.el7.noarch.rpm                                             |  78 kB  00:00:00
------------------------------------------------------------------------------------------------------------------------
Total                                                                                   243 kB/s | 172 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : pyparsing-1.5.6-9.el7.noarch                                                                         1/2
  Installing : python2-certbot-nginx-1.11.0-1.el7.noarch                                                            2/2
  Verifying  : python2-certbot-nginx-1.11.0-1.el7.noarch                                                            1/2
  Verifying  : pyparsing-1.5.6-9.el7.noarch                                                                         2/2

Installed:
  python2-certbot-nginx.noarch 0:1.11.0-1.el7

Dependency Installed:
  pyparsing.noarch 0:1.5.6-9.el7

Complete!

인증을 시작합시다.
아래의 키워드를 입력합니다.
$ certbot --standalone -d [도메인주소] certonly

그렇다면 아래처럼 노출되는데요,
이메일 입력 해주시고 넘어갑니다.

$ certbot --standalone -d [도메인주소] certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): [이메일주소]

다음으로 서비스 약관을 읽고 동의하라는 문구가 노출되는데요.
y를 눌러 동의하고 넘어갑니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

제공한 이메일을 이용하여,
EFF와 공유하고 이곳 저곳에 사용하는걸 동의하냐는 말인데요.
y누르고 넘어갑니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

완료되면 아래처럼 노출됩니다.

Account registered.
Requesting a certificate for [도메인주소]
Performing the following challenges:
http-01 challenge for [도메인주소]
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: [이메일주소]).
Starting new HTTPS connection (1): supporters.eff.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/[도메인주소]/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/[도메인주소]/privkey.pem
   Your certificate will expire on 2021-08-31. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

여기서 인증키가 저장 되어있는 두 패스를 잘 보시면 됩니다.

/etc/letsencrypt/live/[도메인주소]/fullchain.pem
/etc/letsencrypt/live/[도메인주소]/privkey.pem

nginx.conf에 가서 다음과 같이 ssl 전용 server를 세팅합니다.

 server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  [도메인주소];
        root         /usr/share/nginx/html;

        ssl_certificate /etc/letsencrypt/live/[도메인주소]/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/[도메인주소]/privkey.pem;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
}

기존에 80포트로 제공중이던 기본 서버를,
443 포트로 redirect 해주도록 아래와 같이 세팅을 변경합니다.

 server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  [도메인주소];
        return 301 https://$host$request_uri;
}

시간이 지남에 따라서 자동 갱신이 가능하도록 crontab을 등록해줍니다.
다음을 이용하여 에디터 페이지로 이동합니다.
crontab -e

매일 밤 1시에 자동으로 업데이트가 가능하도록 다음과 같이 입력합니다.

0 1 * * * sudo certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"

잘 등록 되었는지 확인합니다.

$ crontab -l
0 1 * * * sudo certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"

세팅이 완료되었습니다.

참고한 사이트
https://certbot.eff.org/lets-encrypt/centosrhel7-nginx
https://www.burndogfather.com/187

Google에 Kafka on docker site:github.com 라고 검색하면

아래의 레포지토리가 가장 맨 위에 랭크된다.
https://github.com/wurstmeister/kafka-docker

해당 레포지토리를 따라가면서 다음 튜토리얼에 접속하여 따라 하다보면 여러가지 에러가 발생하여, 해당 부분이 정상적으로 동작하게끔 한 부분에 대해서 기재 하겠다.

Pull 받은 후 Dockefile 수정하자.

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    build: .
    ports:
      - "9092"
    environment:
    // Kafka host로 사용할 장비의 IP. 개인 장비에서 돌릴거면 private IP, 그 외는 Public IP가 나와야 한다.
    // 해당 IP를 Kafka host ip라고 부르겠다.
      KAFKA_ADVERTISED_HOST_NAME: 10.64.52.218 
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

도커 내부에 접속

보통 다음과 같은 키워드로 접속을 할텐데
docker -it wurstmeister/kafka-docker /bin/bash

도큐먼트에서 제공하는 방향으로 접속을 하려면 다음과 같이 입력 해야한다.
$ start-kafka-shell.sh <DOCKER_HOST_IP> <ZK_HOST:ZK_PORT>


앞서 수정한 Dockerfile을 바탕으로 위의 스크립트를 사용 하려면 아래와 같이 입력하면 되겠다.
./start-kafka-shell.sh 10.64.52.218 10.64.52.218:2181

컨슈머 접속 안되는 문제.

단순 도큐먼트만 본다면 다음 명령어를 입력할 것 같은데,
$KAFKA_HOME/bin/kafka-console-consumer.sh --topic=topic --zookeeper=$ZK

그러면 정확히 아래의 에러를 보게된다.

zookeeper is not a recognized option

이는 요 문서를 확인해보면 알 수 있는데
--zookeeper=10.64.52.218:2181에서의 --zookeeper 옵션은 Deprecated 되었다.
대신 아래의 명령어로 대체 되었다.
--bootstrap-server

(해당 옵션은 브로커의 주소를 넘겨주는 옵션이다.)

 

그럼 이런 명령어가 완성이 된다.

$KAFKA_HOME/bin/kafka-console-consumer.sh --topic=topic --bootstrap-server=$ZK

위의 명령어를 실행하면 주키퍼에서는 아래와 같은 에러를 무한정으로 뱉는데,

zookeeper_1  | 2021-03-24 13:09:14,685 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /172.18.0.1:51072
zookeeper_1  | 2021-03-24 13:09:14,688 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@949] - Client attempting to establish new session at /172.18.0.1:51072
zookeeper_1  | 2021-03-24 13:09:14,692 [myid:] - INFO  [SyncThread:0:ZooKeeperServer@694] - Established session 0x10000068f5b0004 with negotiated timeout 30000 for client /172.18.0.1:51072
zookeeper_1  | 2021-03-24 13:09:14,916 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@487] - Processed session termination for sessionid: 0x10000068f5b0004
zookeeper_1  | 2021-03-24 13:09:14,922 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /172.18.0.1:51072 which had sessionid 0x10000068f5b0004
zookeeper_1  | 2021-03-24 13:10:15,769 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /172.18.0.1:51090
zookeeper_1  | 2021-03-24 13:10:15,788 [myid:] - WARN  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@383] - Exception causing close of session 0x0: Unreasonable length = 1818570083
zookeeper_1  | 2021-03-24 13:10:15,788 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /172.18.0.1:51090 (no session established for client)
zookeeper_1  | 2021-03-24 13:10:15,898 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /172.18.0.1:51096
zookeeper_1  | 2021-03-24 13:10:15,899 [myid:] - WARN  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@383] - Exception causing close of session 0x0: Unreasonable length = 1818570083
zookeeper_1  | 2021-03-24 13:10:15,899 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /172.18.0.1:51096 (no session established for client)
zookeeper_1  | 2021-03-24 13:10:16,003 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /172.18.0.1:51102
zookeeper_1  | 2021-03-24 13:10:16,004 [myid:] - WARN  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@383] - Exception causing close of session 0x0: Unreasonable length = 1818570083
zookeeper_1  | 2021-03-24 13:10:16,005 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /172.18.0.1:51102 (no session established for client)
zookeeper_1  | 2021-03-24 13:10:16,110 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /172.18.0.1:51108
zookeeper_1  | 2021-03-24 13:10:16,112 [myid:] - WARN  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@383] - Exception causing close of session 0x0: Unreasonable length = 1818570083
zookeeper_1  | 2021-03-24 13:10:16,112 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /172.18.0.1:51108 (no session established for client)

이는 기본 레포에 있는 스크립트를 실행하여 브로커의 정보를 가져오면 된다.

$ ./broker-list.sh
:32772

가져온 정보를 바탕으로 다음과 같이 실행하자.

$KAFKA_HOME/bin/kafka-console-consumer.sh --bootstrap-server 10.64.52.218:32772 --topic "topic" --from-beginning

정상 실행된다.

 

제목이 무슨 Jira 티켓처럼 보이네

내가 주로 사용하는 CentOS 7 환경에서 SSH 연결을 끊으면

mvn, npm, node와 같은 프로세스들이 자동으로 죽는 문제가 빈번히 발생한다

 

예전에는 바쁘다는 핑계로 넘어 갔었는데,

코로나 덕분에 연말 약속이 없어져서 해당 이슈를 조금 자세히 볼 기회가 생겼다.

사족을 붙히자면 디자이너 친구가 FE + BE을 도전하고 있는데, 서버 세팅이 필요해서 도와주기로 했었다. 

 

그 과정에서 서버를 키고 SSH 연결을 끊으면 서버 프로세스가 함께 죽는 현상이 발생했다. 

-> npm를 이용하여 react, nodejs 서버를 키고가 더 맞겠다. 참고로 나는 npm을 사용할줄 모른다 그냥 그려러니 하자

1급장애..

 

아래의 키워드로 구글링 해보니까 해당 이슈는 CentOS에서만 발생 하는 이슈는 아닌 것 같았다. 

keeping a process running after putty or terminal has been closed on centos

역시 나에게 맞는 문서가 찾긴 어려웠고 이것저것 하다보니 아래의 문서가 나의 케이스에서 동작했다.

stackoverflow.com/questions/26568135/keep-alive-express-process-after-close-the-terminal

 

Keep alive express process after close the terminal

I'm trying to keep live a process after close the terminal. Is a node.js project with express. Basically, for other process I kept alive processes with: $ node server.js & I with that, was po...

stackoverflow.com

 

잘 동작하긴 한데, nohup이 무엇인지 찾아보니까 아래의 문서에서 친절하게 설명 해준다. 

www.egr.msu.edu/decs/software/nohup/usage

 

Using Nohup | DECS

Home Software Using Nohup What is Nohup? Nohup is a command used to run a process(job) on a server and have it continue after you have logged out or otherwise lost connection to the server. Nohup is best suited for long job runs. Using Nohup Nohup is prese

www.egr.msu.edu

짧은 문서지만 이거마저 읽기 귀찮은 사람들을 위해 간략히 설명 해주자면 다음과 같다.

  • 서버에서 로그아웃 하거나, 갑작스레 연결이 끊어져도 계속 동작하는 프로세스
  • 커맨드가 정상적으로 종료되면 "nohup.out" 이라는 파일로 실행 결과가 남는다.

 

나에게 맞춰서 이해를 해보니 다음과 같이 이해할 수 있었다.

  • nohup으로 실행 시키면 ssh로 접속한 정보로 프로세스를 띄우는 것이 아닌 새로운 프로세스를 띄움.
  • CI서버가 서버를 재시작 할 경우에도 nohup.out 이라는 파일에 서버 시작 성공 여부 데이터가 남겨짐. 
    • 나는 사이드프로젝트엔 golang으로 만든 경량화 ci서버를 사용함.
    • 요것의 단점은 로그를 보기가 힘든거였는데 요걸 보완해주네 ?

 

내가 세팅한 서버의 환경은 master 브랜치에 데이터가 push, merge되면 서버가 계속해서 재시작 되는 구조다

따라서 실패 했을경우에만 로그를 보기 위하여 다음과 같이 스크립트를 짜서 운영할 예정이다.

#! /bin/bash
rm nohup.out
nohup npm run dev &

 

반영 후 잘 동작한다.

$ sudo ./npm_startup.sh
$ nohup: appending output to ‘nohup.out’

 

오늘도 보람찬 하루군

 

'linux' 카테고리의 다른 글

CentOS 7.x의 nginx에 letsencrypt 설치하기.  (0) 2021.06.03

회사에서 오랫동안 준비하고 지난 화요일에 큰 배포를 하고 나보니, 

퇴근 후 여유로움을 느끼고 있던 때 쯤, 

지난 겨울에 넥스터즈에서 진행했던 앱에 기능을 넣고 있던 중 갑자기 궁금한 부분이 생겼다. 

 

음악과 관련된 앱이라 soundCloud API를 사용하는 부분이 있는데

soundCloud의 노래들은 각각의 고유한 trackId를 소유하고 있다. 

 

또한 우리가 만든 어드민 툴에서는 신규 노래를 등록할 때 다음과 같은 두 가지의 종류의 URL로 넘겨주고 있다.

1. https://api.soundcloud.com/tracks/607910394

2. https://api.soundcloud.com/tracks/607910394/stream

딱 보면 알겠지만, 마지막에 /stream의 존재 유무이다. 

 

기존에 돌아가던 코드는 아래처럼 노가다성으로 사용하고 있었으며,

String을 매 번 짤라서 사용하기 때문에 메모리를 사용함에 있어서도 매우 비 효율적일 것 같다는 생각이 들었다.

물론 매직 넘버들이 상수화가 안 되어 있어서 가독성도 떨어졌다. 

public String getTrackId(String url) {
    String[] split = StringUtils.split(url, "/");
    int size = split.length;

    if (NumberUtils.isNumber(split[size - 1])) {
        return split[size - 1];
    }

    return split[size - 2];
}

 

맥주 한 캔 하면서 요걸 바라본 결과,

이것보다 정규식을 사용하면 더 빠르게, 더 메모리를 적게 사용하면서 가독성도 높힐 수 있을 것 같다는 생각이 들었고,

생각과 동시에 바로 아래와 같이 코드를 작성했다.

private static final Pattern GET_TRACK_ID_PATTERN = Pattern.compile(".+/(\\d+)(/stream)?");
private static final int TRACK_ID_IDX = 1;
public String getTrackId2(String url) {
    Matcher matcher = GET_TRACK_ID_PATTERN.matcher(url);

    return matcher.find() ? matcher.group(TRACK_ID_IDX) : StringUtils.EMPTY;
}

 

그런 다음.. 바로 아래의 코드로 테스트를 해보았는데

결과는 생각 했던거와 달라서 조금 신기하긴 했다 

@Test
void getTrackIdTimeCheck() {
	//given
	List<String> urlList = IntStream.rangeClosed(0, 1_000_000_000)
			.boxed()
			.map(each -> "https://api.soundcloud.com/tracks/607910394/stream")
			.collect(Collectors.toList());

	//when
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	urlList.stream().forEach(SoundCloundUtils::getTrackId);
	stopWatch.stop();

	//then
	log.info("time : {}", stopWatch.getTime());
}

 

5년만에 보는 것 같다

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:265)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
	at java.util.ArrayList.add(ArrayList.java:462)
	at java.util.stream.Collectors$$Lambda$32/649734728.accept(Unknown Source)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
	at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110)
	at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.music.nexters.utils.SoundCloundUtilsTest.getTrackIdTimeCheck(SoundCloundUtilsTest.java:46)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$110/1675763772.apply(Unknown Source)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall$$Lambda$111/1757143877.apply(Unknown Source)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$$Lambda$247/824208363.apply(Unknown Source)

 

ㅋㅋㅋ 돌리고 보니 내가 취기가 올라오긴 했나보구나 생각했다

 

아래처럼 다시 수정해서 돌렸는데,

//노가다 로 작성한 코드
@Test
void getTrackIdTimeCheck() {
	//given
	List<String> urlList = IntStream.rangeClosed(0, 100_000_000)
			.boxed()
			.map(each -> "https://api.soundcloud.com/tracks/607910394/stream")
			.collect(Collectors.toList());

	//when
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	urlList.stream().forEach(SoundCloundUtils::getTrackId);
	stopWatch.stop();

	//then
	log.info("time : {}", stopWatch.getTime());
}
//time : 20166

 

//정규식 사용한 코드 
@Test
void getTrackIdTimeCheck() {
	//given
	List<String> urlList = IntStream.rangeClosed(0, 100_000_000)
			.boxed()
			.map(each -> "https://api.soundcloud.com/tracks/607910394/stream")
			.collect(Collectors.toList());

	//when
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	urlList.stream().forEach(SoundCloundUtils::getTrackId);
	stopWatch.stop();

	//then
	log.info("time : {}", stopWatch.getTime());
}
//time : 56496

 

결과는 정규식이 2배이상 느리다는걸 보여줬다. 

많은 자바 개발자들이 정규식은 run-time 시에 pre-compile 해주면 빠르다고 하긴 하는데.

역시 문자열 속 문자를 찾는건 오래 걸리나보다. 

 

항상 간단한 문자열 속에서 간단한 문자 찾는 코드가 있을 때, 

노가다 코드가 빠를지 ? 정규식이 빠를지 ? 에 대한 해답이 되었다.

맥주 한 잔 한 김에 나와 비슷한 궁금증을 갖고 있는 사람들이 있을 것 같아서 끄적끄적 적어본다.

 

2년전, 학생때 이런 정보를 제대로 포스팅 해줬던 분들이 없었던 것 같아서 고생을 많이 했었던적이 몇 번 있었는데,

지금은 2년전 나와 같은 분들을 위하여 이 글을 작성합니다.

 

본 글은 Google Cloud Platform의 Compute Engine, Centos7 환경에서 세팅한 글입니다.

 

편의상 VM을 만들고, 접속하는 단계까지는 사람마다 방법이 모두 다를 수 있으니,

SSH를 통하여 서버에 접속한 것 부터 진행하겠습니다.

 

먼저 로컬에 mysql 5.7버전을 다운로드 합시다.

$ sudo yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

localinstall은 처음 보는사람들이 있을 것 같아서 제가 알고있는대로 말씀 드리자면,

터미널의 working directory를 찾아서 여기에 다운로드 의존성 있는 애들을 다운로드하고, 설치까지 해줍니다.

여기에서 말하는 다운로드 의존성이 있는건, mysql 5.7버전과 관련된거겠죠.

여기까지 치면 아래처럼 실행될겁니다.

뭐 물어보면 다 그냥 y 누르시면 됩니다.

$ sudo yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
Loaded plugins: fastestmirror
mysql57-community-release-el7-11.noarch.rpm                                                                                                   |  25 kB  00:00:00     
Examining /var/tmp/yum-root-bArCKx/mysql57-community-release-el7-11.noarch.rpm: mysql57-community-release-el7-11.noarch
Marking /var/tmp/yum-root-bArCKx/mysql57-community-release-el7-11.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package mysql57-community-release.noarch 0:el7-11 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=====================================================================================================================================================================
 Package                                      Arch                      Version                    Repository                                                   Size
=====================================================================================================================================================================
Installing:
 mysql57-community-release                    noarch                    el7-11                     /mysql57-community-release-el7-11.noarch                     31 k

Transaction Summary
=====================================================================================================================================================================
Install  1 Package

Total size: 31 k
Installed size: 31 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : mysql57-community-release-el7-11.noarch                                                                                                           1/1 
  Verifying  : mysql57-community-release-el7-11.noarch                                                                                                           1/1 

Installed:
  mysql57-community-release.noarch 0:el7-11                                                                                                                          

Complete!

그 다음 로컬에 설치한 mysql을 아래의 키워드로 정식으로 설치해 주면 됩니다.

$ sudo yum install mysql-community-server

 

정상적으로 설치가 완료되면 다음처럼 노출될겁니다.

$ sudo yum install mysql-community-server
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: repos-va.psychz.net
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.team-cymru.com
 * updates: repos-va.psychz.net
ㅛ
mysql-tools-community                                                                                                                         | 2.5 kB  00:00:00     
mysql57-community                                                                                                                             | 2.5 kB  00:00:00     
(1/3): mysql-connectors-community/x86_64/primary_db                                                                                           |  41 kB  00:00:00     
(2/3): mysql57-community/x86_64/primary_db                                                                                                    | 177 kB  00:00:00     
(3/3): mysql-tools-community/x86_64/primary_db                                                                                                |  58 kB  00:00:00     
Resolving Dependencies
--> Running transaction check
---> Package mysql-community-server.x86_64 0:5.7.26-1.el7 will be installed
--> Processing Dependency: mysql-community-common(x86-64) = 5.7.26-1.el7 for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: mysql-community-client(x86-64) >= 5.7.9 for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libnuma.so.1(libnuma_1.2)(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libnuma.so.1(libnuma_1.1)(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libaio.so.1(LIBAIO_0.4)(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libaio.so.1(LIBAIO_0.1)(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libnuma.so.1()(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Processing Dependency: libaio.so.1()(64bit) for package: mysql-community-server-5.7.26-1.el7.x86_64
--> Running transaction check
---> Package libaio.x86_64 0:0.3.109-13.el7 will be installed
---> Package mysql-community-client.x86_64 0:5.7.26-1.el7 will be installed
--> Processing Dependency: mysql-community-libs(x86-64) >= 5.7.9 for package: mysql-community-client-5.7.26-1.el7.x86_64
---> Package mysql-community-common.x86_64 0:5.7.26-1.el7 will be installed
---> Package numactl-libs.x86_64 0:2.0.9-7.el7 will be installed
--> Running transaction check
---> Package mariadb-libs.x86_64 1:5.5.60-1.el7_5 will be obsoleted
--> Processing Dependency: libmysqlclient.so.18()(64bit) for package: 2:postfix-2.10.1-7.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18(libmysqlclient_18)(64bit) for package: 2:postfix-2.10.1-7.el7.x86_64
---> Package mysql-community-libs.x86_64 0:5.7.26-1.el7 will be obsoleting
--> Running transaction check
---> Package mysql-community-libs-compat.x86_64 0:5.7.26-1.el7 will be obsoleting
--> Finished Dependency Resolution

Dependencies Resolved

=====================================================================================================================================================================
 Package                                           Arch                         Version                                Repository                               Size
=====================================================================================================================================================================
Installing:
 mysql-community-libs                              x86_64                       5.7.26-1.el7                           mysql57-community                       2.2 M
     replacing  mariadb-libs.x86_64 1:5.5.60-1.el7_5
 mysql-community-libs-compat                       x86_64                       5.7.26-1.el7                           mysql57-community                       2.0 M
     replacing  mariadb-libs.x86_64 1:5.5.60-1.el7_5
 mysql-community-server                            x86_64                       5.7.26-1.el7                           mysql57-community                       166 M
Installing for dependencies:
 libaio                                            x86_64                       0.3.109-13.el7                         base                                     24 k
 mysql-community-client                            x86_64                       5.7.26-1.el7                           mysql57-community                        24 M
 mysql-community-common                            x86_64                       5.7.26-1.el7                           mysql57-community                       274 k
 numactl-libs                                      x86_64                       2.0.9-7.el7                            base                                     29 k

Transaction Summary
=====================================================================================================================================================================
Install  3 Packages (+4 Dependent packages)

Total download size: 194 M
Is this ok [y/d/N]: y
Downloading packages:
warning: /var/cache/yum/x86_64/7/mysql57-community/packages/mysql-community-common-5.7.26-1.el7.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY
Public key for mysql-community-common-5.7.26-1.el7.x86_64.rpm is not installed
(1/7): mysql-community-common-5.7.26-1.el7.x86_64.rpm                                                                                         | 274 kB  00:00:00     
(2/7): mysql-community-libs-5.7.26-1.el7.x86_64.rpm                                                                                           | 2.2 MB  00:00:00     
(3/7): mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm                                                                                    | 2.0 MB  00:00:00     
(4/7): mysql-community-client-5.7.26-1.el7.x86_64.rpm                                                                                         |  24 MB  00:00:00     
(5/7): libaio-0.3.109-13.el7.x86_64.rpm                                                                                                       |  24 kB  00:00:00     
(6/7): numactl-libs-2.0.9-7.el7.x86_64.rpm                                                                                                    |  29 kB  00:00:01     
(7/7): mysql-community-server-5.7.26-1.el7.x86_64.rpm                                                                                         | 166 MB  00:00:05     
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                 34 MB/s | 194 MB  00:00:05     
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
Importing GPG key 0x5072E1F5:
 Userid     : "MySQL Release Engineering <mysql-build@oss.oracle.com>"
 Fingerprint: a4a9 4068 76fc bd3c 4567 70c8 8c71 8d3b 5072 e1f5
 Package    : mysql57-community-release-el7-11.noarch (installed)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
Is this ok [y/N]:y   
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : mysql-community-common-5.7.26-1.el7.x86_64                                                                                                        1/8 
  Installing : mysql-community-libs-5.7.26-1.el7.x86_64                                                                                                          2/8 
  Installing : mysql-community-client-5.7.26-1.el7.x86_64                                                                                                        3/8 
  Installing : libaio-0.3.109-13.el7.x86_64                                                                                                                      4/8 
  Installing : numactl-libs-2.0.9-7.el7.x86_64                                                                                                                   5/8 
  Installing : mysql-community-server-5.7.26-1.el7.x86_64                                                                                                        6/8 
  Installing : mysql-community-libs-compat-5.7.26-1.el7.x86_64                                                                                                   7/8 
  Erasing    : 1:mariadb-libs-5.5.60-1.el7_5.x86_64                                                                                                              8/8 
  Verifying  : mysql-community-server-5.7.26-1.el7.x86_64                                                                                                        1/8 
  Verifying  : numactl-libs-2.0.9-7.el7.x86_64                                                                                                                   2/8 
  Verifying  : mysql-community-client-5.7.26-1.el7.x86_64                                                                                                        3/8 
  Verifying  : mysql-community-libs-5.7.26-1.el7.x86_64                                                                                                          4/8 
  Verifying  : mysql-community-common-5.7.26-1.el7.x86_64                                                                                                        5/8 
  Verifying  : mysql-community-libs-compat-5.7.26-1.el7.x86_64                                                                                                   6/8 
  Verifying  : libaio-0.3.109-13.el7.x86_64                                                                                                                      7/8 
  Verifying  : 1:mariadb-libs-5.5.60-1.el7_5.x86_64                                                                                                              8/8 

Installed:
  mysql-community-libs.x86_64 0:5.7.26-1.el7         mysql-community-libs-compat.x86_64 0:5.7.26-1.el7         mysql-community-server.x86_64 0:5.7.26-1.el7        

Dependency Installed:
  libaio.x86_64 0:0.3.109-13.el7   mysql-community-client.x86_64 0:5.7.26-1.el7   mysql-community-common.x86_64 0:5.7.26-1.el7   numactl-libs.x86_64 0:2.0.9-7.el7  

Replaced:
  mariadb-libs.x86_64 1:5.5.60-1.el7_5                                                                                                                               

Complete!

 

여기까지 진행 되셨으면,

mysql을 시작해 주면서, 서버가 부팅/재부팅 될 때 자동으로 실행될 수 있도록 다음 키워드를 입력해 줍시다.

$ sudo systemctl enable mysqld
$ sudo systemctl start mysqld

 

다음 키워드로 mysql가 정상적으로 실행 되었는지 확인해볼 수 있어요.

$ sudo systemctl status mysqld

● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2019-07-10 16:39:32 UTC; 6s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 5835 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 5758 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 5838 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─5838 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Jul 10 16:39:22 instance-2 systemd[1]: Starting MySQL Server...
Jul 10 16:39:32 instance-2 systemd[1]: Started MySQL Server.

 

보통 mysql을 설치하면, default password를 몰라서 재설치 했던적이 엄청 많은데요.

다음 키워드를 입력하면 Mysql 을 설치하면서 자동으로 세팅되었던 비밀번호를 알 수 있어요.

$ sudo grep 'A temporary password' /var/log/mysqld.log

2019-07-10T16:39:28.194886Z 1 [Note] A temporary password is generated for root@localhost: %11/dxwc_OG2

 

mysql에서 알려준 password는 %11/dxwc_OG2였네요.

요걸로 로그인하면 아래처럼 정상적으로 로그인할 수 있습니다.

$ sudo mysql -u root -p

Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

 

그런데 요 상태에서 뭔갈 해보려고 하니까, 아래처럼 패스워드를 바꾸라고 하네요.

mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

 

그럼 다음 키워드를 입력하여 mysql를 나와주시고,

mysql> exit
Bye

 

다음 키워드를 입력해서 비밀번호를 바꿔줍시다.

$ sudo mysql_secure_installation

처음 입력하라는 비밀번호는, Mysql에서 처음 발급해줬던 임시 비밀번호입니다.

저는 다음과 같이 입력했어요.

 

$ sudo mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root: 

The existing password for the user account root has expired. Please set a new password.

New password: 


Re-enter new password: 
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 100 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : y

New password: 

Re-enter new password: 

Estimated strength of the password: 100 
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : n

 ... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : n

 ... skipping.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done! 

$ 

-> yyynny

nn했던것들

1. 원격에서 DB 접근 막을거냐 ? => 로컬장비에서 서버로 붙어서 쓸거라 n

2. test database가 있는데 이거 지울거야 ? => 테스트할 때 필요할 수도 있을 것 같아서 n

 

이렇게하면, 세팅은 끝납니다.

 

최종적으로 다음처럼 실행되면 됩니다.

$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.26 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.06 sec)

mysql> 

 

 

어라? test database가 사라졌네 ?

왜지 ? ㅎㅎㅎ

 

 

언제 쓸지는 모르겠지만, 다음 글에서는 golang에서 DB연결하는걸...써볼까요 

추천받습니다.

 

 

참고 : 

구글링 하면서 나온 수 많은 사이트들.

'Database > MySQL' 카테고리의 다른 글

MySQL에서 Grant 권한  (0) 2016.04.22

3장.

앗...? DB가 없는 환경에서 동작하게 만들라고...!??!


처음 go를 쓰면서 커피 어드민 툴을 만들 때 제가 들었던 말이예요 .

지금 남는 서버가 있긴 한데, 그 서버에 있는 DB는 사용하면 안 되는게 서버를 사용할 수 있는 조건 이였어요.


그래서 FileIO를 통하여 프로그램을 작성하기로 결심했어요.


파일 io는 2가지 정도의 조건이 있을 것 같아요.

1. CSV(comma seperate version )

2. normal version.


자, 이 두 가지를 사용하기 앞서서,

앞으로 우리가 사용할 모델을 정의해 줄거예요.

앞에서 이야기 한 조건들을 생각해 보면,

"개발자 말고 다른 직군(디자이너, 기획자)도 같이 먹을 수 있게 해주세요"

"하루 이틀은 제가 빠질 수 있도록 조정하고 싶어요"

이 말을 바탕으로 생각해보면,


이름, 직군, 이메일, 참가여부

정도의 정보를 갖는 모델이 필요해요. (이메일은 결과를 메일로 받아야하기 때문이예요!)

이를 바탕으로 모델을 만들면 다음처럼 될 수 있을 것 같아요.

type Colleague struct {
Name string
Position string
Email string `gorm:"PRIMARY_KEY"`
Attend string
}


여기서 email에서 gorm을 사용했는데요, golang에서 많이 사용하는 orm이예요 . 

이거에 대해서도 하나의 포스팅으로 분리할게요!



csv파일을 컨트롤 하기 위해서는 encoding/csv 패키지의 기본 라이브러리를 사용 할거예요.

백문이 문여일견, 먼저 읽어들이는 코드를 보고 갈게요.

func getColleagueInfoFromCsv(filename string) []Colleague {
// 파일 오픈 !
file, _ := os.Open(filename)

// csv reader 생성
rdr := csv.NewReader(bufio.NewReader(file))

// csv 내용 모두 읽기
rows, _ := rdr.ReadAll()

colleagues := []Colleague{}

var temp Colleague

// 행,열 읽기
for i := range rows {
temp.Email = strings.TrimSpace(rows[i][0])
temp.Name = strings.TrimSpace(rows[i][1])
temp.Position = strings.TrimSpace(rows[i][2])
temp.Attend = strings.TrimSpace(rows[i][3])

colleagues = append(colleagues, temp) // 1
}
return colleagues
}

나 아직 여기에서 어떻게 최적화를 해야할지 모르겠어요

// 1에 있는 부분도 최적화가 가능할 것 같은데,

일단은 돌아가는 코드를 만들고, 리팩토링 하는 리뷰도 한번 만들게요.


---- 여기부터는 작성중인 문서입니다. ---- 

2장.

Golang을 이용하여 hello-world restful api 만들기.

개발 환경.

IDE : goland

web framework : echo



이 글에서는 기초적인 go를 알고 있다는 전제조건으로 진행할거예요.


그래도 go가 처음이신 분들이 있을터이니 공부할 수 있는 링크를 같이 첨부해 둘게요.


go를 익힌 다음으로 어떤 웹 프레임워크를 사용해야하나 고민이 많았어요.


java는 spring을 쓰면 되고,

javscript는 node+express를 사용하면 되고,

python은 django를 쓰면 되는데


go는 한번도 뭘 사용해야할지 잘 모르겠더라구요.

그래서 읽은 문서들이 다음 문서들이예요.


https://wikinote.bluemir.me/golang/choose-web-framework.md

https://jaehue.github.io/post/go-my-way-1-webframework/

https://okky.kr/article/386116

https://www.buzzvil.com/ko/2018/02/12/tech-blog-go-%EC%84%9C%EB%B2%84-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0/

https://dev.to/speedwheel/top-6-web-frameworks-for-go-as-of-2017-34i 


결국에 제가 고른 웹 프레임워크는 echo 에요

마지막 업데이트가 1년전이라, 요즘엔 iris를 보고있긴 해요

처음부터 iris를 봤으면 좋을텐데..

맨 마지막 링크를 보시면 알다싶이, iris가 learning curve가 가장 낮아요. 

마지막 업데이트도 글 쓴 날 기준(2019년 1월 6일)으로 두 달 전이구요.


그래도 다른걸 써봐야지 어떤게 더 좋은지 아니까 ㅎㅎ


echo는 document를 봤을 때 정리가 너무 잘 되어있어서 사용 해야겠다고 결심했어요.


시작 전, 다음 코드를 터미널에서 실행하여 다운로드 해주세요


go get -u github.com/labstack/echo/...


최종코드.

reference : https://github.com/KwonGiho/go-starter/blob/master/go-simple-restful-api.go

package main

import (
"github.com/labstack/echo"
"net/http"
)

func main() {

e := echo.New() // 1

e.GET("/say", func(c echo.Context) error { // 2
return c.JSON(http.StatusOK, "hi")
})

e.Logger.Fatal(e.Start(":1331"))
}





1번. 

echo는 echo.New() 함수를 호출하면 

Echo 변수를 생성하고, 포인터 변수에 이 변수의 주소를 저장해요.

그리고 이 변수의 주소를 반환해요.


c언어를 좀 더 많이 하셨던 분을 위해서 좀 더 명확하게 작성해 드리면,

다음과 같이 작성할 수도 있어요.

var e echo.Echo
e = *echo.New()
e.GET("/say", sayHi)

e.Logger.Fatal(e.Start(":1332")) // 3


변수 사용 & 미사용 버전

reference : https://github.com/KwonGiho/go-starter/blob/master/go-simple-restful-api-seperate.go



2번.

앞으로 URI:1331/say로 오는 모든 요청을 이 함수가 책임질 예정이예요.


실행 url : localhost:1331/say

curl localhost:1331/say 

아래로 요청하면, "hi"라는 결과가 노출되요.

쿼리 스트링으로 요청을 보내고 싶으시면,

다음과 같이 사용하시면 됩니다.

name := c.QueryParam("name")


하위 url을 두고 싶으시면, 다음과 같이 사용하시면 되요.

e.GET("/say/:name", func(c echo.Context) error {
name := c.Param("name")
return c.JSON(http.StatusOK, name)
})


3번.

Fatal은 에러가 있을 시, 에러 메시지를 노출하고, os.Exit(0이 아닌 정수)을 호출하여 프로그램을 종료합니다.

이상이 없을 경우엔 아무 로그도 발생시키지 않아요.

+ Recent posts