<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peerapat A</title>
    <description>The latest articles on DEV Community by Peerapat A (@nuboat).</description>
    <link>https://dev.to/nuboat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F357146%2Fc42a6576-6ea2-4b49-8631-4dab7fd13d2a.png</url>
      <title>DEV Community: Peerapat A</title>
      <link>https://dev.to/nuboat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nuboat"/>
    <language>en</language>
    <item>
      <title>เราไม่ทิ้งกัน clone v. open source สำหรับงานแบบนี้ในอนาคต</title>
      <dc:creator>Peerapat A</dc:creator>
      <pubDate>Wed, 01 Apr 2020 07:45:24 +0000</pubDate>
      <link>https://dev.to/nuboat/clone-v-open-source-5ge9</link>
      <guid>https://dev.to/nuboat/clone-v-open-source-5ge9</guid>
      <description>&lt;p&gt;ทีมท่าแซะ ทำงานไม่เป็น ดีแต่ปากดีไปวันๆ ได้ฟังพี่โดม Live สัมภาษณ์หนึ่งในทีมผู้พัฒนาระบบเรื่องกาทำงานของระบบ "เราไม่ทิ้งกัน" เท่าที่จับใจความได้ คือรันบน K8S GCP, ทุก services แบ่งออกมาเป็น microservices ของใครของมัน มีการใช้งาน Redis เป็น Database จากการฟังแล้วก็นึกสนุก อ่ะงั้นเราจะมาลองออกแบบ รวมถึงออกเป็น open source สำหรับใครที่อยากได้ไว้ใช้เลยดีกว่า ว่าแล้วก็เลย draft system architecture คร่าวๆ ไว้ก่อน แต่เพื่อความสบายใจ เลยขอเพิ่มส่วน disk persists ด้วย PostgreSQL DB&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2Lk89aoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u57b3rbjo9v9zkactijz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2Lk89aoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u57b3rbjo9v9zkactijz.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ก่อนจะมาถึงส่วนออกแบบกัน เรามาย้อนดู fact กันก่อนคือ high throughput สูงสุดที่ 2M / 10นาที หรือมี traffic สูงสุดที่ 3334 TPS สำหรับงานนี้ หรือเราต้องการระบบที่แต่ละ services สามารถรับโหลดได้สูงสุดที่ 3334 TPS ตั้งแต่ Static html, eConsent, Persist, OTP, Captcha ... &lt;/p&gt;

&lt;h3&gt;
  
  
  ต้องบอกก่อนว่าระบบนี้น่าจะไม่เหมือนกับตัวจริงที่ทางทีม KTB พัฒนา แต่มันไม่ถือว่าเป็นสาระของการ open source
&lt;/h3&gt;

&lt;p&gt;เริ่มกันเลยดีกว่า ถ้าทุกคนจำได้ว่าระบบนี้เริ่มด้วยการขอ consent ให้เรา accept term ก่อนที่จะเริ่มเข้าไปหน้ากรอกข้อมูล ในส่วนนี้นั้นควรมีการเก็บ cookie_id or something ไว้ก่อนเพื่อให้ธุรกรรมที่เกิดหลังจากนี้ถูกต้องตามหลักการขอ consent ก่อน&lt;/p&gt;

&lt;p&gt;POST /econsent/submit&lt;br&gt;
KEY: "random_uuid", VALUE: "7bb376c2b20f44d2b16114e8d0957778"&lt;br&gt;
KEY: "checked", VALUE:  true | false&lt;br&gt;
response&lt;br&gt;
HTTP Status : 200, 401&lt;/p&gt;

&lt;p&gt;งานควรจะเป็นแค่การเก็บ cookie_id ที่ checked == true ลงใน redis เพื่อให้ transaction หลังจากนี้จะทำงานต่อเฉพาะ cookie_id ที่ได้มีการ accept ไว้เท่านั้น&lt;/p&gt;




