레이블이 springboot인 게시물을 표시합니다. 모든 게시물 표시
레이블이 springboot인 게시물을 표시합니다. 모든 게시물 표시

2020년 9월 26일 토요일

Nuxtjs, Springboot docker 이미지 만들기

 1.  nuxtjs 

Dockerfile 생성후

FROM node:12

WORKDIR /app
ADD . /app/

# global install & update
RUN npm i -g npm
#&& npm i -g yarn

RUN rm yarn.lock
RUN yarn
RUN yarn build

ENV HOST 0.0.0.0
EXPOSE 80

# start command
CMD [ "yarn", "start" ]

#sudo docker build --tag web-front:1.0.0 .
#docker run --name web_80 -p 80:80 web-front:1.0.0
#docker run --name web_8081 -p 8081:80 web-front:1.0.0

2.springboot
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.war
COPY ${JAR_FILE} web-backend.war
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=local","-jar","/web-backend.war"]
#docker build --build-arg "JAR_FILE=build/libs/*.war" -t web-backend:1.0.0 .
#docker run --name hehe3 -p 8081:8081 web-backend:1.0.0

2020년 6월 29일 월요일

springboot 에 swagger 설치해서 api 확인하자

swaggerConfig.java (이름이야뭐..아무거나..) 를 만들어서

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration@EnableSwagger2public class SwaggerConfig {

@Bean public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any()) //모든 url 리스트 찾아내줘 스웍 .paths(PathSelectors.any()) // 모든 패스 전부. .build();
}
}
이것만으로 잘 안되서..


@Overridepublic void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/api/v2/api-docs", "/v2/api-docs");
registry.addRedirectViewController("/api/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/api/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/api/swagger-resources", "/swagger-resources");
}

@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/api/swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("/api/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
...
}

했더니 localhost:8080/api/swagger-ui.html 에서 보게 되었다. 
http://localhost:8081/swagger-api/swagger-ui.html#/

2020년 6월 27일 토요일

Spring boot Eureka 해보자

Spring boot Cloud Eureka 

마이크로서비스에서 다수의 서버들에 대한 정보를 관리하는게 필요하다. 유레카가 그거다. 유레카서버를 두고 각 클라이언트들이 유레카서버에 등록하면 된다.
스프링부트에서는 의존성추가해서 서버-클라이언트 지정하면 끝. 노드제이에스 같은경우 라이브러리로 가능.

유레카 서버는 음..그냥 현재 클라우드에 구성된 하위 마이크로 서비스들에 대한 구성값을 저장할 뿐이다. 사용자의 요청에 따른 라우팅 , 또는 로드밸런싱을 위해서는 Zuul 서비스를 연동한다.

유레카 서버는 30초마다 등록된 클라이언트에 핑을 보내서 이용가능한 서비스인지 확인하다. 로드밸런싱을 위해 리본(클라이언트 로드밸런서?) 를 사용한다.

1. Spring boot Cloud Eureka Server
의존성과 포트 설정만 지정하면 일단 서버 기동은 끝. 스프링부트 정말 좋다.
- spring initializr 사이트에서 eureka 의존성 추가해서 프로젝트 생성, web도 추가.
다른언어로 개발됬거나 별도로 디스커버리서버(유레카 서버가 들고 있는정보) 가 필요할때는 제공되는 유레카 API를 이용한다.
( /eureka/apps, euraka/instance 등등..)

implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'

- application.yml 에 서버 설정
server:
port: 8761 <-- 포트는 맘대로 보통 8761 인가보다

# -- Eureka
eureka:
instance:
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false <-- 서버자신이 유레카에 등록할지를 결정, 지가 서버이면서 클라이언트도 가능
fetch-registry: false <-- 클라이언트들이 로컬에 서버로부터 받은 클라이언트리스트정보를 로컬에 캐싱할지 결정 server: enable-self-preservation: false <-- true일때는 클라이언트가 죽어도 서버에서 죽지 않은걸로 인식, 보통 false 다

