본문 바로가기

카테고리 없음

38. 마이크로서비스 레퍼런스 4편

블로그에서는 서비스 메시 솔루션으로 이스티오를 소개했다. 다양한 오픈소스 서비스 메시가 있으며, 컨설은 하시코프 서비스 메시 및 검색 솔루션이다. 서비스 메시와 검색 솔루션으로 컨설을 사용하기 위한 주요 단계는 다음과 같다.

 

  • 서비스 정의를 고려할 때 서비스 식별자, 메세지 모델, 인터페이스 등의 정의는 중앙 집중식 관리 없이 수행 가능한 작업이다. 그러나 이러한 서비스 정의는 중앙 집중식 서비스 레지스트리에 게시돼야 한다. 서비스 레지스트리는 중앙 집중식 구성 요소이며, 서비스를 설명하기 위한 정규 모델을 정의한다. 모든 서비스 소유자는 정규형으로 서비스 정의를 서비스 레지스트리에 게시해야 한다. 서비스가 크게 상이한 기술로 구현된 경우에도 해당 서비스에 대한 공통 메타데이터를 찾아서 서비스 레지스트리에 추가할 수 있다(API 포탈 및 관리와 유사한 점이 많다)
  • 서비스 수명 주기 관리는 종종 서비스 배포 수준에서 구현된다. 예를 들어 특정 서비스를 여러 환경에 배포하는 경우 배포 프로세스는 각 환경에 동일한 서비스 코드를 복제하거나 이동해야 한다는 요구 사항을 처리한다. 여기에는 다양한 데브옵스 관련 배포 방법론(블루그린, 카나리아, AB테스트)이 포함되며 개발, 테스트, 품질보증, 준비, 운영 등과 같은 다양한 환경을 관리하는 방법을 설명한다
  • API 관리는 여러 마이크로서비스 거버넌스 측면을 실현하는 데 중요한 역할을 한다. API 관리의 일환으로 런타임 동안 서비스에 보안, 서비스 버전 관리, 스로틀링, 캐싱, 상품화 등을 적용할 수 있다. 이러한 기능의 대부분은 서비스 호출을 위해 중앙에서 적용돼야 함을 이해하는 것이 중요하다. 따라서 API 게이트웨이는 중앙에서 조절되거나 관리되며, 외부 또는 내부 소비자를 대상으로 사용될 수 있다. 또 다른 중요한 측면은 API 관리 솔루션이 API를 검색하고 소비하기 위한 풍부한 기능을 제공한다는 것이다 따라서 API 관리를 활용해 모든 마이크로서비스를 관리할 수 있다
  • 관찰 가능성은 모든 마이크로서비스에 일반적으로 적용되는 것이다. 각 마이크로서비스는 권장되는 관찰 에이전트를 사용해 이러한 관찰 도구 중 하나로 데이터를 푸시할 수 있다. 관찰 도구는 마이크로서비스의 모든 상호작용에 대한 중앙 집중식 뷰를 제공하며, 원래으 비즈니스 메세지 흐름을 방해하지 않는 수동 엔티티로 작동한다. API 관리 솔루션 또는 API 게이트웨이 없이도 관찰 도구와 함께 작동한다

Consul 데모는 다수 마이크로서비스가 Consul에 등록되었고, 서비스 메시를 구성하였다. Grafana Loki를 사용해서 로그를 수집한다

 

root@philip-virtual-machine:/home/philip/다운로드# cd learn-consul-docker/datacenter-deploy-observability
root@philip-virtual-machine:/home/philip/다운로드/learn-consul-docker/datacenter-deploy-observability# docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
latest: Pulling from grafana/loki-docker-driver
838e108781b0: Download complete 
Digest: sha256:8016e6ab43af2aa59a19c7e909c55ca95aac22d635109c1052f6cea8089aa631
Status: Downloaded newer image for grafana/loki-docker-driver:latest
Installed plugin grafana/loki-docker-driver:latest
 
 
 
