요즘 어떤 서비스의 아키텍처를 설계한다고 하면

당연히 "마이크로서비스 아키텍처(MSA)"를 떠올리게 될 정도로 MSA는 이제 거의 표준처럼 되어 버렸다.

 

그렇기에 당연히 우리는 "마이크로서비스 아키텍처(MSA)"를 공부해야 하고,

아마존에서 설계/아키텍처 부분 베스트셀러인 이 책을 살펴보는 것은 자연스러운 수순일 것이다 ^^

 

표지

 

2017년도에 초판으로 출간된 책인데,

빠른 변화와 신기술의 등장에 발맞춰서 얼마전에 전면 개정판으로 새로운 책으로 거듭났다!

 

전면 개정판

 

이 책의 저자는 특정 회사에 속하지 않고 프리랜서로 활동하시는 것 같고,

옮긴이는 포동 서비스를 언급하신 것으로 봐서 LG유플러스에서 근무하시는 것이 아닌가 싶다 ^^

 

지은이/옮긴이

 

책 제목에 "아키텍처"가 들어가있다보니

이 책의 대상독자로 제일 먼저 떠오르는 것이 "어?! 이 책은 Architect를 위한 책인가?"였다.

 

하지만, 뒤에 설명할 목차 등을 보면 알겠지만

이 책은 개발자부터 PL 및 C-level에게도 도움이 될 수 있는

"마이크로서비스 아키텍처(MSA)"에 대한 모든 것을 담고 있는 책이다.

 

대상 독자

 

이 책은 크게 "기초/구현/사람"이라는 3개의 부로 나뉘어져 있다.

 

응?

 

사람?

 

1부 기초

 

개인적으로는 2부 구현 부분에 가장 관심이 많이 간다.

 

2부 구현

 

정말 의외인 "3부 사람" ...

 

뭐 세상 모든 일은 다 사람하기 나름이니.... 가장 중요한 것이 사람인 것 맞지만.... 호오....!

 

3부 사람

 

회사를 다니고 있다면

처음부터 아무 것도 없는 상태에서 새롭게 설계하는 일 보다는

이미 모놀리스 아키텍처로 구성되어 있는 기존의 서비스를

마이크로 서비스 아키텍처로 마이그레이션하는 일이 더 많을 것이다.

 

그래서 "Chapter3. 모놀리스 분해" 부분에 관심이 많이 갔다.

 

CH3 - 모놀리스 분해

 

아마존에서 괜히 베스트셀러가 된 것은 아니기에

책 구성과 내용은 정말 훌륭한 것 같다.

 

다만, 개인적인 취향으로 아쉬운 것은...... 풀컬러가 아니라는 점!?

ㅋㅋ 사실 책 주제 자체가 굳이 풀컬러일 필요가 전혀 없기에 이마저도 단점이 아닌 것 같다 ^^

 

CH1

 

책 내용이 훌륭하다는 예시를 들어보자면,

모놀리스의 유형 중 하나인 "모듈식 모놀리스"에 대한 설명을 한 번 살펴보자.

 

모듈식 모놀리스

 

당연하게 보일 수도 있겠지만

개인적으로는 저렇게 모듈로 나눠서 구성하면

그것을 가지고 마치 마이크로 서비스인 것처럼 착각하는 경우가 종종 있다.

그런 부분에 대한 설명이 차분하게 잘 서술되어 있는 것을 보면 이 책의 내공이 정말 탄탄한 것 같다.

 

그리고 또, 개인적으로 애정하는 쿠버네티스...

 

K8s

 

마이크로서비스 아키텍처(MSA)하면 빼놓을 수 없는 짝꿍 쿠버네티스(Kubernetes) !!!

 

 

전반적으로 이 책은 정말 "마이크로서비스 아키텍처(MSA)"의 교과서라고 불리워도 무방할만큼

탄탄한 내공이 가득차 있는 정말 좋은 책이다.

 

쿠버네티스(Kubernetes)를 공부하는 분들도 필수 도서로 같이 공부하면 정말 많은 도움이 될 것이다!!!

 

 

 

"한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다."

 

반응형

ChatGPT가 정말 범지구적인 인기를 얻고있다.

최근에 그 성장세가 주춤해졌다고 뉴스에서 떠들지만, 그래도 여전히 대단한 인기이다.

 

인기를 얻으면 뭐가 따라올까!?

당연히 Anti가 따라온다.

 

그리고, 일종의 sacarsm(빈정댐, 비꼼)도 등장한다.

https://bratgpt.com/

 

뭔가 깔끔하게 잘 만들어진 인터페이스가 먼저 눈에 들어온다.

그리고, 귀찮게 로그인하지 않아도 사용할 수 있다.

오른쪽 위의 X를 누르자.

https://bratgpt.com/

 

"ChatGPT를 따라했네!?"라며 그냥 넘어가지 말고

그 안의 내용물을 좀 살펴보면... 저절로 웃음이 나올 것이다.

 

AI apocalypse ?????? ㅋㅋㅋ

https://bratgpt.com/

 

한글 질문에 한글 대답도 할 줄 안다.

근데, 말투가 상당히 건방지지 않은가 ?! ㅋㅋㅋ

https://bratgpt.com/

 

저런 X가지 없는 말만 하는 것은 아니다.

가끔 말을 듣기도 하고, 실제로 코드를 생성해주기도 한다.

다만, 그다지 긴 대답을 하지는 못해서 큰 기대를 하면 안된다.

 

 

 

BratGPT는 BratAI에서 만들었다고 한다.

https://newsletter.bratai.com/p/bratgpt-unleashing-comical-sassy-powers-ai

 

그런데, 별 내용은 없다.

https://newsletter.bratai.com/

 

애초에 뭘 얻고자 이런 사이트를 운영하고자 하는 것인지는 모르겠지만,

AI 윤리를 생각해보면.... 음... 뭔가 생각해볼 꺼리가 있을 것 같다.

 

ChatGPT를 생각해보면 많은 이슈거리들이 뉴스를 장식하고 있다.