&lt;p&gt;POST /account/save&lt;br&gt;
KEY: "random_uuid", VALUE: "7bb376c2b20f44d2b16114e8d0957778"&lt;br&gt;
KEY: "citizen_id", VALUE: ""&lt;br&gt;
...&lt;br&gt;
...&lt;br&gt;
KEY: "", VALUE: ""&lt;br&gt;
response&lt;br&gt;
HTTP Status : 200, 401&lt;/p&gt;

&lt;p&gt;งานหลักๆ ควรเริ่มด้วยการการ checked ว่า cookie_id เป็น cookie_id ที่ได้ทำการ accpet มาแล้วเท่านั้นซึ่งสามารถเช็กได้โดยการไป get จากใน redis ออกมา&lt;/p&gt;




&lt;p&gt;POST /account/info&lt;br&gt;
KEY: "random_uuid", VALUE: "7bb376c2b20f44d2b16114e8d0957778"&lt;/p&gt;

&lt;p&gt;HTTP Status : 200, 401 with data&lt;/p&gt;

&lt;p&gt;งานหลักๆ ควรเริ่มด้วยการการ checked ว่า cookie_id เป็น cookie_id ที่ได้ทำการ accpet มาแล้วเท่านั้นซึ่งสามารถเช็กได้โดยการไป get จากใน redis ออกมา&lt;/p&gt;




&lt;p&gt;POST /captcha/request&lt;br&gt;
KEY: "random_uuid", VALUE: "7bb376c2b20f44d2b16114e8d0957778"&lt;br&gt;
response&lt;br&gt;
HTTP Status : 200, with base64 image&lt;/p&gt;

&lt;p&gt;Random Captcha ออกมาเป็น 2 chars, 1 operation เช่น 3 + 1 = _ แล้ว render ออกมาเป็นรูปภาพและเก็บข้อมูลไว้ที่ server&lt;/p&gt;




&lt;p&gt;POST /otp/request&lt;br&gt;
KEY: "random_uuid", VALUE: "7bb376c2b20f44d2b16114e8d0957778"&lt;br&gt;
response&lt;br&gt;
HTTP Status : 200, with OTP&lt;/p&gt;

&lt;p&gt;Random OTP ออกมาเป็นเลขหกหลักส่งไปหา SMS Provider จากนั้น save OTP คู่กับ cookie_id ลงใน Redis&lt;/p&gt;




&lt;p&gt;Initial Repo ไว้ที่ github นะครับ &lt;a href="https://github.com/beid-io/oss-registration"&gt;https://github.com/beid-io/oss-registration&lt;/a&gt; Sourcecode ทั้งหมดอยู่ภายใต้สัญญาอนุญาติแบบ MIT&lt;/p&gt;

&lt;p&gt;ปล.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;เราทำ captcha ตรงไหนหว่า จำไมไ่ด้ ใครจำได้ comment หน่อยจะได้ออกมาแก้ไข&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;COPYRIGHT 2020, Peerapat Asoktummarungsri&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>registration</category>
      <category>kubernates</category>
      <category>opensource</category>
    </item>
    <item>
      <title>MacbookPro cluster สำหรับรันเราไม่ทิ้งกันdotcom</title>
      <dc:creator>Peerapat A</dc:creator>
      <pubDate>Sun, 29 Mar 2020 11:33:00 +0000</pubDate>
      <link>https://dev.to/nuboat/macbookpro-cluster-dotcom-8id</link>
      <guid>https://dev.to/nuboat/macbookpro-cluster-dotcom-8id</guid>
      <description>&lt;p&gt;ทีมท่าแซะ ทำงานไม่เป็น ดีแต่ปากดีไปวันๆ วันนี้เราจะมาโชว์การออกแบบ Macbook Pro Cluster สำหรับรองรับระบบที่มีโหลดน่าจะสูงสุดในประเทศไทยกันเลยอย่าง "เราไม่ทิ้งกัน.com" ว่าต้องมี  Cluster ใหญ่ขนาดไหนจากข้อมูลที่พอหามาได้&lt;/p&gt;

