Sangil's blog

https://github.com/ChoiSangIl Admin

Docker 재미있는 논쟁(Docker Eureka Client detect exposed ports) DEV / DOCKER

2022-05-07 posted by sang12


https://github.com/moby/moby/issues/3778

도커에서는 왜? 내부 컨테이너에서 외부로 동적으로 열린 포트정보를 가져올 수 없나에 대한 논쟁이다.

MSA를 공부하던중, Eureka Client를 아래와 같이 동적 포트로 여러개 올려 Eureka에 client를 등록하고 싶었다.

하지만, 올라간 Client입장에서 등록할 수 있는 ip는 내부 스프링어플리케이션 설정에 따른 server.port=8080 이였다.

결과적으로 여러개를 등록하면 동일한 포트로 유레카에 동일하게 등록이 된다.

허면 어플리케이션 입장에서는 어떻게 도커가 외부적으로 랜덤으로 만든 포트를 알아내서 해당 포트로 유레카에 등록 할 수 있을까?

결과적으로 해당 이슈 게시물을 보면 도커에서 공식적으로 지원해주는 방법은 없는 거 같다.

해결 할 수 있는 가장 간단한 방법으로는 아래와 같이 명시한 포트를 환경변수로 넘겨줘서, Spring Boot에서 해당 Port를 받아 유레카에 등록하는 것이다.

docker run -P 40015:8080 -e PORT=40015 myImage

하지만 이렇게 하면 컨테이너를 올릴때마다 포트를 지정해주는 작업등을 해야 할것이다...

그럼 더 좋은 방법은 무엇일까

스크립트로 사용가능한 포트를 찾고 해당 포트를 넘겨주는 방법이다. (https://github.com/moby/moby/issues/3778) 해당 게시물 중간에 보면 

NullHypothesis 이란 분이 올려놓은 스크립트를 참고하면 될거같다. 그리고 참고로 AWS에서는 스프링 어플리케이션단에서 외부에서 열려있는 정보를 가져올 수 있는거 같다.

아.. 또 1가지 방법으로는 도커 컨테이너가 올라가면 해당 ip, port정보를 공유 Volume에 저장해두고, 해당 어플리케이션에서 Volume의 정보를 가져와서 유레카에 등록하는 방법도 있다.!

어쨋거나.. 깔끔한 방법은 없는거 같다.

일단 공부하는 거니... docker-compose로 포트를 여러개 지정해서 올리는 방법으로 해야겠다..^^

#Eureka Client Docker external port
REPLY

Spring Boot RestTemplate 테스트(MockServer) DEV / WEB

2021-12-30 posted by sang12


Spring Boot에서 RestTemplate 호출(PUT)을 테스트하는 방법은 아래와 같다. 

RestTemplate객체를 MockServer의 인자값으로 넘겨 RestTemplate Mock서버를 만들어주고

호출하는 URL과 리턴받을 값을 설정 해준다. 그리고 RestTemplate로 호출해주면 된다.

PUT 메서드를 호출하려고 하니 template.put으로 호출하면 결과 값을 받아오지 못해서 exchange 함수를 사용하였다.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;

import java.net.URI;
import java.net.URISyntaxException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.client.ExpectedCount;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;

@SpringBootTest
public class OrderServiceImplTest {

	@Autowired
	private RestTemplate template;

	private MockRestServiceServer mockServer;

	@BeforeEach
	public void init() throws URISyntaxException {
		mockServer = MockRestServiceServer.createServer(template);
		mockServer.expect(ExpectedCount.once(), 
		          requestTo(new URI("http://localhost:8083/product/stock/order")))
		          .andExpect(method(HttpMethod.PUT))
		          .andRespond(withStatus(HttpStatus.OK)
		          .contentType(MediaType.APPLICATION_JSON)
		          .body("minus stock..."));            
	}

	@Test
	public void testOrder() throws URISyntaxException {
	    HttpHeaders headers = new HttpHeaders();
	    headers.setContentType(MediaType.APPLICATION_JSON);
	    HttpEntity<String> entity = new HttpEntity<String>("", headers); 

	    ResponseEntity<String> response = template.exchange("http://localhost:8083/product/stock/order", HttpMethod.PUT, entity, String.class);
	    assertEquals("minus stock...", response.getBody());
	}
}

* 그리고 Autowried를 사용하여 RestTemplate 객체를 di 받아 왔는데 굳이 테스트를 위해 스프링을 올려가며 받아 와야 하나 싶다. 그래서 @Autowried 어노테이션을 제거하고 직접 RestTemplate객체를 생성하여 넣어주고 @SpringBootTest 어노테이션도 제거했다.

template = new RestTemplate();
mockServer = MockRestServiceServer.bindTo(template).build();

REPLY

쓰레기 줍기 리펙터링 DEV / SEED

2021-12-01 posted by sang12


"코드를 파악하던 중에 일을 비효율적으로 처리하는 모습을 발견할 때가 있다."

"리팩토링 해야할 곳이 보이는데.. 하려던 작업과 관련 없는 일에 너무 많은 시간을 빼앗기긴 싫을 때"

"간단한 수정은 즉시 고치고, 시간이 좀 걸리는 일은 짧은 메모를 남긴 다음, 하던 일을 끝내고 나서 처리한다"

"캠핑 규칙이 제안하듯, 항상 처음 봤을 때보다 깔끔하게 정리하고 떠나자"

출처: 리팩터링 2판 저자:마틴 파울러 아저씨... 재밌는 아저씨네 

REPLY