Quantcast
Channel: cc :: somkiat
Viewing all 1997 articles
Browse latest View live

เรียกใช้งาน gRPC service ผ่าน web browser กัน

$
0
0

อ่านบทความเรื่อง มาทำ gRPC Service ด้วย Go กัน ดูแล้วน่าสนใจดี
ก็เลยคิดว่า น่าจะลองเรียก gRPC service จากฝั่ง web browser กันหน่อย
นั่นคือการเรียกใช้งานผ่าน gRPC Web นั่นเอง
ดังนั้นมาลองดูกันหน่อย

ก่อนอื่นต้องเข้าใจ gRPC Web

เนื่องจาก gRPC นั้นจะทำการสื่อสารกันบน HTTP 2
แต่การติดต่อสื่อสารบน web browser นั่นจะเป็น HTTP 1 เท่านั้น
สิ่งที่ต้องการคือ ตัวกลาง หรือ Gateway/Proxy นั่นเอง
ทำหน้าที่แปลง request จาก HTTP 1 ไปเป็น HTTP 2 แล้วทำการแปลงกลับ
นี่คือหน้าที่หลักของ gRPC Web นั่นเอง
ที่สำคัญตอนนี้อยู่ในสถานะที่สามารถนำขึ้น production ได้แล้ว
ส่วนตัวที่อยู่ตรงกลางจริง ๆ มันชื่อว่า Envoy

ปล. ตอนนี้  gRPC Web มี library ให้ใช้เพียงภาษา JavaScript เท่านั้น
ส่วนภาษาอื่น ๆ เช่น Python และ Java ต้องรอไปก่อน

โครงสร้างของการทำงานเป็นดังนี้

  • ส่วนที่ 1 เป็นระบบ Web app ที่ทำงานบน web browser (Frontend) จะใช้งาน library gRPC web สำหรับส่ง request ไปยัง Gateway/Proxy
  • ส่วนที่ 2 Gateway/Proxy เป็นตัวแปลง request จาก HTTP 1 ไปยัง HTTP 2 โดยในส่วนนี้จะมีความสามารถคล้าย ๆ กับ API Gateway นั่นเอง จากภาพใช้ใช้งาน Envoy
  • ส่วนที่ 3 เป็น  gRPC service นั่นเอง หรือ service การทำงานของระบบงาน (Backend)

เพื่อไม่ให้เสียเวลามาพัฒนาระบบงาน Ping-Pong กันดีกว่า
ซึ่งจากบทความที่อ้างอิงไปข้างต้นอธิบายแล้ว
ดังนั้นในบทความนี้จะอธิบายในส่วนที่ 1 และ 2 เท่านั้น

ส่วนที่ 1 คือระบบ web app ที่พัฒนาด้วย React

ตามจริงใช้ JavaScript ปกติก็ได้นะ
ในส่วนนี้ไม่มีอะไรมาก เป็นการสร้าง web app ปกติ
แต่สิ่งหนึ่งที่ต้องทำก่อนคือ

การ generate code JavaScript สำหรับการเรียกใช้ gRPC ผ่าน JavaScript

ผ่านคำสั่ง protoc นั่นเอง
แต่ต้องติดตั้ง protoc-gen-grpc-web ก่อนด้วย 
เป็น plugin สำหรับการ generate JavaScript code ของ protoc ดังนี้

[gist id="328d992a416132843b1b52820591cda7" file="ping_pong.proto"]

ผลที่ได้คือ สร้างออกมา 2 ไฟล์คือ

  • ping_pong_grpc_web_pb.js
  • ping_pong_pb.js

ปล. จะเกิด error ในไฟล์ ping_pong_pb.js เพราะว่า aslant นะ
ดังนั้นแก้ไขด้วยการ disable ด้วยการเพิ่ม /* eslint-disable */ ในไฟล์ ping_pong_pb.js
เพียงเท่านี้ก็แก้ไขได้แล้ว

ต่อมาเขียน code เพื่อเชื่อมต่อไปยัง Envoy

ตรงนี้อยู่ที่การออกแบบว่า ฝั่ง frontend จะเรียกมายัง Envoy ที่เครื่องอะไร port อะไร จากนั้นก็ทำการไปเรียก gRPC อีกต่อ
เป็นเหมือน middleware หรือพวก API gateway นั่นเอง
โดยที่ในตัวอย่างจะเรียกไปที่ Envoy ซึ่ง run ด้วย port 9999
สามารถเขียน code การเชื่อมต่อได้ดังนี้

[gist id="328d992a416132843b1b52820591cda7" file="App.js"]

ส่วนที่ 2 Gateway/proxy ซึ่งใช้งานผ่าน Envoy

โดยตัว Envoy นี้ถูกเรียกจากฝั่ง web browser
ดังนั้นจำเป็นต้องเปิด CORS ด้วย
รวมทั้งระบุว่า ให้ส่ง request มาด้วย HTTP method อะไรได้บ้าง
รวมถึงชื่อใน HTTP Header ที่สนับสนุนอีกด้วย
ตัวอย่างของการ config Envoy เป็นดังนี้

  • Port ของ Envoy คือ 9999
  • Port ของ gRPC service คือ 9090
[gist id="328d992a416132843b1b52820591cda7" file="envoy.yml"]

ในตัวอย่างจะทำการ run ผ่าน Docker 

จึงต้องสร้าง Dockerfile สำหรับสร้าง image ที่เราต้องการใช้งานตาม config จากไฟล์ข้างต้น

[gist id="328d992a416132843b1b52820591cda7" file="Dockerfile"]

run ด้วยคำสั่ง

[code] $docker build -t gateway . $docker run -d --rm -p 9090:9090 gateway [/code]

ส่วนที่ 3 คือการสร้าง gRPC service

ในส่วนนี้ไม่มีอะไรมาก เขียนด้วยภาษาอะไรก็ได้ 
โดยตัวอย่างที่ใช้คือ NodeJS ดังนี้ ใช้ gRPC library นั่นเอง