차별적인 발언을 해도 문제고, 가치 판단을 해도 문제고 ... 도덕적으로 완전무결.... 거의 순결해야 한다고 강요하고 있다.

 

과연 이것이 맞는 것일까?!

 

뭐 그냥 그렇다고.... ^^

반응형

전자제품을 구매하고 언박싱을 하면 매번 튀어나오는 매뉴얼...

하지만, 우리는 보통 그 매뉴얼을 거들떠 보지도 않는다. 어!? 나만 그런가!? ^^

 

리눅스 서버를 구성하고 종종 확인하는 리소스...

솔직히... 그 의미가 어떤 것인지 경험으로만 파악했지, 정확한 의미는 잘 모른다. 어?! 나만 그런가?! ^^

 

[ Environment ]

- VM : VirtualBox v7.0.6 r155176

- OS : Ubuntu 20.04 LTS

 

VirtualBox

 

 

[ top ]

내 서버가 왠지 힘들어하는 것 같으면 가장 먼저 확인하는 것이 'top' 명령어이다.

> top

 

여기에서 주로 보는 것은 다음의 'load average' 영역일 것이다.

load average

 

'load average'는 시스템의 부하정도를 알려주는 지표인데,

실행중인 프로세스 또는 Disk I/O 등을 위해 대기하고 있는 프로세스의 정도를 알려주는 정보로써

CPU core 1개당 1 이상의 값을 갖는다면 대기해야하는 task가 있다는 의미로 이해하면 된다.

 

그런데, 왜 3개의 값이 보일까?!

1분 / 5분 / 15분 순서로 값을 보여주는데, 이를 통해 부하가 심해지고 있는지 해소되고 있는지 경향을 볼 수 있다.

 

개인 PC라면 가성비로 사용해야하기에 1에 맞춰서 Spec을 확보해도 괜찮겠지만

서비스를 위한 서버라면 아무리 돈이 없어도 평균 0.5 이하로 맞춰야 그나마 성능 저하 없이 사용할 수 있다.

 

일단 여기까지만 알아도 충분하지 않을까!? ^^

 

 

[ core ]

우리가 요즘 사용하는 CPU는 거의 multi-core일 것이다.

어!? 그런데, 생각해보니 Kubernetes에서 POD의 core를 소숫점으로도 줄 수 있는데... 일단 지금은 무시!!! ^^

core

 

실습을 하고 있는 환경은 일단 VirtualBox에서 2 core를 할당했다.

정말 잘 되어있는지 확인해보자.

> cat /proc/cpuinfo

 

스크린샷을 다 찍기에는 너무 길어져서 잘랐는데.... 그냥 심플하게 확인하려면 다음과 같이 하면 된다.

> grep -c processor /proc/cpuinfo

 

2 core가 잘 할당되어 있는 것을 볼 수 있다.

 

다른 명령어로도 확인할 수 있다.

> lscpu

 

 

[ full-load CPU ]

CPU 관련한 부하가 한계치까지 가면 어떻게 되는지 시뮬레이션을 해보자.

 

> nano cpu.py
#!/usr/bin/python

test = 0
while True:
    test = test + 1

 

Terminal 탭을 2개를 열고 진행을 해보자.

> python ./cpu.py

 

> top

 

응?! 그런데, 2 core 인데...

CPU 100%라고 하면, load 값이 2가 되어야 할 것 같은데 ... 1 값으로 수렴하고 있는 것 처럼 보인다.

 

그 이유는!

지금 실행되고 있는 python은 core 1개에서 실행되고 있기 때문이다!

 

그러면... python을 하나 더 실행해보자.

> python ./cpu.py

 

그리고나서 top을 다시 한 번 확인해보면,

> top

 

2 core이기 때문에, 각각 100% 실행이 되고 있으니... 2 값으로 나온다.

 

어!? 그러면 하나 더 실행하면!?

> top

 

밑에 보이는 리스트 형식의 내역을 보면 CPU는 총 200%를 3으로 나눠서 사용하고 있는 것이 보일 것이다.

'load average' 값은 3값으로 수렴하고 있다.

 

 

[ uptime]

'top' 명령어 말고 다른 명령어도 알아보자.

> uptime

 

지속적으로 값을 보여주는 것이 아니라 1회성으로 뿌려주고 끝난다.

 

 

[ /proc/loadavg ]

또 다른 방법으로도 확인해볼 수 있다.

> cat /proc/loadavg

 

 

[ w ]

top 명령어와 uptime 명령어의 중간쯤에 위치하고 있는 것 같은 'w' 명령어도 있다.

> w

 

 

그런데, 'load average'를 발생시키는 요인이 CPU 사용만 있을까!?

답은.... 당연히... 아니다 !!!

 

 

[ full-load Disk I/O ]

디스크에 읽고 쓰는 것도 부하를 야기한다.

 

> nano io.py
#!/usr/bin/python

while True:
    f = open("./test.txt", 'w')
    f.write("TEST")
    f.close()

 

> python ./io.py

 

> top

 

CPU 사용량은 9%를 찍고 있지만 'load average'를 보면 1에 수렴하고 있다.

 

CPU 100%를 찍으면 어떻게 될까?

 

> python ./cpu.py

 

> top

 

'load average'를 보면 2에 수렴하고 있지만 CPU 사용량을 보면 차이가 있다.

 

 

그렇다.

'load average'는 단순하게 Running 중인 프로세스 뿐만 아니라 Disk I/O로 인해 대기타는 것도 같이 바라보고 있다.

 

그러면, 이렇게 부하가 잡히고 있을 때 분석은 어떻게 하면 될까!?

일단은 뭐, top으로 확인 가능한 아래 리스트 목록으로 추적이 가능하다.

 

하지만, CPU 부하가 문제인지 Disk I/O 대기가 문제인지 어떻게 알 수 있을까?

 

 

[ vmstat ]

어떤 상태인지 'vmstat' 명령어를 사용해보자.

> vmstat

 

