diff --git a/README.md b/README.md
index 2d1b60fb..e59f0b21 100644
--- a/README.md
+++ b/README.md
@@ -38,10 +38,447 @@
|:-:|:-:|
|
|
|
|[zbqmgldjfh](https://github.com/zbqmgldjfh)|[ngwoon](https://github.com/ngwoon)|
+
+
+## ๐ง Pain Point
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
+
+๊ธฐ์กด์ ํ๊ต ๊ณต์ง๋ฅผ ํ์ธํ๊ธฐ ์ํด์๋ ์ฑ์ด ์๋ ํํ์ด์ง๋ก ์ ๊ทผ โ ํด๋น ํ๊ณผ๋ก ์ด๋ โ ํ๊ณผ ๋ด์ ๊ณต์งํจ ์ ์
+๊ณผ๊ฐ์ด ๋ถํ์ํ step์ ์งํํด์ผ๋ง ๊ณต์ง๋ฅผ ํ์ธํ ์ ์์์ผ๋ฉฐ, ๋
ธํธ๋ถ์ด ์๋ค๋ฉด ๊ณต์ง๋ฅผ ํ์ธํ๊ธฐ๊ฐ ๋งค์ฐ ๋ถํธ ํ์ต๋๋ค.
+
+์ด๋ฌํ ๋ถํธํจ์ ์์ ๊ณ , ๋ชจ๋ ๊ฑด๊ตญ๋ ํ์๋ค์๊ฒ ํธ๋ฆฌํ ๊ณต์ง๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ๋ง๋ ์๋น์ค์
๋๋ค.
+๋น๋ก ์์ง๋ ๋ง์ด ๋ถ์กฑํ์ง๋ง, ์ ์ฌ์ฉํ๊ณ ์๋ค๋ ํผ๋๋ฐฑ์ ๋ฐ์๋์ ๋ฟ๋ฏํจ์ ์๋๋ ฅ์ผ๋ก ๊ฐ์ ํด๋๊ฐ๋ ์ค ์
๋๋ค.
+
+
+
+## ๐ EventStorming
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
+๋๋ฉ์ธ ๋ชจ๋ธ ๋ถ๋ฆฌ๋ฅผ ์ํ Event Storming (4์ผ ์์)
+์ด๋ฒคํธ ์คํ ๋ฐ ๋์ค ์ถ๊ฐ๋๋ ์ด๋ฒคํธ๋ ์ถฉ๋ถํ๊ฒ ๋ฐ์ํ ์ ์์ผ๋ฉฐ, ์ง๊ธ์ ์ ํ์ด 100% ๋ชจ๋๊ฐ ๋์ ๊ฐ๋ฅํ ๋ชจ๋ธ ๋ถ๋ฆฌ๋ ์๋ ์ ์๋ค.
+
+### 2-2-1) ****Event (Orange Sticker)****
+
+์ฐ์ ์๊ฐ์ ํ๋ฆ์ ๋ฐ๋ผ ๋น์ง๋์ค์ ์ํ ๋ณ๊ฒฝ์ ์๋ฏธํ๋ ๋๋ฉ์ธ ์ด๋ฒคํธ๋ฅผ ๋์ถํด๋ณด์์ต๋๋ค.
+
+ํ์๋ค๊ณผ ํจ๊ป ์ค๋ ์ง์ ํฌ์คํธ์์ ์ด๋ฒคํธ ๋ช
์ ์์ฑํ์๋๋ฐ, ์ด๋ **์ด๋ฒคํธ ๋ช
์ ๊ณผ๊ฑฐ๋ช
์ผ๋ก ์์ฑํ๋ค.** ๋ผ๋ ๋ด์ฉ์ ์ค์ํ๋ ค ๋
ธ๋ ฅํ์์ต๋๋ค.
+
+์ด๋ฒคํธ๊ฐ์ ๊ณต๊ฐ์ ๋๋ ์ด๋ฒคํธ๊ฐ ์ฐ์์ ์ผ๋ก ๋ฐํํ๋ ๊ฒฝ์ฐ ๋ฐ๋ก ์์ ๋ถ์ธ๋ค. ๊ฐ์ ์์ ์ ๋น์ง๋์ค ์กฐ๊ฑด์ ๋ฐ๋ผ ๋์ฒด์ ์ผ๋ก ๋ฐ์๋ ์ ์๋ ์ด๋ฒคํธ๋ ์๋์ ๊ฐ์ ๋ผ์ธ์ ์์ผ๋ก ๋ถ์ธ๋ค.
+
+๋๋ฉ์ธ ์ด๋ฒคํธ๋ ๋น์ง๋์ค์ ์ด๋ค ์ํ๋ฅผ ์์ฑ,๋ณ๊ฒฝ,์ญ์ ํ๋ ์์๋ผ ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์์คํ
์ ํ๋ฉด์ ์ฐ์ํ์ง ๋ง๊ณ ๋น์ง๋์ค๊ฐ ํ๋ฌ๊ฐ์ ๋ฐ๋ผ ๋น์ง๋์ค๋ฅผ ๊ตฌ์ฑํ๋ ์์๋ค์ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋๋์ง๋ฅผ ์๊ฐํ๋๋ก ํ์์ต๋๋ค.
+
+์ฐ๋ฆฌ ํ์ ์์คํ
์ ์ฌ์ฉํ๋ ์ญํ (์ฌ์ฉ์, ๋์์ด๋, ๊ฐ๋ฐ์)๋ก ๋๋์ด์ ์ฌ๋๋ค์ ๋ฐฐ์ ํ์ฌ ์
๋ฌด๋ณ๋ก ๋
ผ์๊ฐ ๊ฐ๋ฅํ ์์ค์ธ ์ ์ ํ ์ธ์์ด(4๋ช
) ์ฐธ์ฌํ์์ต๋๋ค.
+
+
+### 2-2-2) ****Command (Blue Sticker)****
+
+์ด๋ฒคํธ๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋(๋ฐ์์ํค๋) ์ปค๋งจ๋๋ฅผ ๋์ถํ์์ผ๋ฉฐ ์ ์ฌ์ง๊ณผ ๊ฐ์ต๋๋ค.
+
+์ปค๋งจ๋์ ๊ฒฝ์ฐ ํ๋์ ํฌ์คํธ์์ ์์ฑํ์ฌ ๋ถ์์ผ๋ฉฐ, ์ปค๋งจ๋๋ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ฉด ์ฝ๊ฒ ์ ์ถํ ์ ์๋ค๊ณ ์๊ฐ๋ฉ๋๋ค.
+**ํ๋์ ์ปค๋งจ๋์ ์ํด ์ฌ๋ฌ๊ฐ์ ์ด๋ฒคํธ๊ฐ ์ฐ์ ๋ฐ์๋ ์ ์์ผ๋ฉฐ ์ปค๋งจ๋ ํ๋์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ค๋ฅธ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์ ์์์ ์ ์ํ์!**
+
+> *[์ด๋ฒคํธ] ํ ๋๋ ํญ์ [์ปค๋งจ๋] ํ๋ค*
+
+### 2-2-3) ****Actor (Yellow Sticker)****
+
+์ํฐ๋ ์ฌ๋์ด๋ ์กฐ์ง์ด ๋ ์ ์๋๋ฐ ์ญํ ๊ด์ ์ผ๋ก ๋์ถํด๋ณด์์ต๋๋ค. ์ํฐ๋ ์ถ์์ ์ผ๋ก ์๋ณํ์ง ๋ง๊ณ **๋น์ง๋์ค๋ฅผ ์ํํ๋ ๊ตฌ์ฒด์ ์ธ ์ญํ ๋ก ๊ณ ๋ คํ์ฌ ๋์ถํ๋ค.**
+
+์ฆ ๊ทธ๋ฅ ๋ชจ๋ ์
๋ฌด์์ ๋ณดํธ์ ์ผ๋ก ์ฌ์ฉ๋๋ ํ์, ๊ด๋ฆฌ์๋ก ๋ฝ์ง ๋ง๊ณ ํน์ ๋น์ง๋์ค๋ฅผ ์ค์ ์ ์ผ๋ก ์ํํ๋ ์ญํ ์๋ฅผ ๋์ถํ๋ ค๊ณ ๋
ธ๋ ฅํ์์ผ, ์กํฐ๊ฐ ๊ตฌ์ฒดํ ๋ ์๋ก ์๋ณํ์ง ๋ชปํ ์ปค๋งจ๋์ ์ด๋ฒคํธ๊ฐ ์ถ๊ฐ์ ์ผ๋ก ๋์ถ ๋ ์ ์์ต๋๋ค.
+
+์ฐ๋ฆฌ์ ์๋น์ค๋ ์ํฐ๋ ํ๊ต์ ๋ค๋๋ ํ์, ๊ต์ง์ (๊ณต์ง์ฑ ์ฌ์ฉ์) ์ ๋๋ก ์๊ฐํ์์ต๋๋ค. ์ํฐ๋ฅผ ๋์ถํ๊ณ ๋ณด๋, ์ฌ์ง๊ป ๊ต์ง์์ ์ํ ๊ธฐ๋ฅ์ ์์์์ ํ๋ฒ ์๊ธฐํ๊ฒ ๋์์ต๋๋ค.
+
+### 2-2-4) ****Aggregate (Yellow Sticker)****
+
+์ด๊ทธ๋ฆฌ๊ฒ์ดํธ๋ โ๊ฒฐํฉ๋ฌผโ์ ์๋ฏธํ๋๋ฐ ์ด๋ ํ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์ค์ฌ์ผ๋ก ์๊ฐํ์์ผ๋ฉฐ,
+ํ๋์ ACIDํ ํธ๋์ญ์
์ ๋ฌถ์ฌ ๋ณํ๋์ด์ผ ํ ๊ฐ์ฒด์ ๋ฌถ์์ ๋์ถํ๊ณ , ๊ทธ๊ฒ๋ค์ ์ปค๋งจ๋, ์ด๋ฒคํธ์ ํจ๊ป ๋ฌถ์ด๋ณด์์ต๋๋ค.
+
+### 2-2-5) ****๋ฐ์ด๋๋ ์ปจํ
์คํธ๋ก ๋ฌถ๊ธฐ****
+
+Bounded Context(BC)๋ ๋์ผํ ๋ฌธ๋งฅ์ผ๋ก ํจ์จ์ ์ผ๋ก ์
๋ฌด ์ฉ์ด(๋๋ฉ์ธ ํด๋์ค)๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฒด ๋ฒ์๋ฅผ ๋ปํ๋ค๊ณ ํฉ๋๋ค.
+ํ๋์ BC๋ ํ๋ ์ด์์ ์ด๊ทธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ์์๋ก ๊ตฌ์ฑ๋ ์ ์์ผ๋ฉฐ, ์ด BC๋ฅผ ๋ง์ดํฌ๋ก์๋น์ค ๊ตฌ์ฑ ๋จ์๋ก ์ ํ๊ฒ ๋๋ฉด ์ด๋ฅผ ๋ด๋นํ๋ ํ ๋ด์ ์ปค๋ฎค๋์ผ์ด์
์ด ํจ์จํ ๋ ๊ฒ ๊ฐ์ต๋๋ค?
+
+์ถํ MSAํ๋ฅผ ๊ณ ๋ ค์ค์ด๊ธฐ์ ํจ๊ป ๊ณ ๋ คํด๋ณธ ๋์์
๋๋ค.
+
+### 2-2-6) ์ธ๋ถ ์์คํ
์ถ๊ฐ
+
+์ปค๋งจ๋ & ์ด๋ฒคํธ ๋ฐ์ ์ ํธ์ถ๋๊ฑฐ๋ ๊ด๋ จ๋๋ ๋ ๊ฑฐ์ ์์คํ
์ด๋ ์ธ๋ถ ์์คํ
๋๋ ์ฅ๋น๋ฅผ ๋์ถํ์ฌ ํํฌ์ ํฌ์คํธ์์ ์์ฑํ์ฌ ์ด๋ฒคํธ์ ์ค๋ฅธ์ชฝ ์๋จ์ ์ถ๊ฐ!
+
+๋ณธ ์์คํ
์ ๊ตฌํ ๋์์ด ์๋์ง๋ง ์์คํ
์ ๊ธฐ๋ฅ ๊ตฌํ์ ์ํด ์ฐ๊ณ๊ฐ ํ์ํ ์์คํ
๋ค์ ๋ชจ๋ ๋์ถํด๋ณธ ๊ฒฐ๊ณผ, FCM์ ์๋ฆผ ๊ธฐ๋ฅ ์ ๋๊ฐ ์ธ๋ถ ์์กด์ผ๋ก ์ถ๊ฐ๋์์ต๋๋ค.
+
+### 2-2-7) ****Policy (Lilac Sticker)**** ๋์ถ
+
+ํด๋ฆฌ์(Policy)๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ํ ์ฐ์ด์ด ๋ฐ์ํ๋ ๋ฐ์ํ ์ก์
์ผ๋ก, **ํ ์๋น์ค ์ด๋ฒคํธ์ ๋ํด ์ํ๋์ด์ผ ํ ํ ์๋น์ค์ ์ก์
๋ค๋ก**, ๋จผ์ ์ ์๋ ์ด๋ฒคํธ ์๋์ ์ถ๊ฐํ์์ต๋๋ค.
+ํ๋์ ์ด๋ฒคํธ์ ๋ฐ์ํ์ฌ ์ํ๋์ด์ผ ํ ํด๋ฆฌ์๋ ์ฌ๋ฌ ํ์์ ๋์ถ๋ ๋ฉํฐ ์ก์
์ด ์กด์ฌํ ์ ์๋ค.
+
+### 2-2-8) **ํด๋ฆฌ์์ ์ด๋๊ณผ ์ปจํ
์คํธ ๋งคํ (์ ์ ์ Pub/Sub, ์ค์ ์ Req/Resp)**
+
+์์ ๊ฐ์ด ์ต์ข
์ ์ผ๋ก ๋๋ฉ์ธ ๋ชจ๋ธ์ ๋ถ๋ฆฌํ๊ฒ ๋์์ต๋๋ค!!
+
+
+
+
+# ๐ ๋ฆฌํฉํ ๋ง & ์ฑ๋ฅ ๊ฐ์
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
+---
+
+## 1. ์๋ฏธ์๋ ์ด๋ฆ๊ณผ ํจ์
+
+์ฝ๋๋ฅผ ๋ค์ ๋๋์๋ณด์์ ๋, ๋น์์๋ ์ดํดํ ์ ์์ ์ ๋์ ์ด๋ฆ์ผ๋ก ์ง์๋ค๊ณ ์๊ฐํ์ผ๋ ๋ช
ํํ๊ฒ ์๋ฟ์ง ์๋ ๋ค์ด๋ฐ๋ค์ด ์์์ต๋๋ค.
+๋ฐ๋ผ์ ์ฃผ์์ด ํ์ ์์ ์ ๋๋ก ๋ช
ํํ๊ฒ ๋ณ์๋ช
๊ณผ ํจ์๋ช
์ ์์ ํ์์ต๋๋ค.
+ํจ์์ ๋ํด์๋ Clean Code์์ 5์ค ์ด๋ด๋ฅผ ๊ถ์ฅํ๊ณ ์์์ต๋๋ค. ์ฝ๋๋ฅผ ๋๋์๋ณธ ๊ฒฐ๊ณผ ์๊ฐ๋ณด๋ค ํจ์๊ฐ ๊ธด ๊ฒ๋ค์ด ์กด์ฌํ๊ณ ์ถฉ๋ถํ ์ค์ผ ์ ์๋ ์์ค์ ๋ด์ฉ๋ค์ด์๊ธฐ์ ํ ์ ์๋ ํ์์ 5์ค ๋ด์ธ๋ฅผ ์งํค๋๋ก ์์ ํ์ต๋๋ค.
+
+---
+
+## 2. ๋ ๊ฑฐ์ ์ฝ๋์ ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋จ๋ฐฉํฅ์ผ๋ก!
+JPA์ ๋ํด์๋ ์๋ก ์ด๋ ์ ๋ ์ดํดํ๊ณ ์์ด, ์ ์ ํ fetch join์ ์ฌ์ฉํ์ฌ ์ฝ๋ฉํ์๊ธฐ์ N+1 ๋ฌธ์ ๋ ๋ฐ์ํ์ง ์์์ต๋๋ค.
+ํ์ง๋ง ์ฐ๊ด๊ด๊ณ์ ๋ํด์ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
+๊ฐ์ฅ ์ข์ ์ฐ๊ด๊ด๊ณ ์ค๊ณ๋ ๋จ๋ฐฉํฅ์ ๊ธฐ์ด๋ก ํ๋ ํ์ํ๋ฉด ์๋ฐฉํฅ ์ค๊ณ๋ฅผ ํ๋ ๊ฒ์
๋๋ค.
+
+JPA ํ๋ก๊ทธ๋๋ฐ์ ์ ์, ๊น์ํ ์ ์๋์ ์๊ฒฌ์ ๋น๋ฆฌ์๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
+> ์๋ฐฉํฅ์ผ๋ก ํ๋ฉด ๋ณต์ก๋๊ฐ ๋์์ง๋ ๋จ์ ์ด ์์ง๋ง ์ฑ๋ฅ์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค.
+์ ๋ง ์ฑ๋ฅ์ด ๋๋ฌด ์ค์ํด์ ์ฟผ๋ฆฌ ํ๋๋ฅผ ์ค์ด๋๊ฒ ๊ผญ ํ์ํ ์ํฉ์ด๋ผ๋ฉด ๋ณต์กํด์ง๋๋ผ๋ ์ต์ ํ๋ฅผ ํด์ผํฉ๋๋ค.
+๋ฐ๋ฉด์ ์ฟผ๋ฆฌ๊ฐ ํ๋ ๋ ๋๊ฐ๋๋ผ๋ ์์คํ
์์์ด ์ถฉ๋ถํด์ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ด ๋ฏธ๋ฏธํ๋ค๋ฉด ์ฝ๋ ๋ณต์ก๋๋ฅผ ๋ฎ๊ฒ ์ ์งํ๋ ๊ฒ์ด ๋ ์ค์ํฉ๋๋ค.
+
+
+

+

+
+
+๋๊ฐ์ ์๋ฐฉํฅ์ผ๋ก ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ๊ณ ์๋ค.
+๊ทธ๋ผ UserCategory์ ์ถ๊ฐํด์ค๋, User์ชฝ์ `private List userCategories = new ArrayList<>();` ์๋ UserCategory๋ฅผ ์ถ๊ฐํ๊ณ , UserCategory ์ชฝ์์๋ User๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค!!
+์ด๋ ์๋ฐฉํฅ์ผ๋ก ๋งคํ์ค์ด๊ธฐ ๋๋ฌธ์ด๋ค.
+
+๋น์ฐํ ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ด UserCategory ์ด๊ธฐ ๋๋ฌธ์ UserCategory์ ์ถ๊ฐํ๋์ ์ ์ ํฉํ๋ค.
+ํ์ง๋ง ๋ค์ ์ฝ๋๋ UserCategory์ชฝ์๋ง ์ถ๊ฐ์ค์ด๋ค. ํํ ๋งํ๋ JPA ํธ์ ๋ฉ์๋๋ฅผ ์์ฑํ์ด์ผ ํ๋๋ฐ, ๋ค์ ์ฝ๋๋ ํธ์ ๋ฉ์๋๊ฐ ์๋ค.
+
+
+๋ฐ๋ผ์ UserCategory์๋ ์ ๊ท UserCategory๊ฐ ์ถ๊ฐ ๋์ง๋ง, User๊ฐ ๋ค๊ณ ์๋ List๋ ๋น์ด ์๊ฒ ๋๋คโฆ
+
+๋ค์ ๊ธ์ 3๋ฒ โ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ ์ฃผ์์ โ์ ๋ณด๋ฉด ์ดํดํ ์ ์๋ค.
+https://blogshine.tistory.com/345
+
+์์ User์์ UserCategory๋ฅผ ์ญ์ ํ๋ ํธ์ด ๋ ์ข์๊ฒ ๊ฐ๋ค. ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๊ฐ ํ์์ ์ธ ํฌ์ธํธ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ด๋ค! โ **User์์ ์ ๊ฑฐ!**
+
+ํ
์ด๋ธ ๊ตฌ์กฐ์ ๋ณํ๋ ์๊ธฐ์ ์ ์ฉ๊ฐ๋ฅ
+---
+
+## 3. ๊ณต์ง Scrap์์
multi-threading ์ฒ๋ฆฌ๋ก ์๊ฐ ๊ฐ์ ํ๊ธฐ
+
+**๋ฌธ์ ์ํฉ**
+
+- ๊ธฐ์กด์ 60๊ฐ์ ํ๊ณผ๋ฅผ ์ ๋ถ Scrapํ๋๋ฐ ๋จ์ผ thread๋ก๋ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฌ๋ ๋ฌธ์ ๋ฐ์
+
+**๋ฌธ์ ํด๊ฒฐ**
+
+- 60๊ฐ ํ๊ณผ์ ๊ณต์ง๋ฅผ scrapํ๋ ๊ณผ์ ์ ๋ณ๋ ฌ์ฒ๋ฆฌ ํ๋ฉด์ **Crawling ์ฑ๋ฅ๊ฐ์ **
+ - ๋จ์ผ ๊ณต์ง ํ์ด์ง ๊ธฐ์ค, core 6๊ฐ : 3๋ถ50์ด โ 49์ด๋ก ์ฑ๋ฅ์ **4.39**๋ฐฐ ๊ฐ์
+ - ์ ์ฒด ๊ณต์ง ํ์ด์ง ๊ธฐ์ค, core 6๊ฐ : 1์๊ฐ 12๋ถ 11์ด โ 15๋ถ 35์ด๋ก ์ฑ๋ฅ์ **4.70**๋ฐฐ ๊ฐ์
+
+**์์ธ ๋ด์ฉ ๋งํฌ : ([๊ธ ๋งํฌ](https://blogshine.tistory.com/660))**
+
+---
+## 4. Full-Text-Index๋์
์ ํตํ **๊ฒ์ ์ฑ๋ฅ๊ฐ์ **
+
+**๋ฌธ์ ์ํฉ**
+
+- ๊ธฐ์กด ๊ฒ์์ like ์ ์ ํ์ฉํ ๋จ์ full-scan๋ฐฉ์์ ๊ฒ์์ด๋ผ๋ ๋จ์
+
+**๋ฌธ์ ํด๊ฒฐ**
+
+- ๊ณต์ง ๊ฒ์ ์ฟผ๋ฆฌ ๋ณ๊ฒฝ, ์ค์ง๋จ์ด, Full-Text-Index๋์
์ ํตํ **๊ฒ์ ์ฑ๋ฅ๊ฐ์ **
+ - ๊ฐ์ **์ ** : ๊ฒ์์ full Scan์ ํตํด ์คํ๊ณํ์ด ์๋ฆฝ โ 11s 59ms
+ - ๊ฐ์ **ํ** : Full Text index๊ณผ stop word ๋์
โ 591ms
+ - ๊ณต์ง 500๋ง๊ฑด ๊ธฐ์ค ๊ฒ์ ์๋ **18.71๋ฐฐ ๊ฐ์ ** ํ๊ฒ ๋์์ต๋๋ค
+
+**์์ธ ๋ด์ฉ ๋งํฌ : ([๊ธ ๋งํฌ](https://blogshine.tistory.com/664))**
+
+---
+## 5. ์ธ์ฆ, ์ธ๊ฐ๋ฅผ ๋น์ฆ๋์ค ๋ก์ง์ผ๋ก๋ถํฐ ๋ถ๋ฆฌํ๊ธฐ
+
+**๋ฌธ์ ์ํฉ**
+
+- ๋ถ๊ฐ์ ์ธ ์ธ์ฆ, ์ธ๊ฐ ๋ก์ง์ด ์ ํ๋ฆฌ์ผ์ด์
์ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ํจ๊ป ํผ์ฌ๋์ด ์๋ ์ํ
+
+**๋ฌธ์ ํด๊ฒฐ**
+
+
+
+- ์ธ์ฆ, ์ธ๊ฐ๋ฅผ ํต์ฌ ๋น์ฆ๋์ค๋ก์ง ์ผ๋ก ๋ถํฐ ๋ถ๋ฆฌํ์ฌ ๋ฆฌํฉํ ๋ง ํ๊ธฐ
+ - Spring Security์ ์ ์ฌ ๊ตฌ์กฐ๋ฅผ ์ง์ ๊ตฌํ
+- ์ง์ ๊ตฌํํ ์ ์ฒด ์ธ์ฆ ๋ก์ง ํ๋ฆ๋
+
+**์์ธ ๋ด์ฉ ๋งํฌ : ([๊ธ ๋งํฌ](https://blogshine.tistory.com/678))**
+
+---
+
+## 6. ํํ๋ ํํ N+1 ์ฟผ๋ฆฌ ๊ฐ์ ๊ธฐ
+
+์๋ ๋ก์ง์์๋ ์ฌ์ฉ์์ Category ์ด๋ฆ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌ๊ฐ ๋๊ณ ์์์ต๋๋ค!
+
+
+
+getUserCategories ๋ ๋ค์๊ณผ ๊ฐ๊ณ ,
+
+```java
+public List getUserCategories(String token) {
+ User user = userRepository.findByToken(token);
+
+ // User์์ ์ด๋ฏธ ์ฐ๊ด๊ด๊ณ๋ก ๋ค๊ณ ์๋ ์ํฉ์ด์๋ค.
+ List userCategories = userCategoryRepository.findAllByUser(user);
+
+ return userCategories.stream()
+ .map(UserCategory::getCategory)
+ .collect(Collectors.toList());
+}
+```
+
+์์ ๊ธฐ์กด ์ฝ๋์์ user๋ฅผ ์ฐพ์์ฌ๋ ์ฌ์ค UserCategory๋ฅผ EAGER๋ก ์ฐพ์์ค๊ณ ์์๋ค.
+
+
+๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝ ํ์ด๋ ๋ฌ์๊ฒ ๊ฐ๋ค!
+
+```java
+List userCategories = user.getUserCategories(); // ์ด๋ฏธ User๋ UserCategory ์ ๋ณด๊ฐ ์์
+```
+
+์ฆ, User๋ฅผ ์ฐพ์์ฌ๋ ์ด๋ฏธ Category๋ฅผ ์ฐพ์์ค๋ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋๋ฐ, findAllByUser๋ก ์ฐพ์์ฌ ํ์๊ฐ ์์๋ค.
+
+(ps, ๋คํ์ด 1์ฐจ ์บ์ ๋๋ถ์ ์์์ฑ ์ปจํ
์คํธ์์ ์ฐพ์์ค๊ธฐ์ ๋์ผํ ์ฟผ๋ฆฌ๊ฐ 2๋ฒ ๋๊ฐ์ง๋ ์๋๋ค)
+
+getCategoryNamesFromCategories ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ๋์ด ์์๋ค!
+
+```java
+public List getCategoryNamesFromCategories(List categories) {
+ return categories.stream()
+ .map(Category::getName)
+ .collect(Collectors.toList());
+}
+```
+
+์ด๋ ๊ฒ ์ฒ๋ฆฌ๋์ด ์ฌ์ฉ์์ Category์ด๋ฆ์ ์ ๋ถ ๋ณด์ฌ์ฃผ๊ณ ์์๋ค!
+
+์ฆ, User ํ๋๋ง ์กฐํํด๋ UserCategory๊น์ง ํจ๊ป ์กฐํํ๊ณ ์์ผ๋~
+
+1) token๊ฐ์ ๊ฐ๋ User๋ฅผ ์ฐพ์์จ ํ // ์ฟผ๋ฆฌ 1๋ฒ
+
+2) User์ UserCategory๋ฅผ ๋ค ์ฐพ์์จ๋ค. // UserCategory๋ฅผ ๋ฐ๋ก ์ฐพ์์ค๋ ์ฟผ๋ฆฌ N๊ฐ (N+1๋ฌธ์ )
+
+3) ์ดํ ์ฐพ์์จ UserCategory ๋ชฉ๋ก์ ํตํด Category ๋ชฉ๋ก์ ์ฐพ๋๋ค. // Category N๊ฐ๋งํผ ์ฟผ๋ฆฌ
+
+4) ์ฐพ์์จ Category ๋ชฉ๋ก์ String ์ด๋ฆ๋ก ๋ฐ๊พผ๋ค.
+
+์ฟผ๋ฆฌ๊ฐ ์ด 1 + 2N ๋งํผ ๋ฐ์์ค์ด๋ค.
+
+### 6 - 1) ๋ณ๊ฒฝ ์ ์ฟผ๋ฆฌ
+
+```bash
+Hibernate:
+ select
+ user0_.id as id1_5_,
+ user0_.token as token2_5_
+ from
+ user user0_
+ where
+ user0_.token=?
+2023-01-25 21:19:36.747 INFO 16011 --- [o-auto-1-exec-5] p6spy : #1674649176747 | took 1ms | statement | connection 22| url jdbc:mariadb://localhost:52131/test
+select user0_.id as id1_5_, user0_.token as token2_5_ from user user0_ where user0_.token=?
+select user0_.id as id1_5_, user0_.token as token2_5_ from user user0_ where user0_.token='test_fcm_token';
+Hibernate:
+ select
+ usercatego0_.user_token as user_tok3_6_0_,
+ usercatego0_.id as id1_6_0_,
+ usercatego0_.id as id1_6_1_,
+ usercatego0_.category_name as category2_6_1_,
+ usercatego0_.user_token as user_tok3_6_1_
+ from
+ user_category usercatego0_
+ where
+ usercatego0_.user_token=?
+2023-01-25 21:19:36.749 INFO 16011 --- [o-auto-1-exec-5] p6spy : #1674649176749 | took 1ms | statement | connection 22| url jdbc:mariadb://localhost:52131/test
+select usercatego0_.user_token as user_tok3_6_0_, usercatego0_.id as id1_6_0_, usercatego0_.id as id1_6_1_, usercatego0_.category_name as category2_6_1_, usercatego0_.user_token as user_tok3_6_1_ from user_category usercatego0_ where usercatego0_.user_token=?
+select usercatego0_.user_token as user_tok3_6_0_, usercatego0_.id as id1_6_0_, usercatego0_.id as id1_6_1_, usercatego0_.category_name as category2_6_1_, usercatego0_.user_token as user_tok3_6_1_ from user_category usercatego0_ where usercatego0_.user_token='test_fcm_token';
+Hibernate:
+ select
+ user0_.id as id1_5_1_,
+ user0_.token as token2_5_1_,
+ usercatego1_.user_token as user_tok3_6_3_,
+ usercatego1_.id as id1_6_3_,
+ usercatego1_.id as id1_6_0_,
+ usercatego1_.category_name as category2_6_0_,
+ usercatego1_.user_token as user_tok3_6_0_
+ from
+ user user0_
+ left outer join
+ user_category usercatego1_
+ on user0_.token=usercatego1_.user_token
+ where
+ user0_.token=?
+2023-01-25 21:19:36.755 INFO 16011 --- [o-auto-1-exec-5] p6spy : #1674649176755 | took 1ms | statement | connection 22| url jdbc:mariadb://localhost:52131/test
+select user0_.id as id1_5_1_, user0_.token as token2_5_1_, usercatego1_.user_token as user_tok3_6_3_, usercatego1_.id as id1_6_3_, usercatego1_.id as id1_6_0_, usercatego1_.category_name as category2_6_0_, usercatego1_.user_token as user_tok3_6_0_ from user user0_ left outer join user_category usercatego1_ on user0_.token=usercatego1_.user_token where user0_.token=?
+select user0_.id as id1_5_1_, user0_.token as token2_5_1_, usercatego1_.user_token as user_tok3_6_3_, usercatego1_.id as id1_6_3_, usercatego1_.id as id1_6_0_, usercatego1_.category_name as category2_6_0_, usercatego1_.user_token as user_tok3_6_0_ from user user0_ left outer join user_category usercatego1_ on user0_.token=usercatego1_.user_token where user0_.token='test_fcm_token';
+HTTP/1.1 200
+Content-Type: application/json
+Transfer-Encoding: chunked
+Date: Wed, 25 Jan 2023 12:19:36 GMT
+Keep-Alive: timeout=60
+Connection: keep-alive
+```
+
+N+1 ๋ฌธ์ ๋ก Userํ๋ฒ ์กฐํํ๋๋ฐ ์์ ๊ฐ์ด ์ฟผ๋ฆฌ๊ฐ 3๋ฒ ๋๊ฐ๊ฒ ๋จ
+
+### 6 - 2) ๋ณ๊ฒฝ ํ
+
+๋ณ๊ฒฝ ํ ํ๋ฐฉ ์ฟผ๋ฆฌ๋ก ์กฐํ ๋
+```java
+public List getUserCategoryNamesByToken(String token) {
+ return queryFactory
+ .select(userCategory.category.name)
+ .from(userCategory)
+ .where(userCategory.user.token.eq(token))
+ .fetch();
+}
+```
+
+
+
+___
+
+## 7. Test Container๋ฅผ ํตํ ํ
์คํธ์ ๋ฉฑ๋ฑ์ฑ ๋ณด์ฅํ๊ธฐ
+ํ
์คํธ์, ์ค์ ์ด์ DB๋ฅผ ๋๋ค MariaDB ํ๊ฒฝ์ผ๋ก ์ฌ์ฉํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ผ์ด ์๋ค ์๊ฐํ์์ต๋๋ค.
+ํ์ง๋ง, utf8๊ณผ ๊ฐ์ ์ธ์ฝ๋ฉ ๋ฐฉ์์ด ๋ก์ปฌ๊ณผ ํ๋ก๋์
์ด ๋ฌ๋ผ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์์ผ๋ฉฐ, ์ด๋ํ ํ
์คํธ ํ๊ฒฝ์์ ๊ฑธ๋ฌ๋ด์ง ๋ชปํ ๊ฒ์ด ๋ฌธ์ ๋ผ ์๊ฐํ์์ต๋๋ค.
+
+๋ฐ๋ผ์ ์ดํ๋ถํฐ๋ ํ๊ฒฝ ์์ฒด๋ฅผ ๋์ผํ๊ฒ ๋ง๋ Test ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๋์
ํ๊ฒฝ๊ณผ ๋์ผํ ํ๊ฒฝ๋ณ์ ํ๊ฒฝ์์ ํ
์คํธ๋ฅผ ์งํํ๋๋ก ํ์์ต๋๋ค.
+ํ
์คํธ์์ ์ํ ์๊ฐ์ด ์กฐ๊ธ ๊ธธ์ด์ก์ง๋ง, ํ
์คํธ์ ๋ชฉ์ ์ ๋ถํฉํ๋๋ก ๋์ํ๊ฒ ๋์์ต๋๋ค.
+
+---
+
+## 8. CI / ์ ์ ๋ถ์๊ธฐ(SonarCloud, jacoco)๋ฅผ ์ฌ์ฉํ ์ฝ๋ ์ปจ๋ฒค์
์ ๋ํ ์ฝ๋๋ฆฌ๋ทฐ ์๋ํ
+
+**๋ฌธ์ ์ํฉ**
+
+- ์ ์ ๋ถ์ ๋๊ตฌ๊ฐ ์์ด ์ฝ๋์ ํ์ง ๊ด๋ฆฌ๋, ๋ฒ๊ทธ ๋ฐ๊ฒฌ๋ฑ์ด ์ด๋ ค์ ๋ ์ํฉ
+
+**๋ฌธ์ ํด๊ฒฐ**
+
+
+
+- ์ ์ ๋ถ์ ๋๊ตฌ๋ฅผ ํตํ ๋ถ์์ ํตํ์ฌ ์ฌ์ ์ ๋ฏธ๋ฆฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ ์ง์ ๋ค์ ๋ณด์ํ ์ ์์
+- ํ
์คํธ ์ฝ๋์ ์ปค๋ฒ๋ฆฌ์ง์ ๋ํ ๊ด๋ฆฌ๊ฐ ํธ๋ฆฌํ๋ค ์
+
+**์์ธ ๋ด์ฉ ๋งํฌ : ([๊ธ ๋งํฌ](https://blogshine.tistory.com/658))**
+
+---
+
+## 9. ์๋ฒ ๋ชจ๋ํฐ๋ง
+
+**๋ฌธ์ ์ํฉ**
+
+- ์ด์ ์๋ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๊ฐ ์์ด ์ค์๊ฐ์ผ๋ก ์๋ฒ์ ์ํ๋ฅผ ํ์ธํ ์ ์์๋ค.
+- ์๋ฒ์ ์ํ๋ฅผ ํ์ธํ๊ธฐ ์ํด ์๋ฒ์ ์ ์ํ์ฌ ๋ก๊ทธ๋ฅผ ํ์ธํด์ผ ํ๋ค.
+
+**๋ฌธ์ ํด๊ฒฐ**
+
+
+
+- ์๋ฒ์ ์ํ๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ์ ์์ด ์๋ฒ์ ์ํ๋ฅผ ๋น ๋ฅด๊ฒ ํ์
ํ ์ ์๋ค.
+- ์ผ์ ๊ธฐ๊ฐ๋์์ ์๋ฒ ์ ๋ณด๊ฐ ์ ์ฅ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ฐ์์ ์ญ์ถ์ ํด๋ณผ ์ ์๋ค.
+- ๋ค์ ๊ธ ๋งํฌ์์๋ ์ด๋ฅผ ํตํ์ฌ ์๋ฒ๊ฐ ๋ค์ด๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๊ธ ์ด๋ค!
+
+**์์ธ ๋ด์ฉ ๋งํฌ : ([๊ธ ๋งํฌ](https://blogshine.tistory.com/669))**
+
+---
+
+
+
+# ๐ ์ ์ด ๊ธฐ์ ์ ์ฌ์ฉํ๋๊ฐ?
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
+----
+
+## 1. Querydsl
+
+
+Spring Data JPA๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํด์ฃผ๋ CRUD ๋ฉ์๋ ๋ฐ ์ฟผ๋ฆฌ ๋ฉ์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋๋ผ๋, ์ํ๋ ์กฐ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ธฐ ์ํด์๋ ํ์ฐ์ ์ผ๋ก JPQL์ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
+๊ฐ๋จํ ๋ก์ง์ ์์ฑํ๋๋ฐ ํฐ ๋ฌธ์ ๋ ์์ผ๋, ๋ณต์กํ ๋ก์ง์ ๊ฒฝ์ฐ ๊ฐํ์ด ํฌํจ๋ ์ฟผ๋ฆฌ ๋ฌธ์์ด์ด ์๋นํ ๊ธธ์ด์ง๋๋ค.
+JPQL ๋ฌธ์์ด์ ์คํ ํน์ ๋ฌธ๋ฒ์ ์ธ ์ค๋ฅ๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ, ์ ์ ์ฟผ๋ฆฌ๋ผ๋ฉด ์ดํ๋ฆฌ์ผ์ด์
๋ก๋ฉ ์์ ์ ์ด๋ฅผ ๋ฐ๊ฒฌํ ์ ์์ผ๋ ๊ทธ ์ธ๋ ๋ฐํ์ ์์ ์์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
+์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ฃผ๋ ๊ฒ์ด Querydsl์ด๊ธฐ์ Querydsl์ ๋์
ํ์ต๋๋ค.
+Querydsl ๋์
์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ป์์ต๋๋ค.
+
+1. ๋ฌธ์๊ฐ ์๋ ์ฝ๋๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํจ์ผ๋ก์จ, ์ปดํ์ผ ์์ ์ ๋ฌธ๋ฒ ์ค๋ฅ๋ฅผ ์ฝ๊ฒ ํ์ธํ ์ ์๋ค.
+2. ์๋ ์์ฑ ๋ฑ IDE์ ๋์์ ๋ฐ์ ์ ์๋ค.
+3. ๋์ ์ธ ์ฟผ๋ฆฌ ์์ฑ์ด ํธ๋ฆฌํ๋ค.
+4. ์ฟผ๋ฆฌ ์์ฑ ์ ์ ์ฝ ์กฐ๊ฑด ๋ฑ์ ๋ฉ์๋ ์ถ์ถ์ ํตํด ์ฌ์ฌ์ฉํ ์ ์๋ค.
+
+----
+
+## 2. Flyway
+dev, local ํ๊ฒฝ์์๋ ๋จ์ํ ddl์ create-drop ๋๋ update ์ต์
์ ์ฌ์ฉํ๊ณ ์์๊ธฐ์ DB์ ๋ํด ๊ณ ๋ฏผํ ํ์๊ฐ ์์์ต๋๋ค.
+ํ์ง๋ง ์ด์ํ๊ฒฝ์์๋ ddl์ validate ๋๋ none ์ต์
์ ์ฌ์ฉํด์ผํ๊ธฐ ๋๋ฌธ์ ์ด๊ธฐ์๋ DB script๋ฅผ ๋ฝ์์ ๋ณ๋๋ก ๊ด๋ฆฌ๋ฅผ ํ์ต๋๋ค.
+์ดํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๋ฉด์ script๊ฐ ๋ณ๊ฒฝ๋๋ ์ผ์ด ๋น๋ฒํด์ก๊ณ , ๋งค๋ฒ ์ผ์ผ์ด ์คํฌ๋ฆฝํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ฒ๊ฑฐ๋ก์ธ ๋ฟ ์๋๋ผ ์ค์ํ๊ธฐ ๋ฑ ์ข์ ๋ถ๋ถ์ด๋ผ Flyway๋ฅผ ๋์
ํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์๊ด๋ฆฌ๋ฅผ ์งํํ์ต๋๋ค.
+
+์ถ๊ฐ๋ก ์ ์ ์๊ฐ์ ์ด์ ์
+1. ํ์
์ ํ์์ด ddl์ ์ฝ๋๋ฆฌ๋ทฐ๋ฅผ ํ๊ธฐ ๋งค์ฐ ํธํ๋ค.
+2. ๋ด๊ฐ ์์ฑํ ddl์ด ์ ์์ ์ผ๋ก ์ถ๊ฐ๋๋ค, ์ฆ ๋ณต๋ถ์ด๋ ํ์ดํ ํ๋ค ๋๋ ํด๋จผ์๋ฌ ๋ฑ์ ๋ฐฉ์งํ ์ ์๋ค.
+
+----
+
+
+
+
+
+# โฐ ํ์
๋ฐฉ์ - Jira
+
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
+
+์ ํฌ ์ฟ ๋งํ์ ํ์
๋ฐฉ์์ผ๋ก Jira๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
+
+๊ตฌํํด์ผํ ํฐ ๊ธฐ๋ฅ๋ค์ ์ํฝ์ผ๋ก ์ ์ํ์ฌ ์ผ์ ์ ์ค์ ํ๊ณ ํ๋์ ์ํฝ์ ํ์ํ ๊ธฐ๋ฅ๋ค์ธ task๋ฅผ ์ธ์ธํ๊ฒ ๋๋์์ต๋๋ค.
+์นธ๋ฐ๋ณด๋๋ฅผ ํตํด task๋ค์ ๊ฐ๋ฐํด์ผํ ๋ชจ๋ ๊ธฐ๋ฅ๋ค, ์ด๋ฒ์ฃผ์ ๊ฐ๋ฐํด์ผํ ๊ธฐ๋ฅ, ๊ฐ๋ฐ ์งํ์ค, ๊ฐ๋ฐ ์๋ฃ๋ ์นธ์ผ๋ก ์ฎ๊ธฐ๋ฉด์ ํ๋์ ๋ณผ ์ ์๋๋ก ์งํํ์ต๋๋ค.
+
+์คํ๋ฆฐํธ๋ 1์ฃผ์ผ ๋จ์๋ก ์ค์ ํ์ฌ Jira ๋ด Confluence์์ ์คํ๋ฆฐํธ ์ฃผ๊ธฐ๋์ ์งํํด์ผํ ๊ธฐ๋ฅ๋ค์ ์ ์ํ๊ณ ๋ง์๊ฐ์ง๊ณผ ์คํ๋ฆฐํธ๋ฅผ ๋ง์น ํ ํ๊ณ ๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ์คํ๋ฆฐํธ๋ฅผ ์งํํ์ต๋๋ค.
+
+## ๋ก๋๋งต
+
+

+
+
+## ์นธ๋ฐ๋ณด๋
+
+

+
+
+
+
## ๐ Infrastructures
+
+ ๋ณธ๋ฌธ ํ์ธ (๐ Click)
+
### CI Flow
-
+
+
+### CD Flow
+
+
+### CD Detail Flow (Test Server)
+
+
+๊ณผ์ ์ ๋ฆฌ๊ธ
+1) [Github Actions, CodeDeploy, Nginx ๋ก ๋ฌด์ค๋จ ๋ฐฐํฌํ๊ธฐ - 1](https://blogshine.tistory.com/427)
+2) [Github Actions, CodeDeploy, Nginx ๋ก ๋ฌด์ค๋จ ๋ฐฐํฌํ๊ธฐ - 2](https://blogshine.tistory.com/428)
+3) [Github Actions, CodeDeploy, Nginx ๋ก ๋ฌด์ค๋จ ๋ฐฐํฌํ๊ธฐ - 3](https://blogshine.tistory.com/429)
+4) [Github Actions, CodeDeploy, Nginx ๋ก ๋ฌด์ค๋จ ๋ฐฐํฌํ๊ธฐ - 4](https://blogshine.tistory.com/430)
+
+
[](https://hits.seeyoufarm.com)
+