[gist id="328d992a416132843b1b52820591cda7" file=“service.js"]

เมื่อทุกอย่างเรียบร้อย ก็ run สิครับ

จะแสดงใน web browser ดังรูป เป็นอันเสร็จสิ้นกรรมวิธี
ของการเรียกใช้งาน gRPC service ผ่าน web browser

ลองดูครับ แนวคิดใหม่ ๆ น่าสนุกดี

ตัวอย่าง code ที่ลองทำดูอยู่ที่ GitHub:Up1

Reference Websites


ทำไมนำแนวคิด Microservices ไปใช้งานแล้ว กลับมีปัญหากว่าเดิม ?

$
0
0

ทำไมนำแนวคิด Microservices ไปใช้งานแล้ว กลับวุ่นวายหรือมีปัญหากว่าเดิม ?

ส่วนใหญ่มักพูดกันว่า
เมื่อเราทำงานแบ่งงานใหญ่ ๆ ออกเป็นงานเล็ก ๆ แล้ว
ผลที่ได้มันจะแจ่มมากเพราะว่า พัฒนาและจัดการได้ง่าย
และมักจะอธิบายในแง่ดีว่า

  • ช่วยเพิ่ม productivity ของการพัฒนาให้ดีขึ้น
  • Time to market เร็วมาก
  • Scale ระบบได้เร็วมาก
  • คุณภาพของระบบงานที่ดีขึ้น
  • มีความยืดหยุ่นสูงทั้งเรื่องของคนและเทคโนโลยี

นั่นคือคำที่เอาไว้ขายซึ่ง มันอาจจะไม่ถูกมากสักเท่าไร
เพราะว่าการแยกเป็นงานเล็ก ๆ มันมีต้นทุนหลาย ๆ อย่าง
ที่จำเป็นต้องแก้ไขและปรับปรุงให้ดีขึ้น
มิเช่นนั้นแทนที่จะมีประโยชน์กลับมีโทษ !!
ยกตัวอย่างเช่น

โครงสร้างขององค์กรและทีม

บ่อยครั้งพบว่าในทีมที่เรียกว่า Microservices team นั้น จะมีแต่นักพัฒนาเท่านั้น
เมื่อเห็นก็จะงง ๆ ว่า มันต่างจากเดิมอย่างไร
คำตอบคือ ก็ Microservices team ไงละ
พัฒนาอย่างเดียว
ออกความคิดเห็นไม่ได้
ทำตาม timeline ที่กำหนด
เมื่อพัฒนาเสร็จ จะส่งให้อีกทีม deploy และจัดการต่อไป !!
แต่เมื่อมีปัญหาก็ส่งกลับมาให้ทีม

ดังนั้น สิ่งแรกที่ต้องทำการปรับเปลี่ยนก่อนคือ 
โครงสร้างของการทำงานขององค์กร
จากเดิมที่ต่างฝ่ายต่างทำงานของตนเองไป
จำเป็นต้องมีการทำงานร่วมกันตั้งแต่
คุย ออกแบบ วิเคราะห์ พัฒนา ทดสอบ deploy และดูแล

การจัดการ dependency ที่เกี่ยวข้อง

ปัญหาที่เจอบ่อยมาก ๆ คือ การจัดการ dependency หรือสิ่งที่ service หนึ่ง ๆ ต้องใช้งาน
ทั้ง internal และ external system
บ่อยครั้งพบว่า ไม่สามารถควบคุมและจัดการได้เลย
สามวันดีสี่วันไข้
หนักกว่านั้นก็ต้องรอให้ระบบที่เราต้องใช้งานเสร็จก่อน
มันทำให้สูญเสียเรื่องความเป็นอิสระของ Microservices ไปอย่างมาก
ไหนจะยากต่อการพัฒนา ทดสอบและ deploy
ส่งผลให้แทนที่จะได้ประโยชน์กลับเกิดโทษมากกว่า

ดังนั้นจำเป็นต้องมีแนวทางและเครื่องมือในการจัดการ dependecy ที่ดี
ยกตัวอย่างเช่น พวกเครื่องมือจัดการ container เช่น Docker และ Kubernetes เป็นต้น มาช่วยจัดการ

  • security
  • networking
  • storage
  • monitoring
  • complexity

ดังนั้นทีม infrastructure, network หรือ operation team จะต้องแข็งแกร่ง
และทำงานร่วมกัน development team ได้อย่างดี
แต่ถ้าไม่ส่งเสริมกันก็อาจจะก่อให้เกิดปัญหาใหญ่ตามมาได้

การจัดการเรื่อง communication ระหว่าง services

เนื่องจากเราทำงานแบ่งเป็น service ย่อย ๆ แล้ว
แต่ละ service อาจต้องติดต่อสื่อสารกัน
คำถามที่น่าสนใจคือ การติดต่อสื่อสารจะเป็นอย่างไร
ทั้ง Synchronous และ Asyschonous
เพราะว่าทั้งสองแบบก็มีข้อดีและข้อเสียต่างกันไป

เช่นถ้าเป็นแบบ synchronous แล้วเกิดปัญหาที่ระบบ network ก็ต้องรอกันไป
ส่งผลให้ประสิทธิภาพแย่ลงไปอีก
หรือถ้าเป็น asyschonous ก็จะเป็นต้องมีคนกลางหรือ message system
แน่นอนว่าประสิทธิภาพดีขึ้น แต่ส่งผลให้ระบบมีความซับซ้อนขึ้นมาอีก

หนักว่านั้น ถ้าแต่ละ service มันมีปัญหาหรือพังขึ้นมา
จะทำการจัดการแก้ไขอย่างไร หรือรู้จุดที่เกิดปัญหาได้รวดเร็วอย่างไร
บางครั้งเราจะใช้ค่า MTTR (Mean Time To Recovery) มาใช้วัดผลอีกด้วย

การจัดการกับความหลายหลาย

เนื่องจากประโยชน์หนึ่งของ Microservices คือ
การเลือกเครื่องมือให้เหมาะสมกับงาน
ดังนั้นอาจจะส่งผลให้มี technology ที่หลากหลายขึ้นมา
แน่นอนว่า มันทำให้เกิดปัญหาในการดูแลจัดการ ทั้ง

  • Programming language
  • Database
  • APIs
  • Configuration
  • Operating system

คำถามที่ต้องตอบให้ได้คือ 

เราจำเป็นต้องนำแนวคิด Microservices มาใช้จริง ๆ ไหม ?
หรือเพียงตามกระแสนิยม ว่าถ้าไม่ทำจะตก trend เท่านั้นเอง !!
หรือถ้าระบบไม่ใหญ่ก็เริ่มจาก Monolithic ไปก่อน
แต่แยกให้เป็น modular ที่ดี
จากนั้นถ้าใหญ่ขึ้นจึงค่อยแยกออกไปเป็น service ต่อไป

แต่ถ้าเป็นระบบขนาดใหญ่มันก็คือ
หนึ่งในความท้ายทายอย่างมาก
แต่ขอให้เริ่มต้นจากปัญหาก่อนเสมอ



เมื่อใดที่ไม่ควรเขียน code ?

$
0
0

อ่านหนังสือ The Art of Readable Code: Simple and Practical Techniques for Writing Better Code
ไปเจอเรื่องที่น่าสนใจคือ
ความสามารถหนึ่งที่สำคัญของ developer ที่ต้องมี
นอกเหนือจากการ coding นั่นก็คือ
รู้ว่าเมื่อใดที่ไม่ควรเขียน code
เนื่องจากบ่อยครั้งมักจะเขียนเยอะไป

Developer รู้ว่า code ที่เขียนขึ้นมานั้น

  • ต้องอ่านและเข้าใจได้ง่ายทั้งจากตัวเราเองและผู้อื่น
  • ต้องผ่านการทดสอบมาทั้งหมด
  • ต้องไม่เพิ่มข้อผิดพลาดเข้ามายังระบบทั้งปัจจุบันและอนาคต

แต่ว่าเมื่อใดที่ไม่ควรเขียน code บ้างละ ?

ถ้าเรารู้ว่าเมื่อใดต้องไม่เขียน code แล้ว

ผลที่ตามมาคือ code จะมีขนาดเล็กหรือมีเท่าที่ต้องการและจำเป็นจริง ๆ
แต่โชคไม่ดีที่เราพบว่า
เมื่อเวลาผ่านไปนานเท่าไร
Code ของระบบงานกลับใหญ่โตขึ้นเรื่อย ๆ
จนอยู่เหนือการควบคุมใด ๆ
ยากต่อการดูแลรักษาอย่างมาก แสดงดังรูป

ความยากคือ code ที่ไม่จำเป็นมันเป็นแบบไหน ?
ถ้าลบ code เหล่านั้นทิ้งไป มันจะไม่ส่งผลต่อระบบใช่ไหม ?
แต่บางคนบอกว่า วันที่ productivity ดีมาก ๆ คือ
วันที่ได้ลบ code ทิ้งไป !!

ดังนั้นก่อนที่จะเขียน code

Developer ควรเข้าใจก่อนว่า
เป้าหมายหลักของสิ่งที่กำลังทำคืออะไรกันแน่
ถ้าทำไปแบบไม่เข้าใจ และ ไม่ชัดเจน
ก็จะมีแต่ความกลัว
เพื่อลดความกลัว จะเขียน code ให้เยอะ ๆ เข้าไว้
ผลที่ตามมาคือ code ที่ไม่จำเป็นเต็มไปหมด
จะลบทิ้งก็ทำไม่ได้แล้ว

ปล. มันมีเส้นบาง ๆ ระหว่าง good enough กับ perfect !!
มาเน้นที่การเขียน code ให้ทำงานได้ตามที่ต้องการก่อนดีไหม ?

Keep coding ครับ
ทุกสิ่งทุกอย่างมันเกิดจากการเขียน code
เรียนรู้กับสิ่งที่เกิดขึ้น และปรับปรุงกันอย่างต่อเนื่อง

Elasticsearch ใส่ระบบ security มาให้แบบฟรี ๆ แล้ว

$
0
0

ทางบริษัท Elastic ได้ประกาศทางบทความ Security Elasticseach is now free
นั่นหมายความว่า Elasticsearch ตัวใหม่ตั้งแต่ version 6.8 และ 7.1 ขึ้นมา
จะมีความสามารถเรื่อง securirty มาให้ใช้งานแบบฟรี ๆ
ไม่ต้องไป config ข้างนอกเองอีกแล้ว
โดยมีความสามารถคร่าว ๆ ดังนี้

  • TLS สำหรับการเข้ารหัสของการติดต่อสื่อสารระหว่าง node
  • มีการจัดการเรื่อง Authentication
  • มีการจัดการเรื่อง Authorization แบบ roles-based (RBAC) ทั้งการใช้งานระดับ index และ cluter นั่นเอง

การปรับเปลี่ยนครั้งนี้

น่าจะมาจากความต้องการจากทาง Enterprise อย่างแน่นอน
เพราะว่า เรื่องนี้ถูกถามเยอะมาก ๆ
เนื่องจากค่า default ของ Elasticsearch คือไม่มี security อะไรเลย !!
หรือถ้าต้องไปใช้จริง ๆ อาจจะต้อง configuration ในระดับ network เอง
หรือต้องไปซื้อ subscription จากทาง Elastic นั่นเอง
ส่วนใครใช้งาน Elastic Cloud อยู่แล้ว ก็สบายไป !!

TLS สำหรับการเข้ารหัสของการติดต่อสื่อสารระหว่าง node

ถ้าไม่มี certificate ก็ทำการเตรียม command elasticsearch-certutil มาให้
สำหรับการสร้าง certificate ให้
เป็นขั้นตอนที่สำคัญ ต้องทำก่อนจึงจะเปิด security ได้นะ ดังนี้

[gist id="c907490fb100344e5b4ee54b7f2f2222" file="elasticsearch.yml"]

จากนั้นลองเข้าใช้งาน Elasticsearch ดู แสดงดังรูป

ยังไม่พอนะยังเตรียม command elasticsearch-setup-passwords auto
สำหรับสร้าง password ในการใช้งานให้อีกด้วย
จะทำการสร้าง password ให้ครบเลย
ใน product หลัก ๆ ที่ต้องใช้งาน elasticsearch
ทั้ง APM, Kibana, Logstash, Beats และ Monitoring system

ส่วนเรื่องของ performance ก็ต้องลองทำ performance testing ดูกันนะ

ว่าจะ drop ลงไปเท่าไรกัน !!!

ส่วนการจัดการเรื่องของ Authentication และ Authorization นั้นจะทำผ่าน Kibana

ซึ่งค่า default นั้นเรื่องของ security จะปิดหมดเลย
(แต่ถ้าใครลงผ่าน X-Pack จะเปิดอยู่แล้ว)
ดังนั้นให้ไปเปิดในไฟล์ config/kibana.yml ดังนี้

[gist id="c907490fb100344e5b4ee54b7f2f2222" file="kibana.yml"]

เข้าใช้งาน Kibana กัน

ไปในส่วนของการ Setting จะมี section ของ Security ให้ใช้งาน
ทั้งการจัดการ users และ roles ดังรูป

มาลองใช้งานกันดู Security on Elasticsearch

สรุปเรื่อง Distributed tracing จากงาน Go Get TH Meetup ครั้งที่ 5

$
0
0

มีโอกาสไปแบ่งปันเรื่อง Distributed Tracing ในงาน Go Get TH Meetup ครั้งที่ 5 โดยเนื้อหาประกอบไปด้วย

  • Observability ของระบบงาน
  • Tracing ระบบงาน
  • ตัวอย่าง code การใช้งาน tracing ด้วยภาษา Go

มาเริ่มกันเลย

ระบบงานมักจะประกอบด้วยส่วนการทำงานมากมาย
คำถามคือ เราควรมีอะไรมาช่วยดูหรือตรวจสอบการทำงานของระบบกันไหม ?

ในระบบงานต่าง ๆ นั้นควรจะมี Observability

เพื่อใช้ดูการทำงานของระบบ
เพื่อใช้ทดสอบการทำงานของระบบ ประกอบไปด้วย

  • Audit logging
  • Application metric
  • Distributed tracing
  • Health check API
  • Exception tracking
  • Log aggregation
  • Log deployment and change

สิ่งต่าง ๆ เหล่านี้ล้วนเกิดมา 

เพื่อช่วยให้เรารู้ปัญหาและแก้ไขได้รวดเร็วยิ่งขึ้น
หรือลดเวลา MTTR (Mean Time To Recovery)
ยกตัวอย่างเช่น
เราจะมี dashboard แสดงค่าต่าง ๆ และระบบ alert เพื่อแจ้งปัญหาให้เรารู้ได้ทันที
ซึ่งข้อมูลต่าง ๆ จะเป็นตัวเลขหรือ metric นั่นเอง
จากนั้นถ้าระบบงานประกอบไปด้วยส่วนตการทำงานมากมาย
คำถามคือ เราจะรู้ได้อย่างไรว่า
ปัญหาที่เกิดขึ้นของระบบนั้น มันอยู่ตรงส่วนไหน ?
หนึ่งในวิธีการดูคือ การ Tracing นั่นเอง แสดงดังรูป

จากนั้นสามารถนำรายละเอียดเพิ่มเติมมาจาก logging ได้อีก
แต่จะนำมาใช้ไม่ได้เลย
ถ้าระหว่าง logging และ tracing ไม่มีสิ่งที่สัมพันธ์กัน
สิ่งนั้นก็คือ tracing id หรือ correlation id นั่นเอง แสดงดังรูป

ดังนั้นเรื่องของ tracing จึงมีความสำคัญขึ้นมา

ยิ่งในระบบที่อยู่อย่างกระจาย
หรือยิ่งมาสู่แนวทางของ Microservices ที่มี service จำนวนมากมาย
จึงเกิดแนวคิดของ Distributed tracing ขึ้นมา
ทำหน้าที่ tracking และ analyzing ว่าในแต่ละ request ที่เกิดขึ้นมานั้น
มันไปส่งผลหรือทำงานกับ service หรือส่วนการทำงานใดบ้าง
เพื่อทำให้เรารู้ได้อย่างทันท่วงที เหมือนกับการ X-Ray ร่างกายนั่นเอง

ระบบ Distributed tracing จะตอบคำถามเหล่านี้

  • แต่ละ request ที่เกิดขึ้นมานั้น ผ่านส่วนการทำงานใดบ้าง
  • ส่วนการทำงานใดเป็นปัญหาหรือเป็นคอขวดของระบบ
  • ส่วนการทำงานใดที่ช้าทั้งจากการทำงานภายในและระบบ network
  • แต่ละส่วนการทำงานเกิดอะไรขึ้นบ้าง นั่นคือต้องมีรายละเอียดของการทำงานด้วย

มาดูโครงสร้างของ Tracing กันบ้าง

ประกอบไปด้วย 2 คำคือ

  • Trace คือภาพรวมของการทำงานในแต่ละ request โดยประกอบไปด้วย span จำนวนมาก
  • Span คือส่วนการทำงานย่อย ๆ มีทั้งอยู่ใน service เดียวกันหรือต่าง service

ซึ่งในแต่ละ Span สามารถมีความสัมพันธ์กับแบบ parent-child 
เพื่อทำให้เห็นลำดับการทำงานที่ชัดเจนมากยิ่งขึ้น

จากแนวคิดนี้จะเห็นได้ว่า มีสิ่งที่มีความสำคัญแต่ยังไม่พูดถึงคือ

  • รูปแบบของ Tracing message เป็นอย่างไร
  • จัดเก็บข้อมูล Tracing อย่างไร
  • ทำการแสดงผลหรือวิเคราะห์อย่างไร

เรื่องของ Tracing message นั้น

ได้มีการกำหนดมาตรฐานขึ้นมา นั่นก็คือ 

ทั้งสอง project มีส่วนการทำงานคล้าย ๆ กัน ตามจริงใช้แทนกันได้
แต่ OpenTracing นั้นเกิดมามีเป้าหมายเฉพาะ service เท่านั้น
ส่วน OpenCensus นั้นจะกว้างกว่าคือ
สามารถ integrate เข้ากับ software หรือระบบต่าง ๆ ไปเลย
แต่เท่าที่ไปดูทั้งสอง project มาพบว่า
มีแนวคิดที่ทำการรวมทั้งสอง project เข้าด้วยกัน ไว้ต้องลองดูกันต่อไป

ต่อมาก็เรื่องที่จัดเก็บและแสดงผลของ Tracing

จากที่เคยใช้มาจะมี

  • Zipkin พัฒนาด้วยภาษา Java
  • Jaeger พัฒนาด้วยภาษา Go

โดยใน meetup นั้นทำการเลือกใช้ Jaeger

ใช้ OpenTracing ในการจัดการรูปแบบของ tracing message
ซึ่งทำการสร้าง Trace ชื่อว่า service-1 ประกอบไปด้วย Span จำนวน 3 span คือ

  1. Call เป็น span ที่อยู่ภายใต้ trace
  2. step-1เป็น span ที่เป็นลูกของ span ที่ 1
  3. Span เป็น span ที่เป็นลูกของ span ที่ 2 แต่สามารถสร้างจาก context ได้

มาดูตัวอย่าง code กัน ซึ่งทำให้การทำ Tracing ง่ายขึ้น
ทั้งภายใน service เดียวกัน หรือ ต่าง service

[gist id="b25b45c8078529256fc04e87c5d607ea" file="main.go"]

ผลการทำงานจะส่งข้อมูลไปยัง Jaeger ดังรูป

มาดูรายละเอียดของแต่ละ trace กัน
ช่วยทำให้เราเห็นการทำงานของระบบงานชัดเจนขึ้นมา

แถมทำการสร้าง graphความสัมพันธ์ของ service ต่าง ๆ ในระบบงานให้อีกด้วย

ตัวอย่าง code อยู่ที่ GitHub:Up1

Slide อยู่ที่ Slideshare

[slideshare id=147568986&doc=sck-go-tracing-190525154428&w=600]


[VDO] Java ยังคงฟรีอยู่ใช่ไหม ?

$
0
0

จากงาน QCon London 2019 นั้นมี session น่าสนใจเพียบเลย
หนึ่งในนั้นคือ panel discussion เรื่อง Java is Still Free ?
ผู้ตอบคำถามต่าง ๆ จากคนดูแล OpenJDK, Oracle และ IBM
มาดูว่าเป็นอย่างไร ?

https://www.youtube.com/watch?v=Lt5JPx0Dvws

จาก VDO อธิบายสั้น ๆ คือ

Oracle JDK 8 นั้นยังคงใช้งานบน production ได้เช่นเดิม
แต่จะไม่มี update ต่าง ๆ แล้ว
เพราะว่าทาง Oracle แจ้งออกมาแล้วว่า หมดเวลา support แล้ว
แต่ถ้าใครต้องการก็มี 2 แนวทางคือ
ทำการซื้อ subscription จากทาง Oracle
หรือเปลี่ยนไปใช้ OpenJDK แทน
หรืออีกแนวทางคือ ไม่ต้องไปสนใจ !! (อันนี้ผมใส่ไปเอง)

เมื่อมาถึง JDK 9 และ 10 จะมีปัญหาคือ
ปัญหาคือ Oracle JDK ซึ่ง build มาจาก OpenJDK และ OpenJDK นั้น
ไม่ compatible กัน ทำให้เกิดปัญหาในการทำงาน
หรือไม่สามารถเปลี่ยนไปมาได้นั่นเอง
ถือว่าเป็นข่าวร้ายมาก ๆ แต่คิดว่า คงยังไม่มีใครใช้มั้ง !!
แต่เมื่อมาถึง JDK 11 ก็แก้ไขปัญหาแล้ว


จากที่อธิบายไปทาง Oracle ได้สร้างโลกของตัวเองขึ้นมาคือ

  • Oracle OpenJDK build ขึ้นมาภายใต้ licence GLPv2 + CE ซึ่ง update ทุก ๆ 6 เดือน
  • Oracle JDK สำหรับ commercial เท่านั้น แต่สามารถใช้ free ได้สำหรับ desktop app, personal use, testing และ demo เท่านั้น !!

สุดท้ายเพื่อความปลอดภัย ก็ลองไปใช้ตัวอื่นได้

[Part 2] สรุปการเรียน Domain-Driven Design ในเรื่องของการออกแบบ

$
0
0

จาก Part 1 เรื่องที่มาของ Domain-Driven Design (DDD)
ต่อมาใน Part 2 เป็นเรื่อง workshop การออกแบบตามแนวทาง DDD
แต่มีสรุปเรื่องของการออกแบบระบบงานใน class Domain-Driven Design แล้ว
ที่ blog สรุป Class Domain-Driven Design by Roofimon
ผมจึงทำการสรุปในมุมมองเล็ก ๆ น้อย ๆ ดีกว่า
เพื่อให้เห็นมุมมองในการออกแบบเพิ่มขึ้น

เริ่มจากทำความเข้าใจร่วมกันในงานที่จะทำ

หรือทำความเข้าใจกับปัญหา
จากนั้นทำการ modeling domain ต่าง ๆ ออกมา ประกอบไปด้วย

  • Strategic design
  • Tactical pattern

Model ที่ได้จากการออกแบบนั้น จะมีหลายรูปแบบได้
เพราะว่าไม่มี model ใดที่ดีที่สุด
แต่ในทุก ๆ model ล้วนมีประโยชน์

แสดงความแตกต่างระหว่าง Strategic design กับ Tactical pattern ดังรูป

เริ่มจาก Strategic Design กันเลย

ในการออกแบบเชิง Object-Oriented หรือ OOD นั้น

จะออกแบบหรือคิดส่วนการทำงานต่าง ๆ ในรูปแบบของ class/object
ส่วนในโลกของ DDD นั้นจะมองในรูปแบบของ Domain
และในแต่ละ domain จะมี Context มากกว่า 1
แต่ละ context ก็มีขอบเขตการทำงานที่ชัดเจน เรียกว่า Boundary Context
เป็นสิ่งที่ที่เราให้ความสนใจหรือเป็นสิ่งสำคัญนั่นเอง

ในระบบงานหนึ่ง ๆ มีส่วนการทำงานเยอะเหลือเกิน
ดังนั้นการที่จะเน้นไปเสียทุกส่วนจึงเป็นไปไม่ได้เลย (แต่เรามักจะทำกัน)
ผลที่ตามมาคือ ไม่มีอะไรดีสักอย่าง !!
ดังนั้นเราจำเป็นต้องเลือกว่า จะเริ่มทำความเข้าใจจากส่วนไหนก่อนหรือหลัง

ยกตัวอย่างดังรูป

ด้านซ้ายคือรูปโต๊ะอาหาร คือ Domain ที่เราสนใจ
ประกอบไปด้วยส่วนต่าง ๆ มากมาย
ทั้งอาหาร จาน ช้อนส้อม แก้วน้ำ โต๊ะ ผ้าปูโต๊ะ และอื่น ๆ อีกมากมาย
ทั้งหมดนี้คือ context สิ่งที่สนใจ

ดังนั้นอย่างแรกที่เราควรต้องทำคือ การ focus ไปยังส่วนที่สำคัญที่สุด
ถ้าในเชิงธุรกิจก็คือ ส่วนจะมีคุณค่าทาง business สูงสุดนั่นเอง


จากภาพจะให้ความสำคัญกับอาหาร นั่นก็คือ Pizza
ดังนั้นในตัวอย่าง สิ่งที่สนใจคือ Pizza 
ตรงนี้แหละคือ จุดเริ่มต้นของการออกแบบ
จากนั้นก็ได้เวลาเริ่มต้นการทำ workshop แล้ว

ใน workshop นั้นจำเป็นต้องมีผู้เชี่ยวชาญในด้านต่าง ๆ (Domain Expert)

ที่เกี่ยวกับ domain และ context นั้น ๆ
ประกอบไปด้วย Business Expert, Domain Expert
รวมไปถึงฝั่ง Implement หรือ Technical ด้วย
ในจุดนี้ผมมองว่า เป็นเรื่องที่สำคัญมาก ๆ
เพราะว่า ถ้าเราไม่มีผู้เชี่ยวชาญหรือทำในสิ่งนั้น ๆ มาพูดคุยด้วย
อาจทำให้ workshop หรือกระบวนการทำความเข้าใจผิดพลาดไปได้มากมาย

อีกอย่างใน workshop นี้มีคนมาจากหลาย ๆ ส่วนงาน
แน่นอนว่าความรู้ความเข้าใจแตกต่างกัน
ภาษาที่ใช้คุยก็ต่าง
ทำให้ยิ่งคุยยิ่งไม่รู้เรื่อง !!!

ยกตัวอย่างเช่น Business vs Technical มักจะใช้ภาษาพูดที่ต่างกัน
ยิ่งมาจากลุ่มอื่น ๆ อีกยิ่งไปกันใหญ่ 
ดังนั้นเราจำเป็นต้องมีภาษากลางที่ใช้สื่อสารกัน
ทาง DDD นั้นจะเรียกภาษากลางนี้ว่า "Obiquitous language"

จากหนังสือ The Anatomy of Domain-Driven Design
อธิบายได้ชัดเลยว่า
ต้องเน้นไปที่ domain term มากกว่า technical term นะ
แสดงดังรูป

ในขั้นตอนนี้ไม่ใช่การหา solution หรือวิธีการแก้ไขปัญหา (Solution space)

แต่เพื่อทำให้เราเข้าใจปัญหาหรือสิ่งที่ต้องการจริง ๆ (Problem space)
ในขั้นตอนนี้เราจะเริ่มจาก Problem space นั่นเอง แสดงดังรูป

ปัญหาใน workshop จะมี 2 แบบคือ

  1. จบในแต่ละ role หรือ domain ของตัวเอง ยกตัวอย่างเช่น โรงพยาบาลและโรงแรมเป็นต้น
  2. ต้องทำงานข้าม  role หรือ domain ยกตัวอย่างเช่น การซื้อสินค้า เป็นต้น

ใน DDD นั้นจะแบ่ง domain ออกเป็น 3 กลุ่มคือ

  1. Core domains ส่วนการทำงานหลักที่เราให้ความสำคัญ และเราจะพูดคุยกันในส่วนนี้เป็นหลัก
  2. Generic domains ส่วนการทำงานที่เป็นมาตรฐาน สามารถซื้อระบบงานมาติดตั้งใช้งานได้เลย ช่วยลดเวลาในการ implement ลงไปอย่างมาก ใช้การจัดการมากกว่าการพัฒนา
  3. Supporting domains เป็นส่วนที่ช่วยสนับสนุนการทำงาน สามารถให้ทีมที่มีประสบการณ์น้อย ๆ ทำได้ หรืออาจจะจ้าง outsource เข้ามาช่วยพัฒนา

จะให้ความสนใจหรือลงแรงไปยัง Core domain เป็นหลัก

ใน domain นั้นจะมี context หรือ boundary context มากกว่า 1 context
ดังนั้นแต่ละ context ต้องมีความสัมพันธ์กัน
สิ่งต่าง ๆ เหล่านี้เราจะเรียกว่า Context Map นั่นเอง
เพื่อเข้าใจความสัมพันธ์หรือความเกี่ยวข้องของแต่ละ context มากขึ้น


โดยมีรูปแบบต่าง ๆ ดังนี้ (แต่ละอย่างมันคืออะไรนะ ?) !!

  • Shared kernel
  • Customer/supplier teams
  • Conformist
  • Partnership
  • Anti-corruption layer (ACL)
  • Open-host service
  • Publish language
  • Separate ways

ตัวอย่างของการนำ Context map มาใช้แสดงดังรูป

เมื่อมาถึงตอนนี้ทำให้เราเข้าใจมากขึ้นว่า

  • มี Domain อะไรบ้าง
  • ในแต่ละ domain มี context อะไรบ้าง
  • แต่ละ context มีความสัมพันธ์ รวมทั้งแลกเปลี่ยนข้อมูลกันอย่างไร

โดยเราจะนำ model ที่ได้นี้ไปลงรายละเอียดต่อไป
นั่นก็คือ การนำ Tactical pattern มาใช้นั่นเอง
แต่ หมดแรงแล้ว เอาไว้เขียนต่อใน part ต่อไปดีกว่า !!

ก่อนจบ !!
แนวทางที่ทำมานี้ ไม่ได้บอกว่าจะถูกต้องและทำได้จริง

แต่มันคือแผนที่นำทาง
ซึ่งทุกคนที่เกี่ยวข้องสร้างมันมาจากความเข้าใจร่วมกัน
นั่นหมายความว่า
ทุกคนมองในภาพเดียวกัน
ดังนั้นถ้าผิดก็ผิดร่วมกัน หรือได้เรียนรู้ไปพร้อม ๆ กัน
ไม่ต้องมาเถียงกันว่าใครผิดหรือถูก

มันคือ วิธีการเรียนรู้ ลงมือทำ และรับ feedback เพื่อแก้ไขปรับปรุงให้ดีขึ้น
จนอาจจะทำให้เราได้แนวทางที่ถูกต้องและเหมาะสมกับเราในที่สุด
ยกตัวอย่างเช่น  Framework ของ Design Thinking ดังรูป

ลองเขียน Unit test ในภาษา Lua

$
0
0

ลองนั่งเขียน Unit test สำหรับภาษา Lua นิดหน่อย
ซึ่งพบว่าตัวภาษา Lua มีสรุป library ต่าง ๆ ไว้ที่ Lua Unit Testing 
ที่สำคัญตัวภาษาเองตังแต่ version 5.0 ขึ้นมา
มีชุดการทดสอบของภาษาให้ดูด้วย มันดีมาก
แล้วทำไมนักพัฒนาจะไม่เขียนละ !!
ดังนั้นมาลอง สวัสดีกันหน่อย

เริ่มจากเราจะเริ่มอย่างไรดี ?

จากที่ลองหาข้อมูลพบว่า
ต้องทำการติดตั้งตัว run ของภาษา Lua ที่เครื่อง
จากนั้นทำการติดตั้ง library ที่ต้องการ ผ่าน Lua package manager ชื่อว่า luarocks 
เท่านี้ก็เขียนชุดการทดสอบได้แล้ว

แต่เพื่อความง่ายก็เลยใช้ Docker ดีกว่า

มี Docker image หลายตัวให้ใช้เลย (ไม่เห็นมี official เลยนะ)
ก็เลยเลือก image มาสักตัวเพื่อ custom นิดหน่อย
เพราะว่าต้องติดตั้ง library ของการทดสอบเพิ่มเติม ประกอบไปด้วย

  • Luaunit เป็น unit test module
  • Luacov เป็น code coverage module

โดยไปใช้ base image จาก Docker LueRocks
นำมาติดตั้ง module ที่ต้องการเพิ่มเติมดังนี้

[gist id="690b0b72c90cbcf0c0306a8b65c42ab5" file="Dockerfile"]

จากนั้นก็ทำการสร้าง Image ชื่อว่า my_lua ด้วยคำสั่ง

[code] $docker image build -t somkiat/my_lua . [/code]

เผื่อใครอยากใช้ก็ pull image ได้ที่  Docker Hub

ต่อมาเริ่มทำการเขียนชุดการทดสอบแบบง่าย ๆ บวกเลขนี่แหละ

[gist id="690b0b72c90cbcf0c0306a8b65c42ab5" file="hello_test.lua"]

ทำการ run ง่าย ๆ ดังนี้ ผ่านฉลุย

[gist id="690b0b72c90cbcf0c0306a8b65c42ab5" file="run.txt"]

มันก็ไม่ยากอะไรมากนะ
มาลองเขียน Lua กัน น่าสนุกดี



[Part 3] ว่าด้วยเรื่องของรูปแบบความสัมพันธ์ระหว่าง Boundary context ใน DDD

$
0
0

ในระบบงานหนึ่ง ๆ นั้นมักจะซับซ้อนเสมอ มี context หรือส่วนการทำงานจำนวนมาก
ดังนั้นจำเป็นต้องแยกและกำหนดกรอบทำงานที่ชัดเจนให้แต่ละ context
หรือเรียกว่า Boundary context
แต่ปัญหาที่เกิดตามมาก็คือ
แต่ละ Boundary context จะต้องติดต่อสื่อสาร
หรือต้องทำการแลกเปลี่ยนข้อมูลกัน
หรือเรียกว่าความสัมพันธ์ระหว่าง Boundary context
กันอย่างไร ?

รูปแบบความสัมพันธ์มีดังต่อไปนี้

  • Shared Kernel
  • Customer / Supplier
  • Conformist
  • Anticorruption Layer (ACL)
  • Separate Ways
  • Open Host Service
  • Published Language

มาดูกันว่าแต่ละความสัมพันธ์เป็นอย่างไร ?

1. Share Kernel

เป็นรูปแบบที่ context ต่าง ๆ
ทำการ share พวก Domain model หรือใช้ข้อมูลใน database เดียวกัน
เมื่อทำการเปลี่ยนแปลง Domain model นั้น ๆ
ผลที่ตามมาคือ จะกระทบต่อ context อื่น ๆ ที่ใช้ร่วมกันด้วยเสมอ !!

เรื่องนี้ต้องระมัดระวังกันอย่างมาก
แต่ประโยชน์ที่ได้รับคือ เปลี่ยนแปลงเพียงที่เดียว
ทำให้เราพบเจอการใช้งานความสัมพันธ์แบบนี้เยอะมาก ๆ แต่ ... !!!
Domain model ที่ share กันนี้เราเรียกว่า Kernel model แสดงดังรูป

2. Customer/Supplier

แปลง่าย ๆ คือ ลูกค้าและผู้ผลิต
หรืออาจจะเรียกว่า Consumer-Driven Contract Relationship
โดยจะเรียกผู้ผลิตหรือผู้ถูกเรียกใช้งานว่า Upstream context
เตรียม contract หรือจุดบริการให้ทาง customer หรือ Downstream context ไว้ใช้งาน

ทำให้ทั้งสองฝั่งทำงานกันเป็นอิสระ
ตราบเท่าที่ contract ไม่มีการเปลี่ยนแปลง !!
และ contract ที่ทาง supplier เตรียมให้จะเฉพาะเจาะจงให้กับแต่ละ consumer ไปเลย

ตรงนี้แหละที่ทั้งสองทีม
ควรต้องเขียน acceptance test สำหรับ interface ที่ตกลงกันไว้ (Contract Testing)
จากนั้นนำ acceptance test เหล่านี้ ไป run ไว้ที่
Upstream context ในทุกครั้งที่มีการเปลี่ยนแปลง (Continuous Integration)
เพื่อทำให้ทาง Downstream context หรือ customer นั้นมีความมั่นใจ
ว่าจะไม่เกิดความผิดพลาดขึ้นมา

สังเกตว่า  Supplier team นั้นจะมีข้อมูลและการทำงานต่าง ๆ เตรียมไว้ให้
แต่ว่าทาง Customer team นั้นสามารถขอเปลี่ยนแปลงตามที่ต้องการได้
ทำให้ทาง Supplier team ต้องสร้าง service เฉพาะเจาะจงกับ customer นั้น ๆ ไว้เลย
เรามักเรียกสิ่งที่เฉพาะเจาะจงของแต่ละ customer ว่า contract หรือสัญญานั่นเอง

ทำให้ทั้งสองทีมต้องมีการพูดคุยหรือสื่อสารกันมากขึ้น
เพื่อให้ได้ตามสิ่งที่ต้องการทั้งสองฝั่ง

3. Conformist

การทำงานจะมีลักษณะใกล้เคียงกับ Customer/Supplier
แต่ว่า conformist จะต่างออกไปคือ
ในส่วนของ Supplier นั้นจะทำการเตรียมข้อมูลและการทำงานที่เป็นมาตรฐานไว้
จะไม่เปลี่ยนไปตามที่ฝั่ง Customer ต้องการ
เพราะว่า Customer แต่ละที่ก็ต้องการต่างกัน !!
หนักกว่านั้นอาจจะทำให้เกิดความซับซ้อนในการทำงานของ Supplier ขึ้นมาอีก

ดังนั้นฝั่ง customer ต้องเอาข้อมูลที่ได้ไปแปลงตามที่ต้องการเอง
โดยเราจะเรียกข้อมูลในฝั่ง customer ว่า Value object

ดังนั้นทางฝั่ง Supplier หรือ Downstream ต้องดีด้วย
มิเช่นนั้นก็จะก่อให้เกิดปัญหาตามมามากมาย
ถ้าลองสังเกต แนวทางนี้จะเหมือนเอาเรื่อง Share kernel มาใช้งาน
เพียงแต่ไม่ให้ share model กันแบบตรง ๆ เท่านั้นเอง

ตัวอย่างแสดงดังรูป


จะเห็นได้ว่าฝั่ง Expense tracking context
จะทำการดึงข้อมูล Banking Account มาจากทาง Banking context
จากนั้นทางฝั่ง Expense tracking context ก็นำข้อมูล  Banking Account ไปใช้งานต่อ
เช่นการแปลงข้อมูลให้เข้ากับความต้องการของตนเอง
โดยที่ทางฝั่ง Banking context ไม่ต้องทำให้

ทำให้ทั้งสองทีมไม่ต้องพูดคุยอะไรกันมากนัก

4. Anti-corruption Layer (ACL)

เป็นอีกรูปแบบหนึ่งที่พบมาก
เมื่อทั้งสอง context แยกระบบกันอย่างชัดเจน
ทำให้ทั้งสอง context เป็นอิสระอย่างมาก
แต่ทั้งสองต้องทำงานร่วมกัน
คำถามคือ จะทำอย่างไรดี ?
เพราะว่าแต่ละฝั่งมีความต้องการต่างกัน ทำงานต่างกัน
วิธีการที่ชอบใช้กันคือ สร้าง Integation system ขึ้นมา
หรือเรียกว่า ACL นั่นเอง

ในส่วนของ ACL มันจะทำการสร้างด้วยชื่อต่าง ๆ ดังนี้

  • Facade
  • Adapter
  • Translator

ทำหน้าที่เป็นคนกลางแปลงข้อมูลจากฝั่ง suppiler ไปยังฝั่ง customer
และก็แปลงข้อมูลจากฝั่ง customer กลับไปยังฝั่ง supplier อีกที
ซึ่งเราจะพบมากในระบบขนาดใหญ่ ที่มีระบบงานแยกกันจำนวนมาก
หรือต้องทำงานร่วมกับ Legacy system
และเป้าหมายคือสร้างระบบใหม่เข้ามาทดแทน

ยกตัวอย่างเช่นระบบ Banking
อาจจะมีระบบ PFM (Personal Financial Management) ที่ทำงานดีอยู่แล้ว
จากนั้นต้องการสร้างระบบงาน Online Banking ขึ้นมา เช่น Mobile Banking เป็นต้น
สิ่งที่ต้องทำขึ้นมาคือการ integrate กันระหว่าง 2 ระบบ
แน่นอนว่า ทำไม่ได้แน่ ๆ 
ดังนั้นจึงต้องสร้าง ACL ขึ้นมา
เพื่อแปลงข้อมูลหรือ process บางอย่างก่อนเสมอ
ยกตัวอย่างเช่น การแปลงข้อมูลจากรูปแบบ Legacy มาในรูปแบบที่ใช้งานได้ง่าย
เช่น XML และ JSON เป็นต้น

บ่อยครั้งพบว่า เรามักจะทำ ACL บ่อยมาก ๆ 
บางครั้งก็เป็น ACL ซ้อน ACL ตามเทคโนโลยีที่เปลี่ยนไป
เช่น Legacy -> WebService -> RESTFul API -> GraphQL -> ???
แบบนี้น่ากลัวมาก ๆ ระวังกันด้วย

5. Separate Ways

เนื่องจากถ้ายังต้องติดต่อสื่อสารหรือแลกเปลี่ยนข้อมูลกันมันมีปัญหามากนัก
ดังนั้นทำการแยกแต่ละ boundary context ออกจากกันเด็ดขาดไปเลย
ทำให้แต่ละส่วนงาน ต่างทำกันไป ตามแนวทางของตนเอง
ทำให้แต่ละส่วนงานไปได้รวดเร็วและคล่องตัว
แต่อาจทำให้เกิดข้อมูลและ process ที่ซ้ำซ้อนกันได้

แต่ถ้าทั้งสองต้องทำงานร่วมกัน
มักจะมีหน่วยงานกลางมาจัดการ เช่น Middleware เป็นต้น
หรือทำงานเชื่อมผ่าน User Interface ก็ได้

6. Open Host Service

ถ้า boundary context หนึ่งถูกใช้งานจากส่วนอื่น ๆ เยอะมากแล้ว
การที่จะพัฒนาหรือสร้างหรือแปลงให้ตรงตามแต่ละระบบเรียกใช้งาน 
น่าจะเป็นสิ่งที่ยากและใช้เวลาเยอะ
ยกตัวอย่างเช่นสร้าง ACL เพียบเลย

ดังนั้นเพื่อลดปัญหานี้ 
จึงมีแนวคิดที่จะพยายามสร้างกลุ่มของ APIs ใน boundary context ที่ถูกเรียกใช้ไว้เลย
โดยใน API นี้จะมีกลุ่มของ service ที่ผู้เรียกใช้งานต้องการ
และมีมาตรฐานชัดเจน

พบว่ามีแนวคิดคล้าย ๆ Conformist เลย
แต่ต่างกันตรงที่ data model ของข้อมูลที่คุยกัน
กับ standard ของการเรียกใช้ที่เป็นกลาง 
เช่น WebService หรือ RESTFul API เป็นต้น
โดยที่ทั้งสองฝั่งคือ
ผู้เรียกใช้และผู้ให้บริการต้องตกลงกันไว้ หรือพูดคุยกันมากขึ้นนั่นเอง
ทำให้ทั้งสองฝั่งทำงานร่วมกันได้ง่ายขึ้น
เน้นไปที่ส่วนการ integration มากกว่า implementation

7. Published Language

ในส่วนนี้จะมีพัฒนาการมาจาก Open Host Service
แต่ Open Host Service นั้นยังต้องคุยกันระหว่างทีมสูง
ว่าแต่ละทีมจะมี data model ระหว่างกันอย่างไร
ถึงแม้จะมี standard ในการพูดคุยแล้วก็ตาม
ที่สำคัญยังคงผูกมัดกันอย่างมาก

จะดีกว่าไหมถ้าจะลดการผูกมัดกันลงไป
ด้วยการพูดคุยผ่านข้อมูลในรูปแบบที่กำหนดเช่น XML, JSON เป็นต้น
ให้แต่ละส่วนงานที่ต้องการทำงานร่วมกัน ให้ตกลงผ่านรูปแบบข้อมูลเท่านั้น
จากนั้นให้ทำการสร้าง message ขึ้นมา
เมื่อทำการสร้าง message ออกไปแล้ว
ส่วนงานอื่น ๆ ก็ทำงานตามความต้องการของระบบ ด้วย message ที่สร้างขึ้นมา

ยกตัวอย่างเช่น
จะสร้าง message เมื่อมีการสั่งซื้อเข้ามาในระบบ e-commerce
จากนั้นระบบอื่น ๆ ก็จะทำการ
ส่ง email ไปยังผู้ซื้อและผู้ขาย
ทำการตัด stock สินค้าที่ถูกซื้อ
ซึ่งแต่ละระบบจะใช้ message เดียวกัน

ผลที่ตามมาคือ
แต่ละระบบแยกกันอย่างชัดเจน
เพียงแค่กำหนดรูปแบบของ message ในแต่ละเหตุการณ์ที่เกิดขึ้นเท่านั้น
อีกอย่างคือ message เหล่านี้จะต้องมีที่จัดเก็บ ที่ระบบอื่น ๆ
สามารถเข้ามาคอยดูการเปลี่ยนแปลงได้อีกด้วย
เป็นแนวคิดเหมือนกับพวก event-based architecture เลยนะ 

จะพบว่าความสัมพันธ์ทั้ง 7 แบบนั้น มันสะท้องเรื่องโครงสร้างขององค์กร

ทั้งรูปแบบการติดต่อสื่อสารและทีม
และที่สำคัญแต่ละระบบงานก็จะมีรูปแบบที่แตกต่างกันไปเช่นกัน
ไม่สามารถใช้รูปแบบใดรูปแบบหนึ่งได้

  • Upstream vs Downstream
  • Customer vs Supplier
  • Anti-corruption layer

หรือจะทำงานกันแบบ Partnership คือทำงานร่วมกันไปด้วยกัน

Reference Websites



สวัสดี GraalVM จาก Oracle

$
0
0

GraalVM นั้นเป็นงานวิจัยจาก Oracle Lab
และถูกใช้งานบน production ของ Twitter

GraalVM นั้นมีเป้าหมายเพื่อให้เราสามารถ share runtime ให้กับภาษาต่าง ๆ
แน่นอนว่า ไม่ใช่เพียงแค่ JVM เท่านั้น
ที่สามารถ run พวก Java, Kotlin, Scala, Groovy ได้
แต่ยังสนับสนุนภาษาอื่น ๆ เช่น JavaScript, Ruby, Python และ R
นี่มัน Polyglot ชัด ๆ
โดยที่ performance ของการทำงานยังคงสูงอยู่
มาลองใช้งานกันดู

ทำการ Download มาใช้งานกันหน่อย

ตอนนี้ GraalVM version 19.0 ประกอบไปด้วย

  • JDK 1.8.0_212
  • Node 10.15.2
  • JavaScript engine ซึ่งสนับสนุนพวก ECMAScript 2019 
  • Runtime สำหรับ run  LLVM 6.0.0 bitcode

จะมีทั้งของฟรีและเสียเงิน 

  • Community Edition (CE) ตัวนี้ฟรี
  • Enterprise Edition (EE) ตัวนี้เสียเงิน เพิ่มเรื่อง performance, security และการ scale

ใน blog นี้จะใช้ตัวฟรี

เมื่อติดตั้งเรียบร้อยแล้ว GraalVM จะมี command ให้ใช้ดังนี้

  • gu (GraalVM Updater) สำหรับ update และติดตั้ง runtime ภาษาอื่น ๆ
  • node คือ JavaScript Engine ของ GraalVM เอง
  • js คือ JavaScript console
  • lli สำหรับการ run native language บน GraalVM

ยกตัวอย่างเช่น การติดตั้งภาษาต่าง ๆ ด้วยคำสั่ง

[gist id="61cc5cea40942d7ace8aa4b033028761" file="ruby.txt"]

เห็นใน GitHub Issue มีเกี่ยวกับภาษา Go ด้วยนะ

แต่ละภาษาจะใช้ Runtime ดังต่อไปนี้

จากภาพจะเห็นได้ว่า
ภาษาอื่น ๆ ที่ไม่ใช่ JVM language เช่น R, JavaScript, Ruby และ C/C++ นั้น
จะทำงานบน Truffle framework
ดังนั้นสามารถใช้เครื่องมือในการ monitor, debug และ profiling เดียวกัน
น่าจะช่วยทำให้การพัฒนาระบบงานง่ายขึ้น
ยกตัวอย่าง การ debug ผ่าน Chrome DevTool protocol

หรือสามารถใช้งานผ่าน Docker ก็ง่ายกว่า

โดย Docker Image ใช้ OS คือ Oracle Linux
ขนาดของ Docker Image ก็ใหญ่น่าดูคือ 1.71 GB !!

[gist id="61cc5cea40942d7ace8aa4b033028761" file="docker.txt"]

จากนั้นก็ลองใช้งานกันดูเลย
ว่าแต่จะเอาไปทำอะไรดีละ ?

VDO สำหรับการ tuning performance ของ Scala จากทาง Twitter

https://www.youtube.com/watch?v=RG9Ne2tkRuQ

VDO :: นำ Clojure มา run ก็ได้นะ

https://www.youtube.com/watch?v=topKYJgv6qA

มาลองลดขนาด Docker Image ของ Java ด้วย GraalVM กัน

$
0
0

หลังจากที่ติดตั้ง GraalVM ไปแล้ว
คิดไม่ออกว่าจะเอาไปทำอะไรบ้าง !!
ลองนั่งอ่านไปเรื่อย ๆ ก็พบว่ามี GraalVM Native Image ให้
มี command ชื่อว่า Native Image Generator ให้ใช้
ทำการ compile มายัง native binary ให้เลย
นั่นหมายความว่า
ถ้าเป็นพวกภาษา Java, Kotlin และ Scala ก็ไม่จำเป็นต้องมี JVM นะสิ

ดังนั้นจึงคิดว่า
น่าจะนำวิธีนี้ มาใช้ลดขนาดของ Docker Image ของระบบ
ที่พัฒนาด้วยภาษา Java ดูหน่อย
จากเดิมที่มีขนาดใหญ่มาก ๆ หรือประมาณ 100 MB ขึ้นไป
หรืออาจจะ custom หน่อยก็ประมาณ 50-70 MB
แต่ถ้านำ GraalVM Native Image มาใช้น่าจะลดลงไปได้อีก
มาเริ่มกันเลย

เริ่มจาก code ตัวอย่าง เป็น Hello World ง่าย ๆ

[gist id="5ac03b839bf2fa6f72a0227b33ba13a4" file="Hello.java"]

จากนั้นมีขั้นตอนการใช้งานดังนี้

  1. ทำการ compile ด้วยคำสั่ง javac
  2. ทำการสร้าง JAR file ที่สามารถ execute ได้ ด้วยคำสั่ง jar
  3. ทำการติดตั้ง GraalVM Native Image
  4. ทำการสร้าง native binary จาก JAR file ด้วยคำสั่ง native-image

ขั้นตอนทั้งหมดเขียนไว้ใน Dockerfile
จะได้ Docker Image ที่ต้องการ มาดูผลงานกัน

[gist id="5ac03b839bf2fa6f72a0227b33ba13a4" file="Dockerfile"]

ทำการ run ด้วยคำสั่ง

[gist id="5ac03b839bf2fa6f72a0227b33ba13a4" file="run.txt"]

สิ่งที่เห็นได้ชัดคือ ขนาดของ Docker Image ที่ได้คือ  12.5 MB เท่านั้นเอง
มันน่าสนใจดีนะครับ ส่วนเรื่อง performance ค่อยว่ากันอีกที

ลองใช้งาน Test Plan สำหรับ XCTest ใน XCode 11.0 beta

$
0
0

จากงาน WWDC19 มี session เรื่อง Testing in XCode
มี feature ใหม่ที่น่าสนใจคือ Test Plan 
ซึ่งทำการ extend มาจาก XCTest นั่นเอง
มีเป้าหมายเพื่อ การจัดการและควบคุมการทดสอบให้สะดวกยิ่งขึ้น
มาลองใช้งานกันดู

ยกตัวอย่างการใช้งาน เช่นการแบ่งกลุ่มชุดการทดสอบ
ก่อนหน้านี้ต้องแบ่งกลุ่มการทดสอบเช่น Unit test และ UI test ด้วย scheme
ทำให้จำนวน scheme เยอะมาก ๆ ตามแต่กลุ่มการทดสอบที่มี
แน่นอนว่า ไม่ค่อยสะดวกเท่าไรนัก

ใน XCode 11 นั้นจึงสร้าง Test Plan ขึ้นมา

สำหรับทำการจัดการในเรื่องดังกล่าวซึ่งมีความสามารถต่าง ๆ ดังนี้

  • การทดสอบอยู่ในส่วนหนึ่งของการ build
  • สามารถทดสอบแบบ random ได้
  • จัดการผลการทดสอบได้ เช่นพวก report และ scheenshot
  • ทำการจัดกลุ่มการทดสอบตาม resource ที่มีได้
  • ทำการ run ชุดการทดสอบตาม location ได้อีกด้วย

และอีกความสามารถหนึ่งคือ
การ migrate จาก scheme มายัง Test Plan (Convert to use Test Plans)
ประกอบไปด้วย

  • Create test plan from scheme
  • Create empty Test Plan
  • Choose Test Plan

เมื่อทำการ migrate หรือสร้าง Test Plan ขึ้นมา
จะต้องทำการบันทึก Test Plan ด้วยนามสกุล .xctestplan

จากนั้นสามารถทำการสร้าง configuration ในแต่ละ Test Plan ได้เลย

ซึ่งมีทั้งแบบ share กันทั้งหมด กับ custom configuration ยกตัวอย่างเช่น

  • ส่ง Argument ต่าง ๆ มายัง Test Plan ได้
  • กำหนด Location ต่าง ๆ
  • กำหนดรูปแบบการทดสอบเป็นแบบ random 
  • เปิดการใช้งาน Code Coverage
  • สำหรับ UI test สามารถกำหนดการบันทึก screenshot ได้

ในส่วนนี้มีความยืดหยุ่นมาก ๆ

ถึงตรงนี้น่าจะทำให้การทดสอบใน XCode ง่ายและสะดวกขึ้นแล้ว
วันนี้คุณเขียนชุดการทดสอบแล้วหรือยัง ?
ถ้ายัง... เริ่มได้เลย

[Golang] การจัดเรียง property ใน Struct เพื่อลดจำนวน memory ที่ใช้งาน

$
0
0

วันนี้น้องในทีมมาถามเรื่อง 
การใช้งาน memory ของ struct ในภาษา Go
ซึ่งมีเรื่องของ Alignment และ Padding ที่อาจจะดูงง ๆ
เลยลองไปเปิดเอกสารของภาษา Go ดูกันหน่อย
ได้ความว่า

ลำดับของ property ใน Struct

มีผลต่อขนาดของ memory ที่ใช้งานด้วย
ซึ่งถ้าเราจัดการดี ๆ หรือมีความเข้าใจดี ๆ แล้ว
ก็จะช่วยทำให้ระบบงานของเราใช้ memory น้อยลงไปด้วย
น่าจะมีประโยชน์พอสมควรเลย
ปล. ใช้งานบน Architecture แบบ 64 bit

เริ่มด้วย code ประมาณนี้

[gist id="612846d0fb82f1ee63b8d37984d25cb5" file="1.go"]

ผลที่ได้คือ Struct นั้นจะใช้หน่วยความจำไป 24 byte

ทำไมถึงใช้ถึง 24 byte ?
เนื่องจากลองบวกขนาดของ data type ใน struct แล้วไม่ถึงนะ
คือ 1 + 8 + 4 =  13 byte เท่านั้น !!!

เมื่อลองไปอ่านเอกสารดูพบว่า

แต่ละตัวแปรใน Struct นั้น (สำหรับ Architecture แบบ 64 bit)
จะทำการ padding ทุก ๆ  8 byte เสมอ
ทำให้ผลรวมของการจองหน่วนความจำคือ 24 byte นั่นเอง
ทำให้การจองพื้นที่ในหน่วยความจำเป็นดังนี้

จะเห็นว่าตัวแปรชนิด float64 จะใช้พื้นที่ขนาด 8 byte
ซึ่งใหญ่กว่าที่มีให้หลังจากที่ boolean ในไป 1 byte
ทำให้ต้องไปจองเพิ่มอีก 8 byte ตามรูปแบบการจองหน่วยความจำ (Allocate memory)

คำถามคือ จะลดขนาดของหน่วยความจำที่ใช้ลงไปอย่างไร ?

ง่าย ๆ คือ เปลี่ยนลำดับของ property ใน Struct ไงละ !!
ยกตัวอย่างเช่น จะเหลือเพียง 16 byte เท่านั้น

[gist id="612846d0fb82f1ee63b8d37984d25cb5" file="2.go"]

แสดงดังรูป

เพียงแค่เปลี่ยนลำดับ ชีวิตก็เปลี่ยนเลย
ประเด็นหลัก ๆ คือ  เพียงเรื่องเล็ก ๆ น้อย ๆ นั้น
มันช่วยให้เราปรับปรุงประสิทธิภาพการทำงานของระบบได้มากขึ้นแล้ว
ลองนำไปใช้กันดูนะครับ

Reference Websites

สร้าง RESTFul API ด้วยภาษา Elixir

$
0
0

ช่วงวันหยุดว่าง ๆ ลองเขียนภาษาใหม่ ๆ ดูหน่อย
พอดีไปเจอตัวอย่าง code ภาษา Elixir แล้วชอบ เลยต้องลอง
คิดว่าน่าจะลองหาอะไรทำดูหน่อย
ตั้งโจทย์ว่า จะลองทำ RESTFul API แบบง่าย ๆ ทำการส่งผลกลับมาในรูปแบบของ JSON
จึงทำการบันทึกผลการลองครั้งนี้ไว้ดังนี้

ขั้นตอนที่ 1 ทำการติดตั้ง Elixir 1.8.2

ในส่วนนี้ใช้งานผ่าน Docker ด้วย Image Elixir 
พบว่าขนาดใหญ่มาก ๆ ถึง 1.08 GB !!!
โหดร้ายต่อการเริ่มมาก ๆ

ขั้นตอนที่ 2 ลองสร้าง project เล่นชื่อว่า hello

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="1.txt"]