&lt;p&gt;คำนิยมแรกโดยพี่โดมแห่ง (โดมคลาวด์)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;เราไม่ทิ้งกัน ประสบความสำเร็จอย่างมาก ทำให้เกิดการตื่นตัวในการทำระบบลงทะเบียนให้รองรับคนจำนวนมากได้ 
ก่อนเปิด นอบอแซะไว้นิดหน่อยว่าไม่น่ารอด จนเมื่อดึกๆราวๆ 4 ทุ่มผม Chat คุยกับนอบอ 
เราสองคนเห็นตรงกันว่า เจ๋งว่ะ ไม่ธรรมดา ปรบมือรัวๆ จากตัวเลขที่เห็นจากจอที่พี่สมคิดโพสต์ทำเห็นอะไรหลายอย่าง 
นอบอ เลยทำระบบขึ้นมาทดสอบเล่นๆ แต่ได้ความรู้เยอะ เชิญเสพย์
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ว่าแล้วก็มาดูกันก่อนดีกว่าว่าจริงๆ แล้วเราต้องประเมินขนาดของ cluster กันยังไงดี&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BMO2Ebf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j4r28vq3d3zjiiacpw9y.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BMO2Ebf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j4r28vq3d3zjiiacpw9y.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากแทรฟฟิกที่เห็นมีการเพิ่มความชันของจำนวนคนลงทะเบียนจาก 3M เป็น 4M สูงชัดเจนมากในเวลาแค่ 12 นาที เราจะใช้ความชันช่วงนี้มาคำนวนขนาดของระบบที่ต้องการกันซึ่งจะได้ว่าระบบต้องการ Peak throughput ประมาณ ~1400 TPS &lt;/p&gt;

&lt;p&gt;ต่อไปเราจะมาก่อนว่า Macbook Pro 1 เครื่อง สามารถรองรับ traffic ได้ขนาดไหน โดยเราจะมาทำการ Load Test, Simple Spring Boot 2 ง่ายๆ โดยการทำ register data แบบ simple คือ just persist to RDBMS&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lE8jLW1z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zhlukmpyv4818u5ml5qs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lE8jLW1z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zhlukmpyv4818u5ml5qs.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากการรัน ab command จะเห็นว่าจะเห็นว่า throughput ที่ได้คือประมาณ 171.47 TPS อันนี้คือการเขียนโปรแกรมง่ายๆ 2 hrs เสร็จ ก็เอาตามนี้ละกัน&lt;/p&gt;

&lt;p&gt;ตัวเลขที่ได้มาหมายถึงอะไร หมายถึงเราต้องการใช้ MBP 8.187 หรือ 9 เครื่องสำหรับรับเฉพาะ API Load. ในกรณีนี้ผมให้ 10 เครื่องเลย เผื่อมีเครื่องดาวน์ได้มีพอ buffer เผื่อ restart &lt;/p&gt;

&lt;p&gt;แต่เดี๊ยวก่อน เดี๊ยว ระบบนี้จะมีแค่นี้ไม่ได้ เพราะว่าการมีหลายเครื่องเป็น API เราต้องการ Load Balance สำหรับกระจาย traffic ไปยังเครือ่ง API ด้านหลังด้วย ซึ่งผมคงเตรียมไว้ที่ 2 เครื่องสำหรับให้มี HA model (งาน LB นี่ 1 machine น่าจะทำได้ระดับ 50K TPS สบายๆ)&lt;/p&gt;

&lt;p&gt;จากเราต้องมี Web Server สำหรับโหลดพวก Static File ต่างๆ ด้วย เท่ากับเราจะเพิ่ม Web Server เข้ามาอีก 3 เครื่อง สำหรับงานอื่นๆ &lt;/p&gt;

