๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

25-03-21

๐Ÿ“Œ Daily Reportโ€‹

https://github.com/ssginc-be/DOKI/issues/130


๐Ÿ“Œ ํ”„๋กœ์ ํŠธ ์ƒํ™ฉโ€‹

์‹ ๊ธฐํ•œ ๊ฒฝํ—˜์„ ํ•˜๊ณ  ์žˆ๋‹ค. ์•„๋ฌด๋ฆฌ ์ž๋„ ์ž” ๊ฒƒ ๊ฐ™์ง€๊ฐ€ ์•Š์Œ;

์ตœ๋Œ€ํ•œ ๋‚ฎ์— ์—ด์‹ฌํžˆ ํ•ด๋ณด๊ณ  ํ† ์š”์ผ ๋Œ€๋น„๋ฅผ ํ•ด์•ผ๊ฒ ๋‹ค ํ›„... ์‚ฐ์ฑ…๋„ 1์‹œ๊ฐ„๋ฐ–์— ๋ชปํ•˜๊ธ‹๋„ค

๋„ค์ด๋ฒ„ ์ƒ๋ฐ˜๊ธฐ ์ผ์ •์ด๋ž‘ ์ตœ์ข… ๋ฐœํ‘œ๋ž‘ ๊ฒน์ณ์„œ ์ •๋ง ๋ถ„๋‹จ์œ„๋กœ ๋ญ์— ๋” ๋ฆฌ์†Œ์Šค๋ฅผ ํ• ๋‹นํ• ์ง€ ์ƒ๊ฐ์ด ๋ฐ”๋€Œ๊ณ  ์žˆ๋‹ค.


๐Ÿ“Œ DateTimeFormatter locale ์„ค์ •โ€‹

๋ฐฐํฌํ•˜๋‹ˆ๊นŒ ์—ญ์‹œ ์„œ๋ฒ„ ๋จธ์‹  ์„ธํŒ… ๋”ฐ๋ผ์„œ locale์ด ๊นจ์ง€๊ธธ๋ž˜ ๊ณ ์ •์‹œ์ผœ์คฌ๋‹ค.