สิ่งที่ต้องการคือ สร้าง RESTFul API + JSON  ซึ่งจะใช้งาน library ดังนี้

  • Cowboy เป็น HTTP framework ที่เล็ก ๆ เพราะว่าไม่ต้องการอะไรมากมาย
  • Poison สำหรับการจัดการข้อมูลในรูปแบบ JSON

ทำการเพิ่ม library เข้าไปใน project ด้วยการแก้ไขไฟล์ mix.exs

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="mix.exs"]

ปัญหาที่เจอคือ ไม่สามารถใช้งานผ่าน Docker Image ปกติได้
ต้องทำการติดตั้งบางอย่างก่อน จึงทำการ custom image นิดหน่อยดังนี้

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="Dockerfile"]

ขั้นตอนที่ 3 Elixir เตรียมเรื่องของการทดสอบและ formatting code มาให้

ในส่วนนี้ชอบมาก ๆ เพราะว่ามีมาให้เลย

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="2.txt"]

ขั้นตอนที่ 4 มาสร้างระบบงานที่ต้องการ

จากที่อ่านเอกสารของ Cowboy มานั้น
การใช้งานก็ไม่ยากเท่าไร
แต่ต้องการแยกส่วนการทำงานชัดเจนและ configuration ได้ง่าย
จึงแบ่งเป็นส่วนงานดังนี้

  • Endpoint สำหรับกำหนด endpoint ของ API ต่าง ๆ
  • Application สำหรับกำหนดจุดเริ่มต้นการทำงานของระบบ เพื่อ load สิ่งต่าง ๆ ที่ต้องใช้งานในการ start service ของระบบงาน
  • มี config สำหรับการใช้งานในแต่ละส่วนเช่น dev, test และ prod เป็นต้น ซึ่ง Elixir project มีให้แล้ว แค่ใช้ให้ถูกเท่านั้นเอง ตรงนี้ไม่ง่าย