root@philip-virtual-machine:/home/philip/다운로드/learn-consul-docker/datacenter-deploy-observability# docker-compose up --detach
Creating network "datacenter-deploy-observability_vpcbr" with driver "bridge"
Pulling consul-server (hashicorp/consul:1.8.10)...
1.8.10: Pulling from hashicorp/consul
339de151aab4: Pull complete
7507a12a1d1e: Pull complete
0ee788d3cc3d: Pull complete
d17b4413655c: Pull complete
15b70aecd86a: Pull complete
b3ec1073ad48: Pull complete
Digest: sha256:8668823254dd1d8d278069779fa58a9b251541f5a098c282273ea61e08b5eb07
Status: Downloaded newer image for hashicorp/consul:1.8.10
Pulling ingress (nicholasjackson/fake-service:v0.21.0)...
v0.21.0: Pulling from nicholasjackson/fake-service
ba3557a56b15: Pull complete
0163f3cd4a39: Pull complete
2ddbae95ec9b: Pull complete
058a79cc9cb6: Pull complete
Digest: sha256:9b631edb7bbd6df37689d3079d594a2702361c9adfac87444db9fe6f4a615512
Status: Downloaded newer image for nicholasjackson/fake-service:v0.21.0
Pulling ingress_proxy (nicholasjackson/consul-envoy:v1.6.1-v0.10.0)...
v1.6.1-v0.10.0: Pulling from nicholasjackson/consul-envoy
6c40cc604d8e: Pull complete
4723172fad74: Pull complete
df9074b2a4a3: Pull complete
bf33c54f8f52: Pull complete
9cb15126f016: Pull complete
eea65c87ad90: Pull complete
93bf6885a29e: Pull complete
eb22e6bd2b31: Pull complete
3d8af528297d: Pull complete
5e3258a7e9ef: Pull complete
9164c427f575: Pull complete
Digest: sha256:bb3eb94d80ec279c7676806cba4e06e383e4857d19f68a6e1480cb207e6909df
Status: Downloaded newer image for nicholasjackson/consul-envoy:v1.6.1-v0.10.0
Pulling web_proxy (nicholasjackson/consul-envoy:v1.6.0-v0.10.0)...
v1.6.0-v0.10.0: Pulling from nicholasjackson/consul-envoy
6c40cc604d8e: Already exists
4723172fad74: Already exists
df9074b2a4a3: Already exists
bf33c54f8f52: Already exists
9cb15126f016: Already exists
eea65c87ad90: Already exists
93bf6885a29e: Already exists
be5da91cf197: Pull complete
dcd0631c35d7: Pull complete
4025ada60e8a: Pull complete
04572f0763d6: Pull complete
Digest: sha256:778f12dee9e43d8001b809168e605b7b1ea8b01ebf44ba35fbb103da548f616c
Status: Downloaded newer image for nicholasjackson/consul-envoy:v1.6.0-v0.10.0
Pulling node-exporter (prom/node-exporter:v1.1.2)...
v1.1.2: Pulling from prom/node-exporter
dc6dd4561653: Pull complete
613f88646930: Pull complete
edad907fb257: Pull complete
Digest: sha256:22fbde17ab647ddf89841e5e464464eece111402b7d599882c2a3393bc0d2810
Status: Downloaded newer image for prom/node-exporter:v1.1.2
Pulling prometheus (prom/prometheus:v2.26.0)...
v2.26.0: Pulling from prom/prometheus
e5d9363303dd: Pull complete
3430c2c42129: Pull complete
7631b5d56c90: Pull complete
343e06690c48: Pull complete
dc32e90574e9: Pull complete
a6d5d01cd646: Pull complete
832428480103: Pull complete
83e775ff1768: Pull complete
1ec97f567836: Pull complete
0cdf5b797911: Pull complete
eb7d1f2acc9f: Pull complete
541ffe559bd5: Pull complete
Digest: sha256:38d40a760569b1c5aec4a36e8a7f11e86299e9191b9233672a5d41296d8fa74e
Status: Downloaded newer image for prom/prometheus:v2.26.0
Pulling tempo (grafana/tempo:1f1c40b3)...
1f1c40b3: Pulling from grafana/tempo
31603596830f: Pull complete
1a0ecc881277: Pull complete
c1a2b907d8ca: Pull complete
Digest: sha256:5edb5029de49baa542b392088388e4f607b09159ed7c906fe163459d4ded82ce
Status: Downloaded newer image for grafana/tempo:1f1c40b3
Pulling grafana (grafana/grafana:7.5.3)...
7.5.3: Pulling from grafana/grafana
532819f3e44c: Pull complete
26963e599e4e: Pull complete
75e9c655866a: Pull complete
ed56f4081c23: Pull complete
27d9d8938687: Pull complete
4f4fb700ef54: Pull complete
fd9688983ff2: Pull complete
a5cf79ad8085: Pull complete
Digest: sha256:88d5dec7f18a06c726211eefca40b04c58cc94e99819c5dead046633d535b82d
Status: Downloaded newer image for grafana/grafana:7.5.3
Pulling loki (grafana/loki:2.1.0)...
2.1.0: Pulling from grafana/loki
31603596830f: Already exists
8c7e15197876: Pull complete
c1b6a8fac623: Pull complete
27859f61b3ae: Pull complete
75da1bac962f: Pull complete
c4cbe3fbfb06: Pull complete
8285f63343e7: Pull complete
Digest: sha256:b393f409fa9ada5327e7fb5ec8ac90300ae498560417f08fec2f10e14a89aa7c
Status: Downloaded newer image for grafana/loki:2.1.0
Creating tempo         ... done
Creating node-exporter ... done
Creating loki          ... done
Creating grafana       ... done
Creating consul-server ... done
Creating prometheus    ... done
Creating web           ... done
Creating ingress       ... done
Creating api           ... done
Creating web_proxy     ... done
Creating api_proxy     ... done
Creating ingress_proxy ... done
 
 
root@philip-virtual-machine:/home/philip/다운로드/learn-consul-docker/datacenter-deploy-observability# docker-compose ps
    Name                   Command               State                                   Ports                                