'vmstat' 명령어는 일단 Virtual Memory Statistics의 약자로써 현재 CPU 및 Memory 사용량을 알 수 있다.

 

지금 여기에서 살펴볼 것은 앞 부분에 있는 "r"과 "b" 부분이다.

 

"r"은 현재 실행하려고 하거나 실행 중인 프로세스의 개수를 알려주는 것이고

"b"는 uninterruptible sleep 상태의 프로세스 개수, 즉 I/O 대기를 하고 있는 프로세스의 개수를 알려준다.

 

중간에 io.py의 실행을 종료하면 어떻게 나오는지를 살펴보자.

> vmstat 1

 

중간에 보면 "b" 부분이 0으로 바뀌는 것을 확인할 수 있다.

 

 

우리 서버가 지금 힘들어하지는 않는지

머리(CPU)가 아픈지 손(I/O)이 바쁜지 파악해서 해결해주도록 하자.

반응형

받아보는 메일링 리스트를 통해 알게된 재미있는 Framework가 있어서 한 번 다뤄보려 한다.

https://oneoneone.kr/content/d9b579e3

 

나온지 꽤 된 것임에도 잘 몰랐는데,

'노마드 코더'의 극찬 영상으로 인해 호기심을 확 끌었다.

https://www.youtube.com/watch?v=DlyoFFOcPCg

 

 

이 framework의 분류를 정확히 뭐라해야할지 애매한데, 구글링을 통해 확인한 여러 별칭은 다음과 같다.

  - CMS

  - App Framework

  - App Backend

  - Backend Framework

  - Admin Panel

  - Library

 

음... 아직 명확한 naming은 안되어있는 분류인 것이다.

하지만, 뭘 말하고자 하는 것인지는 왠지 알 수 있을 것만 같은 느낌적인 느낌!?

 

 

일단, 이번에 다뤄보고자 하는 것은 "Keystone JS"라는 아이이다.

https://keystonejs.com/

 

재빨리 설치하고 웹을 띄워보자!!!

 

 

[ Environment ]

일단 개발 환경은 다음과 같다.

- 운영 체제: Ubuntu 20.04 LTS

 

❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

 

 

[ Node ]

이 아이도 Node.JS 기반이고 npm을 이용하기 때문에 node부터 설치를 해야 한다.

 

버전 호환성으로 인한 어려움이 종종 발생하기 때문에

우리는 node의 다양한 버전을 다룰 수 있는 방법이 필요하다!

 

그래서, 나의 선택은 nvm !!!

아래 링크를 통해 nvm, node, npm 설치를 하자 !!!

- https://www.whatwant.com/entry/npm

 

❯ git clone https://github.com/nvm-sh/nvm.git ~/.nvm
'/home/chani22/.nvm'에 복제합니다...
remote: Enumerating objects: 9051, done.
remote: Counting objects: 100% (1830/1830), done.
remote: Compressing objects: 100% (111/111), done.
remote: Total 9051 (delta 1764), reused 1730 (delta 1719), pack-reused 7221
오브젝트를 받는 중: 100% (9051/9051), 3.28 MiB | 10.09 MiB/s, 완료.
델타를 알아내는 중: 100% (5790/5790), 완료.


❯ cd ~/.nvm


❯ git tag


❯ git switch -c v0.39.3 tags/v0.39.3
새로 만든 'v0.39.3' 브랜치로 전환합니다
 3.8.16  chani22@chani22-VBox  ~/.nvm   v0.39.3


❯ nano ~/.zshrc

 

...
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

 

- shell 재접속 후

 

❯ nvm --version
0.39.3


❯ nvm install node
Downloading and installing node v20.4.0...
Downloading https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-x64.tar.xz...
######################################################################################################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v20.4.0 (npm v9.7.2)
Creating default alias: default -> node (-> v20.4.0)


❯ node --version  
v20.4.0


❯ npm --version 
9.7.2

 

 

[ Keystone JS ]

npm을 이용해서 keystone-app을 생성할 수 있다.

나의 app 이름을 지어주면 기본적인 boilerplate를 생성해준다.

 

❯ mkdir keystone


❯ cd keystone


❯ npm init keystone-app@latest
Need to install the following packages:
  create-keystone-app@9.0.1
Ok to proceed? (y) 

✨ You're about to generate a project using Keystone 6 packages.

✔ What directory should create-keystone-app generate your app into? · my-app

⠋ Installing dependencies with yarn. This may take a few minutes.
⚠ Failed to install with yarn.
✔ Installed dependencies with npm.


🎉  Keystone created a starter project in: my-app

  To launch your app, run:

  - cd my-app
  - npm run dev

  Next steps:

  - Read my-app/README.md for additional getting started details.
  - Edit my-app/keystone.ts to customize your app.
  - Open the Admin UI
  - Open the Graphql API
  - Read the docs
  - Star Keystone on GitHub


❯ cd my-app/


❯ ls -al
합계 484
drwxrwxr-x   4 chani22 chani22   4096  7월 12 16:28 .
drwxrwxr-x   3 chani22 chani22   4096  7월 12 16:26 ..
-rw-rw-r--   1 chani22 chani22     46  7월 12 16:26 .gitignore
drwxr-xr-x   2 chani22 chani22   4096  7월 12 16:28 .keystone
-rw-rw-r--   1 chani22 chani22   2874  7월 12 16:26 README.md
-rw-rw-r--   1 chani22 chani22   2710  7월 12 16:26 auth.ts
-rw-rw-r--   1 chani22 chani22   1014  7월 12 16:26 keystone.ts
drwxrwxr-x 570 chani22 chani22  20480  7월 12 16:28 node_modules
-rw-rw-r--   1 chani22 chani22 410056  7월 12 16:28 package-lock.json
-rw-rw-r--   1 chani22 chani22    397  7월 12 16:26 package.json
-rw-rw-r--   1 chani22 chani22   9506  7월 12 16:26 schema.graphql
-rw-rw-r--   1 chani22 chani22   1056  7월 12 16:26 schema.prisma
-rw-rw-r--   1 chani22 chani22   5178  7월 12 16:26 schema.ts
-rw-rw-r--   1 chani22 chani22    195  7월 12 16:26 tsconfig.json
 3.8.16  chani22@chani22-VBox  /srv/workspace/ks/my-app