ส่วนที่ 1 Endpoint

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="endpoint.ex"]

ส่วนที่ 2 Application

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="application.ex"]

เมื่อทุกอย่างเตรียมพร้อมแล้ว

ก็มากำหนดจุดเริ่มต้นของการทำงานคือ Application ในไฟล์ mix.exs ดังนี้

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="mix2.exs"]

ขั้นตอนที่ 5 ทำการ compile และ run ระบบงาน

ด้วยคำสั่ง

[gist id="9b6601f4d9c959698c67d00581a7f9c4" file="3.txt"]

ได้ลองเรียนรู้ภาษา Elixir มานิดหน่อย
ต่อไปจะได้ลองลงรายละเอียดของภาษาต่อไป
มันสนุกดีนะ

Source code ตัวอย่างอยู่ที่ GitHub::Up1

การพัฒนา Software ต้องเตรียมอะไรบ้าง ?

$
0
0

จากการแบ่งปันเรื่องของ Microservices คำถามหนึ่งที่มักได้รับคือ
เราจำเป็นต้องปรับปรุงหรือเปลี่ยนแปลงอะไรบ้าง ?
เพื่อให้สามารถนำแนวคิดของ Microservices มาใช้งานได้อย่างดี
ผมจึงทำการแนะนำในเรื่องของ คน, skill และ process ที่ควรต้องมี
โดยเน้นในเรื่องของ feedback ที่รวดเร็วและมีคุณภาพไว้ดังนี้

