ํ์ฌ ํ๋ก์ ํธ
- ํด๋งฅ์ค๋ชจ๋น๋ฆฌํฐ ์ฃผ์ฐจ์ฅ ์๋น์ค ๊ฐ๋ฐ
- SpringBoot + MySQL + Docker + AWS EC2(Amazon Linux 2)
- ์ฃผ์ฐจ์ฅ ๊ฒ์ ์ ์ฌ๋ผ๊ฐ๋ ์นด์ดํธ๋ฅผ ํตํด ์ธ๊ธฐ๋ ์ถ๋ ฅ
- ๊ธฐ์กด MySQL์search_count
๋ฅผ ->Redis
๋ก ์ด๊ดํ๊ธฐ ์ํ ์์ ์งํ
๐ [Redis] Redis ์ค์น ๋ฐ ๊ฐ๋จํ ์ฌ์ฉ ๋ฐฉ๋ฒ (Mac)
Mac Os์ Homebrew๋ฅผ ํตํ ์ค์น๋ฅผ ์งํํ์ต๋๋ค.
$ brew install redis
์ค์น๊ฐ ์๋ฃ๋๋ฉด ๋ค์์ ๋ช
๋ น์ด๋ก redis๋ฅผ ์คํํฉ๋๋ค.
$ brew services start redis
redis-cli์ ํตํด ์คํํ ์ ์์ต๋๋ค.
$ redis-cli
https://wlswoo.tistory.com/44
-> ์ฌ๊ธฐ๋ณด๊ณ ์ ๋ฆฌํด๋๊ธฐ
์ฐ์ ์ ๋ธ๋์น๋ก ๋์์์ ํ
์คํธ๋ฅผ ํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ checkout ํ๋, resources/application.yml์ด ์...์ด์ก..์ต๋๋ค๐ฎ
์์ฒญ ๋นํฉํ๋๋ฐ ๊ทธ๋ฅ ์ ๊ฐ ์ ์ฅ์ํ๊ณ ๋ค๋ฅธ ๋ธ๋์น๋ก ๋์ด๊ฐ๋ค๊ฐ ์์ ๊ทธ๋ฐ ๊ฒ ๊ฐ์์, ๊ทธ๋ฅ ๋ง๋ค์์ต๋๋ค..!
๋ค์ ๋ง๋๋๊น ์์์ ignore ์ฒ๋ฆฌ๊ฐ ๋ฐ๋ก ๋์ด์ ์์ฌํ๊ณ commitํ์ต๋๋ค.
๊น์ ์ ๋ง ๋ค ์์๋ค๊ณ ์๊ฐํ๋ ์๊ฐ ์ฒ์ ๋ณด๋ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํค๋ ๊ฒ ๊ฐ์์๐
๊น ๊ณต๋ถํ๊ธฐ(๋ฉ๋ชจ)
.
.
๋ค์ ๋์์์ ๋ณ๊ฒฝํ ๋ถ๋ถ์ ๋ง์๋๋ ค๋ณผ๊ฒ์.
Spring Boot ๋ด์ Redis๋ฅผ ์ง์ํด์ฃผ๋ spring-boot-starter-data-redis
๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ด์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๐ bulid.gradle
...
// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
...
Redis๋ฅผ ์ค์นํ๊ณ , ์๋ฌด ์ค์ ์ ํ์ง ์์์ ๊ฒฝ์ฐ
์ด๋ ๊ฒ ์ค์ ์ด ๋์ด ์์ต๋๋ค.
์ด ์ค์ ์ application.yml์ ์ถ๊ฐํด์ฃผ์๋ฉด ๋ฉ๋๋ค.
โฐ ๋ฐ๋์ spring: ๋ฐ๋ก ์๋ indentation์ ์์ฑํด์ฃผ์ด์ผ ํฉ๋๋ค. โฐ
๐ application.yml
spring:
redis:
host: localhost
port: 6379
...
spring-boot-starter-data-redis
์ ์์ฒด์ ์ผ๋ก RedisTemplete์ ์๋ ์ฃผ์
ํด์ฃผ์ง๋ง, ์ฝ๊ฐ์ ์ค๋ฅ๊ฐ ์์ด ์ถ๊ฐํด์ฃผ์์ต๋๋ค.
์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋๋ค๋ฉด ์ถ๊ฐํ์ง ์์๋ ๋ฉ๋๋ค!
๐ config/RedisConfig.java
package com.humax.parking.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
๊ธฐ์กด์ MySQL์์์ search_count๋ฅผ Redis๋ก ์ฎ๊ฒจ์ฃผ๊ณ , MySQL์๋ ์ฃผ๊ธฐ์ ์ผ๋ก ๊ฐฑ์ ๋ง ํด์ฃผ๋๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
๐ service/UserService.java
๐ ๊ธฐ์กด
private void updateSearchCount(List<ParkingEntity> parkingEntities){
for(ParkingEntity parkingEntity : parkingEntities){
parkingEntity.setSearchCount(parkingEntity.getSearchCount()+1);
}
}
๐ ๋ณ๊ฒฝํ
...
private final StringRedisTemplate stringRedisTemplate;
private static final String SEARCH_COUNT_KEY_PREFIX = "search_count:";
...
private void updateSearchCount(List<ParkingEntity> parkingEntities) {
for (ParkingEntity parkingEntity : parkingEntities) {
String key = SEARCH_COUNT_KEY_PREFIX + parkingEntity.getParkingId();
stringRedisTemplate.opsForValue().increment(key);
// ๋ก๊ทธ ์ถ๊ฐ
System.out.println("์ถ๊ฐ๋ ์ฃผ์ฐจ์ฅ parking_id: " + parkingEntity.getParkingId());
}
}
SEARCH_COUNT_KEY_PREFIX
๋ก search_count๋ฅผ ๋ช
์ํ ์ ์๋๋ก ํ์ต๋๋ค.SEARCH_COUNT_KEY_PREFIX
๋ฅผ ํตํด ์นด์ดํธ์ KEY ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ , ์ค์ ๋ก ๊ฒ์๋ ํ key๊ฐ์ด increment ๋๋๋ก ์ฝ๋๋ฅผ ์์ฑํ์ต๋๋ค.search_count์ ๋์ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1. ์ฌ์ฉ์๊ฐ ๊ฐ๊น์ด ์ฃผ์ฐจ์ฅ์ ๋ฐ๊ฒฝ, ์๋์ ๊ฒฝ๋๋ก ์กฐํํฉ๋๋ค.
(๋ฐ๋์ ์์
๋ก๊ทธ์ธ์ด ๋์ด ์๋ ์ ์ ์ฌ์ผ๋ง ํฉ๋๋ค)
URI
localhost:8080/api/v1/user/search
Body(JSON)
{ "distance": 2000, "lon":"37.5170112", "lat":"126.9019532" }
๐ฉ ๊ฐ๊น์ด ์ฃผ์ฐจ์ฅ ์กฐํ
๐ฉ ํ๋ก์ ํธ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋์๋์ง ํ์ธ
๐ฉ Redis ํ์ธ
GET search_count:{parking_id}
๐ฉ MySQL ํ์ธ
์ผ๋ฐ์ ์ผ๋ก ์ด ์ฟผ๋ฆฌ๊ฐ ์ข
๋ฃ๋ ์ฆ์, MySQL์์ ์ ์ฉ์ด ๋์ด์ผ ํ์ง๋ง ๋ฐ๋ก ์ ์ฉ๋์ง ์๋ ๋ฌธ์ ๋ฐ์
๐ service์ redis ํจํค์ง ์์ฑ/GSearchCountUpdateTask.java
package com.humax.parking.service.redis;
import com.humax.parking.service.UserService;
import java.util.ArrayList;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@SpringBootApplication
@EnableScheduling
public class SearchCountUpdateTask {
private final UserService userService;
public SearchCountUpdateTask(UserService userService) {
this.userService = userService;
}
@Scheduled(fixedDelay = 60000) // 1๋ถ๋ง๋ค ์คํ (๋ฐ๋ฆฌ์ด ๋จ์) -> ์ถํ ์ค์ ๋ฐฐ์น ์์
์ 1์๊ฐ์ผ๋ก ๋ณ๊ฐฑ
public void updateSearchCount() {
try {
// ์ฌ๊ธฐ์ userService์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ MySQL์ ๊ฒ์ ํ์๋ฅผ ๊ฐฑ์
userService.updateSearchCount(new ArrayList<>());
System.out.println("๊ฐฑ์ ์๋ฃ");
} catch (Exception e) {
// ์์ธ ์ฒ๋ฆฌ
e.printStackTrace();
}
}
}
๐ UserService.java ์์
public void updateSearchCount(List<ParkingEntity> parkingEntities) {
for (ParkingEntity parkingEntity : parkingEntities) {
String key = SEARCH_COUNT_KEY_PREFIX + parkingEntity.getParkingId();
stringRedisTemplate.opsForValue().increment(key);
// ๋ก๊ทธ ์ถ๊ฐ
System.out.println("์ถ๊ฐ๋ ์ฃผ์ฐจ์ฅ parking_id: " + parkingEntity.getParkingId());
}
}
๊ฒฐ๊ณผ
ํ ์คํธ์ฉ์ด๋ผ 1๋ถ์ ํ๋ฒ์ฉ MySQL์ ๊ฐฑ์ ์ด ๋๋๋ก ํ์ต๋๋ค.
ํ์ง๋ง ์ค์ MySQL์์ ๊ฐ์ด ์์ง ๋ฐ์๋์ง ์๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
๋ฐฐ์น ์์ ์ ํ์ง ์๋ ๊ฒ์ผ๋ก ๊ฒฐ๋ก .
๋ค์ ํธ : ๐งฃ SpringBoot + Redis - ๋ฉ์ธ ํ๋ฉด ์ธ๊ธฐ ์ฃผ์ฐจ์ฅ ๋์ฐ๊ธฐ