<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발 블로그</title>
    <link>https://spring-studyy.tistory.com/</link>
    <description>스프링 공부부터 시작해서 백엔드 개발에 필요한 전반적인 IT 지식 및 프로젝트 개발 과정 등을 정리하는 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Wed, 6 May 2026 17:53:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>chanhee01</managingEditor>
    <item>
      <title>스프링 클라우드 게이트웨이 글로벌 필터와 지역 필터</title>
      <link>https://spring-studyy.tistory.com/308</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rkIBh/btsIV5wt9St/zJzni1bWXulEQIbsCfPtC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rkIBh/btsIV5wt9St/zJzni1bWXulEQIbsCfPtC0/img.png&quot; data-alt=&quot;사진 출처 : 스프링 클라우드 MSA 유튜브 강의 (강의자 : 개발자 유미)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rkIBh/btsIV5wt9St/zJzni1bWXulEQIbsCfPtC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrkIBh%2FbtsIV5wt9St%2FzJzni1bWXulEQIbsCfPtC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;278&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사진 출처 : 스프링 클라우드 MSA 유튜브 강의 (강의자 : 개발자 유미)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA 환경에서 각각의 마이크로 서비스로 요청을 하기 전에 jwt 검증, IP에 대한 접근 권한 등을 해야 하기에 필터를 적용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;order라고 필터의 숫자가 있는데, 숫자가 작을 수록 가장 먼저 필터가 수행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;글로벌 필터 - 모든 서비스를 거치기 전에 거치는 필터&lt;/li&gt;