การพัฒนาระบบ software ที่มีคุณภาพนั้น

ไม่ใช่เรื่องที่ง่าย
เนื่องจากต้องการแนวปฏิบัติต่าง ๆ และประสบการณ์มากพอควร
แต่บ่อยครั้งเราอาจจะมองว่า
มีงานที่เพิ่มเข้ามาอาจจะทำให้งานล่าช้าและไม่ทัน deadline แน่นอน
ดังนั้นเราจึงมักจะไม่ทำหรือละทิ้งไป !!

การแก้ไข ดูแลรักษายากขึ้นเรื่อย
หรือบางครั้งอาจจะพูดว่ามีหนี้เชิงเทคนิคสูงขึ้น
นั่นทำให้
ทีมต้องใช้เวลาในการพัฒนาสูงขึ้น
Software ที่พัฒนาออกมามีข้อผิดพลาดสูงขึ้น

เมื่อเกิดเหตุการณ์นี้บ่อย ๆ แล้ว
ผลที่ตามมาคือ เกิดความกลัวเมื่อต้องแก้ไข
การปรับปรุงให้มันดีขึ้น จึงไม่มีใครอยากจะทำ
เพราะว่าไม่รู้ว่า แก้ไขหรือปรับปรุงไปแล้ว จะไปกระทบการทำงานหรือไม่ !!!