❯ nano keystone.ts


❯ npm run dev

> keystone-app@1.0.2 dev
> keystone dev

✨ Starting Keystone
⭐️ Server listening on :3000 (http://localhost:3000/)
⭐️ GraphQL API available at /api/graphql
✨ Generating GraphQL and Prisma schemas
✨ sqlite database "keystone.db" created at file:./keystone.db
✨ Your database is now in sync with your schema
✨ Connecting to the database
✨ Creating server
✅ GraphQL API ready
✨ Generating Admin UI code
✨ Preparing Admin UI app
- warn You have enabled experimental feature (appDir) in next.config.js.
- warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.

- event compiled client and server successfully in 195 ms (18 modules)
✅ Admin UI ready
- wait compiling /_error (client and server)...
- event compiled client and server successfully in 6.5s (1706 modules)

 

'npm run dev'를 하면 웹앱을 띄워준다.

크롬으로 접속하면 된다.

http://localhost:3000/

 

첫 사용자를 생성해야 한다.

귀찮지만 8자 이상의 패스워드를 넣어줘야 한다.

Create user

 

예쁜 화면을 볼 수 있다.

Dashboard

 

User List를 확인해보면 다음과 같은 화면을 볼 수 있다.

Users

 

상세 정보도 확인할 수 있다.

User detail

 

Posts 화면을 살펴보자.

Posts

 

Create Post 버튼을 누르면 멋진 화면이 나온다.

Create Post

 

입력 인터페이스가 정말 산뜻하다. (직접 구현하려면 엄청 귀찮았을....)

Edit

 

 

[ GraphQL ]

API를 확인하기 위해서는 주소가 다르다.

 

http://localhost:3000/api/graphql

 

멋지지 않은가?!

 

 

하지만, 주의 사항은 있다.

관련된 공부를 하지 않고서는 이 편리함을 누릴 수 없다.

 

귀차니즘의 해결이지, No Study & Easy Use는 아니다 !!!

 

 

반응형

'Programming > Web' 카테고리의 다른 글

Vite로 React 앱 만들기  (0) 2024.11.07
npm, node 그리고 nvm  (0) 2023.01.04

최근에 "git sparse-checkout" 명령어를 살펴보면서 git version을 좀 따져보았었다.

  - https://www.whatwant.com/entry/sparse-checkout-size

 

"떡 본 김에 제사지낸다"고,

이번 기회에 Git 최신 버전을 사용하기 위한 방법을 살펴보도록 하겠다.

 

 

[ Environment ]

릴리즈된지 좀 오래되긴 했지만,

실무에서 주력으로 사용되는 Ubuntu 20.04 버전을 기준으로 하겠다.

(설마 우리 회사에서만? ^^)

 

❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal


❯ uname -a
Linux chani22-VBox 5.15.0-76-generic #83~20.04.1-Ubuntu SMP Wed Jun 21 20:23:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

 

 

[ Default ]

Ubuntu 20.04 설치 후에 "git" 설치는 손쉽게 가능하다.

버전까지 바로 확인해보자.

 

❯ sudo apt install git


❯ git --version
git version 2.25.1

 

 

[ Check ]

그러면, 지금 현재 git 최신 버전은 어떻게 될까?

공식 홈페이지에서 확인되는 최신 버전은 "v2.41.0"이다.

 

https://git-scm.com/

 

최신 버전을 사용하는 것이 중요할까!?

"Release Notes"를 한 번 살펴봐보자.

 

https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.41.0.txt

 

밑으로 스크롤을 내려보면 지난 버전의 Release Note도 확인 가능한데,

뭔가 새로운 명령어나 기존 명령어의 변경 및 개선 사항들이 많이 보인다.

 

즉, 새로운 버전이 필요한 상황이 발생할 수 있는 여지가 많다!

 

 

[ Install ① Using Apt ]

Git PPA를 추가해서 apt를 이용해 Git 최신 버전을 설치해보자.

 

❯ sudo add-apt-repository ppa:git-core/ppa
 The most current stable version of Git for Ubuntu.

For release candidates, go to https://launchpad.net/~git-core/+archive/candidate .
 더 많은 정보: https://launchpad.net/~git-core/+archive/ubuntu/ppa 
[ENTER]을 눌러 진행하거나 Ctrl-c를 눌러 추가하는것을 취소합니다.

기존:1 http://packages.microsoft.com/repos/code stable InRelease
기존:2 https://dl.google.com/linux/chrome/debstable InRelease
...


❯ sudo apt upgrade
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
업그레이드를 계산하는 중입니다... 완료
다음 패키지를 업그레이드할 것입니다:
  git git-man
2개 업그레이드, 0개 새로 설치, 0개 제거 및 0개 업그레이드 안 함.
9,438 k바이트 아카이브를 받아야 합니다.
이 작업 후 10.1 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n] 
받기:1 http://ppa.launchpad.net/git-core/ppa/ubuntu focal/main amd64 git amd64 1:2.41.0-0ppa1~ubuntu20.04.1 [7,325 kB]
받기:2 http://ppa.launchpad.net/git-core/ppa/ubuntu focal/main amd64 git-man all 1:2.41.0-0ppa1~ubuntu20.04.1 [2,113 kB]                                       
내려받기 9,438 k바이트, 소요시간 31초 (302 k바이트/초)                                                                                                         
(데이터베이스 읽는중 ...현재 186326개의 파일과 디렉터리가 설치되어 있습니다.)
Preparing to unpack .../git_1%3a2.41.0-0ppa1~ubuntu20.04.1_amd64.deb ...
Unpacking git (1:2.41.0-0ppa1~ubuntu20.04.1) over (1:2.25.1-1ubuntu3.11) ...
Preparing to unpack .../git-man_1%3a2.41.0-0ppa1~ubuntu20.04.1_all.deb ...
Unpacking git-man (1:2.41.0-0ppa1~ubuntu20.04.1) over (1:2.25.1-1ubuntu3.11) ...
git-man (1:2.41.0-0ppa1~ubuntu20.04.1) 설정하는 중입니다 ...
git (1:2.41.0-0ppa1~ubuntu20.04.1) 설정하는 중입니다 ...
Processing triggers for man-db (2.9.1-1) ...


