๐Ÿšจ ๋ฌธ์ œ ์ƒํ™ฉ

  • ์ฆ์ƒ: ๋ ˆ๊ฑฐ์‹œ๋กœ ํ”„๋กœ๊ทธ๋žจ์— JDBC ์ปค๋„ฅ์…˜์„ ๋ชป ์žก์•„์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ฐ„ํ—์ ์œผ๋กœ ํ„ฐ์ง
  • ํ™˜๊ฒฝ: HikariCP ์‚ฌ์šฉ ์ค‘, MySQL max_connections = 10,000
  • ์˜๋ฌธ: ์ปค๋„ฅ์…˜ ํ’€๋„ ์žˆ๊ณ  MySQL ์„ค์ •๋„ ์ถฉ๋ถ„ํ•œ๋ฐ ์™œ?

๐Ÿ” ์›์ธ ๋ถ„์„

1. ์Šค๋ ˆ๋“œ ์ˆ˜ vs ์ปค๋„ฅ์…˜ ํ’€ ํฌ๊ธฐ ๋ถˆ๊ท ํ˜•

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์Šค๋ ˆ๋“œ ๊ตฌ์„ฑ:
โ”œโ”€ ์Šค์ผ€์ค„๋Ÿฌ ์Šค๋ ˆ๋“œ: 15๊ฐœ
โ”œโ”€ ๋น„๋™๊ธฐ ์Šค๋ ˆ๋“œ: 5-20๊ฐœ  
โ”œโ”€ SMS ์›Œ์ปค ์Šค๋ ˆ๋“œ: 3๊ฐœ
โ””โ”€ LED ์Šค๋ ˆ๋“œ: 3-10๊ฐœ
์ด ์ตœ๋Œ€ 48๊ฐœ ์Šค๋ ˆ๋“œ

HikariCP ์ปค๋„ฅ์…˜ ํ’€: 15๊ฐœ โŒ
→ ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ์ปค๋„ฅ์…˜ ํ’€๋ณด๋‹ค 3๋ฐฐ ๋งŽ์Œ!

2. 1๋ถ„ ์Šค์ผ€์ค„๋Ÿฌ์˜ ๋Œ€๋Ÿ‰ ๊ฐœ๋ณ„ UPDATE

// ๋งค 1๋ถ„๋งˆ๋‹ค 2๊ฐœ ์Šค์ผ€์ค„๋Ÿฌ ๋™์‹œ ์‹คํ–‰
@Scheduled(cron = "0 0/1 * * * *")
public void startMethod2() { /* ์ž๋™ํ‡ด์‹ค, ์Šคํ„ฐ๋””๋ฃธ ๊ด€๋ฆฌ */ }

@Scheduled(cron = "0 0/1 * * * *") 
public void startMethod3() { /* ์ž์Šต์‹ค ์‹œ๊ฐ„ ์Šค์ผ€์ค„ */ }

์ปค๋„ฅ์…˜ ํญ์ฆ ์‹œ๋‚˜๋ฆฌ์˜ค:

๋งค 1๋ถ„ ์ •๊ฐ:
โ”œโ”€ ์ž๋™ํ‡ด์‹ค 50๋ช… × ๊ฐœ๋ณ„ UPDATE = 50๊ฐœ ์ปค๋„ฅ์…˜
โ”œโ”€ ์Šคํ„ฐ๋””๋ฃธ 20๊ฐœ × ๊ฐœ๋ณ„ UPDATE = 20๊ฐœ ์ปค๋„ฅ์…˜
โ”œโ”€ ๊ธฐํƒ€ ์กฐํšŒ/์—…๋ฐ์ดํŠธ = 30๊ฐœ ์ปค๋„ฅ์…˜
โ””โ”€ ์ผ๋ฐ˜ ์›น ์š”์ฒญ = 10๊ฐœ ์ปค๋„ฅ์…˜
์ด 110๊ฐœ ์ปค๋„ฅ์…˜ ๋™์‹œ ์‚ฌ์šฉ! (ํ’€ ํฌ๊ธฐ: 15๊ฐœ)

3. ๋ถˆํ•„์š”ํ•œ SMS DB ์„ค์ •

<!-- ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” SMS DB (์ปค๋„ฅ์…˜ ํ’€ ์—†์Œ) -->
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- ๋งค๋ฒˆ ์ƒˆ ์ปค๋„ฅ์…˜ ์ƒ์„ฑ/ํ•ด์ œ → ์„ฑ๋Šฅ ์ €ํ•˜ -->
</bean>

๐Ÿš€ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

1. HikariCP ์ปค๋„ฅ์…˜ ํ’€ ์ตœ์ ํ™”

<!-- ๊ธฐ์กด ์„ค์ • -->
<property name="minimumIdle" value="3"/>
<property name="maximumPoolSize" value="15"/>
<property name="idleTimeout" value="30000"/>      <!-- 30์ดˆ -->
<property name="maxLifetime" value="1200000"/>    <!-- 20๋ถ„ -->