ดังนั้นใครที่บอกว่า
เดี๋ยวจะกลับมาแก้ไขให้ดีขึ้น
บอกได้เลยว่า คือการโกหกล้วน ๆ

นี่คือปัญหามักจะเจอมาก ๆ ในการพัฒนา software หรือไม่ ?
ว่าด้วยเรื่องของคุณภาพของ software ล้วน ๆ

การแก้ไขปัญหาพื้นฐาน แบ่งเป็นกลุ่ม ๆ ดังนี้

  • กำหนด Development process, Technology และ เครื่องมือ ซึ่งคนทำงานหรือเกี่ยวข้องจะต้องกำหนดขึ้นมา
  • รูปแบบพื้นฐานของเอกสารที่เป็นประโยชน์ ทั้ง API document, อธิบายการใช้งาน เช่น Wiki หรือพวก Makedown เป็นต้น
  • กำหนดรูปแบบของ coding standard และต้องนำไปใช้งานด้วยเสมอ
  • กำหนดเครื่องมือพวก Static code analysis สำหรับตรวจสอบ code smell ได้อย่างทันที เช่น SonarQube เป็นต้น
  • ชุดการทดสอบแบบอัตโนมัติ ตั้งแต่ unit, integration, component, contract ไปจนถึง end-to-end test
  • สร้าง environment สำหรับการพัฒนาที่เหมาะสม ให้เหมือนหรือคล้ายกับ production มากที่สุด เพื่อลดความผิดพลาด
  • สร้าง process ของการส่งมอบ software หรือ Delivery pipeline

