Advertisement

Micro service architecture

CEO at uEngine Solutions
Dec. 26, 2017
Advertisement

More Related Content

Similar to Micro service architecture(20)

Advertisement

More from uEngine Solutions(20)

Advertisement

Micro service architecture

  1. Micro-services Architecture PaaS Multi-tenancy DevOps Micro-services Architecture 장진영 uEngine.org (jyjang@uengine.org) 1
  2. History of SOA 2 Source: pwc
  3. Background: 성공적 서비스 • Economist Intelligence 에 의한 국제적 조사 • (293개 기업 CIO, 조사국가: 미국 39%, 영국 31%, 호주 30%)에 의하면, • 서비스의 제공 방식의 변화로 가장 많은 40% 로 대답한 것은 바로 ‘구독형 서 비스(Subscription Service)’의 도입 3
  4. Background: 성공적인 서비스들 4
  5. DevOps: Issues Continuous Delivery 5 Company Deploy Frequency Deploy Lead Time Reliability Customer Responsiveness Amazon 23,000 / day Minutes High High Google 5,500 / day Minutes High High Netflix 500 / day Minutes High High Facebook 1 / day Hours High High Twitter 3 / week Hours High High Typical enterprise Once every 9 months Months or quarters Low / Medium Low / Medium 출처: 도서 The Phoenix Project Amazon, Google, Netflix, Facebook, Twitter는 얼마나 자주 배포할까요?
  6. 6 4. Canary를 통해서 확신 갖기 • Canary란? 실제 production 환경에서 small subset에서 새로운 코드를 돌려보고 옛 날 코드와 비교해서 새로운 코드가 어떻게 돌아가는 지 보는 것 • Canary 분석 작업(HTTP status code, response time, 실행수, load avg 등이 옛날 코 드랑 새로운 코드랑 비교해서 어떻게 다른 지 확인하는 것)은 1000개 이상의 metric 을 비교해서 100점 만점에 점수를 주고 일정 점수일 경우만 배포할 수 있음. 출처: http://techblog.netflix.com/2013/08/deploying-netflix-api.html Supporting Continuous Delivery Netflix
  7. 출처 : 2010 architecting for the cloud (http://www.slideshare.net/simone.brunozzi/2010-architecting-for-the-cloud-4719195) DevOps: Issues Managing Scalability 7
  8. 성공적 서비스로의 여정 운영자동화 • Business Continuity • Zero-downtime 수익화 • Subscription Business 구현 • Mashups • Multi-tenancy • Self-Serviced 마이크로 서비스 • Separation of Concerns 8
  9. 서비스가 죽지 않으면 어떨까? 9
  10. 항상성 (Self-Healing) 이 자동으로 유지되면 어떨까? 10
  11. 자원을 최대한 공유할 수 있을까? 11
  12. Continuous Delivery & Zero Downtime Deployment 가 되면 어떨까? 12
  13. Pets vs. Cattle Strategy 13
  14. Monolithic Architecture  모든 서비스가 한번에 재배포  한팀의 반영을 위하여 모든 팀이 대기  지속적 딜리버리가 어려워 14
  15. Micro Service Architecture Contract based, Polyglot Programming  Separation of Concerns, Parallel Development, Easy Outsourcing Written in Java Written in Node Written in PHP 15
  16. Example of Aggregate from different data sources 16
  17. REST Maturity Model 17
  18. Level 0: Swamp of POX • Use as a RPC, returns full serialized document 18 <openSlotList> <slot start = "1400" end = "1450"> <doctor id = "mjones"/> </slot> <slot start = "1600" end = "1650"> <doctor id = "mjones"/> </slot> </openSlotList>
  19. Level 1: Resources Level 1 tackles the question of handling complexity by using divide and conquer, breaking a large service endpoint down into multiple resources. 19 <openSlotList> <slot _link = ”http://openslots/1234"/> <slot _link = ”http://openslots/1235"/> </openSlotList> # http://openslots/1234 <slot start = "1400" end = "1450"> <doctor id = "mjones"/> </slot> # http://openslots/1235 <slot start = "1600" end = "1650"> <doctor id = "mjones"/> </slot>
  20. Level 2: HTTP Verbs Level 2 introduces a standard set of verbs so that we handle similar situations in the same way, removing unnecessary variation. 20 Operation HTTP / REST Create PUT / POST Read (Retrieve) GET Update (Modify) PUT / PATCH Delete (Destroy) DELETE # http://openslots/1234 <slot start = "1400" end = "1450"> <doctor id = "mjones"/> </slot>
  21. Level 3: Hypermedia Controls 21 <appointment> <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/> <patient id = "jsmith"/> <link rel = "/linkrels/appointment/cancel" uri = "/slots/1234/appointment"/> <link rel = "/linkrels/appointment/addTest" uri = "/slots/1234/appointment/tests"/> <link rel = "self" uri = "/slots/1234/appointment"/> <link rel = "/linkrels/appointment/changeTime" uri = "/doctors/mjones/slots?date=20100104@status=open"/> <link rel = "/linkrels/appointment/updateContactInfo" uri = "/patients/jsmith/contactInfo"/> <link rel = "/linkrels/help" uri = "/help/appointment"/> </appointment> Level 3 introduces discoverability, providing a way of making a protocol more self-documenting.
  22. Level 3: In another words, HATEOAS • Hypermedia As The Engine Of Application State • A RESTful API can be compared to a website. As a user, I only know the root URL of a website. Once I type in the URL (or click on the link) all further paths and actions are defined by other links. Those links may change at any moment, but as a user, all I need to know is the root URL and I’m still able to use the website. 22
  23. Recommended Book • REST in Practice • Domain Driven Design Quickly 23
  24. Micro Service Architecture • 변경된 서비스만 재배포  Side effect 최소화 • 자율성  각 서비스에 대한 자유로운 언어, 아키텍처, 아웃소싱 용이 • 병렬 개발, 타임 투 마켓, 린 개발 24
  25. 25
  26. Tip: monolithic and MSA 26 monolithic MSA Aggregation (데이터 통합) Backend 가 주도 Front 가 주도 Database 통합 데이터베이스 서비스 별 데이터베이스 필수 환경 WAS DevOps, PaaS (Grid Engine) 서비스 굵기 업무 비즈니스 기능별 구현 팀별, 10000 라인 이 하로?, 관심사별 Front 기술 JSP, Struts 등 Server-side rendering MVVM, AJAX 등 Client-side rendering Container / Packaging WAS / WAR Spring-Boot, Docker
  27. 27 Source: pwc
  28. MSA Trade-offs (from Martin Fowler) 28
  29. 29
  30. Conclusion • MSA 는 성공적인 SaaS 의 디자인 패턴: • Single-Page Application • Client-Side UI Composition • Front-End Data Aggregation • Back-end API 설계가 중요 • REST MM Level 3 – HATEOAS • Aggregation of data from multi micro-services • Multi-tenant Data Aggregation 30
  31. • UI Framework for MSA • AngalarJS • React • Polymer • VueJS • API Gateway • APIGee (Commercial) • Kong • OCE Gateway • Amazon Cognito (Public) • Spring Cloud • IAM • Amazon IAM (Public) • Spring Cloud • OCE IAM • Metering / Billing • Exem’s Metering Framework – BigData based • OCE Billing Micro Service Architecture Platforms for MSA
  32. Micro Service Architecture Design Factor for Front-end Single Page N-Screen & Responsive Dynamic & Real-time 32
  33. Front-end Image Server (Python) Business Logic Server (Java) Extended Role of Front-end in Cloud Applications Aggregator for multiple (polyglot programmed) micro-services Component Service (C) AJAX, RESTful Concurrent Cloud Applications are composed of multiple Micro Services and front-end serves as an aggregator of the services 33
  34. Writing One Page Web App Problems: One Page Web App  Low Cohesion and High Coupling <style> style for A style for B style for C </style> <html> element for A element for B element for C </html> <script> script for A script for B script for C </script> 34
  35. W3C Web Components <style> style for A style for B style for C </style> <html> element for A element for B element for C </html> <script> script for A script for B script for C </script> #A.html <style> style for A </style> <html> element for A </html> <script> script for A </script> #B.html <style> style for B </style> <html> element for B </html> <script> script for B </script> #C.html <style> style for C </style> <html> element for C </html> <script> script for C </script> #index.html <A> <A> <B> <B> <B> <C> 35
  36. Web Components : Implementations • Provides Cohesive Component Model • Component Composition by HTML markup • Dynamic Data Binding • Responsive Web by Material Design • Standard Polymer VueJS 36
  37. MVVM 37
  38. W3C Web Components • Custom elements • HTML imports • Template • Shadow DOM
  39. Why vue.js Angular and React are not a STANDARD While Polymer is heavy and needs Polyfill But Vue.js is 1. Fastest (compared with React and Angular) 2. Light (low dependencies) 3. Usable with jQuery or existing .js libraries,
  40. Tag based Components
  41. Data binding <div id="demo"> <p>{{message}}</p> <input v-model="message"> </div> <a v-bind:href="url"></a>
  42. v-model <span>Message is: {{ message }}</span> <br> <input type="text" v-model="message" placeholder="edit me">
  43. v-if:conditional element v-else <h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
  44. v-for <ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul> var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
  45. v-on <div id="example"> <button v-on:click="greet">Greet</button> </div> var vm = new Vue({ el: '#example', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // 方法内 `this` 指向 vm alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 alert(event.target.tagName) } } }) // 也可以在 JavaScript 代码中调用方法 vm.greet() // -> 'Hello Vue.js!'
  46. • init • created • beforeCompile • compiled • ready • attached • detached • beforeDestroy • destroyed Life cycle
  47. User defined Component (Your own HTML Tag) Vue.component('child', { // public attributes, properties props: ['msg'], template: '<span>{{ msg }}</span>’ data: function(){// private attributes, properties return {a:’aaa’, b:’bbb’} }, // behaviors methods:{ } }) <child msg="hello!"></child>
  48. One File Component - .vue <template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> module.exports = { data: function () { return { msg: 'Hello World!' } } } </script> <style scoped> h1 { color: #42b983; } </style>
  49. Lab time: Shopping Mall 만들기 49 기능 • 상품 카탈로그 • 검색 • 주문 비기능 • SPA (Single Page App) • Responsive Web • Front-end Data Aggregation (AJAX)
  50. Lab time: 간단한 SNS 만들기 50 코드: https://github.com/jinyoung/msa-social-network-example 기능 • 피드 • 글/파일/설문 비기능 • SPA (Single Page App) • Responsive Web • Front-end Data Aggregation (AJAX) • Lazy Loading • Pagination
  51. Lab time: CRM Application 만들기 51 Code here: https://github.com/TheOpenCloudEngine/mw4-example-crm 기능 • 고객등록 • 티켓발행 • 서포트 / 티켓 수정 비기능 • SPA (Single Page App) • Responsive Web • Front-end Data Aggregation (AJAX) • HATEOAS APIs • HATEOAS-Javascript Object Mapping • Data Binding
  52. Lab time: Test without UI 52 $ http localhost:8080/customer name="장진영" HTTP/1.1 201 Content-Type: application/json;charset=UTF-8 Date: Mon, 27 Nov 2017 03:29:44 GMT Location: http://localhost:8080/customer/1 Transfer-Encoding: chunked X-Application-Context: ticket:prod:8080 { "_links": { "customer": { "href": "http://localhost:8080/customer/1" }, "self": { "href": "http://localhost:8080/customer/1" } }, "address": null, "name": "장진영" }
  53. Lab time: Test without UI 53 $ http localhost:8080/ticket title="크리티컬 문제" raiser="http://localhost:8080/customer/1" HTTP/1.1 201 Content-Type: application/json;charset=UTF-8 Date: Mon, 27 Nov 2017 03:30:30 GMT Location: http://localhost:8080/ticket/2 Transfer-Encoding: chunked X-Application-Context: ticket:prod:8080 { "_links": { "raiser": { "href": "http://localhost:8080/ticket/2/raiser" }, "self": { "href": "http://localhost:8080/ticket/2" }, "supports": { "href": "http://localhost:8080/ticket/2/supports" }, "ticket": { "href": "http://localhost:8080/ticket/2" } }, "content": null, "issueDate": null, "raiserName": null, "status": null, "title": "크리티컬 문제", "type": null }
  54. Lab time: Navigating Hateoas API with Conventional AJAX Libraries 54 var xhr = new XMLHttpRequest(); xhr.open('GET', ”http://localhost:8080/tickets”); xhr.onload = function () { me.tickets = JSON.parse(xhr.responseText)._embedded.tickets; tickets.forEach(function(ticket){ var xhr = new XMLHttpRequest(); xhr.open('GET', tiket._links.raiser.href); xhr.onload = function () { var customer = JSON.parse(xhr.responseText); me.tickets.customer = (customer); } xhr.send(); } Verbose & Complex = Error-prone
  55. Lab time: Navigating Hateoas API with Conventional AJAX Libraries 55 var xhr = new XMLHttpRequest(); xhr.open('GET', ”http://mycompany.com:8080/tickets”); xhr.onload = function () { me.tickets = JSON.parse(xhr.responseText)._embedded.tickets; tickets.forEach(function(ticket){ var xhr = new XMLHttpRequest(); xhr.open('GET', http://www.facebook.com/users/” + tiket.raiserId); xhr.onload = function () { var customer = JSON.parse(xhr.responseText); me.tickets.customer = (customer); } xhr.send(); } Verbose & Complex = Error-prone
  56. 56 var backend = hybind("http://localhost:8080"); backend.$bind("ticket", this.tickets); this.tickets.$load().then(function(tickets){ tickets.forEach(function(ticket){ ticket.raiser.$load(); }); }); Lab time: Navigating Hateoas API with Hybind Intuitive & Clean = Robust
  57. Lab time: Invocation of Hateoas APIs with Hybind 57 Vue.component('crm-ticket', { … methods: { save: function () { var me = this; this.data.$save().then(function(){ me.editMode = false; }) }, delete: function () { var me = this; this.data.$remove().then(function(){ me.removed = true; }) }, …
  58. Case Study: uEngine5: A BPM as a Service 58
  59. BPM: Process Design 59
  60. BPM : Save Process and Run 60
  61. 61 BPM : Process Monitoring
  62. Requirements of uEngine5 1. Multi-tenant 2.Horizontally Scalable 3. Automated Operation 4. API Routing / Integration 5.Application Generation 62 1. SPOSAD Architecture 2. Micro Services Architecture 3. Work-load Distribution Engine 4.API Gateway 5.PaaS Platform requirements solutions
  63. 웹 브라우저 Client-driven Data Aggregation API GW (ZUUL) Service 기타 연동 어플리케이 션들 모니터링IAM CRUD Data Sync via REST REST Call Service Service Service Process Service Worklist Definition Service Container Part Issue Token ID/PWD Collect Usage MSA Reference Architecture: BPM DevOps Portal EUREKA 63
  64. Challenges on front-end • Vector-graphics 64 https://vuejs.org/v2/examples/svg.html
  65. Challenges on front-end • Data (BPMN Model) = View (SVG Graphics) 65 데이터체인지 뷰체인지
  66. Challenges on front-end • Data (BPMN Model) = View (SVG Graphics) 66 데이터 Undo (복구) 뷰 복구
  67. Challenges on front-end • Multi-tenancy Data isolation and Customization
  68. Running Sample App - login 68 Default login id / pw is jyjang@uengine.org / test Login will be processed through the IAM server: http://iam.uengine.io:8080
  69. Example: Auto Insurance - multi-tenancy 69 Java Back-end + RDB (Spring REST/JPA/MySQL) NoSQL (Couchbase Bucket API) Tenant-dataCommon-data
  70. Running Sample App – Self Service 70 필드추가
  71. Example: Auto Insurance – IAM & API GW 71 Spring REST/JPA/MySQL Couchbase Bucket API API GW • Token Validation • JSON trimming, transformation • Cross Origin Resource Sharing • Adding Hateoas links* IAM Id/pwd JWT token
  72. Self Service Portal <ssp-class/> 72 필드추가
  73. Challenges on Back-end • API Level 3 • Productivity
  74. API 수준: HATEOAS { "_links": { "instantiation": { "href": "http://localhost:8080/definition/instance/process.json" }, "raw": { "href": "http://localhost:8080/definition/raw/process.json" }, "self": { "href": "http://localhost:8080/definition/process.json" } }, "directory": false, "name": "process.json", "path": "process.json" } { "_links": { "definition": { "href": "http://localhost:8080/definition/process.json" }, "role-mapping": { "href": "http://localhost:8080/instance/3451/role- mapping/{roleName}"}, "self": { "href": "http://localhost:8080/instance/3451" }, "stop": { "href": "http://localhost:8080/instance/3451/stop" }, "suspend": { "href": "http://localhost:8080/instance/3451/stop" }, "variables": { "href": "http://localhost:8080/instance/3451/variables" } }, "name": "Volatile_0" } POST: instantiation 프로세스 개시 POST: stop (멈춤) POST: suspend GET: variables (변수 목록 보기) Definition instance 74
  75. Generated Entity Classes (JPA) • All Entity Codes are POJO Classes that are described with Java Annotations meaning entity field descriptions and relationships. 75
  76. Repository  REST, JSON 76 Entity PK type
  77. Generated REST (Level 3) Service • CRUD • Pagination / Sorting • HATEOAS 77
  78. Association REST 78 # http://www.auto.com:8080/customers [{ ”id" : 1, ”firstName": ’jinyoung', ”lastName": ’jang', "tenantProperties": 'http://mongodb.auto.com:8080/tenantData/td_1'}, {...},{...},....] # http://mongodb.auto.com:8080/tenantData/td_1 { "ext1": 'aaa’, "ext2": 'bbb’ }
  79. Entity, Resource, Service 선택 우선순위 • DDD(Domain Driven Design) 분석 기법 적용한 최적의 생산성 도메인 용어 기반 도메인 클래스 후보 도출 도메인 클래스가 Entity 유형인가? Spring Data Rest 사용 @Entity 로 선언, JPA 매핑, Repository 생성 빠른 CRUD / REST MM 3 Level 의 구현 (라인수 매우 적음) Resource Model로 만들 수 있는가? 서비스로 개발 직접 Spring MVC 를 사용하여 RequestMapping 구현 (라인수 매우 많음) Spring Hateoas 프레임워크만 사용, Resource 로 포장 Resource를 서비스로 Expose (라인 수 중간) 각 도메인 클래스에 대하여 (최대한 지양) N N Y Y
  80. DDD 적용 예시: Entity, Value Object, Aggregation Root • DDD(Domain Driven Design) 분석 기법 적용한 최적의 생산성 Source: https://www.slideshare.net/madvirus/ddd-final
  81. The Length of Code 81 323Lines For Developing Full-CRUD, RESTful, MSA-based, Material- Designed, Responsive, Grid+Form, Multi-tenant and Self- Served Application: • Number of fields of the entity: 10 • Total lines of code per an entity: 92 for front-end, 215 for domain class, 16 lines for repository.
  82. How it works Common Metadata Domain Model Classes Class model for tenant1 ORM for tenant1 Common class model Metadata of Tenant1 Metadata of Tenant2 Metadata of Tenant3 Class model for tenant2 ORM for tenant2 Class model for tenant3 ORM for tenant3 Override by tenantID
  83. Model metadata Front (Vue.js / polymer) REST backend (Spring hateoas) ORM (Spring JPA) Domain Class Developer generates generates generates How it works
  84. Model metadata Front (Vue.js / polymer) REST backend (Spring hateoas) ORM (Spring JPA) Domain Class Developer generates generates generates How it works ALPS IETF Standard for metadata
  85. Multi-tenant / Self service Support Self service Self service portal • Add new attribute • Attributes can be String, number, Data from referenced class (table) • Change the title, order of attributes • Hide/Show attribute
  86. Design factors on developing cloud applications 1.Don't code your application directly to a specific topology 2.Do not assume the local file system is permanent 3.Don't keep session state in your application 4.Don't log to the file system 5.Don't assume any specific infrastructure dependency 6.Don't use infrastructure APIs from within your application 7.Don't use obscure protocols 8.Don't rely on OS-specific features 9.Don't manually install your application 86
  87. 프로젝트 구성 • APIs-and-Domain • 공통 API Contracts • 공통 도메인 클래스 • 나머지 서비스들이 모두 이를 import 함 • Definition-Service • 프로세스 정의 보존 • 프로세스 정의 열람 • 프로세스 정의 배포/수정 • 프로세스 정의 버전관리 • Process Service • 프로세스 실행과 관련한 모든 서비스 • Workspace Service • 워크아이템 처리 • 업무 화면 연계 87
  88. 서비스의 호출 방식 2가지 • 프론트-엔드 에서 • 마이크로 서비스 간 (inter-microservice call) HTTPClient 로 REST 호출 Feign 을 사용, @Autowired 로 proxy 객체리턴 Ribbon 이 Eureka 를 통하여 직접 마이크로 서비스가 로드밸런싱 된 대상을 선택 AJAX 로 REST 호출 Hybind 를 사용, 자바스크립트객체와 Resource 바인딩 Zuul 을 경유하여 Eureka 에서 발견된 path 에 따른 서비스가 라우팅 88
  89. Front-end 호출 코드 89
  90. Front-end 호출 경로 웹 브라우저 API GW (ZUUL) Process WorklistDefinition EUREKA /definition/** /instance/** /role-mapping/** /variables/** /work-item/** Definition: ip1, ip2 Instance: ip3 Worklist: ip4, ip5 90
  91. Inter-Microservices Call (Java) @Autowired DefinitionService definitionService; public Object getDefinition(String defPath) throws Exception { Object returned = definitionService.getXMLDefinition(defPath); } 91
  92. Inter-microservices Call 웹 브라우저 API GW (ZUUL) Process Worklist Definition EUREKA /definition/** /instance/** /role-mapping/** /variables/** /work-item/** Definition: ip1, ip2 Instance: ip3 Worklist: ip4, ip5 Ribbon Ribbon Zuul 을 경유하지 않고 직접 내부 IP 로 접근 92
  93. 공통 참조 모듈 • Bounded Context 도메인 클래스들 • Service Contract 들 93
  94. 공통 참조 모듈: Service Contract ---- Service Id 이걸로, Autowired 시에 식별됨 94
  95. 각 Service 들의 설정 spring: application: name: bpm server: port: 8090 servletPath: / eureka: client: serviceUrl: defaultZone: http://localhost:9090/eureka/ healthcheck: enabled: true instance: statusPageUrlPath: ${server.servletPath}info healthCheckUrlPath: ${server.servletPath}health 내가 누구다 (serviceId=bpm) 부트업 되면서 출생신고할 동사무소(유레카) 주소 95
  96. 각 Service 들의 설정 @SpringCloudApplication @EnableEurekaClient @EnableFeignClients(basePackageClasses = {DefinitionService.class}) public class uEngine5Application extends Metaworks4BaseApplication { protected uEngine5Application(DataSource dataSource, JpaProperties properties, ObjectProvider<JtaTransactionManager> jtaTransactionManagerProvider, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) { super(dataSource, properties, jtaTransactionManagerProvider, transactionManagerCustomizers); } public static void main(String[] args) { SpringApplication.run(uEngine5Application.class, args); } } 유레카에 등록시켜달라 인터-마이크로서비스간 호출할 대상 서비스 목록 96
  97. EUREKA Registry 출근부 97
  98. Lab time: building spring-boot $ git clone https://github.com/TheOpenCloudEngine/uEngine5-base.git Cloning into 'uEngine5-base'... remote: Counting objects: 4420, done. remote: Compressing objects: 100% (164/164), done. remote: Total 4420 (delta 123), reused 234 (delta 76), pack-reused 4124 Receiving objects: 100% (4420/4420), 6.78 MiB | 708.00 KiB/s, done. Resolving deltas: 100% (2062/2062), done. Checking connectivity... done. 1. 먼저, 샘플 애플리케이션을 다운로드 받는다 98
  99. Lab time: build Spring Boot Application $ cd uEngine5-base/ $ mvn package –B [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] uEngine-five-api [INFO] uEngine5 [INFO] uEngine5-definition-service [INFO] uEngine5-process-service [INFO] uEngine5-standalone-server [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building uEngine-five-api 1.0.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] Downloading: https://repo.maven.apache.org/maven2/org/springframework/security/spring-security-core/maven- metadata.xml [INFO] Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/springframework/security/spring-security- core/maven-metadata.xml [INFO] Downloading: https://repo.spring.io/libs-release 99
  100. Lab time: Running Registry and Proxy 1. 가장 먼저 실행할 것은 Registry (Eureka 서버) 임. [동사무소] 2. 다음으로 실행할 것은 Proxy (Zuul 서버) 임. [이정표 서비스] $ cd uengine-proxy-server/ $ mvn spring-boot:run $ cd uengine-registry-server/ $ mvn spring-boot:run 100
  101. Lab time: Running Micro Services 1. Run and test Definition Service 2. Run and test Process Service $ cd definition-service/ $ mvn spring-boot:run –Dserver.port=8088 -Drun.arguments="--spring.profiles.active=msa" Launch another shell and confirm server is up: $ http localhost:8088/definition $ cd process-service/ $ mvn spring-boot:run –Dserver.port=8089 -Drun.arguments="--spring.profiles.active=msa" Launch another shell and check the server is up: $ http localhost:8089/instance 101
  102. Lab time: Test Services { "_links": { "instantiation": { "href": "http://localhost:8080/definition/instance/process.json" }, "raw": { "href": "http://localhost:8080/definition/raw/process.json" }, "self": { "href": "http://localhost:8080/definition/process.json" } }, "directory": false, "name": "process.json", "path": "process.json" } { "_links": { "definition": { "href": "http://localhost:8080/definition/process.json" }, "role-mapping": { "href": "http://localhost:8080/instance/3451/role- mapping/{roleName}"}, "self": { "href": "http://localhost:8080/instance/3451" }, "stop": { "href": "http://localhost:8080/instance/3451/stop" }, "suspend": { "href": "http://localhost:8080/instance/3451/stop" }, "variables": { "href": "http://localhost:8080/instance/3451/variables" } }, "name": "Volatile_0" } POST: instantiation 프로세스 개시 POST: stop (멈춤) POST: suspend GET: variables (변수 목록 보기) Definition instance 102
  103. Lab time: Deploy Definition $ http POST localhost:8080/definition/raw/process2.json < process.json HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Date: Tue, 21 Nov 2017 10:53:20 GMT Transfer-Encoding: chunked X-Application-Context: definition:msa:8080 { "_links": { "instantiation": { "href": "http://localhost:8080/instance?defPath=/process2.json" }, "raw": { "href": "http://localhost:8080/definition/raw//process2.json" }, "self": { "href": "http://localhost:8080/definition//process2.json" } }, "directory": false, "name": "process2.json", "path": "/process2.json" } This is the next action link 103
  104. Lab time: Run a Process Instance $ http POST http://localhost:8080/instance?defPath=/process2.json { "_links": { "definition": { "href": "http://localhost:8080/definition/process.json" }, "role-mapping": { "href": "http://localhost:8080/instance/3451/role-mapping/{roleName}"}, "self": { "href": "http://localhost:8080/instance/3451" }, "stop": { "href": "http://localhost:8080/instance/3451/stop" }, "suspend": { "href": "http://localhost:8080/instance/3451/stop" }, "variables": { "href": "http://localhost:8080/instance/3451/variables" } }, "name": "Volatile_0" } This is the next action link 104
  105. Lab time: Run the front-end server $ npm install $ npm run dev Id: jyjang@uengine.org Pw: test 105
  106. Lab time: Running all Services with Compose file services: process-api: image: uengine-five-process:latest ports: - "8089:8080” depends_on: definition-api definition-api: image: uengine-five-definition:latest ports: - "8088:8080" depends_on: registry proxy: image: uengine-proxy-server:latest ports: - "8080:8080" depends_on: registry registry: image: uengine-registry-server:latest ports: - "8761:8761" Registry Proxy Definition Process Front-End 106
  107. Lab time: Building docker images $ cd definition-service $ mvn package -B $ docker build –t uengine-five-definition . $ cd ../process-service $ mvn package -B $ docker build –t uengine-five-process . $ cd ../uengine-proxy-server $ mvn package -B $ docker build –t uengine-proxy-server . $ cd ../uengine-registry-server $ mvn package -B $ docker build –t uengine-registry-server . $ docker images REPOSITORY TAG IMAGE ID definition latest fc1db168d69d process latest 61bcb1e489f0 registry latest 12e06df7a34a proxy latest 53efac1deda3 107
  108. Lab time: Using docker-maven-plugin $ cd definition-service $ mvn package docker:build –B $ cd ../process-service $ mvn package docker:build –B $ cd ../uengine-proxy-server $ mvn package docker:build –B $ cd ../uengine-registry-server $ mvn package docker:build –B $ docker images REPOSITORY TAG IMAGE ID uengine-five-definition latest fc1db168d69d uengine-five-process latest 61bcb1e489f0 uengine-registry-server latest 12e06df7a34a uengine-proxy-server latest 53efac1deda3 108
  109. Lab time: Starting up the stack $ docker stack deploy -c docker-compose.yml uengine Creating network uengine_webnet Creating service uengine_definition-api Creating service uengine_process-api Creating service uengine_registry Creating service uengine_proxy $ docker service ls $ docker stack rm uengine 109
  110. Lab time: Scale services by changing Compose file 110
  111. 자동화를 통해 릴리스 가능한 소프트웨어를 짧은 기간 반복하여 생산하는 것. 효과적인 소프트웨어를 더 자주 출시. 지속적 배포는 항상 배포만을 의미하는 것이 아니라, 코드가 언제나 릴리스 가능하도록 준비된 상태임을 보장하는 약속이자 철학. Devops
  112. DevOps: 온라인코드에디팅
  113. DevOps: 코드리뷰
  114. DevOps: 배포 파이프라인 • GitLab 기반 Pipeline • 코드 변경시 (git push) 자동 빌드 • 빌드 후 도커 이미지 동적 생성 • 생성 후 클러스터 디플로이 • 테스트 자동화 • 서비스 가용성 테스트 실패시 자동 롤백
  115. DevOps: 칸반(스크럼)보드
  116. DevOps: 이슈트래킹
  117. DevOps 기능 개발 코드리뷰 이슈 트래킹 배포 자동화 프로젝트 관리 커밋 117
  118. Zero Down-time DeploymentZero Down-time Deployment 118
  119. Strategy: Blue/Green Now, Green is production 119
  120. Strategy: Blue/Green Now, Blue is production 120
  121. Strategy: Blue/Green 앗, 롤백 요청! Now, Green is production again 121
  122. Strategy: Blue/Green 롤백 가능 허용시간 경과  Shutdown Green servers Deploy NEW-NEW version as Green NEW-NEW VERSION 122
  123. Strategy: Blue/Green Now, Green(NEW-NEW) is production NEW-NEW VERSION 123
  124. Blue/Green Deployment with Zuul 124
  125. Canary Deployment 125
  126. Canary Deployment: Facebook 126
  127. 프라이빗 PaaS 구축하기 • 상용 제품 구매 vs. 오픈소스로 구축 • 대기업 / 중견기업 / 스타트업 별 상황 • 프로젝트 성격 • 제공자로서 • 퍼블릭 PaaS 플랫폼 제공자인 경우 – 오픈소스로 구축 • E.g. 블루믹스의 경우 최초 Pivotal 의 도움을 받아 구축 • 사용자로서 • 빠른 시장 진입 – 퍼블릭 PaaS • But, 적당한 PaaS 가 존재하지 않거나 시장에서 독자적인 DevOps 환경이 필요할 때 • – uEngine 의 케이스 127
  128. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service Open Cloud Engine: A Private PaaS 128
  129. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service : Workload Distribution Engine – Mesosphere’s DCOS DCOS: • Proven and • Powerful 129
  130. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service : CI/CD Tool - GitLab 130
  131. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service : Microservice Chassis – Spring Boot 131
  132. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service : Microservice API G/W and Registry – Spring Cloud / Netflix OSS 132
  133. Open Cloud Engine Client-driven Data Aggregation API GW (ZUUL) Service 3rd Party Apps BillingIAM Data Sync via REST REST Call Service Container Part Issue Token ID/PWD Collect Usage DevOps Portal EUREKA Service Service Service : Front-End – Vue JS, Hybind and Spring Data Rest 133
  134. Open Cloud Engine: Management Console - mimics public PaaS’ UI/UX 134
  135. Open Cloud Engine: Management Console – Creating an App 135
  136. Open Cloud Engine: Management Console – Managing an App 136
  137. Open Cloud Engine: Management Console – Managing an App - Environment 137
  138. Open Cloud Engine: Management Console – CI/CD Settings 138
  139. Open Cloud Engine: Management Console – Source Control – SSO with GitLab 139
  140. References and Resources • http://github.com/TheOpenCloudEngine • www.docker.com • www.uengine.org • www.metaworks4.io 140
Advertisement