------------------------------------------------------------------------------------------------------------------------------
api             /app/fake-service                Up                                                                           
api_proxy       /entrypoint.sh consul conn ...   Up                                                                           
consul-server   docker-entrypoint.sh consu ...   Up      8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp,                    
                                                         0.0.0.0:8500->8500/tcp, 8600/tcp, 8600/udp                           
grafana         /run.sh                          Up      0.0.0.0:3000->3000/tcp                                               
ingress         /app/fake-service                Up      0.0.0.0:9090->9090/tcp                                               
ingress_proxy   /entrypoint.sh consul conn ...   Up                                                                           
loki            /usr/bin/loki -config.file ...   Up      0.0.0.0:3100->3100/tcp                                               
node-exporter   /bin/node_exporter --path. ...   Up      0.0.0.0:9100->9100/tcp                                               
prometheus      /bin/prometheus --config.f ...   Up      0.0.0.0:9092->9090/tcp                                               
tempo           /tempo -config.file=/etc/t ...   Up      0.0.0.0:14268->14268/tcp, 0.0.0.0:32768->3100/tcp,                   
                                                         0.0.0.0:9411->9411/tcp                                               
web             /app/fake-service                Up                                                                           
web_proxy       /entrypoint.sh consul conn ...   Up                                                                           
root@philip-virtual-machine:/home/philip/다운로드/learn-consul-docker/datacenter-deploy-observability#
 
 
 

프로메테우스 메트릭 정의

 

그라파나 Loki 추적 및 로그분석

이제까지 로그 분석을 위해서 ELK를 사용하였다. 새로운 로그 분석 솔루션을 소개한다 그라파나에서 Loki를 발표하였고, 그라파나 대시보드와 통합되었다.

 
 
 
 
 
 

그라파나 대시보드 생성

 
 
 
 
 

컨설