ส่วนที่สำคัญมาก ๆ คือ Delivery pipeline

เป็นการรวมเอาการทำงานต่าง ๆ 
มาร้อยเรียงเป็นขั้นตอนการทำงานแบบอัตโนมัติ
ปรับเปลี่ยนมาจากขั้นตอนที่เป็นแบบ manual นั่นเอง

เริ่มตั้งแต่มีการเปลี่ยนแปลง
ทั้ง code, configuration, environment
ต้องทำงานตามขั้นตอนหรือ stage ที่ตกลงร่วมกัน
เพื่อปรับปรุงคุณภาพของ software ที่พัฒนา
และพร้อมที่จะส่งมอบอยู่ตลอดเวลา
ยกตัวอย่างเช่น

  1. build
  2. Static code analysis
  3. Unit test
  4. Integration test
  5. Acceptance test
  6. Deployment
  7. Security test
  8. Performance test

แต่ทั้งหมดนี้จะเกิดขึ้นไม่ได้เลย
ถ้าแต่ละคนที่เกี่ยวข้องไม่เห็นคุณค่าหรือความจำเป็น
ดังนั้นคนจึงมีความสำคัญอย่างมาก

ลองนำไปใช้ในการปรับปรุงดูครับ


มาดูข้อมูลว่า ทำไมภาษา Python ที่ได้รับความนิยมสูง

$
0
0

ข้อมูลจาก web จัดอันดับความนิยมของภาษาโปรแกรม
Tiobe Index ขึ้นมาอยู่อันดับสองที่สำคัญความนิดยมพุ่งมาสุด
PyPL อยู่อันดับ 1
Redmonk อยู่ในอันดับที่ 3


โดยที่แต่ละที่เขานำข้อมูลมากจาก
Tiobe Index นำข้อมูลจากการค้นหา search engine ต่าง ๆ และ Wikipedia
PyPL นำข้อมูลมาจากการค้นหาใน google
Redmonk นำข้อมูลมาจาก code ใน GitHub และการพูดคุยใน StackOverflow

เมื่อลองไปดูในรายละเอียดพบว่า

ทาง Tiobe Index อธิบายว่า
ภาษา Python นั้นถูกใช้ในการเรียนการสอนในสถาบันการศึกษาต่าง ๆ
รวมทั้งบริษัทพัฒนา software ต่าง ๆ
เนื่องง่ายต่อการเรียนรู้และ deploy
รวมไปถึงการใช้งานที่เฉพาะเจาะจงมากขึ้น

ปล. ในปีหน้า Python จะหยุดพัฒนา version 2.x แล้ว ดังนั้นควรจ้องย้ายมายัง version 3.x ได้แล้ว

แต่สิ่งที่ทำให้ภาษา Python ได้รับความนิยมสูงมาก ๆ คือ

โลกของ Data Science, Machine และ AI นั่นเอง
เมื่อลองไปดูข้อมูลของ package ของภาษา Python ก็เป็นจริง

  • Pandas, Numpy และ  Matplotlib สำหรับการจัดการ ประมวลผลและแสดงผลข้อมูล
  • Django และ flask คือ web framework
  • ยังมี TensorFlow, Scikit-Learn, Keras อีกนะ เยอะไปหมด !!

ดังรูป

ที่น่าสนใจคือ สามารถนำภาษา Python ไปสร้างระบบที่ทำงานแบบอัตโนมัติง่าย ๆ อีกด้วย
ทั้งในสาวนของ System admin และ DevOps เป็นต้น
ยกตัวอย่างการใช้งานตามหนังสือ Automate the boring stuff with Python

ด้วยความหลากหลายในการนำไปใช้งานนี่เอง

ส่งผลให้ภาษา Python ได้รับความนิยมสูงขึ้น
รวมทั้งเรื่องของความต้องการจากบริษัทต่าง ๆ ที่สูงมาก
อีกทั้ง community ก็มีขนาดใหญ่มากเช่นกัน

... เพิ่มเติมผลการสำรวจในปี 2018 จาก Python Developer survey พบว่า

มีการนำภาษา Python ไปใช้งานที่หลากหลายมาก ๆ แสดงดังรูป

ส่วนการติดตั้งและใช้งาน Python
ก็ใช้ดังนี้

กำหนดลำดับการ start ของ service ใน Docker compose ให้ถูกต้อง

$
0
0

ปัญหาหนึ่งที่ได้มักเจอเมื่อใช้งาน Docker compose คือ
ลำดับการ start ของ service ต่าง ๆ นั่นเอง
แน่นอนว่าใน docker compose ก็จะมี depends_on ให้ใช้งาน
แต่ปัญหาก็ยังมีอยู่คือ Service ต่าง ๆ ก็ start ตามลำดับ
แต่ว่ามีบาง service ที่ start แล้วแต่ยังไม่พร้อมใช้งาน
ซึ่งอาจจะทำให้เกิดปัญหากับ service อื่น ๆ ที่ต้องใช้งานตอน start เช่นกัน

ยกตัวอย่างเช่น
Service A เป็น database 
Service B ทำหน้าที่สร้าง table และ สร้างข้อมูล
แน่นอนว่า ถ้าใช้ depends_on ก็ได้แค่ลำดับ คือ
ให้สร้าง service A ก่อน B 
แต่ B จะทำงานผิด ถ้า A ยังไม่ start เสร็จสมบูรณ์


"คำถาม แก้ไขปัญหานี้อย่างไรดี ?"

คำตอบ 
เอกสารของ Docker ก็เตรียมไว้ให้แล้วคือ 
Control startup and shutdown order in Compose

แน่นอนว่ามีคนทำไว้ให้แล้วทั้ง

หรือเขียน shell script เองก็ได้

โดยนำคำสั่งเหล่านี้ไปใส่ที่ command ของแต่ละ service
ในไฟล์ docker compose ได้เลย

แต่อย่าลืมตรวจสอบด้วยว่า
Docker image ที่ใช้งานมีคำสั่งต่าง ๆ ที่ใช้ใน script ด้วยหรือไม่
มิฉะนั้นก็อาจจะพังได้

ตัวอย่างเขียน shell script เอง
ทำการตรวจสอบว่า mysql ทำการ start เสร็จแล้วหรือยัง
ถ้ายัง start ไม่เสร็จจะวนถามไปเรื่อย ๆ ทุก ๆ 1 วินาที 

[gist id="cd96e28fa5cb7a460b0b542621413915" file="docker-compose.yml"]

หรืออาจจะทำการเขียน code เองเลยก็ได้
ยกตัวอย่างเช่น

[gist id="cd96e28fa5cb7a460b0b542621413915" file="wait.py"]

เพียงเท่านี้ก็สามารถจัดลำดับการทำงานของ service ได้ถูกต้องตามที่ต้องการแล้ว

Code ตัวอย่างอยู่ที่ GitHub::Up1

บันทึกการ Release software บน GitHub

$
0
0

วันนี้ต้องการที่จะ release software บางตัวที่ source code อยู่บน GitHub
ปกติก็จะจัดการด้วย tag แบบง่าย ๆ
แต่ครั้งนี้อยากจะให้ในการและ tag หรือ release นั้น
มี executable file ของระบบงาน ไม่ใช่แค่ code เท่านั้น
ยกตัวอย่างเช่น JAR และ EXE เป็นต้น
จึงหาวิธีการดูหน่อย