❯ git --version
git version 2.41.0

 

이걸로 끝이다.

 

이렇게 하면 너무 쉽기에 추천할만한 방법이지만...

간혹 내부망 등의 이슈로 PPA 추가가 어려운 경우가 있으니 다른 방법도 알아보자.

 

 

[ Install ② Source Build ]

좀 번거로울 수도 있지만, 소스코드를 내려 받아서 직접 빌드를 해보자.

 

일단 apt로 설치한 git 패키지를 삭제하자.

 

❯ sudo apt purge git
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  git-man liberror-perl
'sudo apt autoremove'를 이용하여 제거하십시오.
다음 패키지를 지울 것입니다:
  git*
0개 업그레이드, 0개 새로 설치, 1개 제거 및 0개 업그레이드 안 함.
이 작업 후 46.6 M바이트의 디스크 공간이 비워집니다.
계속 하시겠습니까? [Y/n] 
(데이터베이스 읽는중 ...현재 186489개의 파일과 디렉터리가 설치되어 있습니다.)
git (1:2.41.0-0ppa1~ubuntu20.04.1)를 제거합니다...
(데이터베이스 읽는중 ...현재 185600개의 파일과 디렉터리가 설치되어 있습니다.)
Purging configuration files for git (1:2.41.0-0ppa1~ubuntu20.04.1) ...

 

빌드에 필요한 것들을 미리 설치해두자.

 

❯ sudo apt install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev make gettext libz-dev libssl-dev libghc-zlib-dev asciidoc docbook2x
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
주의, 'libz-dev' 대신에 'zlib1g-dev' 패키지를 선택합니다
패키지 make는 이미 최신 버전입니다 (4.2.1-1.2).
패키지 libexpat1-dev는 이미 최신 버전입니다 (2.2.9-1ubuntu0.6).
libexpat1-dev 패키지는 수동설치로 지정합니다.
패키지 libssl-dev는 이미 최신 버전입니다 (1.1.1f-1ubuntu2.19).
패키지 zlib1g-dev는 이미 최신 버전입니다 (1:1.2.11.dfsg-2ubuntu1.5).
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  git-man liberror-perl
'sudo apt autoremove'를 이용하여 제거하십시오.
다음의 추가 패키지가 설치될 것입니다 :
  autoconf automake autopoint autotools-dev debhelper dh-strip-nondeterminism dwz ghc intltool-debian libarchive-cpio-perl libarchive-zip-perl libbsd-dev
  libcroco3 libdebhelper-perl libfile-stripnondeterminism-perl libltdl-dev libmail-sendmail-perl libsigsegv2 libsub-override-perl libsys-hostname-long-perl
  libtool m4 po-debconf
제안하는 패키지:
  autoconf-archive gnu-standards autoconf-doc dh-make gettext-doc libasprintf-dev libgettextpo-dev ghc-prof ghc-doc haskell-doc llvm-6.0 libcurl4-doc
  libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev libghc-zlib-doc libghc-zlib-prof libtool-doc gfortran | fortran95-compiler gcj-jdk m4-doc
  libmail-box-perl
다음 새 패키지를 설치할 것입니다:
  autoconf automake autopoint autotools-dev debhelper dh-autoreconf dh-strip-nondeterminism dwz gettext ghc intltool-debian libarchive-cpio-perl
  libarchive-zip-perl libbsd-dev libcroco3 libcurl4-gnutls-dev libdebhelper-perl libfile-stripnondeterminism-perl libghc-zlib-dev libltdl-dev
  libmail-sendmail-perl libsigsegv2 libsub-override-perl libsys-hostname-long-perl libtool m4 po-debconf
0개 업그레이드, 27개 새로 설치, 0개 제거 및 0개 업그레이드 안 함.
74.8 M바이트 아카이브를 받아야 합니다.
이 작업 후 799 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n]

 

소스코드를 내려받을 곳을 확인해보자.

 

https://github.com/git/git

 

오른쪽 하단의 tags를 클릭해보자.

 

https://github.com/git/git/tags

 

소스코드 내려받고, 압축을 해제하자.

 

❯ wget https://github.com/git/git/archive/refs/tags/v2.41.0.tar.gz
--2023-07-12 00:42:52--  https://github.com/git/git/archive/refs/tags/v2.41.0.tar.gz
github.com (github.com) 해석 중... 20.200.245.247
다음으로 연결 중: github.com (github.com)|20.200.245.247|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 302 Found
위치: https://codeload.github.com/git/git/tar.gz/refs/tags/v2.41.0 [따라감]
--2023-07-12 00:42:53--  https://codeload.github.com/git/git/tar.gz/refs/tags/v2.41.0
codeload.github.com (codeload.github.com) 해석 중... 20.200.245.246
다음으로 연결 중: codeload.github.com (codeload.github.com)|20.200.245.246|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 200 OK
길이: 지정하지 않음 [application/x-gzip]
저장 위치: `v2.41.0.tar.gz'

v2.41.0.tar.gz                              [          <=>                                                                   ]  10.30M  5.51MB/s    / 1.9s     

2023-07-12 00:42:55 (5.51 MB/s) - `v2.41.0.tar.gz' 저장함 [10804275]


❯ tar zxvf v2.41.0.tar.gz

 

이제 빌드 진행하면 된다. 어렵지 않다.

 

❯ cd git-2.41.0


❯ make prefix=/usr/local all doc info
GIT_VERSION = 2.41.0
    * new build flags
    CC oss-fuzz/fuzz-commit-graph.o
    CC oss-fuzz/fuzz-pack-headers.o
    CC oss-fuzz/fuzz-pack-idx.o
    CC daemon.o
    * new link flags
    CC common-main.o
    CC abspath.o
    CC add-interactive.o