예전에는 집킨을 사용했지만, 요즘은 Jaeger와 Tempo를 추천한다. 관찰 가능성은 다양한 오픈소스를 사용해서 구현한다. 만약 이스티오, 예거를 사용해서 관찰 가능성을 구현한다면

  1. 로그 수집 시 레벨 조절이 가능하고, 별도 필터링도 가능하다. 기본적으로 로그 수집은 다양하고 많은 정보를 포함하기 때문에, 대용량 데이터를 저장해야 한다. 일반적으로 샘플링 적용이 쉽지 않다. 비즈니스적인 분석을 하려면 로그가 가장 많은 정보를 제공한다. 대용량 로그 분석이라면 Splunk를 추천하며, 우수한 오픈소스는 EFK, ELK를 추천한다
  2. 프로메테우스와 그라파나를 사용한 대시보드 모니터링은 수집되는 메트릭 기반으로 시스템과 기술적인 분석이 가능하다.
  3. Kiali는 시각화가 우수하며, 예거와 그라파나가 통합되어 있다. 간략하게 추적과 모니터링이 필요한 경우와 배포와 테스트 시에 유용하게 사용된다. Kiali는 예거와 그라파나 링크를 제공한다.
  4. 예거를 통해 상세 추적을 분석한다.

Consul, Tempo, Loki를 사용하는 경우에는

  1. Loki를 사용해서 로그를 분석한다.
  2. Tempo를 사용해서 추적을 분석한다. Loki, Tempo, Prometheus가 Grafana에 통합되어서 제공되므로 한 화면에서 쉽게 분석이 가능하다. 이스티오, 예거와 비교해서 성능, 시각화 측면에서 장점이 있고 향후에 많이 사용될거라 판단된다.
  3. ELK로 대용량 로그 분석이 어렵다. Loki의 대용량 처리 성능이 더 우수하다고 판단된다.

 

 

마이크로서비스 디자인 패턴을 정확히 따르지 않더라도, 근래의 어플리케이션 개발은 마이크로서비스의 근간이 되는 소프트웨어를 가지고 개발하는 것이 사실이다. 스프링부트, REST, JPA 등이 그러한 예이다. 