พบว่ามันง่ายมาก ๆ
นั่นคือ การ upload file ที่ต้องการขึ้นไปเท่านั้นเอง
ผ่าน menu release จากนั้นก็กดปุ่ม Draft a new release
แสดงดังรูป

จากนั้นก็ใส่รายละเอียด เลือก tag ที่มีอยู่หรือสร้างใหม่ก็ได้
และทำการ upload file ที่ต้องการ เป็นอันจบพิธี

ว่าง ๆ ลองสร้าง Docker Image ของ Libra client และใช้ดูหน่อย

$
0
0

เห็นเพื่อน ๆ ใน timeline ลอง Libra และภาษา Move กันเพียบเลย
พอดีไม่ค่อยมีความรู้เรื่องพวกนี้ จึงได้แต่เฝ้าดูอยู่ห่าง ๆ
แต่พอไปอ่านบทความรวมทั้งเอกสารต่าง ๆ แล้ว
ทำให้อยากทดลองใช้ดู
เขาบอกว่า ก่อนอื่นต้องติดตั้งก่อน
ดังนั้นมาเริ่มกัน

จะติดตั้งทั้งทีก็สร้าง Docker Image เก็บไว้ใช้เลย

ซึ่งทาง Libra ก็ได้เตรียม Dockerfile ไว้ให้
สำหรับสร้าง Libra client เพื่อไปใช้งาน Test network ของ Libra เลย
ดังนั้นก็ build กันด้วยคำสั่ง

[gist id="caa2cf2dc455ddc4ea1129b7c2603ffd" file="0.txt"]

ใช้เวลานานมาก ๆ ว่าจะ build เสร็จ
นานมากจนน่าจะอาบน้ำได้สัก 1 รอบ
ส่วนขนาดของ Docker image ไม่ใหญ่มากคือ  497 MB

มาใช้งานกันดีกว่า

ในตอนนี้ได้ Libra client แล้ว ก็สร้าง container มาใช้งานกันเลย
ซึ่งใช้งานไม่ยาก เพราะว่ามีเอกสารอธิบายชัดเจน

[gist id="caa2cf2dc455ddc4ea1129b7c2603ffd" file="1.txt"]

ลองสร้าง account บน Test network (ac.testnet.libra.org:8000) ของ Libra กัน
ด้วยคำสั่ง account create ดังนี้

[gist id="caa2cf2dc455ddc4ea1129b7c2603ffd" file="2.txt"]

เนื่องจากใน account ที่สร้างใหม่นั้น มี balance = 0 ซึ่งทำอะไรไม่ได้

ดังนั้นใน Test network จึงเตรียมการเติมเงินไว้ให้
เป็นบริการที่ชื่อว่า Faucet
ส่วนใน Main network ไม่มีนะ
ขั้นตอนเป็นดังนี้

[gist id="caa2cf2dc455ddc4ea1129b7c2603ffd" file="3.txt"]

เมื่อ account มีเงินแล้ว จากนั้นก็มาทำการโอนไปให้คนอื่นต่อ

จะได้ครบวงจรการเงิน

[gist id="caa2cf2dc455ddc4ea1129b7c2603ffd" file="4.txt"]

ต่อไปก็เข้าสู่ My First Transaction กันได้เลย

ไม่ยากเท่าไรนะ แต่นานหน่อย
และยังมีคำสั่งอื่น ๆ ให้ลองเล่น น่าสนุกมาก ๆ ครับ เช่น

  • ดูสถานะของ account
  • ดู transaction ที่เกิดขึ้นของแต่ละ account

ลองมาเล่นกันครับ

ว่าด้วยเรื่องที่ควรรู้และเข้าใจเกี่ยวกับ Elasticsearch

$
0
0

หลังจากที่มีโอกาสแบ่งปันเรื่องของ Elastic Stack ไปพอสมควร
จึงทำการสรุปสิ่งที่แบ่งปันไว้นิดหน่อย
ซึ่งเป็นอีกมุมมองที่คนใช้งานหรือคนที่สนใจควรรู้ไว้บ้าง
มาเริ่มกันเลย

Elastic Stack มีอะไรบ้าง ?

ตัวหลัก ๆ ที่น่าจะรู็จักกันคือ ELK stack ประกอบไปด้วย

  • Elasticsearch คือ search engine database
  • Logstash เครื่องมือสำหรับสร้าง pipeline ของการ process ข้อมูล
  • Kibana เครื่องมือสำหรับ visualization

แต่ในปัจจุบันนั้นใน Elastic stack มี product อื่น ๆ ออกมาอีก
ยิ่งนับวันจะมีมากขึ้นอีกด้วย
ยกตัวอย่างเช่น

  • Beats เป็น product ที่มีเครื่องมือย่อย ๆ เฉพาะทางสำหรับเรื่องของ data shipper
  • Elastic cloud เป็น hosting สำหรับ Elasticsearch cluster
  • APM (Application Performance Monitoring)
  • Machine Learning

รูปแบบข้อมูลที่จัดเก็บใน Elasticsearch

ประกอบไปด้วยข้อมูล 2 รูปแบบคือ

  1. Static data หรือ business transaction
  2. Time-serie data

โดยสิ่งที่ต่างกันของข้อมูลทั้งสองแบบคือ 
อัตราการเติบโตของข้อมูล ขนาดของข้อมูล
ทำให้ต้องมีการจัดการที่แตกต่างกันอย่างมาก
ทั้งเรื่อง index จัดเก็บ
ทั้งเรื่องของการ replicate ข้อมูล
ทั้งเรื่องการ sync ข้อมูล
ทั้งเรื่องการจัดการกับข้อมูลที่ไม่ถูกใช้งาน

Data modeling

Elasticsearch นั้นทั้งเร็วและสามารถ scale ได้ง่าย
แต่จะเป็นไปไม่ได้เลยถ้าข้อมูลที่จัดเก็บไม่มีคุณภาพ
หรือไม่ตรงกับสิ่งที่ต้องการ
ผลที่ตามมาคือ
จัดเก็บข้อมูลเยอะเกินไป
ค้นหาข้อมูลช้า หรือ ไม่เจอข้อมูลตามที่ต้องการ

ดังนั้นขั้นตอนของการ indexing และค้นหาข้อมูลจึงสำคัญมาก ๆ
เพราะว่าทั้งสองขั้นตอนการทำงานนั้น
จะมีการทำ data analysis หรือการวิเคราะห์ข้อมูล
ก่อนที่จะทำการ indexing และค้นหา

โดย data analysis ของ Elasticsearch ประกอบไปด้วย

  • Character filter การกรองข้อมูลว่าจะใช้ข้อมูลอะไรมาตัดคำต่อไป
  • Tokenizer การตัดคำข้อมูล โดยแต่ละคำที่ตัดจะเรียกว่า token เช่น Standard, Whitespace และ Thai เป็นต้น
  • Token filter ทำการ filter token เช่น lowercase เป็นต้น

ทาง Elasticsearch จะมี build-in สิ่งต่าง ๆ ข้างต้นมาให้
แน่นอนว่า เราสามารถนำทั้งสามเรื่อง
มารวมกันเพื่อสร้างให้ตรงตามที่ต้องการได้เลย

การดึงข้อมูลจาก Elasticsearch นั้นสำคัญมาก ๆ

การดึงข้อมูลแยกออกเป็นสองส่วนคือ

  • Query API สำหรับค้นหาข้อมูล
  • Aggregation API สำหรับสรุปข้อมูล เหมือนกับการ group by และ count/sum/avg ใน SQL นั่นเอง

ทั้งสองเรื่องถือเป็นหัวใจสำคัญมาก ๆ
ซึ่งคนที่นำไปใช้งานควรทำความรู้และเข้าใจให้ดี
ที่สำคัญจะสัมพันธ์กับ Data modeling อีกด้วย

หน้าที่ของแต่ละ Node ใน Elasticsearch cluster

Node ใน Elasticsearch cluster นั้นมีหน้าที่หลายอย่าง
ประกอบไปด้วย

  • Master สำหรับดูแล nodes, settings และจัดการ index ต่าง ๆ
  • Data สำหรับเก็บข้อมูล
  • Query/Coordinate สำหรับรับ request การค้นหาข้อมูล
  • Ingest
  • Machine learning (commercial เท่านั้น)

ค่า default นั้นในทุก ๆ Node สามารถทำได้ทุกอย่าง
ซึ่งเหมาะสำหรับ Cluster ขนาดเล็ก


แต่ถ้า cluster มีขนาดใหญ่ขึ้น
ควรต้องแบ่งหน้าที่ของแต่ละ node ให้ชัดเจน
เพราะว่าแต่ละหน้าที่นั้น ใช้งาน resource ต่างกันไป
ยกตัวอย่างเช่น

  • Master node จะใช้ CPU, Memory และ Disk ที่น้อย
  • Data node จะใช้ CPU, Memory และ Disk ที่สูงมาก
  • Query node จะใช้ Memory สูง
  • Ingest node จะใช้ CPU สูง

จำนวน Node แนะนำสำหรับ cluster ขนาดใหญ่คือ

  • 3 Master node
  • 2 Query node
  • Data node ขึ้นอยู่กับข้อมูลที่จัดเก็บ

ที่สำคัญอย่าลืมทำ performance testing ด้วย
ว่ารองรับการใช้งานที่คาดหวังได้หรือไม่

เรื่องของ Sharding planning

หน่วยย่อยสำหรับการ scale ข้อมูลใน Elasticsearch cluster จะเรียกว่า Shard
โดยใน version 7.1.1 นั้นค่า default ของจำนวน shard ในแต่ละ index คือ 1
นั่นหมายความว่า shard นี้จะอยู่เพียง 1 node เท่านั้น
เรื่องของ scaling จึงเป็นไปไม่ได้เลย !!
แต่สามารถ replicate ได้นะ

โดยคำถามที่มักได้รับเสมอคือ 
ควรกำหนดจำนวน shard ของแต่ละ index เป็นเท่าไรดี ?
เนื่องจากค่านี้จะต้องกำหนดตั้งแต่สร้าง index กันเลย
ดังนั้นจึงสำคัญมาก ๆ ต้องวางแผนกัน

คำตอบคือ ไม่รู้นะ
ขึ้นอยู่กับข้อมูลนั่นเอง

แต่ความรู้พื้นฐานที่ควรรู้คือ
ในแต่ละ shard จะเก็บข้อมูลได้ประมาณ 20-40 GB
ดังนั้นการวางแผนต้องดูจากจำนวนข้อมูลหรือ growth rate
รวมไปถึงขนาดของข้อมูล และ จำนวนของ memory ที่ใช้งาน
รวมทั้งเป้าหมายของ performance ที่กำหนดไว้ด้วย

ถ้ากำหนดจำนวน shard ผิด หรือไม่รองรับแล้ว
ต้องทำการ reindex ข้อมูลไปยัง index ใหม่เท่านั้น

ปล. จากเอกสารของ Elasticsearch บอกว่า
Performance ของการดึงข้อมูลจาก
50 index ที่แต่ละ index มีจำนวน 1 shard
จะเหมือนกับ
1 index ที่จำนวน 50 shard

Viewing all 1997 articles
Browse latest View live