...


❯ sudo make prefix=/usr/local install install-doc install-html install-info

 

기본 환경 설정은 필수 !!

 

❯ git config --global user.name "whatwant"

❯ git config --global user.email "whatwant@whatwant.com"

 

자동완성 기능을 사용하고 싶다면 추가 설정을 진행하자.

 

bash를 사용하는 경우에는 다음과 같이 하면 된다.

 

 sudo cp ./contrib/completion/git-completion.bash /etc/bash_completion.d/

 

zsh을 사용하는 경우에는 다음과 같이 하자.

 

mkdir ~/.zsh


❯ cp ./contrib/completion/git-completion.bash ~/.zsh/



 cp ./contrib/completion/git-completion.zsh ~/.zsh/_git


nano ~/.zshrc

 

뒷 부분에 다음 라인을 추가하면 된다.

 

fpath=(~/.zsh $fpath)
zstyle ':completion:*:*:git:*' script ~/.zsh/git-completion.bash

 

shell 관련된 사항은 shell에 재진입해야 적용된다.

그게 싫다면 source 하던지...^^

 

 

빌드해서 설치까지 진행하는 과정이 어렵게 느껴질 수도 있지만

직접 버전 선택하고, 환경도 직접 꾸미는 것이 확실한 방법이긴 하다. 화이팅 !!

반응형

구글링을 하다가 우연히 발견한 멋진 제목 하나!

 

"Git 특정 디렉터리만 clone 하기"

 

여러 팀이 하나의 Repository를 사용하는 "Mono-Repo" 방식으로 소스코드를 관리할 때

너무 커져버린 용량으로 인한 어려움이 있을 경우에

이런 제목의 글이 눈에 들어오기 시작한다. ^^

 

 

3개의 팀이 다음 그림과 같이 mono-repo로 개발한다고 해보자.

 

https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

 

 

3개팀에서 각자 개발하는 내용이 하나의 저장소에 모이기 때문에 2가지 이슈가 있다.

 

1. clone 받을 때 용량이 쓸데없이(?) 커서 오래걸린다.

2. 개발할 때 쓸데없는(?) 다른 팀 내용들까지 같이 보인다.

 

 

[ background ]

 

일단 보통의 방법으로 clone을 해보자.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git

'git-sparse'에 복제합니다...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (19/19), 200.06 MiB | 10.03 MiB/s, 완료.

 

200MB 규모의 Repository이다.

tree 방식으로 디렉토리/파일을 보기 위해 tree 유틸리티 설치 후 사용해봤다.

 

❯ sudo apt install tree

❯ tree ./git-sparse

./git-sparse
├── README.md
├── client
│   ├── client-1.dummy
│   └── client-2.dummy
└── server
    ├── server-1.dummy
    └── server-2.dummy

2 directories, 5 files

 

50MB 크기의 파일 4개로 구성된 Repository다. (테스트를 위해 만든 저장소 ^^)

 

 

 

[ sparse-checkout ]

 

0. environment

- 이하 실습을 진행하는 환경은 다음과 같다.

  . OS : Ubuntu 20.04 LTS

  . Git : v2.25.1

 

1. git

- "sparse-checkout" 명령어는 Git v2.25.0 부터 추가되었다.

- 천만 다행으로 Ubuntu 20.04에서 제공되는 Git 패키지의 버전이 가까스로 0.00.1을 넘겼다 ^^

 

- 과거 Git v1.17.0 부터 "sparse checkout"을 제공했었다! (사이에 "-"가 있고 없고의 차이)

  . 그 때의 명령어 사용법과 차이가 있는데, 많은 웹 포스팅에서 이를 섞어서 설명하고 있다.

 

 

2. 어렵게 clone 받기

- 블로그를 돌아다니다 보면 조금 어렵게(?) 아니 번거롭게(?) clone 받는 방법을 소개하고 있다.

 

❯ git init git-sparse-client
/srv/workspace/git-sparse-client/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다

❯ cd git-sparse-client 

❯ git remote add origin git@github.com:whatwant-school/git-sparse.git 

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ cat .git/info/sparse-checkout 
/client/

❯ git pull origin main  
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트 묶음 푸는 중: 100% (19/19), 200.06 MiB | 7.07 MiB/s, 완료.
github.com:whatwant-school/git-sparse URL에서
 * branch            main       -> FETCH_HEAD
 * [새로운 브랜치]   main       -> origin/main

 

으응?!

 

❯ tree ./                  
./
└── client
    ├── client-1.dummy
    └── client-2.dummy

1 directory, 2 files

 

- Work Directory의 내용만 보면 내가 원하는대로 client/ 디렉토리만 존재한다.

- 하지만, clone 받는 용량이 줄어든 것은 아니다.

 

- sparse-checkout 명령어는 work directory를 다루기 위한 명령어이지 전송받는 데이터 용량을 줄여주는 것은 아니다.

- 그렇다면, 위와 같이 어렵게(?) clone을 받을 필요가 없다.

 

 

3. 편하게 sparse-checkout 적용하기

- 일반적인 방법으로 clone을 받고 sparse-checkout을 이용해서 정리하는 것이 훨씬 편하다.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (19/19), 200.06 MiB | 9.44 MiB/s, 완료.

❯ cd ./git-sparse       

❯ tree ./
./
├── README.md
├── client
│   ├── client-1.dummy
│   └── client-2.dummy
└── server
    ├── server-1.dummy
    └── server-2.dummy

2 directories, 5 files

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ tree ./                            
./
└── client
    ├── client-1.dummy
    └── client-2.dummy

1 directory, 2 files

 

- 훨씬 간단하지 않은가?! ^^

 

 

4. 결론

- "sparse-checkout"은 전송 용량을 줄이기 위한 것이 아니고,

- 내가 개발하는 내용(파일)만 보면서 개발하기 위한 용도로 사용하는 것이다.

 

 

 