DateTimeFormatter ์•ˆ์“ฐ๊ณ  thymeleaf ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ ๋‚ด์—์„œ ๋ฐ”๋กœ ์„ธํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๊ธด ํ–ˆ๋Š”๋ฐ, (#temporal ์–ด์ฉŒ๊ตฌ) ํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ ๊ธธ์–ด์ง€๋Š”๊ฑฐ ์•ˆ์ข‹์•„ํ•˜๊ธฐ๋„ ํ•˜๊ณ  locale๋„ DateTimeFormatter๋ณด๋‹ค ๋Š์Šจํ•˜๊ธธ๋ž˜ (๋กœ์ปฌ ๋จธ์‹  locale ์•ˆ๋”ฐ๋ผ๊ฐ) ๊ทธ๋ƒฅ ๊ธฐ์กด์— ์“ฐ๋˜ ๋ฐฉ์‹ ์“ฐ๊ธฐ๋กœ ํ–ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ ๊ธธ์–ด์ง€๋Š”๊ฑฐ ์•ˆ์ข‹์•„ํ•˜๋Š” ์ด์œ ๋Š”, ๋ง๊ทธ๋Œ€๋กœ ๊ทธ๊ฑด view๋ฅผ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ๋ณผ ๋• view์˜ ๊ตฌ์กฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ #temporal ์ด๋Ÿฐ๊ฑธ๋กœ ํƒ€์ž„๋ฆฌํ”„ ๋ฌธ๋ฒ• ๊ธธ์ญ‰๊ธธ์ญ‰ํ•˜๊ฒŒ ๋“ค์–ด๊ฐ€์„œ ๊ฐ€๋…์„ฑ ๋ง๊ฐ€์ง€๋ฉด ๋ฆฌ๋”ฉ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚œ๋‹ค. ๋‚œ ๊ทธ๊ฒŒ ์‹ซ๋‹ค.

๋ฐ์ดํ„ฐ ๊ฐ€๊ณต ๋กœ์ง์€ java์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์—ฌ์ฐจํ•˜๋ฉด ์ „์ฒ˜๋ฆฌ ๋กœ์ง ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ๋ฐ‘์—๋‹ค ๋นผ๋‘๋ฉด ๋˜๊ณ .

StoreController.java
{
// 1. ๋น„ํšŒ์›์ด๊ฑฐ๋‚˜ ๋กœ๊ทธ์ธํ•œ ์ด์šฉ์ž (null ์ฒดํฌ๊ฐ€ ์กฐ๊ฑด์‹ ์•ž์— ์žˆ์–ด์•ผ ํ•จ)
if (role == null || role.equals("MEMBER")) {
if (pageIdx == null) pageIdx = 0; // ๋ฃจํŠธ ๊ฒฝ๋กœ์—์„œ ํ˜ธ์ถœ ์‹œ ์ฒซ ํŽ˜์ด์ง€ ์กฐํšŒ
PageResponseDto page = storeIndexService.getStoreListInternal("", pageIdx); // v2 ํŒ์—…์Šคํ† ์–ด ์กฐํšŒ

model.addAttribute("page", page);
List<StoreMetaDocument> storeList = (List<StoreMetaDocument>) page.getData(); // downcast
model.addAttribute("storeList", storeList);
model.addAttribute("formatter", DateTimeFormatter.ofPattern("MM.dd(E)").withLocale(Locale.forLanguageTag("ko")));

return "index"; // ํŒ์—…์Šคํ† ์–ด ๋ชฉ๋ก ํŽ˜์ด์ง€๋กœ ์ด๋™
}
}

๐Ÿ“Œ 3๊ฐ€์ง€ ์กฐํšŒ ๋กœ์ง ์ž‘์„ฑโ€‹

MySQL, Elasticsearch, Redis cache ์ด 3๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ํŒ์—…์Šคํ† ์–ด ๋ชฉ๋ก ์กฐํšŒ ๋กœ์ง์„ ์ž‘์„ฑํ–ˆ๋‹ค.

...Redis์•ผ LocalDate ์ง€์›์€ ์ข€ ๊ธฐ๋ณธ์œผ๋กœ ํ•ด์ฃผ๋ฉด ์•ˆ๋ ๊นŒ.

๊ท€์ฐจ๋„ˆ

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ config ์„ค์ •๊นŒ์ง€ ๋งŒ์ ธ์ค˜์•ผ ํ•œ๋‹ค.

config์„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋‹ˆ๊นŒ ObjectMapper ์ปค์Šคํ…€ํ•œ๊ฒŒ ํ„ฐ์ ธ์„œ dto serializing์ด ์•ˆ๋˜๋Š”๋ฐ, ์–ด์ฐจํ”ผ ํ…Œ์ŠคํŠธ๋งŒ ํ•˜๋ ค๋Š” ๋ชฉ์ ์ด๋‹ˆ๊นŒ ๊ธ‰ํ•˜๊ฒŒ Object๋กœ ํ‹€์–ด๋ง‰์•˜๋‹ค.

์—ญ์‹œ ๋ง ์•ˆ๋“ค์œผ๋ฉด ๋ถ€๋ชจ๋ฅผ ๋ฐ๋ ค์™€์•ผ ใ…Ž Object๋Š” ์‹œ์กฐ ์•„๋‹Œ๊ฐ€


๐Ÿ“Œ JMeter ๊ทธ๋ž˜ํ”„ ํ”Œ๋Ÿฌ๊ทธ์ธโ€‹

๊ธฐ์กด๊บผ๋Š” ๋ง›์—†๊ฒŒ ์ƒ๊ฒจ์„œ ๊ทธ๋ž˜ํ”„ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ•˜๋‚˜ ๊น”์•˜๋‹ค. ๋””ํดํŠธ listener๋ณด๋‹จ ๋‚ซ๋”๋ผ.

๋ ˆํผ๋Ÿฐ์Šค๋Š” ์ด๊ฑธ ์ฐธ๊ณ ํ–ˆ๋‹ค.


๐Ÿ“Œ Redis ์บ์‹ฑ ์‹ฌํ™”โ€‹

๋‹น์žฅ์€ ๊ฐ„๋‹จํ•œ ์บ์‹ฑ ์„ค์ •์œผ๋กœ ๋ณด๊ณ ์„œ๋ฅผ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ, ์›๋ž˜ ์ด์ •๋„๋Š” ๋˜์–ด์•ผ ํ•˜์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค.

๋ ˆํผ๋Ÿฐ์Šค

๊ทธ๋ฆฌ๊ณ  Grafana ์ง„์งœ ๋ง›์žˆ๊ฒŒ ์ƒ๊ธด๋“ฏ... ๋‹ค์Œ ๋ฒ„์ „์— ๊ผญ ๋ถ™์ด์ž!!


๐Ÿ“Œ JMeter Out of Memory ๋ฌธ์ œโ€‹

์กฐํšŒ ํ…Œ์ŠคํŠธํ•˜๋Š”๋ฐ ์ค‘๊ฐ„์— ์• ๊ฐ€ ๋ฉˆ์ถฐ๋ฒ„๋ ค์„œ bat ํŒŒ์ผ ๋ณด๋‹ˆ๊นŒ...

heap ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•˜๋‹จ๋‹ค... ๊ทธ๋ž˜์„œ ์ตœ๋Œ€ 8GB๊นŒ์ง€ ๋Š˜๋ ค์คฌ๋‹ค ใ…œใ…œ

์ž๊พธ ์„ธํŒ…์— ์† ๊ฐ€๋Š”๊ฑฐ ๊ท€์ฐฎ์Œ.

Image


๐Ÿ“Œ JMeter port ๊ฐœ์ˆ˜ ๋ถ€์กฑโ€‹

3000๊ฐœ๊นŒ์ง„ ๊ทธ๋Ÿญ์ €๋Ÿญ ๊ตด๋Ÿฌ๊ฐ€๋Š”๋ฐ 5000๊ฐœ๋Š” ํ•˜๋„ failed transaction์ด ๋งŽ์ด ๋– ์„œ, ๋ญ”๊ฐ€ ํ•˜๊ณ  Tree๋ฅผ ๋ดค๋Š”๋ฐ ์ด๋Ÿฐ ๋กœ๊ทธ๊ฐ€ ์žˆ์—ˆ๋‹ค.

java.net.BindException: Address already in use: connect

์ด๊ฑฐ ์ฐธ๊ณ ํ•ด์„œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „๋ณด๋‹จ ์กฐ๊ธˆ ๋‚˜์•„์ง€๊ธด ํ–ˆ๋Š”๋ฐ ๊ทธ๋ž˜๋„ ํŠธ๋žœ์žญ์…˜์ด ๋ง‰ํŒ์— ์ข€ ๋ถˆ์•ˆ์ •ํ•จ. ์Œ...

์™œ์ง€?? ๐Ÿ™๐Ÿ™๐Ÿ™


๐Ÿ“Œ ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง• ๋กœ์ง ์ˆ˜์ •โ€‹

์š”๊ธฐ์„œ resizing option ์ž˜ ์„ค๋ช…ํ•ด์ฃผ๋”๋ผ!

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  webp ์ด๊ฑฐ ์˜ˆ์ „์— ๋ ˆํผ๋Ÿฐ์Šค ๋ดค์„๋• ๋ฌด์Šจ ๋ฒ„ํผ ๋‹ค๋ฃจ๊ณ  ๊ทธ๋žฌ์–ด์•ผ ํ–ˆ๋Š”๋ฐ... ๊ทธ๊ฑด sharp ์“ด๊ฒŒ ์•„๋‹ˆ์—ˆ๋‚˜?

์˜์™ธ๋กœ JMeter ํ…Œ์ŠคํŠธ๊ฐ€ ํ•˜๋ฃจ์ข…์ผ ๊ฑธ๋ฆฌ๊ณ  ์ •์ž‘ webp ๋ณ€ํ™˜์€ ๊ธˆ๋ฐฉ ๋๋‚˜์„œ ๊ธฐ๋ถ„์ด ์ข‹์•˜๋‹ค ^ใ……^

์ˆ˜์ •
if (key.includes('thumb')) {
try {
resizedImage_400 = await sharp(originalImage.Body)
.resize(400, 400, {fit: 'inside'})
.jpeg({ quality: 100 })
.toBuffer();
} catch (error) {
console.log(error);
return;
}
...
}
์ˆ˜์ •
if (key.includes('thumb')) {
try {
resizedImage_400 = await sharp(originalImage.Body)
.resize(400, 400, {fit: 'outside'})
.webp({ quality: 100 })
.toBuffer();
} catch (error) {
console.log(error);
return;
}
...
}