- application에 유레카 서버라고 설정
@EnableEurekaServer
@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}
이제 서버주소만 입력해도 정보가 출력된다. 유레카!
** resource 밑에 static, template가 있으면 화이트 지랄 화면이 보인다. 폴더 지우고 리빌드 하고 실행.
여러대의 서버에서 구성하고자 할떄는
spring:
profiles: default
application:
name: eureka-server-clustered
server:
port: 8761
eureka:
instance:
hostname: 192.168.0.103
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://192.168.0.106:8761/eureka/,http://192.168.0.107:8761/eureka/
식으로 디폴트존을 여러개(서로 얽히게끔) 둔다. 일단 peer-to-peer 라고 서버상태를 전부 복제하는 방식이다.
https://projects.spring.io/spring-cloud/spring-cloud.html#_peer_awareness



2. Spring boot Cloud Eureka Client
유레카 클라이언트 의존성을 추가하고 actuator 도 의존성 추가필요. 액튜에이터가 있어야 서버가 클라이언트의 상태를 파악하지.
유레가 서버가 heartbeat 를 보내주는데, 클라이언트가 이를 못받으면 유레카서버는 클라이언트를 삭제한다.
클라이언트는 서버로부터 레지스트리(클라이언트목록)을 캐싱하고 주기적으로 변경사항을 점검한다
- 일단 의존성 추가
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.boot:spring-boot-starter-actuator'

- application.yml 생성
server:
  port: ${PORT:8081}

spring:
  application:
    name: ${NAME:customerservice} <-- 같은 서비스를 여러개(여러서버)를 두고 서비스하고 싶을떄는 이름을 같게 하면
유레카에서 같은 이름끼리 묶어서 표시한다. 이를 zuul등에서 같은 service-id (serviceId: customerservice) 로 지정하면 라운드로빈 방식으로 서버를 돌아가며 요청한다. 따라서 같은 이름의 서비스서버중 1번 서버에는 출력'가'로 되는데, 2번 서버에는 출력'나'로 되어있으면 가->나->가->나..순으로 데이터가 표시된다.

