04/26~04/30
# 기술스택 조사, 적용 예제 생성
- Spring boot 사용해 웹 프로젝트 만들어보기
- Eureka server에 client 2개 생성
- serviceA / serviceB 생성했으나 동시에 띄워지지 않음.
- 포트번호 다르게 설정해 해결
- 포트번호 : 한 컴퓨터 내에서 서비스를 구별하는 식별자. ip주소는 어떤 컴퓨터로 보내는지 식별하는 주소.
- get방식으로 msg입력/출력하는 rest방식 서비스 생성
05/06~05/07
# 해당 서비스를 2개로 분리
- 유레카 사용x. RestTemplate 사용 예제 만들기
- serviceA : 메시지 입력, serviceB 호출, 메시지 전달
- serviceB : 메시지 출력(로그 출력)
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder
.requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
.setConnectTimeout(Duration.ofMillis(5000))
.setReadTimeout(Duration.ofMillis(5000))
.additionalMessageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")))
.build();
}
@Autowired
public RestTemplate rest;
-> serviceB 실행 안 해놓고 serviceA 호출해서 계속 에러남....! serviceB 실행해 해결
# 해당 서비스 유레카 사용해 서버/클라이언트 생성
- server 띄움, 클라이언트 2개(서비스 a,b 만들어 서로 호출) 생성
- service-a : get방식으로 msg 받아서 service-b로 전달, 호출
- service-b : a가 전달한 링크에 입력된 메시지 + 자체 메시지 리턴
- service-a : service-b 에서 받은 메시지들 + 자체 메시지 화면에 출력 예정
- ribbon 사용방법
- @LoadBalanced 사용해 RestTemplate에 리본 적용 : @LoadBalanced 애노테이션을 추가하면 스프링 클라우드는 RestTemplate에 Ribbon을 인식할 수 있는 로드밸런싱 인터셉터를 적용한다.
@SpringBootApplication
@EnableDiscoveryClient
public class SendingClientApplication {
public static void main(String[] args) {
SpringApplication.run(SendingClientApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
- 한 서비스 2개 인스턴스 만드는 방법
- 프로젝트 우클릭 > run as > run configuration > 프로젝트 복사(duplicate) > arguments > vmarguments > -D수정사항=블라블라
- -Dserver.port=8802 / -Dspring.application.name=service-b2 등
- 두 인스턴스 중 무엇이 호출 됐는지 보는 방법
- 어느 플젝 콘솔에 메시지가 찍혔는가 확인
- @Value(${}) 로 .properties의 설정값 가져와 찍어보기
로그 찍기
private final Logger logger = (Logger) LoggerFactory.getLogger(this.getClass());
@GetMapping("/healthcheck")
public String checkState(@RequestParam("msg")String msg) {
logger.info("메시지 : "+msg + "포트번호 : " + portnum);
return " 메시지 : " + msg + " & 포트번호 : " + portnum;
}
- 유레카 서버에 클라이언트 로드 시간이 약 30초. 바로 클라이언트가 띄워지는 것이 아니다!
- HTTP status code
1xx (정보): 요청을 받았으며 프로세스를 계속한다
2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다
200(성공): 서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다.
201(작성됨): 성공적으로 요청되었으며 서버가 새 리소스를 작성했다.
202(허용됨): 서버가 요청을 접수했지만 아직 처리하지 않았다.
203(신뢰할 수 없는 정보): 서버가 요청을 성공적으로 처리했지만 다른 소스에서 수신된 정보를 제공하고 있다.
204(콘텐츠 없음): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 제공하지 않는다.
205(콘텐츠 재설정): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 표시하지 않는다.
204 응답과 달리 이 응답은 요청자가 문서 보기를 재설정할 것을 요구한다(예: 새 입력을 위한 양식 비우기).
206(일부 콘텐츠): 서버가 GET 요청의 일부만 성공적으로 처리했다.
207(다중 상태, RFC 4918)
208(이미 보고됨, RFC 5842)
226 IM Used (RFC 3229)
05/10~
# feign client 적용하기
- Feign client란
- OpenFeign 의존성 추가
- @EnableFeignClients 어노테이션 적용
- RestTemplate 대신 사용하는 개념. annotation으로 설정할 수 있는 편리한 기능.
- retryer을 따로 설정해 주어야 하는 것 인줄 알았는데, 1개의 인스턴스를 강제종료 한 직후 호출해도 오류 없이 바로 다른 인스턴스로 무사히 연결됨... why??
- default retryer 존재 : IOException의 경우는 자동으로 retry 해주는 듯 함. 강제 종료는 입출력 오류로 인식해 ioexception??
- 따로 설정해야만 동작하는 retryer가 대체 왜 계속 동작하는가?????
- OpenFeign 오픈소스 뜯어보기
- FeignClient.class 에서 기본 내장 기능인 boolean decode404() default false; 404에러를 exception으로 인식, 처리.
- true로 어노테이션 overriding 하면 404 에러를 낼 수 있지 않을까??? : 오답
- 내장된 feign.hystrix의 fallback기능(아직 잘 모름)이 원인일까 하여 false 설정해봄 : 오답
- errordecoder : 오답
- OpenFeign에 등록되는 retryer 빈은 따로 설정 안 할 시 동작X. 하지만 IOException에 한해 자동으로 retry하는 기능이 OpenFeign에 내장되어있음. 이 기능 때문에 인스턴스 한 개가 불시에 죽어도 오류나지 않고 바로 다른 인스턴스에 연결되는듯 함.
A bean of Retryer.NEVER_RETRY with the type Retryer is created by default, which will disable retrying.
Notice this retrying behavior is different from the Feign default one, where it will automatically retry IOExceptions,
treating them as transient network related exceptions, and any RetryableException thrown from an ErrorDecoder.
https://docs.spring.io/spring-cloud-openfeign/docs/2.2.8.RELEASE/reference/html/
- DefaultLoadBalancerRetryHandler
- 이를 코드로 확인하기 위해 Eureka의 roadbalancing, OpenFeign의 retryer 소스 분석 예정
- DefaultFeignLoadBalancedConfiguration > LoadBalancerFeignClient > FeignLoadBalancer > RequestSpecificRetryHandler > RetryHandler > DefaultLoadBalancerRetryHandler
- DefaultLoadBalancerRetryHandler : 여기에 정답이 있을 것 같음. 코드 분석이 어려움..
- OpenFeign 정리
- 설정시 spring cloud loadbalancer / ribbon 모두 지원됨
- ribbon 안 쓰고 클라우드 로드밸런서 사용하려면 spring.cloud.loadbalancer.ribbon.enabled=false 설정
- NEVER설정된 OpenFeign 내장 Retryer 그대로 / ribbon enable false 설정 = 오류 터짐!!!!!
- OpenFeign 내장 Retryer 활성화 / ribbon enable false 설정 = 오류 안 터짐.
- ribbon 설정 그대로 / OpenFeign 내장 Retryer 활성화 = 오류 안 터짐.
-> ribbon의 retryer은 자동 작동, OpenFeign 내장 Retryer는 따로 설정 시 작동됨을 알았다.
- retryer 는 rxjava로 구현된 내부 기능임을 디버그로 확인
# Debug & GitLab Repository upload
- Eclipse Debugging
- 좌측 더블클릭 : breakpoint 설정
- f5 : 한 스텝씩 진행(한 라인씩)
- f6 : 한 스텝씩 진행(내부 클래스, 함수, 라이브러리로 들어가면서 진행)
- f7 : 현재 함수의 끝까지 실행해 현재 함수 벗어난다
- f8 : 다음 break point 까지 실행
- ctrl H : java search 로 클래스 루트 검색
- ctrl alt G : search창 켜지면서 커서/블록의 프로젝트 내부에서 사용된 루트 검색
- GitLab Repository
- SourceTree라는 프로그램 사용하니 상당히 편함
- ssh코드를 생성해 암호화해 통신
- 클론 : 동기화하기 위한 링크 공유
- 프로젝트 꼬여서 다시 만들 때, 최소한의 파일들만 남기면 스프링이 프로젝트 재생성해줌.
- src, mvnw, pom . 특히 pom.xml을 기반으로 프로젝트 생성해줌. import > maven > Existing Maven Projects로 !
- commit 후 push 생활화!! commit, push 전에 patch, pull 생활화!!
- merge request 손에 익히기!!!!!
# WebFlux 예제코드
- 1~10 찍기 / 1~10 중 짝수 찍기