Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java/Spring과 Node.js의공존

27,618 views

Published on

playnode 2015 컨퍼런스에서 발표한 내용.

자바/스프링같은 "관리가능"하지만 뻔한 아키텍처와 프레임웍으로 구축된 리거시 시스템에서, Apache Thrift를 활용하여, Node.js와 React 같은 "관리불가능"하지만 재미있는 삽질을 해보자~는 얘기를, 뻔한 게시판을 베베꼬아서 만든 예제 코드를 통해 장황하게 설명.

예제 코드: https://github.com/iolo/playnode-springboard-demo

Published in: Software
  • Login to see the comments

Java/Spring과 Node.js의공존

  1. 1. Java/Spring과 Node.js의 공존 Java/Spring 전성시대에 Node.js가 살아남는 법 Dongsu Jang <iolothebard at gmail dot com>
  2. 2. TOC • BEGIN • AS-IS • TO-BE • VS • CODE • END
  3. 3. BEGIN JUST FOR FUN
  4. 4. 개발자여, 불가능한 꿈을 꾸어라 • java8, tomcat8, spring-boot, spring-cloud, jpa… • mongodb, cassandra, couchbase, elasticsearch… • python, ruby, scala, rust, clojure, julia… • docker, kubernetes, mesos, microservices… • nginx, redis, play framework, akka, spark, node.js, django, flask… • angular, react, EcmaScript6… • IE8 없는 세상…
  5. 5. 그러나, 리얼리스트가 되라 • 현실은 자바 천국… • 스프링 전성 시대… • 봄날은 생각보다 오래 가더라… • “관리가능”한 아키텍쳐의 무거움 • 배포할 줄 아는 마지막 개발자가 퇴사 했어요 OTL • 지금 서비스 하는 버전이 svn 에 있는 거 보다 더 최신인데요 -_-; • 롤백할께요 ㅠ,.ㅠ • 서버 늘려야겠죠? 구매 요청할께요 ^^; • IE8 테스트할 PC가 없어요? XP요~ 그래도… 재밌는 거 해보고 싶어요!
  6. 6. AS-IS AS GOOD AS IT GETS
  7. 7. AS-IS • Java 5.x/6.x/7.x… with Tomcat 5.x/6.x/7.x… • Apache Web Server with mod_jk/ jk2/webapp… • Spring Framework with Spring- WebMVC/Struts… • Template Engine: JSP/Velocity/ Freemark… • DAO: MyBatis/Hibernate/JDBC… • Cache: EHCache/OSCache/Map… • RDBMS: Oracle/MySQL…
  8. 8. AS-IS tomcatapache webapp (war) MySQL tomcat … mod_jk apache … webapp (war) mod_jk MySQL AJPHTTP
  9. 9. AS-IS Spring Framework with Spring-WebMvc/Struts… JVM Template Engine JSP/Velocity/Freemarker… DAO JDBC/MyBatis/Hibernate… Cache EHCache/OSCache/Map… Tomcat Servlet Container Model View Controller
  10. 10. TO-BE STAY HUNGRY STAY FOOLISH
  11. 11. TO-BE • Node.js • Express • Thrift • Redis • React • 원래 있던 거…
  12. 12. TO-BE tomcatapache webapp (war) MySQL tomcat … mod_jk apache … webapp (war)mod_jk MySQL node.js API server + @ redis pm2 nginx React Server React Client node.js … thrift AJPHTTP + @ + @
  13. 13. TO-BE java Thrift Server (thrift/swift/nifty) Thrift Client (node-thrift) node.js RESTful API Server Isomorphic Rendering Server 원래 있던 거… (war) Single Page Webapp browser express react browerify, babel, … react
  14. 14. VS I WANT TO BELIEVE
  15. 15. tomcat-spring-webmvc 100 concurrent user표 1 Label # Samples Average Min Max Std. Dev. Error % Throughput KB/sec Avg. Bytes forum_list 1000 4 0 757 41.15 0% 35.9 32.95 939 login_post 1000 13 1 120 30.97 0% 36.9 30.72 852 post_list 1000 12 2 116 12.68 0% 36.9 667.9 18510.5 post_view 1000 7 2 117 8.32 0% 37 335.97 9301.4 post_save 1000 27 4 145 32.91 0% 37 716.45 19836.4 comment_save 1000 21 3 133 31.21 0% 37 364.2 10083.9 TOTAL 6000 14 0 757 29.78 0% 204 1975.94 9920.5
  16. 16. tomcat-spring-webmvc 100 concurrent user
  17. 17. nodejs-express-thrift 100 concurrent user표 1 Label # Samples Average Min Max Std. Dev. Error % Throughput KB/sec Avg. Bytes forum_list 1000 3 0 420 20.68 0% 37 17.03 471.6 login_post 1000 16 1 248 34.76 0% 37.5 10.16 277 post_list 1000 2 0 113 5.2 0% 37.8 308.3 8361.9 post_view 1000 1 0 107 3.55 0% 37.8 12.61 342 post_save 1000 7 1 109 15.51 0% 37.8 8.93 242 comment_save 1000 8 1 105 17.43 0% 37.8 8.93 242 TOTAL 6000 6 0 420 19.82 0% 209.9 339.39 1656.1
  18. 18. nodejs-express-thrift 100 concurrent user 애고… 의미없다~
  19. 19. tomcat-spring-webmvc 500 concurrent user표 1 Label # Samples Average Min Max Std. Dev. Error % ThroughputKB/sec Avg. Bytes forum_list 5000 782 1 7142 849.82 0% 25.6 23.49 939 login_post 5000 1453 1 10011 1361.53 0% 25.7 21.38 852 post_list 5000 2539 2 13975 2293.41 0% 25.7 2229.89 88919.8 post_view 5000 1678 2 11447 1617.18 0% 25.7 1067.33 42560.5 post_save 5000 3512 5 14182 2853.35 0% 25.7 2384.92 95178.4 comment_save 5000 2726 4 15547 2247.67 0% 25.7 1154.3 46070.7 TOTAL 30000 2115 1 15547 2181.63 0% 152 6793.39 45753.4
  20. 20. tomcat-spring-webmvc 500 concurrent user
  21. 21. nodejs-express-thrift 500 concurrent user표 1 Label # Samples Average Min Max Std. Dev. Error % ThroughputKB/sec Avg. Bytes forum_list 5000 17 0 407 36.84 0% 145.3 66.91 471.6 login_post 5000 58 1 937 79.5 0% 146.5 39.63 277 post_list 5000 38 0 976 89.75 0% 147.5 6517.04 45252.7 post_view 5000 15 0 724 39.26 0% 147.4 49.23 342 post_save 5000 39 1 722 60.66 0% 147.4 34.83 242 comment_save 5000 44 1 969 72.13 0% 147.5 34.85 242 TOTAL 30000 35 0 976 67.72 0% 831 6333.24 7804.5
  22. 22. nodejs-express-thrift 500 concurrent user
  23. 23. CODE SHOW ME THE CODE
  24. 24. springboard forums comments posts users 게시판! ㅋㅋㅋ
  25. 25. springboard /forum_list /signup /post_list /post_view /login /post_form /comment_save/post_save
  26. 26. 원래 있던거…├── src │   ├── main │   │   ├── jaja │   │   │   └── kr │   │   │   └── iolo │   │   │   └── springboard │   │   │   ├── Comment.java │   │   │   ├── Forum.java │   │   │   ├── Post.java │   │   │   ├── Springboard.java │   │   │   ├── SpringboardImpl.java │   │   │   ├── User.java │   │   │   ├── controller │   │   │   │   ├── CommentSaveController.java │   │   │   │   ├── ForumListController.java │   │   │   │   ├── LoginController.java │   │   │   │   ├── PostFormController.java │   │   │   │   ├── PostListController.java │   │   │   │   ├── PostSaveController.java │   │   │   │   ├── PostViewController.java │   │   │   │   └── SignupController.java │   │   └── resources │   │   └── templates │   │   ├── forum_list.html │   │   ├── login.html │   │   ├── post_form.html │   │   ├── post_list.html │   │   ├── post_view.html │   │   └── signup.html 안봐도 비디오~
  27. 27. Thrift Server <dependency>
 <groupId>org.apache.thrift</groupId>
 <artifactId>libthrift</artifactId>
 <version>0.9.3</version>
 </dependency>
 <dependency>
 <groupId>com.facebook.swift</groupId>
 <artifactId>swift-annotations</artifactId>
 <version>0.15.1</version>
 </dependency>
 <dependency>
 <groupId>com.facebook.swift</groupId>
 <artifactId>swift-codec</artifactId>
 <version>0.15.1</version>
 </dependency>
 <dependency>
 <groupId>com.facebook.swift</groupId>
 <artifactId>swift-service</artifactId>
 <version>0.15.1</version>
 </dependency>
 <dependency>
 <groupId>com.facebook.nifty</groupId>
 <artifactId>nifty-core</artifactId>
 <version>0.15.1</version>
 </dependency> IDL 작성하기 귀찮으니 facebook-swift!!
  28. 28. Thrift Server ├── src │   ├── main │   │   ├── java │   │   │   └── kr │   │   │   └── iolo │   │   │   └── springboard │   │   │   ├── ... │   │   │   ├── SpringboardApplication.java │   │   │   ├── cache │   │   │   │   ├── CacheService.java │   │   │   │   ├── DummyCacheService.java │   │   │   │   └── RedisCacheService.java │   │   │   └── thrift │   │   │   ├── TComment.java │   │   │   ├── TForum.java │   │   │   ├── TPost.java │   │   │   ├── TSpringboard.java │   │   │   ├── TSpringboardImpl.java │   │   │   └── TUser.java │   │   └── resources │   │   ├── config │   │   │   └── application.properties │   │   ├── logback.xml │   │   ├── static │   │   │   └── index.html 설정하기 귀찮아서 spring-boot 성능테스트를 위해 redis Node.js 와의 통 신을 위해 thrift!!!
  29. 29. Thrift Server import com.facebook.swift.service.ThriftMethod;
 import com.facebook.swift.service.ThriftService;
 
 import java.util.List;
 
 @ThriftService("Springboard")
 public interface TSpringboard {
 
 @ThriftMethod("getUsers")
 List<TUser> getUsers();
 
 @ThriftMethod("getUserByUsernameAndPassword")
 TUser getUserByUsernameAndPassword(String username, String password);
 
 @ThriftMethod("getUser")
 TUser getUser(int userId);
 
 /* . . . */
 
 @ThriftMethod("createComment")
 int createComment(TComment post);
 
 @ThriftMethod("updateComment")
 boolean updateComment(TComment post);
 
 @ThriftMethod("deleteComment")
 boolean deleteComment(int commentId);
 
 } IDL 작성하기 귀찮으니 facebook-swift!!
  30. 30. Thrift Server import com.facebook.swift.codec.ThriftField;
 import com.facebook.swift.codec.ThriftStruct;
 
 @ThriftStruct("Comment")
 public final class TComment {
 
 private int id;
 private int userId;
 private int postId;
 private String content;
 private String createdAt;
 
 @ThriftField(1)
 public int getId() { return id; }
 
 @ThriftField(2)
 public int getUserId() { return userId; }
 
 /* . . . */
 
 @ThriftField
 public void setId(int id) { this.id = id; }
 
 @ThriftField
 public void setUserId(int userId) { this.userId = userId; }
 
 /* . . . */
 
 } IDL 작성하기 귀찮으니 facebook-swift!!
  31. 31. Thrift Serverimport com.facebook.nifty.processor.NiftyProcessor;
 import com.facebook.swift.codec.ThriftCodecManager;
 import com.facebook.swift.service.ThriftServer;
 import com.facebook.swift.service.ThriftServerConfig;
 import com.facebook.swift.service.ThriftServiceProcessor;
 import kr.iolo.springboard.thrift.TSpringboard;
 
 @SpringBootApplication
 public class SpringboardApplication {
 
 @Autowired TSpringboard springboard;
 
 public static void main(String[] args) {
 final ApplicationContext ctx = SpringApplication.run( SpringboardApplication.class, args);
 
 NiftyProcessor niftyProcessor = new ThriftServiceProcessor( new ThriftCodecManager(), new ArrayList<>(), springboard);
 ThriftServerConfig thriftServerConfig = new ThriftServerConfig().setPort(9876);
 ThriftServer server = new ThriftServer( niftyProcessor, thriftServerConfig);
 server.start();
 Runtime.getRuntime().addShutdownHook(new Thread() {
 @Override
 public void run() { server.close(); }
 }); } 
 } IDL 작성하기 귀찮으니 facebook-swift!!
  32. 32. Thrift Client $ mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get -DremoteRepositories=central::default::http:// repo1.maven.apache.org/maven2 -Dartifact=com.facebook.swift:swift2thrift-generator- cli:RELEASE:jar:standalone -Ddest=/tmp/ $ java -cp target/classes:/tmp/swift2thrift-generator- cli-0.15.1-standalone.jar com.facebook.swift.generator.swift2thrift.Main -v -out src/main/thrift/springboard.thrift -namespace java kr.iolo.springboard.thrift -package kr.iolo.springboard.thrift TSpringboard TUser TForum TPost TComment $ cat src/main/thrift/springboot.thrift . . . $ thrift -v -r -o src/main/node —gen js:node src/main/thrift/springboard.thrift
  33. 33. Thrift Client var thrift = require('thrift');
 
 var conn = thrift.createConnection('localhost', 9876, {debug: true, max_attempts: 5});
 
 conn.on('error', function (err) {
 console.error('*** THRIFT CONNECTION ERROR:', err);
 });
 
 process.on('exit', function () {
 console.log('*** BYE ***');
 conn.end();
 }); var Springboard = require('./gen-nodejs/springboard');
 var Types = require(‘./gen-nodejs/springboard_types'); 
 var springboard = thrift.createClient( Springboard, conn);
  34. 34. RESTful API Server var express = require('express');
 
 var app = express();
 
 app.set('json replacer', function (key, value) {
 if (value instanceof thrift.Int64) {
 return value.toNumber(true);
 }
 return value;
 });
 
 app.use(require('cors')());
 app.use(require('body-parser').json());
 
 app.get('/posts/:postId', function (req, res, next) {
 var postId = req.params.postId; 
 springboard.getPost(postId, function (err, data) {
 if (err) {
 return next(err);
 }
 res.json(data);
 });
 });
  35. 35. Single Page Webapp with React …
  36. 36. Isomorphic Rendering Server with React …
  37. 37. 소스코드 https://github.com/iolo/ playnode-springboard-demo
  38. 38. END SIMON SAYS
  39. 39. ­ John Doe “Do not reinvent the wheel, but make it perfect!”
  40. 40. ­ John Doe “Reinvent the wheel, knowing when and how.”
  41. 41. – 孔子 “溫故而知新 可以爲師矣”
  42. 42. References • Spring Framework: http://projects.spring.io/spring-framework/ • Node.js: https://nodejs.org • Apache Thrift: https://thrift.apache.org • Facebook Swift: https://github.com/facebook/swift/ • Facebook React: https://facebook.github.io/react/ • Microservices by Martin Fowler: http://martinfowler.com/articles/microservices.html • Building Microservices with Spring Boot and Apache Thrift • Part 1: https://dzone.com/articles/building-microservices-spring • Part 2: http://bsideup.blogspot.kr/2015/04/spring-boot-thrift-part2.html • Part 3: http://bsideup.blogspot.kr/2015/04/spring-boot-thrift-part3.html • Isomorphic JavaScript: The Future of Web Apps: http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/ • How to Implement Node + React Isomorphic JavaScript & Why it Matters • https://strongloop.com/strongblog/node-js-react-isomorphic-javascript-why-it-matters/ • From AngularJS to React: The Isomorphic Way • https://blog.risingstack.com/from-angularjs-to-react-the-isomorphic-way/ • Going Isomorphic with React • https://bensmithett.github.io/going-isomorphic-with-react/ • and Google Search https://google.com, StackOverflow http://stackoverflow.com, GitHub https://github.com …
  43. 43. Q&A MAY THE SOURCE BE WITH YOU
  44. 44. Thanks THAT’S ALL FOLKS

×