eureka:
  client:
    serviceUrl:
    defaultZone: ${EUREKA_URL:http://127.0.0.1:8761/eureka/}
    enabled: true
  instance:
    preferIpAddress: true

- 애플리케이션이 유레카 클라이언트라고 지정
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaclientApplication {

public static void main(String[] args) {
SpringApplication.run(EurekaclientApplication.class, args);
}

}
- 이제 유레카 서버페이지에 접속해서 새로고침하면 실행중인 클라이언트 목록이 보인다. 클라이언트의 스타터스를 클릭하면 클라이언트의 액튜에이터 정보페이지가 열린다.
- java -jar -DPORT=8082 -DNAME=taeho  eurekaclient-0.0.1-SNAPSHOT.jar


참고 떙큐
https://projects.spring.io/spring-cloud/spring-cloud.html#_peer_awareness
https://lion-king.tistory.com/12?category=855644
https://coe.gitbook.io/guide/service-discovery/eureka 
https://develop-yyg.tistory.com/5
https://jinhyy.tistory.com/52 <-- 위에게시물을 복불한곳 , 개념이 없는건지....

2020년 6월 26일 금요일

Spring Boot Cloud Config 해보기

Spring Boot Cloud Config 로 분산시스템에서 설정파일을 외부로 분리 해보자
스프링 뿐만 아니라 , 다른 언어로 개발된 외부서버에서도 동일한 설정값을 적용할때 유용하다.

예를들어, 스프링부트 애플리케이션 , 노드제이에스애플리케이션 으로 구성된 프로젝트에서 개발할때는 전부 테스트용 디비에 접속했다가, 프로덕션때는 실서버로 설정파일을 바꾸고자 할때, 스프링 클라우드 콘픽 서버에서 설정값만 바꾸면 두 애플케이션에 동시에 적용되게 한다든지가 가능하다.


일단 로컬에 있는 설정파일을 이용하여 콘픽서버를 구성해보자.

1. Spring Boot Cloud Config Server
누군가는 콘픽설정을 가지고 있어야 되니까 서버가 필요하다.
- spring init 사이트에서 의존성 추가해서 웹어플로 하나 만들자.
- 의존성 : implementation 'org.springframework.cloud:spring-cloud-config-server'
- 설정파일을 로컬에 보관하고 서버에서 그 파일을 사용하겠다고 지정
  -  Config Server 는 application.yml 보다 bootstrap.yml 을 먼저 읽어야하니까 해당화일을 만든다 (또는 bootstrap-local.yml , bootstrap-prod.yml 으로 구분가능)
  - 내용은 일단 간단하게 입력
server:
port: 9000 <- 포트는 아무거나
spring:
profiles:
active: native <- 이게 로컬파일 쓰겠다는 것
cloud:
config:
server:
native:
search-locations: file://${user.home}/springcloud_config <- 콘픽파일들이 들어있는 폴더위치를
지정하면 클라이언트에서 요청한 콘픽파일을 이 폴더에서 찾아서 돌려준다
  - 사용자폴더안에 springcloud_config 폴더를 만들고 파일들을 넣어준다. 내용은 아무거나 좋다.
   단 파일이름사이에 - 표시로 요청 url 가 결정된다.
springcloud_config
 - bootstrap-test1.yml
 - bootstrap-test2.yml
  폴더와 파일들을 만들고
 - bootstrap-test1.yml 파일에는
spring:
  profiles: test1
  message: Hello Spring MemberService Test1 Server!
라고 만들었다.
  - 이제 서버를 기동하고 http://localhost:9000/bootstrap/test1 , 또는 다른컴에서 http://xx,xx,xx,xx:9000/bootstrap/test1 라고 입력하면 json 형태로 설정파일의 데이터가 출력된다.


2. Spring Boot Cloud Config Client
서버에서 Json 형태로 출력이 되니 서버주소만 입력하고 제이손 파싱만하면된다.
같은 스프링부트 프로젝트니까 의존성추가하고 bootstrap.yml 에 콘픽서버놈 설정하고 애플리케이션의 에서 설정속성을 읽어내면 된다. 
기존의 application.yml  에서 읽어 오는걸 콘픽서버에서 읽어 들인다고 생각하면된다.
의존성
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.boot:spring-boot-starter-actuator' <-- 요놈을 추가하면 서버에서 콘픽설정 
정보가 바뀔때 클라이언트 에서 서버의 재기동없이도 해당값이 적용되도록 하는게 가능하다. 밑의 콘트롤러에서 @RereshScope 를 사용할때 설명
bootstrap.yml 파일
server:
port: 8081

spring:
application:
name: bootstrap
profiles:
active: test1
cloud:
config:
uri: http://localhost:9000
콘트롤러
@RestController
@RefreshScope <-- actuator 의존성이 되어 있다면 이 어노테이션을 설정가능하다. 이놈이 붙어있으면 서버의 설정파일에 변경사항이 있을경우 클라이언트에서 POST http://클라이언트/actuator/refresh 요청하여 설정파일의 갱신이 가능하다.
public class HmmConfigClientController {

@Value("${spring.message}")
private String identify;

@GetMapping("/hi")
public String test() {
return identify;
}

}
지금은 http://localhost:8081/hi 하면 화면에 Hello Spring MemberService Local Server22233!!!!! 가 출력됨.
근데, 서버의 bootstrap-test1.yml 의 내용이 변경되었음
spring:
  profiles: test1
  message: Xuck  Apple !!!!!
하지만 아직 test1 설정을 읽어들인 클라이언트들은 예전메시지 나옴
자, 이제 외부에서 POST 로 클라이언트 서버에 actuator/refresh  해서 콘픽서버의 변경된 설정을 반영해보자.
사실은 콘픽 서버가 변경될떄, 각 클라이언트의 actuator/refresh 를 적용하도록 하는게 맞는거다. 유레카 서비스연동한다면 
등록되어 있는 클라리언트를 찾아서 반영하는것도 가능하다.
여튼. 간단히 curl -X POST  http://localhost:8081/actuator/refresh 하면 클라이언트는 콘픽서버로부터 새로운 
설정값을 가져온다.

지금은 http://localhost:8081/hi 하면 화면에 Xuck  Apple !!!!!
이 나옴. 또는 클라이언트 재가동 하든가. 

일단 콘픽 서버는 json 형태로 출력하니까 Json 파싱이 가능한 다른 애플리케이션에서도 이용가능하다. 스프링부트 에서 쓸때는 
좀더 편리할뿐.