<!-- ๊ฐœ์„ ๋œ ์„ค์ • -->
<property name="minimumIdle" value="10"/>         <!-- ์•ˆ์ •์  ๊ธฐ๋ณธ ์—ฐ๊ฒฐ -->
<property name="maximumPoolSize" value="50"/>     <!-- ์Šค๋ ˆ๋“œ 48๊ฐœ ๋Œ€์‘ -->
<property name="idleTimeout" value="600000"/>     <!-- 10๋ถ„ -->
<property name="maxLifetime" value="1800000"/>    <!-- 30๋ถ„ -->
<property name="leakDetectionThreshold" value="60000"/> <!-- 1๋ถ„, ๋น ๋ฅธ ๊ฐ์ง€ -->

2. ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ ๋„์ž…

๊ธฐ์กด ๋ฐฉ์‹ (N+1 ๋ฌธ์ œ):

for(int i=0; i<list.size(); i++) {
    // ๊ฐœ๋ณ„ UPDATE (๋งค๋ฒˆ ์ปค๋„ฅ์…˜ ์‚ฌ์šฉ)
    params.put("querykey", "seat_power_state_update");
    params.put("power_number", powerNumber);
    params.put("power_state", "0");
    comService.simpleUpdate(params);  // ์ปค๋„ฅ์…˜ 1๊ฐœ ์‚ฌ์šฉ
}

๊ฐœ์„ ๋œ ๋ฐฉ์‹ (๋ฐฐ์น˜ ์ฒ˜๋ฆฌ):

List<String> powerNumbers = new ArrayList<String>();

for(int i=0; i<list.size(); i++) {
    // ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์ง‘ (์ปค๋„ฅ์…˜ ์‚ฌ์šฉ ์•ˆ ํ•จ)
    powerNumbers.add(powerNumber);
}

// ํ•œ ๋ฒˆ์— ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ (์ปค๋„ฅ์…˜ 1๊ฐœ๋งŒ ์‚ฌ์šฉ)
comService.batchUpdateSeatPowerState(powerNumbers, "0");

๋ฐฐ์น˜ UPDATE ์ฟผ๋ฆฌ:

<update id="seat_power_state_batch_update">
    UPDATE xe_tbl_seat 
    SET power_state = #{power_state}
    WHERE power_number IN 
    <foreach collection="power_numbers" item="power_number" open="(" close=")" separator=",">
        #{power_number}
    </foreach>
</update>

3. ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” SMS DB ์„ค์ • ์ œ๊ฑฐ

<!-- ์ œ๊ฑฐ๋œ ์„ค์ •๋“ค -->
<bean id="dataSource2">...</bean>
<bean id="sqlSessionFactory2">...</bean>
<bean id="transactionManager2">...</bean>
<bean id="sqlSession2">...</bean>

๐Ÿ“Š ์„ฑ๋Šฅ ๊ฐœ์„  ๊ฒฐ๊ณผ

์ปค๋„ฅ์…˜ ์‚ฌ์šฉ๋Ÿ‰ ๋น„๊ต

์‹œ๋‚˜๋ฆฌ์˜ค ๊ธฐ์กด ๊ฐœ์„  ํ›„ ๊ฐœ์„ ์œจ
์ž๋™ ํ‡ด์‹ค 50๋ช… 50๊ฐœ UPDATE 1๊ฐœ UPDATE 98% ๊ฐ์†Œ
์Šคํ„ฐ๋””๋ฃธ 20๊ฐœ 20๊ฐœ UPDATE 1๊ฐœ UPDATE 95% ๊ฐ์†Œ
์—…๋ฌด ๋งˆ๊ฐ 100์ขŒ์„ 100๊ฐœ UPDATE 1๊ฐœ UPDATE 99% ๊ฐ์†Œ
1๋ถ„ ์Šค์ผ€์ค„๋Ÿฌ ์ „์ฒด 170๊ฐœ ์ปค๋„ฅ์…˜ 20๊ฐœ ์ปค๋„ฅ์…˜ 88% ๊ฐ์†Œ

์‹ค์ œ SQL ์‹คํ–‰ ๋น„๊ต

-- ๊ธฐ์กด: 100๊ฐœ ์ขŒ์„ ์ฒ˜๋ฆฌ ์‹œ
UPDATE xe_tbl_seat SET power_state = '0' WHERE power_number = '1';
UPDATE xe_tbl_seat SET power_state = '0' WHERE power_number = '2';
-- ... 100๋ฒˆ ๋ฐ˜๋ณต

-- ๊ฐœ์„ : 100๊ฐœ ์ขŒ์„ ์ฒ˜๋ฆฌ ์‹œ  
UPDATE xe_tbl_seat SET power_state = '0' 
WHERE power_number IN ('1','2','3',...,'100');