[ --filter=blob:none ]

 

0. background

- 웹서핑을 하다보니, clone을 순식간에 할 수 있다는 옵션을 소개하곤 했다.

 

 

1. clone

- "--filter=blob:none" 옵션을 사용하면 필요한 만큼만 blob를 내려받는다.

❯ git clone --filter=blob:none git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 16 (delta 0), reused 4 (delta 0), pack-reused 12
오브젝트를 받는 중: 100% (16/16), 완료.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 3 (delta 0), reused 1 (delta 0), pack-reused 2
오브젝트를 받는 중: 100% (3/3), 100.03 MiB | 9.65 MiB/s, 완료.
파일을 갱신합니다: 100% (3/3), 완료.

❯ cd git-sparse

❯ du -hs ./
201M ./

❯ tree ./
./
├── README.md
├── client
│   └── client-1.dummy
└── server
    └── server-1.dummy

2 directories, 3 files

 

- 보통의 방식으로 clone 받는 것과 비교해보자.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 21, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 21 (delta 0), reused 5 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (21/21), 200.06 MiB | 10.29 MiB/s, 완료.

❯ cd git-sparse

❯ du -hs ./                                              
301M ./

❯ tree ./
./
├── README.md
├── client
│   └── client-1.dummy
└── server
    └── server-1.dummy

2 directories, 3 files

 

- 어!? 용량이 차이가 난다! 이건 써볼만한 방법이다!!!

 

 

2. with sparse-checkout and 'no-checkout'

- clone 받을 때 "--no-checkout" 옵션을 넣으면 working directory에 checkout을 하지 않는다

- 이렇게 clone을 받은 후 해당 디렉토리를 들어가면 필요한 일부 blob를 내려받느라 시간이 조금 소요된다.

 

❯ git clone --filter=blob:none --no-checkout git@github.com:whatwant-school/git-sparse.git
'git-sparse-no-checkout'에 복제합니다...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 16 (delta 0), reused 4 (delta 0), pack-reused 12
오브젝트를 받는 중: 100% (16/16), 완료.

❯ cd git-sparse

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ du -hs ./
151M ./

❯ tree ./
./
└── client
    └── client-1.dummy

1 directory, 1 file

 

- 용량이 또 줄었다! ^^

 

 

3. 결론

- clone 받을 때 "--filter=blob:none --no-checkout" 옵션을 추가해서 최소한으로 다운받고,

- 'sparse-checkout' 명령어를 섞어주면 내려받는 전체 용량을 확실히 줄여줄 수 있다.

 

 

 

 

git sparse-checkout 명령어에 대한 자세한 내용은 다음 링크를 참조하기 바란다.

https://git-scm.com/docs/git-sparse-checkout/2.41.0

반응형

이전에 "dd"를 이용해서 대용량 더미 파일 생성하는 것을 살펴봤었다.

https://www.whatwant.com/entry/대용량-더미-파일-만들기-Ubutnu-1404-64bit

 

이번에는 좀 다른 명령어를 이용해 보고자 한다.

 

 

0. Environment

  - OS: Ubuntu 20.04.6 LTS

 

 

1. fallocate

  - 소문자 L 옵션을 사용해서 원하는 용량, 파일 이름을 명시하면 된다.

 

❯ fallocate -l 100MB server-1.dummy

❯ ls -al
합계 97668
drwxrwxr-x 2 chani22 chani22           4096  6월 28 00:16 .
drwxrwxr-x 4 chani22 chani22           4096  6월 28 00:15 ..
-rw-rw-r--    1 chani22 chani22 100000000  6월 28 00:16 server-1.dummy

 

 

2. truncate

  - 소문자 S 옵션을 사용하는 것을 제외하고 fallocate 명령어와 동일하다.

 

❯ truncate -s 100MB client-1.dummy

❯ ls -al
합계 8
drwxrwxr-x 2 chani22 chani22      4096  6월 28 00:22 .
drwxrwxr-x 5 chani22 chani22      4096  6월 28 00:22 ..
-rw-rw-r-- 1 chani22 chani22 100000000  6월 28 00:22 client-1.dummy

 

 

3. dd (random)

  - 그냥 0으로 채워버리는 dummy file을 만들면 git 전송 속도 등을 측정할 때 압축이 되어버려 애매해진다.

  - 압축이 제대로 안되도록 하려면 random 값으로 채워지는 dummy file을 만드는 것이 유리하다.

 

❯ dd if=/dev/urandom of=client-3.dummy bs=100M count=1
1+0 레코드 들어옴
1+0 레코드 나감
104857600 bytes (105 MB, 100 MiB) copied, 0.330475 s, 317 MB/s

❯ ls -al
합계 102408
drwxrwxr-x 2 chani22 chani22      4096  6월 28 00:28 .
drwxrwxr-x 5 chani22 chani22      4096  6월 28 00:22 ..
-rw-rw-r-- 1 chani22 chani22 100000000  6월 28 00:22 client-1.dummy
-rw-rw-r-- 1 chani22 chani22 100000000  6월 28 00:23 client-2.dummy
-rw-rw-r-- 1 chani22 chani22 104857600  6월 28 00:28 client-3.dummy

 

  - 자세히 보면 파일 크기가 좀 차이가 있는 것도 확인해볼 수 있다.

 

 

여러 옵션이나 차이점 등이 궁금하긴 하지만,

굳이 시간을 쏟아 파고들 것 까지는 아닌 것 같아 여기서 멈추련다 ~ ^___^

 

반응형

 

옛날에 한 번 만들었다가 방치 끝에 삭제를 당해버린 서버의 부활 프로젝트 !!! ^^

 

"오라클 클라우드"를 처음 들어보신 분도 계실 수 있는데,

나름 어느 정도의 시장은 갖고 있는 ... 우리나라 리전도 갖고 있는 클라우드 플랫폼이다.

 

https://www.oracle.com/kr/cloud/

 

 

다른 클라우드들과 마찬가지로