&lt;li&gt;지역 필터 - 특정 마이크로 서비스 라우팅에 대해서만 동작하는 필터&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 글로벌 필터 - 모든 서비스를 거치기 전에 거치는 필터&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1722842746736&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class G1Filter implements GlobalFilter, Ordered {


    @Override
    public Mono&amp;lt;Void&amp;gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println(&quot;pre global filter order -1&quot;);
        // 마이크로 서비스를 거치기 전의 pre filter

        return chain.filter(exchange)
                .then(Mono.fromRunnable(() -&amp;gt; {

                    System.out.println(&quot;post global filter order -1&quot;);
                    // 마이크로 서비스를 거치고 난 후의 post filter
                }));
    }

    @Override
    public int getOrder() {

        return -1;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 코드가 글로벌 필터이다. @Component 어노테이션으로 필터로 지정하고, 이미 구현된 GlobalFilter, Ordered를 상속받아서 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 filter와 getOrder를 오버라이딩 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;filter 함수를 보면 return 이전의 코드들은 마이크로 서비스에 접근하기 전에 수행되는 pre filter이며, return 이후의 코드들은 마이크로 서비스를 거치고 난 후에 실행되는 post filter이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getOrder 함수는 필터의 순서 값을 return 해주는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 위의 사진에서 보면 pre filter는 숫자가 낮은 필터부터 실행되지만, post filter는 마이크로 서비스를 거치고 난 이후기에 숫자가 큰 것부터 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-2의 pre filter -&amp;gt; -1의 pre filter -&amp;gt; -1의 post filter -&amp;gt; -2의 post filter 순으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722843078382&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080
spring.application.name=SCG-2

spring.cloud.gateway.routes[0].id=ms1
spring.cloud.gateway.routes[0].predicates[0].name=Path
spring.cloud.gateway.routes[0].predicates[0].args.pattern=/ms1/**
spring.cloud.gateway.routes[0].uri=http://localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties에 위와 같이 8081 포트에 라우팅 해주고 8081/ms1/fisrt로 요청을 보내면 아래와 같이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNWWrf/btsIUf77IzN/8hO9sd5rjKIFeSKwta8i01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNWWrf/btsIUf77IzN/8hO9sd5rjKIFeSKwta8i01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNWWrf/btsIUf77IzN/8hO9sd5rjKIFeSKwta8i01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNWWrf%2FbtsIUf77IzN%2F8hO9sd5rjKIFeSKwta8i01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;143&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상했던 것과 정확히 같은 순서로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 지역 필터 - 특정 마이크로 서비스 라우팅에 대해서만 동작하는 필터&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1722843290401&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class L1Filter extends AbstractGatewayFilterFactory&amp;lt;L1Filter.Config&amp;gt; {

    public L1Filter() {

        super(Config.class);
    }


    @Override
    public GatewayFilter apply(Config config) {

        return (exchange, chain) -&amp;gt; {

            if (config.isPre()) {
                System.out.println(&quot;pre local filter 1&quot;);
            }

            return chain.filter(exchange)
                    .then(Mono.fromRunnable(() -&amp;gt; {

                        if (config.isPost()) {

                            System.out.println(&quot;post local filter 1&quot;);
                        }
                    }));
        };
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public static class Config {
        private boolean pre;
        private boolean post;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드가 지역 필터의 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자를 super 클래스로 만들어주고, apply 메서들을 오버라이딩 시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, return이 2번 등장하는데, 첫 번째 return은 pre filter의 부분이고, 두 번째 return은 post filter의 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Config 클래스를 통해 변수 값 또한 받을 수 있다. 이 때는 lombok을 사용해서 받아줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties&lt;/p&gt;
&lt;pre id=&quot;code_1722843410982&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080
spring.application.name=SCG-2

spring.cloud.gateway.routes[0].id=ms1
spring.cloud.gateway.routes[0].predicates[0].name=Path
spring.cloud.gateway.routes[0].predicates[0].args.pattern=/ms1/**
spring.cloud.gateway.routes[0].uri=http://localhost:8081

# 지역 필터 관련 설정
spring.cloud.gateway.routes[0].filters[0].name=L1Filter
spring.cloud.gateway.routes[0].filters[0].args.pre=true
spring.cloud.gateway.routes[0].filters[0].args.post=true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역 필터는 라우터에 대해 여러개의 필터를 등록할 수 있기에 index를 붙여주고, 위와 같이 설정을 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 args를 통해 pre와 post를 true로 넣어줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 로직에서 true일 때만 로그를 찍기 때문에 이러한 변수를 설정해준 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A1HDN/btsITvjg7Er/892ABBJPgVzmNe9GXyQRKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A1HDN/btsITvjg7Er/892ABBJPgVzmNe9GXyQRKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A1HDN/btsITvjg7Er/892ABBJPgVzmNe9GXyQRKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA1HDN%2FbtsITvjg7Er%2F892ABBJPgVzmNe9GXyQRKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;352&quot; height=&quot;163&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 작성한 글로벌 필터를 포함해서 로그가 총 6개가 찍힌 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties의 변수를 false로 설정하면, 해당하는 필터는 로그를 찍지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 스프링 클라우드 MSA를 공부해봤는데, 어려우면서도 재밌는 개념이라 공부를 하는데 즐겁게 할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 클라우드와 MSA의 개념은 매우 중요하고 많이 쓰이는 개념이기 때문에 앞으로도 잘 공부해야겠다는 생각이 들었다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/308</guid>
      <comments>https://spring-studyy.tistory.com/308#entry308comment</comments>
      <pubDate>Mon, 5 Aug 2024 16:40:26 +0900</pubDate>
    </item>
    <item>
      <title>SCG 라우팅 추가와 삭제</title>
      <link>https://spring-studyy.tistory.com/307</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Gateway에서 여러 서비스들을 라우팅하는데, /user, /order 기능 외에 다른 마이크로 서비스 기능이 생겼다고 가정할 때, 추가 시 동작을 멈추고 재시작이 아니라 동작하는 상태에서 라우팅을 추가하는 방식이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필수 의존성 - Spring Boot Actuator&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Actuator는 스프링 어플리케이션의 기능을 엔드 포인트로 제공하는 의존성으로, 가동중인 스프링 클라우드 게이트웨이에 새로운 라우팅을 추가 및 삭제할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722841355533&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080
spring.application.name=SCG

management.endpoint.gateway.enabled=true # 특정 엔드포인트를 사용할 것이지
management.endpoints.web.exposure.include=gateway # 어떤 항목을 사용할 것인지 - gateway&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 주입 후 위와 같이 application.properties를 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be9NGN/btsIVK654n0/OtOkZVuHKu7ZoFzeS1k0s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be9NGN/btsIVK654n0/OtOkZVuHKu7ZoFzeS1k0s1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be9NGN/btsIVK654n0/OtOkZVuHKu7ZoFzeS1k0s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe9NGN%2FbtsIVK654n0%2FOtOkZVuHKu7ZoFzeS1k0s1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;92&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 Eureka Server 등 아무런 설정을 하지 않았기 때문에 localhost:8080/actuator/gateway/routes로 접근할 때아무것도 뜨지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;1138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBPgiL/btsIUtd1OVi/J0yDdNEYKlrd1zybp4hGek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBPgiL/btsIUtd1OVi/J0yDdNEYKlrd1zybp4hGek/img.png&quot; data-alt=&quot;출처 : https://www.devyummi.com/page?id=668bb96a06cc3ded3bced8a8&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBPgiL/btsIUtd1OVi/J0yDdNEYKlrd1zybp4hGek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBPgiL%2FbtsIUtd1OVi%2FJ0yDdNEYKlrd1zybp4hGek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;735&quot; height=&quot;789&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;1138&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://www.devyummi.com/page?id=668bb96a06cc3ded3bced8a8&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우팅을 추가 및 삭제하는 명령어에 대해 정리해둔 블로그가 있어서 첨부했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MuLQT/btsIVHWU4Mn/wUdbvxZjRuUz1qi7XclGWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MuLQT/btsIVHWU4Mn/wUdbvxZjRuUz1qi7XclGWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MuLQT/btsIVHWU4Mn/wUdbvxZjRuUz1qi7XclGWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMuLQT%2FbtsIVHWU4Mn%2FwUdbvxZjRuUz1qi7XclGWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;219&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;postman에 위와 같이 url과 JSON의 body를 넣고, 요청을 보낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MUb26/btsIUhERqTb/wFmuXN1WqZeG8eJyvmhzU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MUb26/btsIUhERqTb/wFmuXN1WqZeG8eJyvmhzU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MUb26/btsIUhERqTb/wFmuXN1WqZeG8eJyvmhzU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMUb26%2FbtsIUhERqTb%2FwFmuXN1WqZeG8eJyvmhzU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;93&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;201 응답이 오면 성공이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTiehM/btsIUK0Tzqe/O2stKkpdPHOckkXNQSPCOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTiehM/btsIUK0Tzqe/O2stKkpdPHOckkXNQSPCOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTiehM/btsIUK0Tzqe/O2stKkpdPHOckkXNQSPCOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTiehM%2FbtsIUK0Tzqe%2FO2stKkpdPHOckkXNQSPCOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;422&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;914&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가한 뒤에 꼭 refresh를 POST 요청으로 보내고, 200 응답이 오면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1368&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nwmxg/btsIWioLddJ/WuA13z06Po0Plr11vG79l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nwmxg/btsIWioLddJ/WuA13z06Po0Plr11vG79l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nwmxg/btsIWioLddJ/WuA13z06Po0Plr11vG79l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnwmxg%2FbtsIWioLddJ%2FWuA13z06Po0Plr11vG79l1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;163&quot; data-origin-width=&quot;1368&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금 추가한 인스턴스가 라우팅에 추가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kkq49/btsITuYZumY/CHHHlqNrRbibNZrGHZWu5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kkq49/btsITuYZumY/CHHHlqNrRbibNZrGHZWu5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kkq49/btsITuYZumY/CHHHlqNrRbibNZrGHZWu5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKkq49%2FbtsITuYZumY%2FCHHHlqNrRbibNZrGHZWu5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;171&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제할 때에는 DELETE 요청을 보내면 되고, 이 때에도 refresh는 꼭 해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 서버를 무중지 상태로 라우팅을 추가할 수 있으며, 액츄에이터는 다른 사람이 외부에서 간단하게 조작할 수 있으므로 실 서비스 시에는 security 설정을 무조건 잘 해줘야 한다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/307</guid>
      <comments>https://spring-studyy.tistory.com/307#entry307comment</comments>
      <pubDate>Mon, 5 Aug 2024 16:20:44 +0900</pubDate>
    </item>
    <item>
      <title>SCG - Eureka 연동 및 로드밸런싱</title>
      <link>https://spring-studyy.tistory.com/306</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MSA는 부하가 걸리면 자동으로 sclae out을 하는 기능을 내부적으로 가진다. 그렇기 때문에 라우팅 테이블에서 auto sclaing 된 후의 ip 주소를 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCG와 연동된 Eureka Server가 SCG에 리스트를 보내줘서 작동을 돕는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722840101663&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' // 추가
	implementation 'org.springframework.boot:spring-boot-starter-webflux'
	implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'io.projectreactor:reactor-test' // WebFlux 테스트에 필요
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCG 프로젝트의 gradle에 eureka client로 동작할 수 있는 의존성을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722840203865&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080

eureka.client.register-with-eureka=true
# eureka server에 나를 등록할 것인가
eureka.client.fetch-registry=true
# eureka에 등록된 클라이언트들의 정보를 등록할 것인가
eureka.client.service-url.defaultZone=http://admin:password@localhost:8761/eureka&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 application.properties에 다음과 같은 설정을 추가해준다. 이전 포스팅에서 eureka client 설정으로 했던 것과 동일한 설정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2716&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WvZpy/btsIUUvzI0G/Sj3lcgPiKitJNaMNpWgikk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WvZpy/btsIUUvzI0G/Sj3lcgPiKitJNaMNpWgikk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WvZpy/btsIUUvzI0G/Sj3lcgPiKitJNaMNpWgikk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWvZpy%2FbtsIUUvzI0G%2FSj3lcgPiKitJNaMNpWgikk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;101&quot; data-origin-width=&quot;2716&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eureka Server 대시보드에 들어가보면 8081 포트와 8082 포트는 같은 비즈니스 로직을 수행하므로 이름을 ms1으로 동일하게 설정해서, 2개가 띄워졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 아래 SCG도 client로 포함되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722840566691&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080
spring.application.name=SCG

spring.cloud.gateway.routes[0].id=ms1
spring.cloud.gateway.routes[0].predicates[0].name=Path
spring.cloud.gateway.routes[0].predicates[0].args.pattern=/ms1/**
spring.cloud.gateway.routes[0].uri=lb://MS1

eureka.client.register-with-eureka=true
# eureka server에 나를 등록할 것인가
eureka.client.fetch-registry=true
# eureka에 등록된 클라이언트들의 정보를 등록할 것인가
eureka.client.service-url.defaultZone=http://admin:password@localhost:8761/eureka&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런싱을 위해 추가 설정을 진행했다. 이전에 진행한 라우팅 설정에서 uri를 살짝 변경해줬는데, 이전에는 http://localhost:8081 같은 경로였는데, 이번에는 Eureka 대시보드에 이름으로 지정된 MS1 이라는 어플리케이션으로 라우팅한다는 의미로 lb://MS1으로 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ms1의 마이크로 서비스&lt;/p&gt;
&lt;pre id=&quot;code_1722840843211&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@RestController
public class HomeController {

    @GetMapping(&quot;/ms1/first&quot;)
    public String home() {
        return &quot;ms1&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ms2의 마이크로 서비스&lt;/p&gt;
&lt;pre id=&quot;code_1722840852826&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@RestController
public class HomeController {

    @GetMapping(&quot;/ms1/first&quot;)
    public String home() {
        return &quot;ms2&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 2개의 마이크로 서비스를 같은 경로로 해둔 다음에 응답을 다르게 해두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AaX05/btsIUEfsw45/or6nTIDKlFmT6yckyF6NSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AaX05/btsIUEfsw45/or6nTIDKlFmT6yckyF6NSk/img.png&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;212&quot; data-is-animation=&quot;false&quot; style=&quot;width: 55.4973%; margin-right: 10px;&quot; data-widthpercent=&quot;56.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AaX05/btsIUEfsw45/or6nTIDKlFmT6yckyF6NSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAaX05%2FbtsIUEfsw45%2For6nTIDKlFmT6yckyF6NSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;822&quot; height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diVFuH/btsIVGXZeEg/nCHmjD257Me3EvpLfmZOY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diVFuH/btsIVGXZeEg/nCHmjD257Me3EvpLfmZOY0/img.png&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;286&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;43.85&quot; style=&quot;width: 43.3399%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diVFuH/btsIVGXZeEg/nCHmjD257Me3EvpLfmZOY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiVFuH%2FbtsIVGXZeEg%2FnCHmjD257Me3EvpLfmZOY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;866&quot; height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:8080/ms1/first로 접근하면, ms1, ms2가 번갈아가며 나온다. 이를 통해 다른 경로의 라우팅 뿐만 아니라 sclae out에 따른 로드밸런싱까지 구현을 완료했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 MSA 환경을 구성하면 AWS의 auto scaling 및 로드 밸런싱을 진행하게 될건데, 비용 등의 이유로 실제로 해보지는 않겠지만 spring cloud의 동작 원리를 로컬에서라도 작동시켜봤다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/306</guid>
      <comments>https://spring-studyy.tistory.com/306#entry306comment</comments>
      <pubDate>Mon, 5 Aug 2024 15:55:50 +0900</pubDate>
    </item>
    <item>
      <title>스프링 클라우드 게이트웨이(SCG)</title>
      <link>https://spring-studyy.tistory.com/305</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Spring Cloud Gateway&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 클라우드 MSA 환경에서 가장 앞단에 존재하며 클라이언트로부터 요청을 받고 적절하게 서버에 보내준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 앞단에서 항상 무중지 상태로 모든 요청을 받기에 잘 신경써야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 부트 어플리케이션, Eureka Server, Config와 같은 서비스는 블로킹 기반으로 톰캣 엔진을 통한 로직을 수행했지만, Gateway는 비즈니스 로직을 처리하기 보다는 단순하게 거쳐가는 라우팅 역할을 하기 때문에 논 블로킹 방식으로 구성되며 &lt;b&gt;WebFlux와 Netty&lt;/b&gt;를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WebFlux는 기존 스프링 부트에서 사용하는 JPA와 같은 블로킹 방식의 의존성을 모두 사용하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필수 의존성 - Spring Cloud Routing의 Gateway&lt;/p&gt;
&lt;pre id=&quot;code_1722839202893&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-webflux'
	implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'io.projectreactor:reactor-test' // WebFlux 테스트에 필요
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle의 의존성은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SCG의 라우팅 방법&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;application.properties 설정&lt;/li&gt;
&lt;li&gt;application.yml 설정&lt;/li&gt;
&lt;li&gt;Config 클래스 설정&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2730&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n4jzM/btsIVFSfNaM/LKP1Jct55lcg2wRRn3twkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n4jzM/btsIVFSfNaM/LKP1Jct55lcg2wRRn3twkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n4jzM/btsIVFSfNaM/LKP1Jct55lcg2wRRn3twkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn4jzM%2FbtsIVFSfNaM%2FLKP1Jct55lcg2wRRn3twkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2730&quot; height=&quot;402&quot; data-origin-width=&quot;2730&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;client를 MS1, MS2로 각각 8081 포트, 8082 포트로 설정한 다음에 8081/ms1/first, 8082/ms2/second 경로를 설정해두었다. 이제 8081, 8082 포트가 아니라 8080 포트로 접근해도 알아서 라우팅해주는 gateway를 만들 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. SCG - application.properties &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1722837979000&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8080

# 라우팅은 index로 0번부터 지정
spring.cloud.gateway.routes[0].id=ms1 # 이름
spring.cloud.gateway.routes[0].predicates[0].name=Path # Path 방식
spring.cloud.gateway.routes[0].predicates[0].args.pattern=/ms1/** # 경로
spring.cloud.gateway.routes[0].uri=http://localhost:8081 # 해당하는 포트

spring.cloud.gateway.routes[1].id=ms2
spring.cloud.gateway.routes[1].predicates[0].name=Path
spring.cloud.gateway.routes[1].predicates[0].args.pattern=/ms2/**
spring.cloud.gateway.routes[1].uri=http://localhost:8082&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCG의 application.properties의 port를 8080으로 지정하고, 아래에 spring.cloud.gateway.routes를 이용해서 하나는 8081 포트로, 하나는 8082 포트로 PATH를 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/niuS6/btsIUjo4a4k/vGzmVmN6kCwK84JluSuCuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/niuS6/btsIUjo4a4k/vGzmVmN6kCwK84JluSuCuk/img.png&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;198&quot; data-is-animation=&quot;false&quot; style=&quot;width: 46.9515%; margin-right: 10px;&quot; data-widthpercent=&quot;47.5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/niuS6/btsIUjo4a4k/vGzmVmN6kCwK84JluSuCuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FniuS6%2FbtsIUjo4a4k%2FvGzmVmN6kCwK84JluSuCuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rREL7/btsIUicEINh/9PgGFAOnyO5zuGQvrbg0PK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rREL7/btsIUicEINh/9PgGFAOnyO5zuGQvrbg0PK/img.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;180&quot; data-is-animation=&quot;false&quot; style=&quot;width: 51.8857%;&quot; data-widthpercent=&quot;52.5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rREL7/btsIUicEINh/9PgGFAOnyO5zuGQvrbg0PK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrREL7%2FbtsIUicEINh%2F9PgGFAOnyO5zuGQvrbg0PK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;868&quot; height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8080 포트는 gateway로서의 설정만 했음에도, 8080/ms1/first, 8080/ms2/second로 요청을 보내면 404 Not Found가 아니라 응답을 한다. 이로 인해 8081 포트와 8082 포트로 라우팅을 한다는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. SCG - application.yml&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1722838941818&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
        - id: ms1
          uri: http://localhost:8081
          predicates:
            - Path=/ms1/**
        - id: ms2
          uri: http://localhost:8082
          predicates:
            - Path=/ms2/**&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml은 다음과 같이 설정하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Config 클래스 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 application.properties나 application.yml 파일에서 포트 번호를 제외하고 나머지는 삭제한다.&lt;/p&gt;
&lt;pre id=&quot;code_1722839398271&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class CustomRoute {

    @Bean
    public RouteLocator ms1Route(RouteLocatorBuilder builder) {

        return builder.routes()
                .route(&quot;ms1&quot;, r -&amp;gt; r.path(&quot;/ms1/**&quot;)
                        .uri(&quot;http://localhost:8081&quot;))
                .route(&quot;ms2&quot;, r -&amp;gt; r.path(&quot;/ms2/**&quot;)
                        .uri(&quot;http://localhost:8082&quot;))
                .build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 @Configuration 어노테이션을 통해서 라우팅을 빈으로 등록해주면 위와 같이 라우팅이 동작한다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/305</guid>
      <comments>https://spring-studyy.tistory.com/305#entry305comment</comments>
      <pubDate>Mon, 5 Aug 2024 15:38:56 +0900</pubDate>
    </item>
    <item>
      <title>Eureka Client 등록 설정</title>
      <link>https://spring-studyy.tistory.com/304</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Eureka Client는 마이크로 서비스로 실행되는 각각의 스프링 서버가 Eureka Server로 관리되기 위해 설정을 통해 client로 작동하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 MSA를 생각하면 떠오르는 각각의 기능을 수행하는 서버로 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle&lt;/p&gt;
&lt;pre id=&quot;code_1722835056457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ext {
	set('springCloudVersion', &quot;2022.0.4&quot;)
}


dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
	implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' // eureka client
}

dependencyManagement {
	imports {
		mavenBom &quot;org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}&quot;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eureka client 의존성을 추가해주고, Eureka client는 스프링 클라우드에서 동작하기 때문에 ext와 dependencyManagement까지 추가해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main class&lt;/p&gt;
&lt;pre id=&quot;code_1722835185116&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootApplication
@EnableDiscoveryClient // Eureka client 어노테이션
public class Ms1Application {

	public static void main(String[] args) {
		SpringApplication.run(Ms1Application.class, args);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 클래스에 @EnableDiscoveryClient 어노테이션을 붙여서 Eureka client로 동작할 수 있게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties&lt;/p&gt;
&lt;pre id=&quot;code_1722835267174&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;eureka.client.register-with-eureka=true
#유레카 서버에 등록할지 여부
eureka.client.fetch-registry=true
#유레카 서버의 정보를 가져올지 여부
eureka.client.service-url.defaultZone=http://admin:password@localhost:8761/eureka
#유레카 서버 주소 (eureka.client.service-url.defaultZone=http://아이디:비밀번호@아이피:8761/eureka&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties에 다음과 같은 설정을 추가해줬는데, 차례대로 유레카 서버에 등록할지 여부, 유레카 서버의 정보를 가져올지 여부, 유레카 서버에 접근하기 위한 연결 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2738&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeBLJ9/btsIS7pq2tM/fR8vq1dRSW9aFt2tLM60eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeBLJ9/btsIS7pq2tM/fR8vq1dRSW9aFt2tLM60eK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeBLJ9/btsIS7pq2tM/fR8vq1dRSW9aFt2tLM60eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeBLJ9%2FbtsIS7pq2tM%2FfR8vq1dRSW9aFt2tLM60eK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2738&quot; height=&quot;314&quot; data-origin-width=&quot;2738&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정을 마치고 프로그램을 실행시켜주면, ms1이라는 이름으로 유레카 서버에 뜨게 된다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/304</guid>
      <comments>https://spring-studyy.tistory.com/304#entry304comment</comments>
      <pubDate>Mon, 5 Aug 2024 14:39:49 +0900</pubDate>
    </item>
    <item>
      <title>Eureka 서버 구축</title>
      <link>https://spring-studyy.tistory.com/303</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅들에서는 스프링 서버에서 공통으로 사용하는 Config Repository와 Config Server에 대해 설명했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에는 각각의 서버가 얼마나 켜져있는지, 어떤 상황인지를 모니터링할 수 있는 Eureka 서버에 대해서 알아볼 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Eureka 서버의 역할&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA를 구성하는 마이크로 서비스들을 모니터링하는 역할&lt;/li&gt;
&lt;li&gt;스프링 클라우드 Gateway에게 마이크로 서비스들을 알려주는 역할&lt;/li&gt;
&lt;li&gt;부하에 따라 자동으로 sclae out 되어도 Gateway에게 그 목록을 알려주는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 생성시 필수 의존성 - Eureka Server, Spring Security&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main Class&lt;/p&gt;
&lt;pre id=&quot;code_1722833327066&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootApplication
@EnableEurekaServer // Eureka Server를 위한 어노테이션
public class EurekaServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 의존성이 전부 주입되었으면, 메인 클래스에 @EnableEurekaServer 어노테이션을 붙여서 Eureka Server로 동작할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties&lt;/p&gt;
&lt;pre id=&quot;code_1722833389111&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties에도 위와 같이 설정을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 port 번호는 8761번 port를 사용한다. 아래의 설정은 Eureka Server가 자기 자신을 등록하는 것을 방지해주는 설정과 client에 대한 fetch registry의 false에 대한 설정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SecurityConfig&lt;/p&gt;
&lt;pre id=&quot;code_1722833568607&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean // 비밀번호 암호화
    public BCryptPasswordEncoder bCryptPasswordEncoder() {

        return new BCryptPasswordEncoder();
    }

    @Bean // http - security 관련 설정들
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .csrf((auth) -&amp;gt; auth.disable());

        http
                .authorizeHttpRequests((auth) -&amp;gt; auth.anyRequest().authenticated());

        http
                .httpBasic(Customizer.withDefaults());


        return http.build();
    }

    @Bean // 서버 접속은 간단하게 하기 위해 인메모리로 저장
    public UserDetailsService userDetailsService() {

        UserDetails user1 = User.builder()
                .username(&quot;admin&quot;)
                .password(bCryptPasswordEncoder().encode(&quot;password&quot;))
                .roles(&quot;ADMIN&quot;)
                .build();

        return new InMemoryUserDetailsManager(user1);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 Eureka Server의 보안을 위한 SecurityConfig 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2738&quot; data-origin-height=&quot;1636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B9GYy/btsITS58WbM/wnLjFGnFnjzl3cm7nM2Wy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B9GYy/btsITS58WbM/wnLjFGnFnjzl3cm7nM2Wy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B9GYy/btsITS58WbM/wnLjFGnFnjzl3cm7nM2Wy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB9GYy%2FbtsITS58WbM%2FwnLjFGnFnjzl3cm7nM2Wy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;346&quot; data-origin-width=&quot;2738&quot; data-origin-height=&quot;1636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링을 실행하고 8761에 접속해서 admin, password를 입력하면 위와 같이 Eureka Server가 뜬다. 아직 스프링 어플리케이션이 없지만, Eureka Server의 대시보드를 띄웠고, 다음 포스팅에서 Eureka Server에 등록할 클라이언트를 공부하도록 하겠다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/303</guid>
      <comments>https://spring-studyy.tistory.com/303#entry303comment</comments>
      <pubDate>Mon, 5 Aug 2024 13:57:27 +0900</pubDate>
    </item>
    <item>
      <title>Config 클라이언트 구축</title>
      <link>https://spring-studyy.tistory.com/302</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에 Config 리포지토리와 서버를 구성했다. Config 서버에서 Config 리포지토리의 데이터를 받아오는 것까지 완료했으니, Config 서버에 접속해서 가져올 수 있도록 스프링 어플리케이션에 Config 클라이언트를 구성해야할 차례이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmpBGz/btsIUe8Bwbb/KkkXVbk2ZjcbmQ1FHf7Nmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmpBGz/btsIUe8Bwbb/KkkXVbk2ZjcbmQ1FHf7Nmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmpBGz/btsIUe8Bwbb/KkkXVbk2ZjcbmQ1FHf7Nmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmpBGz%2FbtsIUe8Bwbb%2FKkkXVbk2ZjcbmQ1FHf7Nmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;129&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Config Client도 관련 의존성을 주입 받아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/09o8f/btsIUkVhcDr/v0sy0HRhaqGpdIaPjKSg1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/09o8f/btsIUkVhcDr/v0sy0HRhaqGpdIaPjKSg1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/09o8f/btsIUkVhcDr/v0sy0HRhaqGpdIaPjKSg1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F09o8f%2FbtsIUkVhcDr%2Fv0sy0HRhaqGpdIaPjKSg1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;94&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties에 Config 깃허브 Repository의 이름, 환경을 넣어주고 spring.config.import에 configServer에 대한 정보를 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpBqvC/btsIVa5uOKg/O08wBz3kvJQlXUny2jSAaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpBqvC/btsIVa5uOKg/O08wBz3kvJQlXUny2jSAaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpBqvC/btsIVa5uOKg/O08wBz3kvJQlXUny2jSAaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpBqvC%2FbtsIVa5uOKg%2FO08wBz3kvJQlXUny2jSAaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;122&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8080 포트에 접근하면 test라고 설정해둔 메시지가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Config Repository와 Config Server에 접근해서 8080 포트로 연결한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2174&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ySsor/btsITu48CnN/9qj3MYzHDvZ8Scblz7UpJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ySsor/btsITu48CnN/9qj3MYzHDvZ8Scblz7UpJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ySsor/btsITu48CnN/9qj3MYzHDvZ8Scblz7UpJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FySsor%2FbtsITu48CnN%2F9qj3MYzHDvZ8Scblz7UpJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;122&quot; data-origin-width=&quot;2174&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션 설정파일이 아니라 Config Repository에서 포트를 8081로 변경하면 아래처럼 8081에 서버가 띄워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgG2HZ/btsIUe8BFBD/dK9bYXdrSJxWasBKa3HYT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgG2HZ/btsIUe8BFBD/dK9bYXdrSJxWasBKa3HYT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgG2HZ/btsIUe8BFBD/dK9bYXdrSJxWasBKa3HYT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgG2HZ%2FbtsIUe8BFBD%2FdK9bYXdrSJxWasBKa3HYT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;129&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 환경에서 여러 서버들을 파일 하나로 통제할 수 있다는 장점이 있다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/302</guid>
      <comments>https://spring-studyy.tistory.com/302#entry302comment</comments>
      <pubDate>Sun, 4 Aug 2024 17:58:25 +0900</pubDate>
    </item>
    <item>
      <title>Config Server 설정</title>
      <link>https://spring-studyy.tistory.com/301</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에서 Config Repository를 구축했는데, 여기서 데이터를 받아서 각각의 스프링 서버로 보낼 수 있도록 도와주는 Spring Config Server를 설정해볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring 초기 세팅을 할 때 Spring Cloud Config의 Config Server와 Spring Security에 대한 의존성은 필수로 추가해야 한다. 이후의 의존성에 대한 세팅은 자유이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필수 의존성 - Config Server, Spring Security&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ejip6/btsITOClrGG/KCjRrWgh0nt8E9PpdSkfOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ejip6/btsITOClrGG/KCjRrWgh0nt8E9PpdSkfOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ejip6/btsITOClrGG/KCjRrWgh0nt8E9PpdSkfOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjip6%2FbtsITOClrGG%2FKCjRrWgh0nt8E9PpdSkfOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1742&quot; height=&quot;326&quot; data-origin-width=&quot;1742&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 설정 완료 시 가장 먼저 main 클래스에 @EnableConfigServer 어노테이션을 붙여준다. 이 어노테이션을 통해서 ConfigServer로 동작이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HLJVD/btsIUrUafpl/d7EPKghAyV05U7YBevEWvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HLJVD/btsIUrUafpl/d7EPKghAyV05U7YBevEWvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HLJVD/btsIUrUafpl/d7EPKghAyV05U7YBevEWvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHLJVD%2FbtsIUrUafpl%2Fd7EPKghAyV05U7YBevEWvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;380&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.properties에서 config server 관련 설정을 해주는데, 보통 config 서버는 9000으로 동작하기에 server.port는 9000으로 지정해줬다. 아래에는 깃허브의 주소, 설정, 접근을 위한 private key를 지정해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(properties 파일은 줄바꿈을 인식 못하기에 \n\으로 줄바꿈을 해준다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722759274339&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .csrf((auth) -&amp;gt; auth.disable());

        http
                .authorizeHttpRequests((auth) -&amp;gt; auth.anyRequest().authenticated());

        http
                .httpBasic(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {

        UserDetails user1 = User.builder()
                .username(&quot;admin&quot;)
                .password(bCryptPasswordEncoder().encode(&quot;password&quot;))
                .roles(&quot;ADMIN&quot;)
                .build();

        return new InMemoryUserDetailsManager(user1);
        // 간단하게 하기 위해서 DB에 연결하지 않고 인메모리에 저장
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 클라우드는 보안이 중요하기 때문에 security를 무조건 설정해줘야 한다. 위에 처럼 Security Config를 만들어서 스프링 빈으로 등록해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 Config 깃허브 Repository에 ms1-dev.properties라는 파일을 만들었는데, 이름을 그냥 지정한 것이 아니라 정해진 규칙에 따라 지정한 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름-환경.properties와 이름-환경.yml 파일에 있는 정보에 접근하기 위해 /이름/환경이라는 엔드포인트로 요청을 보내면 데이터를 받아올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cndrlC/btsISrVLSQS/0Ge8AubvVrskpb5vccKvrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cndrlC/btsISrVLSQS/0Ge8AubvVrskpb5vccKvrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cndrlC/btsISrVLSQS/0Ge8AubvVrskpb5vccKvrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcndrlC%2FbtsISrVLSQS%2F0Ge8AubvVrskpb5vccKvrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;235&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:9000/ms1/dev에 접근했더니, 관련 정보가 나오는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 source에 server.port밖에 없지만, Config Repository 파일에 더 많이 추가하면 source에 다른 요소들이 추가된다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/301</guid>
      <comments>https://spring-studyy.tistory.com/301#entry301comment</comments>
      <pubDate>Sun, 4 Aug 2024 17:20:47 +0900</pubDate>
    </item>
    <item>
      <title>Config 깃허브 Repository 구축</title>
      <link>https://spring-studyy.tistory.com/300</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 MSA 환경에서 공통으로 사용할 환경변수들이 지정된 Config Repository가 필요하다고 했었는데, 깃허브 리포지토리로 Config Repository를 구축할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wzEWB/btsITWtwm7P/ihaHxoaoP8GnIQFegbpaK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wzEWB/btsITWtwm7P/ihaHxoaoP8GnIQFegbpaK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wzEWB/btsITWtwm7P/ihaHxoaoP8GnIQFegbpaK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwzEWB%2FbtsITWtwm7P%2FihaHxoaoP8GnIQFegbpaK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;210&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리포지토리를 만들고 properties 파일을 하나 만들어준다. 이제 서버들에서 리포지토리를 사용할 수 있도록 키를 만들어줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속하는 방법은 비대칭 키를 생성해서 public 키는 깃허브 리포지토리에 등록하고, Spring Config Server에서 private 키를 통해 접근한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1gcIE/btsIUs6A6N8/c96SG1MvKJJOklfs2vtld0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1gcIE/btsIUs6A6N8/c96SG1MvKJJOklfs2vtld0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1gcIE/btsIUs6A6N8/c96SG1MvKJJOklfs2vtld0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1gcIE%2FbtsIUs6A6N8%2Fc96SG1MvKJJOklfs2vtld0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;413&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에 위와 같은 명령어를 입력해서 키를 생성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5t1cO/btsISVIQ612/WZHmlpVwOxHzLYG6ajuyFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5t1cO/btsISVIQ612/WZHmlpVwOxHzLYG6ajuyFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5t1cO/btsISVIQ612/WZHmlpVwOxHzLYG6ajuyFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5t1cO%2FbtsISVIQ612%2FWZHmlpVwOxHzLYG6ajuyFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1356&quot; height=&quot;110&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 경로에 키가 생성되었다. 여기서 pulbic 키의 내용을 복사해서 깃허브 리포지토리에 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2484&quot; data-origin-height=&quot;1202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yANqX/btsITucYQwL/Mqf79qmuL2fCnzyzdhijx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yANqX/btsITucYQwL/Mqf79qmuL2fCnzyzdhijx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yANqX/btsITucYQwL/Mqf79qmuL2fCnzyzdhijx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyANqX%2FbtsITucYQwL%2FMqf79qmuL2fCnzyzdhijx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;340&quot; data-origin-width=&quot;2484&quot; data-origin-height=&quot;1202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Settings &amp;gt; Deploy keys &amp;gt; Add deploy key로 키를 등록해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2490&quot; data-origin-height=&quot;1186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTDZFP/btsIVjBiylA/kq3qWrF58MEsEp0iqrbOjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTDZFP/btsIVjBiylA/kq3qWrF58MEsEp0iqrbOjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTDZFP/btsIVjBiylA/kq3qWrF58MEsEp0iqrbOjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTDZFP%2FbtsIVjBiylA%2Fkq3qWrF58MEsEp0iqrbOjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;307&quot; data-origin-width=&quot;2490&quot; data-origin-height=&quot;1186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public key의 내용을 입력했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 Spring Config Server에서 private key를 가지고 여기에 접근하면 되고, 이에 대한 내용은 다음 포스팅에서 이어질 것이다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/300</guid>
      <comments>https://spring-studyy.tistory.com/300#entry300comment</comments>
      <pubDate>Sun, 4 Aug 2024 15:33:59 +0900</pubDate>
    </item>
    <item>
      <title>스프링 클라우드 MSA</title>
      <link>https://spring-studyy.tistory.com/299</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;모놀로식 개발 vs MSA 개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모놀로식 개발은 프로젝트에서 흔히 사용하는 모든 기능들이 하나의 서버로 동작하는 방식이다. 이 방식은 간편하지만, 오류 발생 시 모든 기능이 사용 불가능하다는 단점과 하나의 프레임워크로만 개발되어야 한다는 단점이 존재한다. 때문에, MSA 구조의 개발에 대한 관심이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;MSA의 장점&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;하나의 기능에서 오류가 발생해도 나머지 기능 사용 가능&lt;/li&gt;
&lt;li&gt;언어, 프레임워크를 기능별로 다르게 사용 가능(스프링과 express 등)&lt;/li&gt;
&lt;li&gt;서비스별 스케일링 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 장점만 존재하지는 않고, 초기에 구축하기 어려우며 분산 관리가 힘들다는 단점도 존재하긴 하지만, 그럼에도 불구하고 장점이 명확하기에 MSA를 공부하게 되었다.&lt;span style=&quot;background-color: #f0f0f0; color: #000000; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1842&quot; data-origin-height=&quot;1060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5tvmN/btsIUgk0BJO/VHMqVHObPoD4uVwbyKGK0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5tvmN/btsIUgk0BJO/VHMqVHObPoD4uVwbyKGK0k/img.png&quot; data-alt=&quot;사진 출처 : 스프링 클라우드 MSA 유튜브 강의 (강의자 : 개발자 유미)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5tvmN/btsIUgk0BJO/VHMqVHObPoD4uVwbyKGK0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5tvmN%2FbtsIUgk0BJO%2FVHMqVHObPoD4uVwbyKGK0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;609&quot; height=&quot;350&quot; data-origin-width=&quot;1842&quot; data-origin-height=&quot;1060&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사진 출처 : 스프링 클라우드 MSA 유튜브 강의 (강의자 : 개발자 유미)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 클라우드 MSA의 구성 환경에 대한 그림이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 스프링 부트 서버는 해당하는 요청을 받아서 로직을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Spring Cloud Gateway(SCG)&lt;/b&gt;는 요청에 해당하는 서버로 요청을 보내게 된다. 예를 들어서 /user로 요청이 왔다면, 해당하는 컨트롤러의 서버에 요청을 보내주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Eureka Server&lt;/b&gt;는 각각의 스프링부트 서버와 Gateway의 상태를 모니터링할 수 있는 서버이다. 여기에는 등록되어 있는 모든 서버의 정보가 뜨며, 각각의 서버에서 등록을 시켜주면 Eureka Client가 생긴다. 추가적으로 Spring Cloud Gateway에 요청을 분배하는 로드밸런싱 역할도 한다. 스프링 MSA는 scale out이 자동으로 이루어지는데, 부하가 커졌을 때 새로운 ip 주소를 SCG에 알려주는 역할을 Eureka Server가 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml나 공통으로 사용되는 것들을 제공해주는 &lt;b&gt;Spring Config Server&lt;/b&gt;가 뒷단에 존재해, 특정 서버의 Config Client에 데이터를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수들은 Spring Config Server에 들어있지 않고 여기는 서빙만 해주는데, 뒤에 있는 &lt;b&gt;Config Repository&lt;/b&gt;라는 곳에 데이터가 있다. 보통 깃허브 리포지토리, redis와 같은 저장소를 사용한다. 여기서 특정 변수값을 수정하면 모든 서버에서 수정된 변수를 사용할 수 있다.&lt;/p&gt;</description>
      <category>스프링/스프링 클라우드 MSA</category>
      <author>chanhee01</author>
      <guid isPermaLink="true">https://spring-studyy.tistory.com/299</guid>
      <comments>https://spring-studyy.tistory.com/299#entry299comment</comments>
      <pubDate>Sun, 4 Aug 2024 15:03:23 +0900</pubDate>
    </item>
  </channel>
</rss>