"C:\Program Files\Java\jdk-11.0.11\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.2.2\lib\idea_rt.jar=63650:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath C:\shop\target\classes;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-data-jpa\2.5.2\spring-boot-starter-data-jpa-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-aop\2.5.2\spring-boot-starter-aop-2.5.2.jar;C:\Users\germany\.m2\repository\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-jdbc\2.5.2\spring-boot-starter-jdbc-2.5.2.jar;C:\Users\germany\.m2\repository\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;C:\Users\germany\.m2\repository\org\springframework\spring-jdbc\5.3.8\spring-jdbc-5.3.8.jar;C:\Users\germany\.m2\repository\jakarta\transaction\jakarta.transaction-api\1.3.3\jakarta.transaction-api-1.3.3.jar;C:\Users\germany\.m2\repository\jakarta\persistence\jakarta.persistence-api\2.2.3\jakarta.persistence-api-2.2.3.jar;C:\Users\germany\.m2\repository\org\hibernate\hibernate-core\5.4.32.Final\hibernate-core-5.4.32.Final.jar;C:\Users\germany\.m2\repository\org\jboss\logging\jboss-logging\3.4.2.Final\jboss-logging-3.4.2.Final.jar;C:\Users\germany\.m2\repository\org\javassist\javassist\3.27.0-GA\javassist-3.27.0-GA.jar;C:\Users\germany\.m2\repository\net\bytebuddy\byte-buddy\1.10.22\byte-buddy-1.10.22.jar;C:\Users\germany\.m2\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;C:\Users\germany\.m2\repository\org\jboss\jandex\2.2.3.Final\jandex-2.2.3.Final.jar;C:\Users\germany\.m2\repository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;C:\Users\germany\.m2\repository\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar;C:\Users\germany\.m2\repository\org\hibernate\common\hibernate-commons-annotations\5.1.2.Final\hibernate-commons-annotations-5.1.2.Final.jar;C:\Users\germany\.m2\repository\org\glassfish\jaxb\jaxb-runtime\2.3.4\jaxb-runtime-2.3.4.jar;C:\Users\germany\.m2\repository\org\glassfish\jaxb\txw2\2.3.4\txw2-2.3.4.jar;C:\Users\germany\.m2\repository\com\sun\istack\istack-commons-runtime\3.0.12\istack-commons-runtime-3.0.12.jar;C:\Users\germany\.m2\repository\com\sun\activation\jakarta.activation\1.2.2\jakarta.activation-1.2.2.jar;C:\Users\germany\.m2\repository\org\springframework\data\spring-data-jpa\2.5.2\spring-data-jpa-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\data\spring-data-commons\2.5.2\spring-data-commons-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\spring-orm\5.3.8\spring-orm-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-context\5.3.8\spring-context-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-tx\5.3.8\spring-tx-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-beans\5.3.8\spring-beans-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-aspects\5.3.8\spring-aspects-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-thymeleaf\2.5.2\spring-boot-starter-thymeleaf-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter\2.5.2\spring-boot-starter-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.5.2\spring-boot-starter-logging-2.5.2.jar;C:\Users\germany\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\germany\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\germany\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;C:\Users\germany\.m2\repository\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;C:\Users\germany\.m2\repository\org\slf4j\jul-to-slf4j\1.7.31\jul-to-slf4j-1.7.31.jar;C:\Users\germany\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\germany\.m2\repository\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;C:\Users\germany\.m2\repository\org\thymeleaf\thymeleaf-spring5\3.0.12.RELEASE\thymeleaf-spring5-3.0.12.RELEASE.jar;C:\Users\germany\.m2\repository\org\thymeleaf\extras\thymeleaf-extras-java8time\3.0.4.RELEASE\thymeleaf-extras-java8time-3.0.4.RELEASE.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.5.2\spring-boot-starter-web-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.5.2\spring-boot-starter-json-2.5.2.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.12.3\jackson-databind-2.12.3.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.12.3\jackson-annotations-2.12.3.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.12.3\jackson-core-2.12.3.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.3\jackson-datatype-jdk8-2.12.3.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.3\jackson-datatype-jsr310-2.12.3.jar;C:\Users\germany\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.3\jackson-module-parameter-names-2.12.3.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.5.2\spring-boot-starter-tomcat-2.5.2.jar;C:\Users\germany\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.48\tomcat-embed-core-9.0.48.jar;C:\Users\germany\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.48\tomcat-embed-websocket-9.0.48.jar;C:\Users\germany\.m2\repository\org\springframework\spring-web\5.3.8\spring-web-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-webmvc\5.3.8\spring-webmvc-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-expression\5.3.8\spring-expression-5.3.8.jar;C:\Users\germany\.m2\repository\com\h2database\h2\1.4.200\h2-1.4.200.jar;C:\Users\germany\.m2\repository\mysql\mysql-connector-java\8.0.25\mysql-connector-java-8.0.25.jar;C:\Users\germany\.m2\repository\org\projectlombok\lombok\1.18.20\lombok-1.18.20.jar;C:\Users\germany\.m2\repository\com\querydsl\querydsl-jpa\4.3.1\querydsl-jpa-4.3.1.jar;C:\Users\germany\.m2\repository\com\querydsl\querydsl-core\4.4.0\querydsl-core-4.4.0.jar;C:\Users\germany\.m2\repository\com\google\guava\guava\18.0\guava-18.0.jar;C:\Users\germany\.m2\repository\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\Users\germany\.m2\repository\com\mysema\commons\mysema-commons-lang\0.2.4\mysema-commons-lang-0.2.4.jar;C:\Users\germany\.m2\repository\com\infradna\tool\bridge-method-annotation\1.13\bridge-method-annotation-1.13.jar;C:\Users\germany\.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar;C:\Users\germany\.m2\repository\org\slf4j\slf4j-api\1.7.31\slf4j-api-1.7.31.jar;C:\Users\germany\.m2\repository\com\querydsl\querydsl-apt\4.3.1\querydsl-apt-4.3.1.jar;C:\Users\germany\.m2\repository\com\querydsl\querydsl-codegen\4.3.1\querydsl-codegen-4.3.1.jar;C:\Users\germany\.m2\repository\com\mysema\codegen\codegen\0.6.8\codegen-0.6.8.jar;C:\Users\germany\.m2\repository\org\eclipse\jdt\core\compiler\ecj\4.3.1\ecj-4.3.1.jar;C:\Users\germany\.m2\repository\org\reflections\reflections\0.9.9\reflections-0.9.9.jar;C:\Users\germany\.m2\repository\com\google\code\findbugs\annotations\2.0.1\annotations-2.0.1.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-devtools\2.5.2\spring-boot-devtools-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot\2.5.2\spring-boot-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.5.2\spring-boot-autoconfigure-2.5.2.jar;C:\Users\germany\.m2\repository\nz\net\ultraq\thymeleaf\thymeleaf-layout-dialect\2.5.1\thymeleaf-layout-dialect-2.5.1.jar;C:\Users\germany\.m2\repository\nz\net\ultraq\extensions\groovy-extensions\0.3.0\groovy-extensions-0.3.0.jar;C:\Users\germany\.m2\repository\nz\net\ultraq\thymeleaf\thymeleaf-expression-processor\1.2.0\thymeleaf-expression-processor-1.2.0.jar;C:\Users\germany\.m2\repository\org\codehaus\groovy\groovy\3.0.8\groovy-3.0.8.jar;C:\Users\germany\.m2\repository\org\thymeleaf\thymeleaf\3.0.12.RELEASE\thymeleaf-3.0.12.RELEASE.jar;C:\Users\germany\.m2\repository\ognl\ognl\3.1.26\ognl-3.1.26.jar;C:\Users\germany\.m2\repository\org\attoparser\attoparser\2.0.5.RELEASE\attoparser-2.0.5.RELEASE.jar;C:\Users\germany\.m2\repository\org\unbescape\unbescape\1.1.6.RELEASE\unbescape-1.1.6.RELEASE.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-security\2.5.2\spring-boot-starter-security-2.5.2.jar;C:\Users\germany\.m2\repository\org\springframework\spring-aop\5.3.8\spring-aop-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\security\spring-security-config\5.5.1\spring-security-config-5.5.1.jar;C:\Users\germany\.m2\repository\org\springframework\security\spring-security-web\5.5.1\spring-security-web-5.5.1.jar;C:\Users\germany\.m2\repository\org\springframework\boot\spring-boot-starter-validation\2.5.2\spring-boot-starter-validation-2.5.2.jar;C:\Users\germany\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.48\tomcat-embed-el-9.0.48.jar;C:\Users\germany\.m2\repository\org\hibernate\validator\hibernate-validator\6.2.0.Final\hibernate-validator-6.2.0.Final.jar;C:\Users\germany\.m2\repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;C:\Users\germany\.m2\repository\org\springframework\security\spring-security-core\5.5.1\spring-security-core-5.5.1.jar;C:\Users\germany\.m2\repository\org\springframework\security\spring-security-crypto\5.5.1\spring-security-crypto-5.5.1.jar;C:\Users\germany\.m2\repository\org\springframework\spring-core\5.3.8\spring-core-5.3.8.jar;C:\Users\germany\.m2\repository\org\springframework\spring-jcl\5.3.8\spring-jcl-5.3.8.jar;C:\Users\germany\.m2\repository\org\thymeleaf\extras\thymeleaf-extras-springsecurity5\3.0.4.RELEASE\thymeleaf-extras-springsecurity5-3.0.4.RELEASE.jar;C:\Users\germany\.m2\repository\org\modelmapper\modelmapper\2.3.9\modelmapper-2.3.9.jar;C:\Users\germany\.m2\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;C:\Users\germany\.m2\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar com.shop.ShopApplication

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