๐Ÿ›ก๏ธ ์•ˆ์ „ํ•œ ์ ์šฉ ์ „๋žต

๋ฐฐ์น˜ ์ ์šฉ ๊ธฐ์ค€

โœ… ์ ์šฉ ๊ฐ€๋Šฅ

  • ์ƒํƒœ๊ฐ’์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋™์ผํ•œ ๊ฒฝ์šฐ
  • ๋กœ์ง์ด ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ
  • ์•ˆ์ „์„ฑ์ด ๋ณด์žฅ๋˜๋Š” ๊ฒฝ์šฐ

โŒ ์ ์šฉ ์ œ์™ธ

  • ์ƒํƒœ๊ฐ’์ด ๋™์ ์œผ๋กœ ๊ณ„์‚ฐ๋˜๋Š” ๊ฒฝ์šฐ
  • ๋ณต์žกํ•œ ์กฐ๊ฑด๋ฌธ์ด ์žˆ๋Š” ๊ฒฝ์šฐ
  • ๊ธฐ์กด ๋กœ์ง ๋ณ€๊ฒฝ ์œ„ํ—˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ

์ ์šฉ๋œ 4๊ฐ€์ง€ ์ผ€์ด์Šค

  1. ์ž๋™ ํ‡ด์‹ค: ์‹œ๊ฐ„ ๋งŒ๋ฃŒ → ๋ชจ๋‘ OFF
  2. ์Šคํ„ฐ๋””๋ฃธ ํ‡ด์‹ค: ์˜ˆ์•ฝ ์ข…๋ฃŒ → ๋ชจ๋‘ OFF
  3. ์Šคํ„ฐ๋””๋ฃธ ์ž…์‹ค: ์˜ˆ์•ฝ ์‹œ์ž‘ → ๋ชจ๋‘ ON โญ
  4. ์—…๋ฌด ๋งˆ๊ฐ: ์šด์˜ ์ข…๋ฃŒ → ๋ชจ๋‘ OFF

๐ŸŽฏ ํ•ต์‹ฌ ๊ตํ›ˆ

1. ์Šค๋ ˆ๋“œ ์ˆ˜์™€ ์ปค๋„ฅ์…˜ ํ’€ ํฌ๊ธฐ์˜ ๊ด€๊ณ„

  • ๋™์‹œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์Šค๋ ˆ๋“œ ์ˆ˜ ≤ ์ปค๋„ฅ์…˜ ํ’€ ํฌ๊ธฐ
  • ์Šค์ผ€์ค„๋Ÿฌ, ๋น„๋™๊ธฐ ์ž‘์—… ๋“ฑ ๋ชจ๋“  ์Šค๋ ˆ๋“œ ๊ณ ๋ ค ํ•„์š”

2. ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ์˜ ์œ„๋ ฅ

  • N+1 ๋ฌธ์ œ ํ•ด๊ฒฐ๋กœ ๊ทน์ ์ธ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  • ์•ˆ์ „ํ•œ ๋ถ€๋ถ„๋งŒ ์„ ๋ณ„ ์ ์šฉํ•ด๋„ ํฐ ํšจ๊ณผ

3. ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ์ค‘์š”์„ฑ

  • ์ปค๋„ฅ์…˜ ๋ˆ„์ˆ˜ ๊ฐ์ง€ ์‹œ๊ฐ„ ๋‹จ์ถ• (5๋ถ„ → 1๋ถ„)
  • ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๋กœ๊น…์œผ๋กœ ํšจ๊ณผ ์ธก์ •

๐Ÿ’ก ๊ฒฐ๋ก 

"์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ๊ณ ๋ คํ•œ ์ปค๋„ฅ์…˜ ํ’€ ํฌ๊ธฐ ์กฐ์ • + ์„ ๋ณ„์  ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ ์ ์šฉ"

  • ์Šค์ผ€์ค„๋Ÿฌ ์‹คํ–‰ ํšŸ์ˆ˜๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€
  • ์ปค๋„ฅ์…˜ ์‚ฌ์šฉ๋Ÿ‰๋งŒ 88% ๊ฐ์†Œ
  • ๊ธฐ์กด ๊ธฐ๋Šฅ ์™„์ „ ๋ณด์กด
  • ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ ๋‘ ๋งˆ๋ฆฌ ํ† ๋ผ ๋ชจ๋‘ ํ™•๋ณด

๊ฒฐ๊ณผ: ์ปค๋„ฅ์…˜ ํ’€ ๊ณ ๊ฐˆ ๋ฌธ์ œ ํ•ด๊ฒฐ๋œ๊ฑฐ๊ฐ™์œผ๋‚˜ ๊ฒฝ๊ณผ๋ฅผ ์ง€์ผœ๋ด์•ผํ• ๊บผ๊ฐ™๋‹ค..