&lt;p&gt;เพื่อให้เกิด Monitoring Tool เราจำเป็นต้องมี Grafana Dashboard และ Data Pipeline ซึ่งถ้ารู้ว่าผมใช้ Kafka มาระบบขึ้นเวที Big Data Conference ที่ Taipei ร่วมกับทีมงาน Kafka จาก Apache มาแล้วยังไงก็ใช้ตัวอื่นไม่เป็นนอกจาก Kafka สำหรับทำ message pipeline เราเลยจะได้ ภาพรวมระบบออกมาประมาณนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ryzGROfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1def7fdpj18t3p5b96ug.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ryzGROfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1def7fdpj18t3p5b96ug.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เท่าที่รู้มา ระบบนี้ใช้ทีมงานเพียงแค่ 20คน เท่านั้น ดังนั้นแล้วถ้าทีมงานทุกคนใช้ Macbook Pro เราจะสามารถเอาเครื่องของทีมงาน 19 คนมารันระบบได้ทันทีเพียงแค่เสียบสายแลนและเตรียม Docker Swarm สำหรับรันเอาไว้ให้เรียบร้อย ... &lt;strong&gt;รู้อย่างนี้แล้วรีบเอาบทความนี้ให้หัวหน้าคุณอ่านสิครับ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;จะเห็นว่าเรายังเหลืออีก 1 เครื่องที่ไม่ถูกใช้ 1 เครื่องนี้เก็บเอาไว้ทำไม ก็เอาไว้สำหรับ fixbug man ไง ที่ต้องคอยตามแก้ปัญหา&lt;/p&gt;




&lt;h2&gt;
  
  
  ไม่ดราม่านะครับ นี่มันบทความเอาสนุกของจริงมันมีเบื้องหลังที่เราไม่เห็นอีกเยอะ นี่แค่เท่าที่เห็นก็ต้องใช้ Macbook Pro กว่า 20 เครื่องแล้ว
&lt;/h2&gt;

&lt;p&gt;ไหนๆ ก็ไหนๆ แล้วมาเอาสาระกันบ้าง ภาพรวมการทำงานจริงที่ Capture ได้ของ Spring Boot เทียบกับ System เป็นอย่างไร จะเห็นว่า Java แทบไม่ได้ใช้งานเลยเพราะไปติดคอขวดที่ PostgreSQL เพียวๆ สำหรับระบบระดับนี้ RDBMS ไม่ใช่คำตอบจริงๆ ครับ ไว้วันอื่นจะมาทำให้ดูว่าถ้าขยับหนีไป No SQL ที่ผมชอบอย่าง Cassandra จะเป็นอย่างไร&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lQUzIgQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2mpab468zh7t8luz7dkz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lQUzIgQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2mpab468zh7t8luz7dkz.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aepdLICZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zoamzuo1upnfqgbib65r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aepdLICZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zoamzuo1upnfqgbib65r.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ปล.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;เป็นการทำ Load Test บน MBP15" Model เก่าแล้ว ถ้าทำบน 16" รุ่นใหม่น่าจะได้ Traffic สูงกว่าระบบที่ทำประมาณ 25% [คอขวดน่าจะที่ Postgres vOSX  hw change ไม่น่ามีผลมาก]&lt;/li&gt;
&lt;li&gt;ZooKeeper / Kafka ไม่ต้องทำ Load Test&lt;/li&gt;
&lt;li&gt;จริงๆ น่าจะยังเขียนโค้ดให้ดีกว่านี้ได้โดยการเลิกใช้ Spring JPA และ Tuning Prepared Statement ให้ดีกว่านี้ [ลองแล้วไม่มีผล คอขวดอยู่ที่อื่น]&lt;/li&gt;
&lt;li&gt;แอบคิดเหมือนกันว่ามันใช้กว่าปกติมาก ทั้งที่ไม่น่าช้าขนาดนี้ ไล่ๆ ดีบักดูเจอว่ามาจาก Spring JPA จะ Select ID ก่อนทุกรอบว่าเป็น New Record หรือเปล่า หลังจากทดลอง override isNew() โดยเปลี่ยนให้เป็น flag แทน เจอว่าสามารถดัน throughput ของ Spring Boot จาก 170 -&amp;gt; 440 TPS&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Copyright (c) 2020. Peerapat Asoktummarungsri &lt;a href="https://www.linkedin.com/in/peerapat"&gt;https://www.linkedin.com/in/peerapat&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
