๐ ์ฐ๋ฆฌ๋ Spring Cloud๋ฅผ ํ์ฉํ์ฌ MSA๋ฅผ ๊ตฌ์ถํ๋ค.
๐ ์ด๋ฒ์๋, Service Discovery๋ฅผ ๊ตฌ์ถํ ๊ฒ์ด๋ค.
Service Discovery ํํธ 1
Service Discovery์ ์ญํ ์ ๊ฐ๋ตํ๊ฒ ์ ๋ฆฌํ์๋ฉด,
Service Discovery๋?
- ๋ง์ดํฌ๋ก์๋น์ค์ ์ ๋ณด(์์น ๋ฑ)๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
- ์ธ๋ถ์ ์์ฒญ์ด๋ ์๋น์ค๊ฐ ๋ง์ดํฌ๋ก์๋น์ค์ ์ ๋ณด๋ฅผ ๊ฒ์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
Spring Cloud์์๋ Spring Cloud Netflix Eureka๊ฐ Service Discovery์ ์ญํ ์ ์ํํ๋ค. Eureka๋ Eureka Server์ Eureka Client๋ก ๊ตฌ์ฑ๋๋ค.
Eureka ์๋ฒ๋?
Eureka ์๋ฒ๋ ๋จ์ํ๊ฒ MSA๋ฅผ ๊ตฌ์ฑํ๋ ๋ง์ดํฌ๋ก ์๋น์ค๋ค์ ๋ชจ๋ํฐ๋งํ๋ ๊ฐ์์ ์๋ฒ์ ์ญํ ์ ํ๋ค๊ณ ๋ณผ ์ ์์ง๋ง. ๊น๊ฒ ๋ณด๋ฉด ํ์ฌ ์กด์ฌํ๋ ๋ง์ดํฌ๋ก ์๋น์ค๋ค์ Gateway์๊ฒ ์๋ ค์ฃผ์ด ์๊ฐ๊ณผ ๋ถํ์ ๋ฐ๋ผ ์ ๋์ ์ผ๋ก ์ค์ผ์ผ ์์๋๋ ์๋ฒ๋ค์ ๋ชจ๋ ๊ฐ์ฉํ ์ ์๋๋ก ํ๋ ์ญํ ์ ์ํํ๋ค. ๋ฐ๋ผ์, Eureka ์๋ฒ๋ ๊ฐ๋๋๋ ์๋ฒ๋ฅผ ํ์ธ ํ Gateway์๊ฒ ๊ทธ ๋ชฉ๋ก์ ์๋ ค์ฃผ๋ ์ญํ ์ ์ํํ๋ค.
๐ ๋จผ์ , Service Discovery์ Eureka Server๋ฅผ ๊ตฌ์ถํ ๊ฒ์ด๋ค.
Spring Cloud Eureka ์๋ฒ ๊ตฌ์ถํ๊ธฐ
1. ํ๋ก์ ํธ ์์ฑ
Eureka ์๋ฒ ์ค์ ์ ์ํ ์์กด์ฑ ์ถ๊ฐ
ํ์ ์์กด์ฑ
- Eureka Server
- Spring Security
// build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
2. Main ํด๋์ค ์ด๋ ธํ ์ด์ ๋ฑ๋ก
Eureka ์๋ฒ๋ก ๋์ํ๊ธฐ ์ํ ์ด๋ ธํ ์ด์ ์ ๋ฑ๋กํด์ผ ํ๋ค.
// EurekaServerApplication
package com.caffeinedoctor.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // EurekaServer๋ก ๋ฑ๋ก
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
main๋ฉ์๋์ @EnableEurekaServer ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํ๋ฉด Discovery ์๋ฒ๋ก์ ์ญํ ์ ์ํํ ์ ์๊ฒ ๋๋ค.
3. Eureka ์๋ฒ ์ค์
application.properties ํ์ผ์ ์ญ์ ํ๊ณ application.yml ํ์ผ์ ์์ฑํ์ฌ ์ค์ ์ ํตํด Eureka ์๋ฒ๋ฅผ ์์ฑํ๋ค.
# application.yml
# ํ์ฌ ํ๋ก์ ํธ์ ํฌํธ ๋ฒํธ ์ง์
# ์ ๋ ์นด ์๋ฒ ํฌํธ ๋ฒํธ๋ ๋ณดํต 8761๋ฒ ์ฌ์ฉ
server:
port: 8761
# ํ์ฌ ํ๋ก์ ํธ์ ์ด๋ฆ ์ง์
spring:
application:
name: eureka-server
# ํ์ฌ ํ๋ก์ ํธ์ eureka ์ค์
eureka:
client:
# eureka ๋ฑ๋ก ์ฌ๋ถ
# ์ ๋ ์นด ์๋ฒ๊ฐ ์๊ธฐ์์ ์ ๋ฑ๋ฃํ๋ ๊ฒ์ ๋ง์
register-with-eureka: false
# Eureka ์๋ฒ๋ก๋ถํฐ ์ธ์คํด์ค๋ค์ ์ ๋ณด๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ๊ฐ์ ธ์ฌ ๊ฒ์ธ์ง ์ค์ ํ๋ ์์ฑ
fetch-registry: false
- ํฌํธ ๋ฒํธ: 8761
- Service ์ด๋ฆ: eureka-server
- register-with-eureka (๋ํดํธ true)
- ๋ ์ง์คํธ๋ฆฌ์ ์์ ์ ๋ฑ๋กํ ๊ฑด์ง์ ๋ํ ์ฌ๋ถ์ด๋ค.
- ์ฆ, ์ ๋ ์นด ์๋ฒ์ ๋ฑ๋กํ๊ฒ ๋๋ ๋ป์ด๋ค.
- ์ง๊ธ Service๋ Eureka Server์ด๋ ๋ฑ๋ก์ด ํ์ ์์ด์ false๋ก ์ค์ ํ๋ค.
- fetch-registry (๋ํดํธ true)
- ๋ ์ง์คํธ๋ฆฌ์ ์๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์ฌ๊ฑด์ง์ ๋ํ ์ฌ๋ถ์ด๋ค.
- true ์ค์ ์ ๊ฒ์ํ ๋๋ง๋ค Eureka server๋ฅผ ํธ์ถํ๋ ๋์ ๋ ์ง์คํธ๋ฆฌ๊ฐ ๋ก์ปฌ๋ก ์บ์ฑ๋๋ค.
- ์ฆ, Client๊ฐ ๊ฒ์ ๊ฐ๋ฅํ๋๋ก ํ๋ ์ค์ ์ด๋ค.
- ์ง๊ธ Service๋ Eureka Server์ด๋ ๊ฒ์์ด ํ์ ์์ด์ false๋ก ์ค์ ํ๋ค.
4. ์ํ๋ฆฌํฐ ์ค์
Eureka ์๋ฒ๋ ๋ด๋ถ๋ง์์๋ง ์กด์ฌํด์ผ ๋๋ค. ํ์ง๋ง ์ธ๋ถ๋ง์ ๊ตฌ์ถํ๊ฑฐ๋ ๋ด๋ถ๋ง์์๋ ๋ณด์์ ์ค์์ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์คํ๋ง ์ํ๋ฆฌํฐ ์ค์ ์ ์งํํ๋ค. ์ํ๋ฆฌํฐ๋ httpBasic ๋ฐฉ์ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
// SecurityConfig
package com.caffeinedoctor.eurekaserver.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
// ์ํ๋ฆฌํฐ ์ปค์คํ
config๋ฅผ ์์ฑํ์ฌ ํน์ ๊ฒฝ๋ก์ ๋ํด ์ ๊ทผ์ ๋ง๋๋ค.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// ์ํธํ ์ํค๊ธฐ
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
// ํน์ ๊ฒฝ๋ก์ ๋ํด์ ๋ณด์ ์ค์ ํ๊ธฐ
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// csrf ๋ฌด์
http.csrf((auth) -> auth.disable());
// ๋ชจ๋ ๊ฒฝ๋ก์ ๋ํด ๊ถํ์ด ํ์ํ๊ฒ ํ๋ค.
http.authorizeHttpRequests((auth) -> auth.anyRequest().authenticated());
// ๋ก๊ทธ์ธ ๋ฐฉ์์ http ๋ฒ ์ด์ง ๋ฐฉ์
http.httpBasic(Customizer.withDefaults());
return http.build();
}
// ์๋ฒ์ ์ ์ํ ์ ์๋ ๋น๋ฐ๋ฒํธ์ ์์ด๋ ๋ฑ๋กํ๊ธฐ (์ธ ๋ฉ๋ชจ๋ฆฌ ํ์
)
@Bean
public UserDetailsService userDetailsService() {
// ์์ฉ์1 ์์ฑ
UserDetails user1 = User.builder()
.username("์์ด๋")
.password(bCryptPasswordEncoder().encode("๋น๋ฐ๋ฒํธ"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user1);
}
}
Spring Cloud Eureka ์๋ฒ ์คํ
์ฐธ๊ณ ์๋ฃ
https://covenant.tistory.com/251
https://devhan.tistory.com/m/260
https://substantial-park-a17.notion.site/6-Eureka-057c942a7a4041bf87ab5cd3043af021