2022-01-04 01:17:43.370  INFO 6148 --- [  restartedMain] com.shop.ShopApplication                 : Starting ShopApplication using Java 11.0.11 on DESKTOP-SLAO439 with PID 6148 (C:\shop\target\classes started by germany in C:\shop)
2022-01-04 01:17:43.385  INFO 6148 --- [  restartedMain] com.shop.ShopApplication                 : No active profile set, falling back to default profiles: default
2022-01-04 01:17:44.089  INFO 6148 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-01-04 01:17:44.089  INFO 6148 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-01-04 01:17:45.693  INFO 6148 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-01-04 01:17:45.942  INFO 6148 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 239 ms. Found 7 JPA repository interfaces.
2022-01-04 01:17:47.332  INFO 6148 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 80 (http)
2022-01-04 01:17:47.379  INFO 6148 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-01-04 01:17:47.379  INFO 6148 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.48]
2022-01-04 01:17:47.942  INFO 6148 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-01-04 01:17:47.942  INFO 6148 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3853 ms
2022-01-04 01:17:47.991  INFO 6148 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-01-04 01:17:48.707  INFO 6148 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-01-04 01:17:48.707  INFO 6148 --- [  restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:mysql://localhost:3306/shop?serverTimezone=UTC'
2022-01-04 01:17:49.160  INFO 6148 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-01-04 01:17:49.301  INFO 6148 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.32.Final
2022-01-04 01:17:51.022  INFO 6148 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-01-04 01:17:51.569  INFO 6148 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
Hibernate: 
    
    alter table cart 
       drop 
       foreign key FKix170nytunweovf2v9137mx2o
Hibernate: 
    
    alter table cart_item 
       drop 
       foreign key FK1uobyhgl1wvgt1jpccia8xxs3
Hibernate: 
    
    alter table cart_item 
       drop 
       foreign key FKdljf497fwm1f8eb1h8t6n50u9
Hibernate: 
    
    alter table item_img 
       drop 
       foreign key FKdd5u08y3ap4c46ayrqjf8g88m
Hibernate: 
    
    alter table order_item 
       drop 
       foreign key FKija6hjjiit8dprnmvtvgdp6ru
Hibernate: 
    
    alter table order_item 
       drop 
       foreign key FKt4dc2r9nbvbujrljv3e23iibt
Hibernate: 
    
    alter table orders 
       drop 
       foreign key FKpktxwhj3x9m4gth5ff6bkqgeb
Hibernate: 
    
    drop table if exists cart
Hibernate: 
    
    drop table if exists cart_item
Hibernate: 
    
    drop table if exists hibernate_sequence
Hibernate: 
    
    drop table if exists item
Hibernate: 
    
    drop table if exists item_img
Hibernate: 
    
    drop table if exists member
Hibernate: 
    
    drop table if exists order_item
Hibernate: 
    
    drop table if exists orders
Hibernate: 
    
    create table cart (
       cart_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        member_id bigint,
        primary key (cart_id)
    ) engine=InnoDB
Hibernate: 
    
    create table cart_item (
       cart_item_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        count integer not null,
        cart_id bigint,
        item_id bigint,
        primary key (cart_item_id)
    ) engine=InnoDB
Hibernate: 
    
    create table hibernate_sequence (
       next_val bigint
    ) engine=InnoDB
Hibernate: 
    
    insert into hibernate_sequence values ( 1 )
Hibernate: 
    
    create table item (
       item_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        item_detail longtext not null,
        item_nm varchar(50) not null,
        item_sell_status varchar(255),
        price integer not null,
        stock_number integer not null,
        primary key (item_id)
    ) engine=InnoDB
Hibernate: 
    
    create table item_img (
       item_img_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        img_name varchar(255),
        img_url varchar(255),
        ori_img_name varchar(255),
        repimg_yn varchar(255),
        item_id bigint,
        primary key (item_img_id)
    ) engine=InnoDB
Hibernate: 
    
    create table member (
       member_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        address varchar(255),
        email varchar(255),
        name varchar(255),
        password varchar(255),
        role varchar(255),
        primary key (member_id)
    ) engine=InnoDB
Hibernate: 
    
    create table order_item (
       order_item_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        count integer not null,
        order_price integer not null,
        item_id bigint,
        order_id bigint,
        primary key (order_item_id)
    ) engine=InnoDB
Hibernate: 
    
    create table orders (
       order_id bigint not null,
        reg_time datetime(6),
        update_time datetime(6),
        created_by varchar(255),
        modified_by varchar(255),
        order_date datetime(6),
        order_status varchar(255),
        member_id bigint,
        primary key (order_id)
    ) engine=InnoDB
Hibernate: 
    
    alter table member 
       add constraint UK_mbmcqelty0fbrvxp1q58dn57t unique (email)
Hibernate: 
    
    alter table cart 
       add constraint FKix170nytunweovf2v9137mx2o 
       foreign key (member_id) 
       references member (member_id)
Hibernate: 
    
    alter table cart_item 
       add constraint FK1uobyhgl1wvgt1jpccia8xxs3 
       foreign key (cart_id) 
       references cart (cart_id)
Hibernate: 
    
    alter table cart_item 
       add constraint FKdljf497fwm1f8eb1h8t6n50u9 
       foreign key (item_id) 
       references item (item_id)
Hibernate: 
    
    alter table item_img 
       add constraint FKdd5u08y3ap4c46ayrqjf8g88m 
       foreign key (item_id) 
       references item (item_id)
Hibernate: 
    
    alter table order_item 
       add constraint FKija6hjjiit8dprnmvtvgdp6ru 
       foreign key (item_id) 
       references item (item_id)
Hibernate: 
    
    alter table order_item 
       add constraint FKt4dc2r9nbvbujrljv3e23iibt 
       foreign key (order_id) 
       references orders (order_id)
Hibernate: 
    
    alter table orders 
       add constraint FKpktxwhj3x9m4gth5ff6bkqgeb 
       foreign key (member_id) 
       references member (member_id)
2022-01-04 01:17:54.922  INFO 6148 --- [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-01-04 01:17:54.937  INFO 6148 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-01-04 01:17:55.095  WARN 6148 --- [  restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-01-04 01:17:59.482  INFO 6148 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Will secure Ant [pattern='/css/**'] with []
2022-01-04 01:17:59.482  INFO 6148 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Will secure Ant [pattern='/js/**'] with []
2022-01-04 01:17:59.482  INFO 6148 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Will secure Ant [pattern='/img/**'] with []
2022-01-04 01:17:59.544  INFO 6148 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5136ee7b, org.springframework.security.web.context.SecurityContextPersistenceFilter@48f79351, org.springframework.security.web.header.HeaderWriterFilter@630e6138, org.springframework.security.web.csrf.CsrfFilter@48704cf4, org.springframework.security.web.authentication.logout.LogoutFilter@6d7397a2, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@3a804f4e, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@33febf13, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6fc22312, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@6928de8c, org.springframework.security.web.session.SessionManagementFilter@4aaa7820, org.springframework.security.web.access.ExceptionTranslationFilter@264b12ac, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3a0b6980]
2022-01-04 01:18:00.592  INFO 6148 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-01-04 01:18:00.654  INFO 6148 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 80 (http) with context path ''
2022-01-04 01:18:00.670  INFO 6148 --- [  restartedMain] com.shop.ShopApplication                 : Started ShopApplication in 18.3 seconds (JVM running for 20.304)

 

개발툴에서 전체 소스를 빌드할 수 있다. 스프링부트 개발을 위해 필요한 기술도 쉽게 설명했고, 소스 코드도 잘 실행된다. 마이크로서비스 디자인 패턴을 고려해서 개발을 진행하지는 않았으며 모놀리식에 가까운 아키텍처를 보여준다. 다른 레퍼런스 어플리케이션과 비교하면서 분석하면 좋을거라 생각한다.