계정 등록을 할 때 신용카드 정보가 필요하다. (1달라인가? 결제하고 곧바로 취소된다)

 

가입을 까막득한 옛날에 했다보니 기억이 가물거려서.... ^^

 

가입 후 화면을 보면 다음과 같다.

 

 

밑에 내려보면 "리소스 실행" 부분에 "VM 인스턴스 생성" 카드가 보인다.

이것을 선택하면 된다.

 

 

기본 이미지가 Orable Linux인데... 다른 배포판을 고를 수도 있다.

 

 

눈치빠른 분은 이미 파악하셨겠지만, 고를 수 있다고 해서 모두 무료가 아니다.

회색 뱃지가 붙어있는 것을 잘 확인해야 한다.

 

나는 익숙한 우분투로 골라봤다.

 

 

 SSH 키 생성해서 내려받는 방법도 있지만,

내가 사용하는 작업용 우분투에 이미 있는 Public-Key를 등록하는 방식으로 진행해봤다.

 

 

갖고 있는 Public-Key 복사해서 넣어줬다.

이렇게 하면 내 작업용 우분투에서 바로 오라클 서버로 접속할 수 있게 된다.

 

 

열심히 생성중이다.

확인해야 할 것은 "공용 IP 주소" 와 "사용자 이름"이다.

 

 

그냥 "ssh ubuntu@ip" 방식으로 접속하면 된다.

 

 

Disk 용량은 위에서 보듯이 50GB가 주어진 것을 알 수 있고,

메모리 용량은 다음과 같이 확인해볼 수 있다.

 

 

무료임에도 1GB를 주는 것은 대단한거다.

하지만, 뭣 좀 해보려면 좀 부족한 것도 사실이니.... swap을 잡아줘보자.

 

ubuntu@instance-20230626-2355:~$ free -h
                      total        used        free         shared    buff/cache   available
Mem:          964Mi       201Mi       168Mi       1.0Mi       594Mi       627Mi
Swap:            0B          0B             0B

ubuntu@instance-20230626-2355:~$ sudo fallocate -l 2G /swapfile

ubuntu@instance-20230626-2355:~$ sudo chmod 600 /swapfile

ubuntu@instance-20230626-2355:~$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=6be33865-5c3a-4cce-bca3-96b4e1880438

ubuntu@instance-20230626-2355:~$ sudo swapon /swapfile

ubuntu@instance-20230626-2355:~$ sudo swapon --show
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2

ubuntu@instance-20230626-2355:~$ free -h
                     total        used          free        shared   buff/cache   available
Mem:          964Mi       202Mi       165Mi       1.0Mi       596Mi       626Mi
Swap:         2.0Gi          0B            2.0Gi

 

위 명령어들을 따라해보면 2GB 사이즈의 swap 메모리를 만들어줄 수 있다.

하지만, 재부팅하게 되면 사라지니... 재부팅해도 유지될 수 있도록 추가 작업을 해주자.

 

ubuntu@instance-20230626-2355:~$ sudo nano /etc/fstab

 

아래 한 줄 추가해주면 된다. (탭으로 구분하는 것 잊지 말고!)

 

 

추가로... 우리는 대한민국 사람이니, 타임존을 맞춰주자.

 

ubuntu@instance-20230626-2355:~$ sudo timedatectl set-timezone Asia/Seoul

ubuntu@instance-20230626-2355:~$ timedatectl
                          Local time: Tue 2023-06-27 00:32:32 KST
                    Universal time: Mon 2023-06-26 15:32:32 UTC
                            RTC time: Mon 2023-06-26 15:32:32    
                           Time zone: Asia/Seoul (KST, +0900)    
System clock synchronized: yes                        
                        NTP service: active                     
                   RTC in local TZ: no

 

굳이 왜 이렇게까지 하냐면.... ^^

예전에 이렇게 만들어놓고 잊어먹어서.... 접속을 하지 않다가.... 결국은 삭제를 당했기에....

 

 

파이썬 환경을 만들어보자.

 

ubuntu@instance-20230626-2355:/srv/workspace/python-gmail$ sudo apt install python3

ubuntu@instance-20230626-2355:/srv/workspace/python-gmail$ sudo apt install python-is-python3

ubuntu@instance-20230626-2355:/srv/workspace/python-gmail$ sudo apt install python3-pip

ubuntu@instance-20230626-2355:/srv/workspace/python-gmail$ pip install requests

 

아래 소스코드를 저장해놓자.

 

#!/usr/bin/env python3
"""
Send email via Gmail SMTP
"""

__author__ = "whatwant"
__version__ = "0.1.0"
__license__ = "BEER-WARE"

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from requests import get


def send_email(sender_email, receiver_email, app_password, subject, text, html):
    message = MIMEMultipart("alternative")
    message["Subject"] = subject
    message["From"] = sender_email
    message["To"] = receiver_email

    part1 = MIMEText(text, "plain")
    part2 = MIMEText(html, "html")

    message.attach(part1)
    message.attach(part2)

    with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
        server.login(sender_email, app_password)
        server.sendmail(sender_email, receiver_email, message.as_string())


def get_ip():
    ip = get("https://api.ipify.org").text
    return ip


if __name__ == "__main__":
    sender_email = "whatwant@whatwant.com"
    receiver_email = "whatwant@gmail.com"
    app_password = "xxxxxx"

    subject = "This is a lucky email from Python"
    text = f"My public IP address : {get_ip()}"
    html = f"<html><body><p>{text}</p></body></html>"

    send_email(sender_email, receiver_email, app_password, subject, text, html)

 

위 코드를 실행하면 다음과 같이 메일이 온다.

 

 

하루에 한 번씩 보내도록 하자 ^^

 

만날 헷갈리는 crontab ... 예쁜 사이트의 도움을 받자.

 

https://crontab.guru/

 

crontab 등록을 해보자.

 

ubuntu@instance-20230626-2355:/srv/workspace/python-gmail$ crontab -e

 

 

이제, 매일 새벽 4시에 메일을 보내준다 ^^

반응형

+ Recent posts