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

วันนี้เราลบ code ที่ไม่ใช้งาน แล้วหรือยัง ?

$
0
0

เพิ่งไปแบ่งปันเรื่องของ Code Quality มีหนึ่งเรื่องที่น่าสนใจคือ dead code หรือ code ที่ไม่ถูก execute หรือ code ที่ไม่ถูกใช้งาน หรือ code ที่ comment ไว้ ทั้ง ๆ ที่ใช้ version control หรือหนักสุดคือ code ที่สร้าง feature ที่ไม่มีผู้ใช้งาน คำถามคือ ทุกวันนี้เรายังดูแลรักษา code เหล่านี้ไว้กันหรือไม่ ? ลองตอบกันหน่อยนะ สิ่งที่น่าสนใจคือ ทำไมเรายังเก็บ code ที่ไม่ใช้งานจากข้างต้นกันไว้นะ ? ยิ่งนับวันมันจะมีจำนวนมากขึ้นเรื่อย ๆ อย่างไม่หยุดยั้ง ยิ่งนับวันมันยิ่งทำให้เราช้าลงไปเรื่อย ๆ ทั้งการอ่านและทำความเข้าใจ code ทั้งเวลาในการ build ที่สูงขึ้น ทั้งการดูแลรักษาที่ยากลำบากขึ้น ทั้งผลกระทบต่าง ๆ ที่อาจจะเกิดขึ้น ทำไมนะ
ทำไมเราไม่ลบ code เหล่านั้นทิ้งไปละ เรากลัว ? เราไม่กล้า ? เราไม่รู้ ? เราไม่สนใจ ?
หรือต้องกลับมาที่คำถามพื้นฐานว่า เรารู้ไหมว่ามี dead code ในระบบของเรามากน้อยเพียงใด ?
วันนี้เราลบ code ที่ไม่ใช้งาน แล้วหรือยัง ?

บันทึกการเรียน Kafka 101 :: Part 1 เรื่อง Messaging system

$
0
0

วันนี้ได้เข้าเรียน Kafka 101 ที่ SCK Dojo ซึ่งสอนโดย Surasit Neng Liangpornrattana ซึ่งหัวข้อต่าง ๆ ที่ได้เรียนประกอบไปด้วย
  • เรื่องของ Messaging system
  • ทำไมต้องใช้งาน Kafka ด้วย
  • RabbitMQ vs Kafka
  • Ecosystem ของ Kafka เช่น Producer, Consumer, Zookeeper เป็นต้น
  • ความรู้พื้นฐานเกี่ยวกับ Kafka เช่น Topics, Partition, Broker เป็นต้น
  • Message Delivery Semantic
  • Workshop ทำงานร่วมกับ Line Chat Bot
เนื่องจากว่าเนื้อหาเยอะมาก ๆ จึงทำการสรุปไว้เป็นหลาย ๆ ส่วน ในส่วนแรกนี้จะเน้นเรื่องของ Messaging system กันนิดหน่อย
มาเริ่มกันเลย

เริ่มต้นด้วยเรื่องของ Messaging system

ระบบงานนั้นมีการใช้ข้อมูลมาทำงาน ทั้งจากภายในและภายนอก มีการทำงานกับข้อมูลจากหลากหลายที่ การ integrate ระบบงานเข้ากับข้อมูลจึงเป็นเรื่องที่ไม่ง่ายเลย ยิ่งมีจำนวนระบบทำงานจำนวนมากยิ่งลำบากไปใหญ่ ดังนั้นถ้ามีระบบที่ช่วยทำให้ง่ายขึ้นน่าจะดีกว่าไหมนะ ?
  • ช่วยให้การ integrate แต่ละระบบง่ายขึ้น
  • แต่ละระบบไม่ผูกมัดกันมากเกินไป (Loose coupling)
  • มีรูปแบบการทำงานร่วมกันที่เป็นมาตฐาน (Standard Interface)
  • ทำให้ Latency ของการทำงานต่ำ
  • มีความเสถียรหรือน่าเชื่อถือสูง
ทั้งหมดนี้มันก็คือ Messaing system นั่นเอง แต่ถ้าใครไม่มี requirement แบบนี้ก็ข้ามไปได้เลย

โดยพื้นฐานของ Messaging system ประกอบไปด้วย

  • Message queue คือ ตัวเชื่อมต่อระหว่าง Producer และ Consumer บ่อยครั้งจะเรียกว่า Queue หรือ Channel นั่นคือทำการรับข้อมูล หรือ message ที่ส่งมาจาก producer และส่งต่อไปให้ทาง consumer ต่อไป
  • Message หรือ Data package คือข้อมูลที่ถูกส่งผ่านระบบ network นั่นเอง โดยข้อมูลจะถูกห่อหุ้มตาม protocol ที่ใช้งาน
  • Sender หรือ Producer ทำการส่งข้อมูลหรือ message ไปยัง message queue
  • Receiver หรือ Consumer ผู้รับ message จาก message queue ไปได้ทั้งแบบ pushing และ polling
  • Data transmit protocol เป็น protocol หรือภาษาในการสื่อสารกันนั่นเอง มีความหลากหลายตาม implementation ของระบบ queue ที่ใช้ ยกตัวอย่างเช่น AMQP (Advance Message Queuing Protocol), MQTT (Message Queue Telemetry Protocol) และ HTTP เป็นต้น
  • Transfer mode เช่น synchronous, asynchronous และ batching เป็นต้น

รูปแบบการทำงานของ Messaging system นั้นมีดังนี้

  • Point-to-Point (PTP)
  • Publish-Subscribe (Pub-Sub)
  • Advance Queuing Messaging Protocol (AQMP)
มาดูในแต่ละแบบกัน

Point-to-Point (PTP)

ง่าย ๆ คือแต่ละ message จะถูก consume จาก consumer เดียวเท่านั้น ถึงแม้จะมี consumer มากกว่า 1 ตัวก็ตาม ทำให้เรามั่นใจได้ว่า จะไม่มี consumer มารับ message ไปทำงานซ้ำแน่นอน การส่งข้อมูลจะตัวกลางซึ่งเราจะเรียกว่า queue (FIFO - First In First Out) ในการ implement นั้น Producer จะทำการส่งข้อมูลไปยังชื่อของ queue ที่กำหนด จากนั้นในส่วนของ consumer จะคอย monitoring ว่ามีข้อมูลเข้ามายัง queue นั้น ๆ หรือไม่ ถ้ามีข้อมูลเข้ามาก็จะนำออกมาทำงานหรือ processing ต่อไป สามารถเพิ่มจำนวนของ producer และ consumer ในขณะ runtime ได้ตามที่ต้องการ แสดงดังรูป Point-to-Point แบ่งได้ 2 แบบตามการทำงาน คือ
  1. Fire-and-Forget model คือเมื่อส่งข้อมูลเข้า queue แล้วเป็นอันจบ ซึ่งมักจะเรียกว่า การทำงานแบบ Asynchronous
  2. Request/Reply model คือเมื่อส่งข้อมูลเข้า queue แล้วจะต้องรอการตอบกลับจาก consomer ด้วยว่าเป็นอย่างไร นั่นทำให้ producer และ consumer ผูกมัดกัน หรืออาจจะเรียกได้ว่า ทำงานแบบ Syschronous

Publish-Subscribe (Pub-Sub)

รูปแบบการทำงานนี้ใช้งานเมื่อ ต้องการส่งข้อมูลหนึ่ง ๆ ไปยัง consumer มากกว่า 1 ตัว โดย consumer นั้นจะถูกเรียกว่า Subscriber producer จะเรียกว่า Publisher ส่วน message queue จะเรียกว่า Topic
ข้อมูลจะถูกจัดเก็บใน Topic ไปจนกว่าข้อมูล จะถูกส่งไปถึง subscriber/consumer ที่ active อยู่ทั้งหมด
การทำงานของ producer และ consumer นั้นจะไม่ผูกมัดกัน นั่นหมายความว่า producer จะไม่สนใจเลยว่าใครคือ consumer ทำหน้าที่ส่งข้อมูลเข้า topic ไปตามที่ต้องการ ส่วน consumer ก็เช่นกันไม่สนใจ producer สนใจเพียงว่าจะทำการไป subscribe ที่ Topic อะไรก็พอ หรือถ้าไม่ต้องการข้อมูลจาก Topic ก็ทำการ unsubscribe ได้เลย เหมือนกับการติดตามข้อมูลข่าวสารตาม website นั่นเอง แสดงการทำงานดังรูป

Advance Queuing Messaging Protocol (AQMP)

เป็น open protocol สำหรับการส่งข้อมูลผ่าน queue แบบ asynchronous มีโครงสร้างการทำงานดังรูป จากรูปนั้น Producer จะทำการส่งข้อมูลไปยัง Broker จากนั้น Broker จะส่งข้อมูลไปยัง consumer ต่อไป แต่ใน Broker นั้นจะมี component ชื่อว่า Exchange Exchange ทำการส่งข้อมูลที่ได้รับเข้ามาไปยัง (routing) queue ตามที่กำหนดในข้อมูล ดังนั้นการส่งข้อมูลจะต้องทำการกำหนดค่าต่าง ๆ มาตามที่ต้องการ (Smart Consumer) ส่วน Consumer ก็ทำตามข้อมูลที่ส่งเข้ามาก็พอ ไม่ต้องคิดมาก (Dumb consumer) โดยรูปแบบการทำงานของ broker มีหลายรูปแบบดังนี้
  • Direct exchange ทำการส่งไปยัง queue ตามที่กำหนดไว้ใน routing key ในข้อมูล
  • Fan-out exchange ทำการส่งข้อมูลไปยังทุก ๆ queue ที่กำหนดไว้ นั่นคือการ copy ข้อมูลนั่นเอง เหมือนกับการ broadcast
  • Topic exchange ทำการส่งข้อมูลไปยัง queue ที่เชื่อมต่อ โดยกำหนดชื่อในรูปแบบ wildcard ได้เลย รูปแบบคล้าย ๆ Pub/Sub หรือทำงานแบบ multicast routing

คำถามที่น่าสนใจคือ

ระบบของเรานั้นต้องการ Messaging system หรือไม่ ? ระบบของเรานั้นต้องการ Messaging system รูปแบบไหน ? และสิ่งที่ต้องพิจารณาเพิ่มอีกคือ
  • อัตราข้อมูลที่เข้าสู่ระบบ
  • การการันตีการส่งข้อมูล (Guarantee Delivery)
  • การจัดเก็บข้อมูล
  • การจัดการเรื่องความปลอดภัย
  • การจัดการเรื่อง Fault tolerance
ต้องตอบให้ได้ก่อนที่จะเลือกเครื่องมือนะครับ

Part 2 :: ว่าด้วยเรื่องความรู้พื้นฐานของ Kafka

$
0
0

หลังจากที่ใน part 1 นั้นได้ทำการสรุปเรื่องของ Messaging system จากการไปเรียนมา มาใน blog นี้จะทำการสรุปเกี่ยวกับความรู้พื้นฐานของ Kafka ว่ามีที่มาที่ไปอย่างไร ? ว่ามี architecture อย่างไร ? ว่าการทำงานในแต่ละส่วนมีอะไร ที่ทำหน้าที่อะไร ? รวมไปถึง ecosystem ของ Kafka ว่าเป็นอย่างไร ? ไปดูกันเลย

จุดเริ่มต้นของ Kafka

เป็นระบบที่พัฒนาใช้ภายในบริษัท LinkedIn เพื่อใช้จะเก็บข้อมูล metric ต่าง ๆ ของระบบ เช่นเก็บข้อมูลการใช้งานระบบของผู้ใช้งานแต่ละคน ซึ่งระบบดั้งเดิมจะเก็บเป็นไฟล์ XML จากนั้นเอามา parser ต่อ แต่ทีมงานเห็นว่า ไม่น่ารอดในอนาคตอันใกล้ รวมทั้งเกิดปัญหามากมาย ทำให้ตัดสินใจสร้างระบบใหม่ที่ชื่อว่า Kafka ออกมานั่นเอง

โดยที่ Kafka สร้างมาเพื่อ

ทำงานแบบกระจาย ไม่ต้องฝืน (Distributed system) เป็นระบบที่คงทนต่อความเสียหาย นั่นคือทำงานได้แม้ระบบบางส่วนจะเสียหาย มีการทำงานแบบ Publish-Subscribe ทำการบันทึกหรือจัดการข้อมูลต่าง ๆ ใน Topic เทียบได้กับ Table ใน RDBMS ผู้สร้างข้อมูลและส่งไปยัง topic เรียกว่า Producer ผู้นำข้อมูลไปใช้งานจาก topic เรียกว่า Consumer ข้อมูลที่ส่งเข้าไปใน topic จะถูกจัดเก็บแบบถาวรลง file system เสมอ ข้อมูลที่ถูกจัดเก็บจะมีอายุ 168 ชั่วโมง ซึ่งสามารถแก้ไขได้ตาม use case Kafka จะทำการบันทึกข้อมูลลงไฟล์หรือ log ก่อนที่ consumer จะเห็นเพื่อนำไปทำงานหรือ process ต่อไป ซึ่งจะเรียกระบบนี้ว่า WAL (Write-Ahead Logging)

เป้าหมายหลักของ Kafka ประกอบไปด้วย

  • เพื่อไม่ให้ Producer และ Consumer ผูกมัดกัน
  • ทำการการจัดเก็บข้อมูลแบบถาวร เพื่อให้ Consumer มีทางเลือกมากขึ้น นั่นคือสนับสนุนรูปแบบการทำงานที่หลากหลาย รวมทั้งง่ายต่อการจัดการเมื่อเกิดข้อผิดพลาดขึ้นมา
  • มีการทำงานที่รวดเร็ว นั่นคือสามารถรองรับข้อมูลที่เกิดมาอย่างรวดเร็วได้ดี เช่น user activity และ logging หรือเกิดมาเพื่อรองรับ Stream Processing Architecture นั่นเอง
  • สามารถ scale ได้ง่าย

มาดูสถาปัตยกรรมของ Kafka กันบ้าง

จากที่อธิบายมานั้น Kafka จะมี Producer, Consumer และ Topic โดยที่ในแต่ละ topic นั้นจะแบ่งการเก็บข้อมูลออกเป็นกลุ่ม ๆ เรียกว่า Partition จำนวนของ partition จะต้องถูกกำหนดไว้ตั้งแต่ต้น (ไม่ควรเปลี่ยนเมื่อระบบทำงานแล้ว เพราะว่า operation เยอะมาก ๆ) แสดงดังรูป

ข้อมูลที่จัดเก็บในแต่ละ partition นั้น

จะเรียงลำดับไปเรื่อย ๆ นั่นคือ ข้อมูลเก่าจะอยู่ด้านหน้า ข้อมูลใหม่จะอยู่ด้านหลัง โดย consumer จะอ่านจากหน้าไปหลัง (อ่านตามค่า offset ในแต่ละ partition) ที่สำคัญการอ่าข้อมูลของ consumer มีหลายรูปแบบอีกด้วย ไว้จอธิบายใน blog ต่อ ๆ ไป แสดงดังรูป จากรูปในแต่ละ partition นั้นข้อมูลจะถูกเรียงลำดับเสมอ

คำถามที่น่าสนใจคือ ข้อมูลแต่ละตัวจะไปลง Partition ด้วยเงื่อนไขอะไร ?

ง่าย ๆ คือ ข้อมูลจะมี key มาด้วยหรือไม่ ซึ่ง key ก็เป็น property หนึ่งข้อมูลมูลที่ producer ส่งเข้ามา ถ้ามี key มาด้วยจะทำการ hash key จึงจะได้ partition ที่จัดเก็บ ถ้าไม่มีจะทำการเลือกแบบ Round-Robin ทำให้เราสามารถมีแนวทางในการออกแบบเยอะขึ้น

คำถาม จำนวน partition ยิ่งมากยิ่งดีหรือไม่ ?

Partition บางครั้งจถูกเรียกว่า Unit of parallelism นั่นหมายความว่า ยิ่งมีจำนวนมาก ยิ่งรองรับการทำงานที่สูงขึ้น แต่ก็ไม่ใช่จะกำหนดเป็นตัวเลขมาก ๆ เพราะว่า ยิ่งมาก partition ยิ่งกระจายไปแต่ละเครื่องมากขึ้น ทำให้เกิด delay time มากขึ้น
Delay Time = (Number of Partition/replication * Time to read metadata for single partition)
และยังทำให้ฝั่ง Producer ต้องใช้ memory เยอะขึ้นด้วย เพราะว่าการทำงานภายในจะต้องเก็บข้อมูลลงใน buffer ก่อนส่งไป ดังนั้นจำนวนของ partition จึงเป็นเรื่องที่สำคัญ

มาดูกันว่า ส่วนการทำงานต่าง ๆ ทำงานร่วมกันได้อย่างไร ?

โดยปกติแล้ว Kafka จะไม่ทำงานเพียงเครื่องเดียว แต่จะทำงานเป็น cluster หรือเรียกว่า Kafka cluster หรือมีการทำงานร่วมกันหลาย ๆ เครื่อง topic ต่าง ๆ จะถูกกระจายไปยัง Kafka broker ทำให้ Kafka cluster รองรับการเขียนละอ่านข้อมูลได้ดียิ่งขึ้น และเพื่อความปลอดภัยของระบบควรมี Kafka broker อย่างต่ำ 3 หรือ 5 ตัวเสมอ Kafka broker นั้นจะทำงานแบบ stateless ดังนั้นถ้าต้องการทำงานกับส่วนอื่น ๆ ใน Kafka cluster ก็ต้องมีตัวจัดเก็บ state ต่าง ๆ นั่นก็เป็นหน้าที่ของ Zookeeper แสดงดังรูป ยังไม่พอนะ แต่ละ partition ของแต่ละ topic ที่จัดเก็บใน Kafka broker หลักหรือเรียกว่า Leader ทำหน้าจัดการการอ่านเขียนนั่นเอง และจะมีการจัดเก็บไว้ใน Kafka broker ที่มีสถานะเป็น Follower ด้วย ซึ่งจะทำ replicate ข้อมูลมาเก็บไว้ เป็นการ backup นั่นเอง ตรงนี้ขึ้นอยู่กับการ configuration ในส่วนของ relication factor Follower นั้นจะถูกเลือกมาเป็น Leader เมื่อ Leader เกิด fail ขึ้นมา คำถามคือใครเป็นคนเลือก Leader ? ตอบง่าย ๆ คือ Zookeeper ไงละ
ปล. ถ้า Zoopkeeper ตายไปนี่ บรรลัยได้เลย ดังนั้นในการใช้งานจริง ๆ Zookeeper ไม่ควรมีเครื่องเดียวนะครับ

การ Replicate นั้นเป็นสิ่งที่สำคัญมาก ๆ ของ Kafka

มันทำให้เรามั่นใจได้ว่า ข้อมูลไม่หายไปไหนแน่ ๆ (ถ้าไม่โชคร้ายแบบสุด ๆ นะ) โดยรูปแบบของการจัดการ replicate ของ Kafka มี 2 แบบคือ
  1. ISR (In-sync replication) ทำการ replicate ข้อมูลไปยัง follower ตามจำนวนที่กำหนด
  2. Primary-backup ทำการ replicate ข้อมูลไปยัง follower ทั้งหมด

มาถึงตรงนี้น่าจะเห็นได้ว่า Kafka มีส่วนการทำงานเยอะเลย

  • Producer
  • Consumer
  • Broker
  • Topic
  • Partition
  • Replication
  • Zookeeper
ใน Part ต่อไปจะสรุปเกี่ยวกับการนำไปใช้งานตาม usecase และ workshop รวมถึงทำความเข้าใจการทำงานของ Producer และ Consumer โดย Kafka นั้น Producer จะทำหน้าที่ส่งข้อมูลมายัง Broker เท่านั้น นั่นคือ Dumb Producer ส่วน Consumer นั้นจะทำงานได้หลากหลายมาก ๆ นั่นคือ Smart Consumer แน่นอนว่าได้เวลาเขียน code กันแล้ว Reference Websites http://cloudurable.com/blog/kafka-architecture-topics/index.html https://www.confluent.io/blog/enabling-exactly-kafka-streams/

มาสร้าง Go Module แบบง่าย ๆ ใน Go 1.11 RC2 เล่นกัน

$
0
0

ตอนนี้ Go 1.11 ได้ออก RC2 มาแล้ว นั่นหมายความว่าตัว final ใกล้เข้ามาทุกที ดังนั้นมาลองสร้าง module ด้วยภาษา Go กันหน่อย ซึ่งเป็น feature ใหม่ที่น่าสนใจ โดยใน blog นี้จะมีเรื่องต่าง ๆ ดังนี้
  • การสร้าง module
  • การจัดการ version ซึ่งเป็นแบบ Semantic version
  • การใช้งาน module
เริ่มกันเลย

1. การสร้าง module

สิ่งแรกที่ต้องเข้าใจคือ ถ้าสร้าง module อยู่ภายใน $GOPATH นั้นจะปิดโดย default ดังนั้นง่าย ๆ ก็ไปสร้างอยู่นอก $GOPATH เลยดีกว่า ดังนี้ [code] $mkdir hey $cd hey $~/go/bin/go1.11rc2 mod init github.com/up1/hey [/code] ผลที่ได้คือ จะสร้างไฟล์ go.mod ขึ้นมา ดังนี้ [gist id="4101d1e396442969ce6be94f9ed76303" file="go.mod"] จากนั้นสร้างไฟล์ hey.go สำหรับการทำงานง่าย ๆ คือ สร้าง function Ha() ขึ้นมา [gist id="4101d1e396442969ce6be94f9ed76303" file="hey.go"] เมื่อทุกอย่างเรียบร้อยก็ push ขึ้น github ที่ Up1/hey จากนั้นลองทำการใช้งานผ่าน go get ได้เลย จะทำการ download จาก branch master ดังนี้ [code] $go get github.com/up1/hey [/code]
แต่ใน Go module นั้นต้องกำหนด version ด้วยเสมอ ซึ่งเป็น version ในรูปแบบ Semantic version ดังนั้นมาจัดการกันหน่อย

2. การจัดการ version ของ module

ง่าย ๆ ก็คือ การติด tag ใน git นั่นเอง ยกตัวอย่างเช่น version v0.0.1 [code] $git tag v0.0.1 $git push origin v0.0.1 [/code]

3. การใช้งาน module

เมื่อทำการสร้างและ publish module เรียบร้อยแล้ว ก็ถึงเวลาใช้งานกันดังนี้ [code] $mkdir try $cd try $touch main.go [/code] [gist id="4101d1e396442969ce6be94f9ed76303" file="main.go"] จากนั้นเปิดการใช้งาน module ใน project ตัวอย่าง [code] $~/go/bin/go1.11rc2 mod init try [/code] ทำการ build [code] $~/go/bin/go1.11rc2 build go: finding github.com/up1/hey v0.0.1 go: downloading github.com/up1/hey v0.0.1 [/code] เมื่อไปดูในไฟล์ go.mod จะเป็นดังนี้ [gist id="4101d1e396442969ce6be94f9ed76303" file="go2.mod"] สุดท้ายทำการ run program ตัวอย่าง ได้ดังนี้ [code] $./try Hey Ha ... [/code]
วันนี้เราพร้อมกับ Go Module แล้วหรือยัง ? ขอให้สนุกกับการ coding ครับ

ความรู้พื้นฐานเกี่ยวกับ Istio

$
0
0

ช่วงนี้พูดถึง Istio กันเยอะ แต่คำถามที่น่าสนใจคือ มันอ่านว่าอะไร ? มีทั้ง ไอ เอส ที ไอ โอ และ อิท ทิ โอ อ่านอย่างไรก็ช่างมันนะ มันคืออะไร ? มันมาจัดการ service mesh ไง แล้ว service mesh คืออะไร ? ทำไมต้องใช้งานมันละ ? สถาปัตยกรรมมันเป็นอย่างไร ? ทำงานอย่างไร ? บ้างก็บอกว่า ปกติก็พัฒนาด้วย Stack ของ Spring Cloud Netflix ทำไมต้องมาใช้ ? ชีวิตดูยากมากมาย ดังนั้นลองมาเริ่มเรียนรู้กันนิดหน่อย (ไม่น่าจะนิดนะ)

ก่อนอื่นเริ่มจากที่มาที่ไปก่อน

นั่นคือ architecture ของระบบงานสมัยใหม่ เริ่มเปลี่ยนจาก monolith มาเป็น microservices นั่นหมายความว่า จะเกิด service จำนวนมากให้พัฒนา ดูแลและจัดการ ส่งผลให้การพัฒนาง่ายขึ้น ส่งผลให้ระบบตายยากขึ้น ส่งผลให้ระบบ scale ง่ายขึ้น แต่การจัดการ รวมทั้ง infrastructure ไม่ง่ายเลย !! ถ้าพูดถึงการพัฒนาระบบ Microservices stack ของการพัฒนาที่ได้รับความนิยมคือ Spring Cloud Netflix ที่พัฒนาด้วยภาษา Java ซึ่งมีเครื่องมือต่าง ๆ ดังนี้
  • Eureka สำหรับจัดการเรื่อง Service Registry และ Discovery
  • Ribbon สำหรับ Load Balancing ในฝั่ง client เพื่อเลือกว่าจะส่ง request ไปยัง server ใด
  • Feign เป็น REST client สำหรับเรียกใช้งาน service อื่น ๆ ซึ่งการทำงานภายในใช้งาน Ribbon นั่นเอง
  • Zuul เป็น API Gateway ทำให้ทุก APIs ถูกเรียกจากที่เดียว รวมทั้งช่วยจัดการเรื่อง rounting ต่าง ๆ อีกด้วย
  • Hystrix เป็น Circuit Breaker สำหรับจัดการเรื่อง fault tolerance ช่วยปิดการติดต่อสื่อสารไปยังส่วนที่ทำงานไม่ปกติ ซึ่งส่งผลดีต่อผู้ใช้งาน service
  • Turbine เป็น dashboard สำหรับแสดง trafic การใช้งาน และ circuit breaker
ชีวิตการพัฒนา Microservices ทำไมมันแยะเยี่ยงนี้ !!!

แต่มันก็มีปัญหาต่อมาอีกคือ การ deploy ทำอย่างไรดี ?

ทั้งการดูแล container ต่าง ๆ ให้มีตามจำนวนที่กำหนด (desired container) ทั้งการ scale แบบอัตโนมัติ การแก้ไขปัญหามีทั้ง Docker Swarm และ Kubernetes ยังไม่พอนะ ก็มีปัญหาอีกคือ ถ้าต้องการความสามารถต่าง ๆ เหมือนกับ Spring Cloud Netflix stack ละ จะต้องทำอย่างไร ? เนื่องจากสิ่งต่าง ๆ เหล่านั้นตาม stack พัฒนาด้วยภาษา Java นั่นหมายความว่า มันผูกมัดกับภาษาโปรแกรมมากจนเกินไป ดังนั้นสิ่งที่ต้องการคือแยกออกมาเป็น platform ที่สามารถดูแลและจัดการระบบที่พัฒนาด้วยภาษาโปรแกรมต่าง ๆ หนึ่งในเครื่องมือคือ Istio นั่นเอง
ปล. เรื่องของ Service Model, Service Mesh และ Istio นั้น สามารถอ่านเพิ่มเติมได้ที่ Site ของอาจารย์ชาญวิทย์ ได้เลย ชัดเจนมาก ๆ หรืออ่านเพิ่มเติมได้จาก What is Istio ?
จาก official website นั้นอธิบาย architecture ของ Istio ไว้ดังรูป จะพบว่ามีส่วนการทำงานเพียบเลย แต่สิ่งแรกที่อยู่ใกล้แต่ละ service มากที่สุดคือ Proxy หรือ Envoy proxy หรือ Sidecar proxy ทำให้ Istio สามารถจัดการสิ่งต่าง ๆ ตามด้านบนได้ง่าย ที่สำคัญสามารถกำหนด rule และ policy ต่าง ๆ ได้อีกด้วย โดยไม่ต้องไปทำการแก้ไข code เช่น
  • การติดต่อระหว่าง service
  • การ tracing การทำงานของ service
  • การจัดการเรื่อง Circuit Breaker
  • การจัดการเรื่อง Retry
  • มีระบบ monitoring และ dashboard สำหรับระบบงาน
  • การจัดการเรื่อง traffic routing เช่น 70% ของ traffic ให้ไปทำงานที่ service version 1 และ 30% ของ traffic ให้ไปทำงานที่ service version 2
  • Canary deployment

มาดูรายละเอียดของแต่ละ component กันบ้าง

Envoy เป็นสิ่งที่พัฒนาต่อยอดมาจาก Envoy proxy ที่พัฒนาจากบริษัท Lyft Envoy พัฒนาด้วยภาษา C++ ทำหน้าที่เป็น proxy ของการเข้าถึงหรือเรียก service ต่าง ๆ โดยที่ Envoy มีความสามารถที่ build-in เข้ามาด้วยดังนี้
  • Dynamic service discovery
  • Load balancing
  • Circuit Breaker
  • HTTP/2 และ gRPC proxy
  • Health check
  • Fault injection
  • Metric
Envoy นั้นจะถูก deploy คู่กับ container ใน Pods เสมอ จะเรียกว่า sidecar นั่นหมายความว่าใน 1 Pod นั้นจะมี 2 container เสมอ
Mixer ทำหน้าที่จัดการ access control policy ของการสื่อสารระหว่าง service ต่าง ๆ ใน cluster และทำหน้าที่รวมข้อมูลการทำงานที่ส่งมาจาก Envoy proxy Pilot ทำการเตรียม Service discovery สำหรับ Envoy proxy ทำการจัดการเรื่องของ traffic routing เช่น A/B testing และ canary deployment เป็นต้น Citadel ทำหน้าที่ authentication ระหว่าง service และจากผู้ใช้งาน อีกทั้งยังสามารถใช้งาน Authorization ได้อีกด้วย
เพื่อให้เห็นภาพชัดขึ้นลองมาสร้าง service และ deploy ด้วย Istio กันต่อไป

มาดูโครงสร้าง code ของ Google I/O 2018 app for Android กัน

$
0
0

จาก session Architecture Components in Real Life (Android) ในงาน Mobile Conf 2018 มีคำถามหนึ่งที่น่าสนใจคือ ทาง Google ได้ปล่อย source code ของ Google I/O 2018 app ออกมา เหล่า Android developer ได้เข้าไปดู เข้าไปศึกษาหรือไม่ ? คำตอบที่ได้รับกลับมาคือ เงียบ (อาจจะมีคนเข้าไปดูก็ได้ แต่ไม่แสดงตัวเท่านั้นเอง) เป็นสิ่งที่แปลกมาก ๆ นะ (หรือเป็นเรื่องปกติไปแล้วนะ)
ดังนั้นเหล่า Android developer มาลองศึกษากันหน่อย ว่า Google I/O 2018 app นั้นเขาพัฒนากันออกมาอย่างไร ? มีโครงสร้างอย่างไรบ้าง ? ดังนั้นมาลองดูกัน

เมื่อเข้าไปดูก็พบว่า

ใน Android Developer Blog เขียนอธิบายไว้คร่าว ๆ แล้ว ถูกเขียนใหม่ ด้วยโครงสร้างใหม่ นั่นก็คือ Architecture Component  และภาษา Kotlin ซึ่งมีโครงสร้างดังรูป จากรูปโครงสร้างของ app ประกอบไปด้วย
  • Presentation layer สำหรับการแสดงผลซึ่งมีสองส่วนหลักคือ Activity/Fragment และ ViewModel โดยในส่วนนี้จะใช้งาน Data Binding Library สำหรับการ binding UI เข้ากับข้อมูล หรือ ViewModel ต่อไป
  • Domain layer สำหรับ Use case หรือ business process ต่าง ๆ
  • Data layer สำหรับการจัดการข้อมูลจาก data source ต่าง ๆ ผ่านสิ่งที่เรียกว่า Repository ประกอบไปด้วย FireStore, Local cache และ Google Cloud Storage โดยที่ข้อมูลจะมีทั้งแบบ static data, schedule data และ realtime data ที่สำคัญ app นี้สนับสนุนการทำงานแบบ offline ด้วยนะ
ข้อมูลที่ส่งไปมาระหว่าง layer ก็คือ LiveData ยังไม่พอนะยังใช้ Library อื่น ๆ อีก เช่น
  • Dagger2 จัดการเรื่อง Dependency Injection
  • OkHTTP จัดการเรื่องการใช้งาน API ผ่านระบบ network
  • Gson สำหรับจัดการข้อมูล JSON
  • ThreeTen สำหรับจัดการเรื่อง datetime
  • Timber สำหรับจัดการเรื่อง logging
  • Crashlytic
เขียน code ใหม่ด้วยภาษา Kotlin ยังไม่พอนะใช้งาน Android Kotlin Extension (KTX) อีกด้วย มาถึงตรงนี้ มันมาเต็มมาก ๆ เหมาะต่อการเรียนรู้สุด ๆ ถ้าใครพลาดแล้วจะเสียใจ

ดูไปดูมามันคือ Clean Architecture ชัด ๆ

ยกตัวอย่างของ Use Case ที่อยู่ใน module shared

ยังไม่พอนะ ยังมีส่วนของการทดสอบอีกด้วย

ทั้ง Unit testing ด้วย jUnit และ Mockito , Mockito-Kotlin ทั้ง UI testing ด้วย Espresso สิ่งที่น่าสนใจคือ code ใน app นี้มีการทดสอบเยอะมาก ๆ มันสะท้อนให้เห็นว่า โครงสร้างของระบบมันทดสอบได้ง่ายมาก (Testable) ดังนั้นสิ่งที่เหล่านักพัฒนาต้องเข้าใจคือ ถ้าระบบงานของเราทดสอบยากแล้ว มันกำลังบ่งบอกว่า โครงสร้างระบบของเรานั้นไม่ถูกอย่างแน่นอน

มาดูโครงสร้าง module ของ app กันหน่อย

ทำการแบ่งออกเป็น module ย่อย ๆ เพื่อแยกส่วนการทำงานต่าง ๆ ออกจากกัน แต่ต้องระวังในเรื่องของ dependency กันด้วยนะ ถ้าออกแบบไม่ดี สิ่งที่เกิดขึ้นคือ cyclic dependency หรือการเรียกกันไปมา Module ต่าง ๆ ประกอบไปด้วย
  • mobile เป็น module หลักของการทำงานประกอบไปด้วย activity, fragment, ViewModel และสิ่งต่าง ๆ ที่เกี่ยวข้องกับ UI เช่น adapter ของ data binding เป็นต้น
  • tv สำหรับ Android TV app
  • model สำหรับ model class ที่ใช้ใน app ทั้งหมด เช่น User, Speaker, Session, Room และ Tag เป็นต้น
  • shared สำหรับ business logic นั่นคือ UseCase ต่าง ๆ ที่แยกออกตาม domain เช่น Agenda, Authentication, Session, User และ Speaker เป็นต้น รวมไปถึง class การทำงานหลักอีกมากมาย
  • test-shared สำหรับสร้างข้อมูลที่ใช้ในส่วนของ Unit testing
  • androidTest-shared สำหรับเก็บ utilities class ที่ใช้ในส่วนของ UI testing
ผลจากการแยก module ทำให้การ build แบบ incremental เร็วขึ้น ถ้าแยกแล้วช้าลงน่าจะผิดนะ รวมทั้งสามารถแยกทีมช่วยกันพัฒนาได้ง่ายอีกด้วย
คำถามคือ เราควรใช้งานสิ่งต่าง ๆ เหล่านี้หรือไม่ ? จาก session นี้บอกไว้ว่า เราควรศึกษาทำความเข้าใจก่อน จากนั้นลงมือทำ PoC (Proof of Concept) ใน use case ต่าง ๆ ไม่ใช่แค่ login หรือ ดึงข้อมูลจาก github นะ เมื่อถึงเวลา และ use case ที่เหมาะสม จะได้นำมาใช้งานได้เลย มาศึกษากันดูครับ ผมว่าน่าจะได้ความรู้และแนวทางการพัฒนาที่ดีเพียบเลย ขอให้สนุกกับการ coding

สวัสดี WebAssembly กับ Go 1.11

$
0
0

ภาษา Go 1.11 ออกตัวเต็ม ๆ มาแล้ว หนึ่งใน feature ที่เพิ่มเข้ามานั่นคือ การทำงานร่วมกับ WebAssembly แต่ยังเป็น experiment feature นะ จากความสามารถนี้ ทำให้เราสามารถพัฒนาระบบด้วยภาษา Go ทำการ compile ไปเป็น WebAssembly จากนั้นทำการเรียกใช้งานผ่าน JavaScript ซึ่งสามารถทำงานผ่าน browser การใช้งานเบื้องต้นสามารถดูได้จากเอกสาร ซึ่งทำการ compile ได้ดังนี้ [code] $GOARCH=wasm GOOS=js go build -o test.wasm main.go [/code] สังเกตุว่า ทำการกำหนด
  • GOARCH=wasm
  • GOOS=js
ผลลัพธ์ที่ได้คือ ไฟล์ main.wasm จากนั้นก็นำไปใช้งานดังนี้ [gist id="21f2ea450716c3becfa7fd680e485c63" file="1.html"]
เมื่อ Hello World ผ่านไป มาดูตัวอย่างที่ดูยากขึ้นมานิดนึง นั่นคือทำการบวกตัวเลข 2 ตัวกันดีกว่า (มันยากตรงไหน ?)

ขั้นตอนที่ 1 ทำการสร้างส่วนของ HTML ดังนี้

[gist id="21f2ea450716c3becfa7fd680e485c63" file="add.html"] แสดงผลดังนี้

ขั้นตอนที่ 2 เขียนภาษา Go กัน

สิ่งที่ต้องการคือ
  • อ่านค่าของ operand 1 และ operand 2 จาก HTML
  • ทำการดักจับ event เมื่อกดปุ่ม Add แล้วนำค่าจาก operand 1 และ operand 2 มาบวกกัน
โดยภาษา Go ได้เตรียม package syscall/js มาให้ ดังนั้นมาลองเขียนกันหน่อย [gist id="21f2ea450716c3becfa7fd680e485c63" file="add.go"] คำอธิบาย ทำการเรียกใช้งาน method จาก JavaScript ตรง ๆ ไปเลย ทั้ง getElementById() และ กำหนดค่าลง property เช่น innerText เป็นต้น อย่าลืมเปิด channel ทิ้งไว้นะครับ ไม่งั้นก็มี error แบบนี้ใน Chrome Dev Tool :: Console ทำการ compile ได้เลย [code] $GOARCH=wasm GOOS=js go build -o add.wasm add.go [/code]

ขั้นตอนที่ 3 เรียกใช้งานไฟล์ add.wasm กัน

[gist id="21f2ea450716c3becfa7fd680e485c63" file="add2.html"] เพียงเท่านี้ก็ทำการบวกเลขได้แล้ว ลองไปใช้งานเล่น ๆ ได้ที่ Github Page :: Demo โดยที่ตัวอย่าง source code อยู่ที่ Github :: Demo WebAssembly with Go สุดท้ายแล้ว มี use case ไหนที่ต้องการทำแบบนี้บ้างนะ ? ผมไม่มีประสบการณ์ และ คิดไม่ออกเลย ขอให้สนุกกับการ coding ครับ

แก้ปัญหาขนาดหน้าจอของ Google Chrome Headless

$
0
0

ในการทดสอบระบบ web application ผ่าน Robotframework ด้วย Library ชื่อว่า SeleniumLibrary นั้น เราสามารถทดสอบบน Google Chrome แบบ Headless ได้ (selenium 3.8 และ seleniumlibrary 3.1 ขึ้นไปนะ) แต่ปัญหาที่เจอคือ ทำไมทดสอบแบบปกติโดยการเปิด Google Chrome ไม่มีปัญหา แต่เมื่อเปลี่ยนมาใช้ Headless mode มีปัญหา ? คือทดสอบไม่ผ่าน เช่นหา element บางตัวไม่เจอ มาหาคำตอบ พร้อมการแก้ไขกันหน่อย เมื่อไปดูปัญหาพบว่า ขนาดหน้าจอของ Google Chrome Headless นั่นเอง โดยค่า default คือ 800 x 600 !! มันจะเล็กไปไหน !! ทำให้บางระบบที่แสดงผลต่างกันในแต่ละขนาดหน้าจอ มีปัญหา ตามจริงมีปัญหาตั้งแต่แนวทางการพัฒนาแล้ว ดังนั้นเราสามารถแก้ไขง่าย ๆ ด้วยการกำหนดขนาดของหน้าจอไปใหม่ ด้วย keyword ชื่อว่า Set Window Size ดังนี้ [code] Set Window Size 1920 1080 [/code] ขอให้สนุกกับการเขียน code นะครับ

ทำการ deploy ระบบงานกับ Istio กัน

$
0
0

หลังจากอธิบายเกี่ยวกับ Istio ไปนิดหน่อย ดังนั้นเพื่อให้เห้นภาพชัดเจนขึ้น มาลองติดตั้ง และ deploy ระบบงานกันดีกว่า โดยใน blog นี้ทำการติดตั้งบน Kubernetes engine ของ Google Cloud เนื่องจากติดตั้งบน local แล้ว memory ไม่พอ !! มาเริ่มกันดีกว่า

ขั้นตอนที่ 1

สร้าง Cluster ใน Kubernetes Engine จำนวน 3 เครื่อง

ขั้นตอนที่ 2

ทำการติดตั้ง Istio แบบง่าย ๆ เริ่มจาก download  จากนั้นทำการ extract และเข้าไปยัง folder istio เพื่อติดตั้งกัน ทำการติดตั้ง component หลัก ๆ ของ Istio [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="1.txt"] ผลการทำงาน จะทำการสร้าง namespace ชื่อว่า istio-system ขึ้นมา โดยจะทำการ deploy control plane component ต่าง ๆ ดังนี้
  1. Pilot
  2. Telemetry ทำการรวม metric และ log ต่าง ๆ เป็นส่วนการทำงานหนึ่งของ Mixer
  3. Policy ใช้กำหนดนโยบายต่าง ๆ เพื่อการจัดการ traffic เป็นส่วนการทำงานหนึ่งของ Mixer
  4. Ingress-gateway สำหรับจัดการ traffic ขาเข้าซึ่งมาจากนอก Cluster
  5. Citadel หรือ Istio-Auth หรือ Istio-CA นั่นเอง
มาดูกันหน่อยว่าสร้าง service อะไรให้บ้าง ? บอกเลยว่า เยอะมากมาย !!! [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="2.txt"] ยังไม่พอต้องไปดู Pods ด้วยว่า สร้างเรียบร้อยหรือไม่ ? [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="3.txt"]

ขั้นตอนที่ 3 ติดตั้ง application กัน

เมื่อทุกอย่างพร้อมแล้ว ก็ทำการติดตั้ง application กันหน่อย ซึ่ง Istio นั้นมีตัวอย่าง application มาให้ด้วย ชื่อว่า Book Info มีโครงสร้างของ service จำนวน 4 service คือ
  1. productpage พัฒนาด้วยภาษา Python
  2. details พัฒนาด้วยภาษา Ruby
  3. reviews พัฒนาด้วยภาษา Java
  4. ratings พัฒนาด้วยภาษา NodeJS
ดังรูป โดยที่ configuration อยู่ในไฟล์ samples/bookinfo/platform/kube/bookinfo.yaml มันคือ Kubernetes configuration นั่นเอง ถ้าเราทำการ deploy แบบปกติผ่าน kubectl ก็จะได้ Pods และ Services ต่าง ๆ เป็นปกติ แน่นอนว่า ไม่มีการใช้ความสามารถของ Istio เลย เช่น Envoy sidecar เนื่องจากค่า default นั้นจะปิดไว้ ดังนั้นเปิดซะ ทำได้ดังนี้ [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="4.txt"] ทำการ deploy ระบบตัวอย่างกันเลย รออะไร จะใช้เวลารอให้สร้าง Pods กันนานหน่อยนะ [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="5.txt"] และให้ลองสังเกตุว่า ในแต่ละ Pods จะมี 2 container นั่นหมายความว่า Istio จะทำการสร้าง Envoy sidecar ให้เรียบร้อย [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="6.txt"]

ขั้นตอนที่ 4 สร้าง Gateway เพื่อให้ trafic เข้ามายัง cluster ได้

คือ ingress traffic นั่นเอง ทำการสร้างด้วยคำสั่ง [gist id="e8e1d02bb50fdc15aca141a460a14e99" file="7.txt"] หรือทำการเปิดผ่าน browser ไปยัง IP ของ EXTERNAL-IP แสดงการทำงานดังรูป แค่ติดตั้งก็เหนื่อยใช้ได้เลยนะ ไว้มาดูความสามารถอื่น ๆ กันต่อไป เช่น Routing, Telemetry และ Authentication/Authorization เป็นต้น น่าจะมีประโยชน์ต่อการพัฒนามากยิ่งขึ้น ขอให้สนุกกับการ coding ครับ

สรุปสิ่งที่น่าสนใจจากหนังสือ Accelerate: The Science of Lean Software and DevOps

$
0
0

ช่วงวันหยุดหยิบหนังสือ Accelerate: The Science of Lean Software and DevOps มาอ่าน เป็นหนังสือที่สรุปส่วนประกอบต่าง ๆ ที่ช่วยให้บริษัท IT ขับเคลื่อนได้อย่างดี (high-performance) ทั้งองค์กรและทีม โดยทำการสรุปข้อมูลมาจาก State of DevOps Report ตั้งแต่ปี 2014 จาก State of DevOps Report นั้น ทำให้เข้าใจได้ว่า การนำแนวคิด DevOps นั้น ต้องนำแนวปฏิบัติ (Practice) อะไรมาใช้บ้าง ? วัฒนธรรมขององค์กรต้องเอื้อและสนับสนุนอย่างไร ? เพื่อปรับปรุงการพัฒนาและส่งมอบระบบงานให้เร็วและมีคุณภาพ (Correctness, Performance และ Security) ส่งผลให้ได้รับ feedback เพื่อปรับปรุง จากข้อมูลต่าง ๆ จึงสรุปออกมาเป็น 24 ข้อ (จะเยอะไปไหน) ซึ่งแบ่งเป็นกลุ่มใหญ่ ๆ 5 กลุ่มคือ
  1. Continuous Delivery
  2. Architecture
  3. Product and Process
  4. Lean management and Monitoring
  5. Cultural
มาดูรายละเอียดในแต่ละกลุ่ม ยกเว้นกลุ่มที่ 5 นะ อธิบายยากไป

กลุ่มที่ 1 Continuous Delivery

ประกอบไปด้วย 8 ข้อคือ
  • ใช้งาน version control สำหรับจัดเก็บ source code ของระบบงาน, configuration และ script สำหรับการทำงานแบบอัตโนมัติต่าง ๆ
  • มีขั้นตอนการ deploy ระบบงานแบบอัตโมัติ โดยไม่มีการทำงานแบบ manual คั่นเลย
  • มีการ implement ระบบ Continuous Integration (CI) ซึ่งเป็นหัวใจและก้าวแรกของ Continuous Delivery เป็นแนวปฏิบัติสำคัญของการพัฒนาเลยทีเดียว ตั้งแต่ source code ใน version control มีการเปลี่ยนแปลง  build -> package -> testing -> deploy -> release
  • ใช้งาน Trunk-Based development นั่นคือมี branch ที่น้อย ๆ นั่นคือไม่เกิน 3 branch ถ้าเกินแนะนำให้ branch นั้นมีชีวิตที่สั้นที่สุด ที่สำคัญต้องไม่มีการ lock code/freeze code ด้วย นั่นคือไม่ให้ใคร check-in code เข้าไปได้ แบบนี้ไม่ดีแน่นอน ยิ่งมาก branch ยิ่งมากความ ยิ่งมากปัญหา
  • เรื่องการทดสอบแบบอัตโนมัติ ขาดไปไม่ได้เลย ลด ละ เลิกการทดสอบแบบ manual ที่สำคัญ ชุดการทดสอบต้องมีความน่าเชื่อถือด้วย คำถามคือใครมีหน้าที่หลักในการสร้างและดูแลรักษาชุดการทดสอบ ? ตอบเลยก็คือ คนที่สร้าง code และระบบขึ้นมาไงละ
  • เรื่องของ Test Data Management สำคัญมาก ๆ เนื่องจากการทดสอบแบบอัตโนมัติจะประสบความสำเร็จหรือไม่นั้น ก็ขึ้นอยู่กับการจัดการข้อมูลสำหรับการทดสอบนี่เอง และมักจะละเลยหรือไม่ได้วางแผนกัน ชุดข้อมูลสำหรับการทดสอบต้องสอดคล้องกับความต้องการของระบบงาน ไม่ต้องเยอะแต่ต้องครอบคลุม ข้อมูลต้องสามารถทดสอบซ้ำได้ซ้ำแล้วซ้ำเล่าตามชุดการทดสอบ
  • เรื่องของ Security หรือความปลอดภัยต้องถูกนำเข้ามาตั้งแต่การออกแบบ การพัฒนา และการทดสอบของการพัฒนาระบบงาน เช่นทำการ review security ของระบบจากทีม Security ตั้งแต่การออกแบบระบบงาน ทำการ approve library ที่จะใช้งาน การ packaging รวมถึงการทดสอบในเชิง security มุมต่าง ๆ อีกด้วย (Automated Security Testing)
  • ปิดด้วยเรื่องของ Continuous Delivery (CD) เป็นแนวปฏิบัติที่สำคัญ เพื่อทำให้มั่นใจว่าทุก ๆ การเปลี่ยนพร้อมที่จะ deploy ไปยัง environment ที่กำหนด เมื่อเห็นว่าระบบ CD เกิดปัญหาขึ้นมา ทีมจะต้องหยุดและแก้ไขให้ผ่านทันที เพื่อทำให้มั่นใจว่าจะส่งมอบระบบงานให้กับผู้ใช้งานได้ตลอดเวลา

กลุ่มที่ 2 Architecture

ประกอบไปด้วย 2 ข้อคือ
  • Loosely coupled architecture คือสถาปัตยกรรมที่ช่วยให้แต่ละทีมทำงานเป็นอิสระแก่กัน ส่งผลทำให้สามารถพัฒนา ทดสอบและส่งมอบระบบงานและคุณค่าต่าง ๆ ให้กับผู้ใช้งานและองค์กรได้อย่างรวดเร็วและมีคุณภาพ
  • ข้อมูลจากรายงานพบว่า ทีมจะต้องสามารถเลือกเครื่องมือ เลือกโครงสร้างเพื่อใช้ในการพัฒนา ทดสอบและส่งมอบระบบได้เอง เนื่องจากไม่มีใครที่จะรู้และเข้าใจไปมากกว่าคนที่ลงมือทำจริง ๆ เรียนรู้ที่จะเลือก เรียนรู้ที่จะแก้ไขและปรับปรุง เพื่อประสิทธิภาพของการทำงาน มันจะดีกว่าให้คนที่ไม่ได้ทำมาเลือกและคนที่ทำไม่ได้เลือก !!

กลุ่มที่ 3 Product and Process

ประกอบไปด้วย 4 ข้อคือ
  • product ที่พัฒนาออกมานั้นต้องมาจาก feedback หรือความต้องการที่รับมาจากผู้ใช้งานจริง ๆ เป็นหลัก เพื่อจะสร้าง product ที่ตรงกับความต้องการ แต่การจะได้มาต้องมี process การทำงานที่ดีด้วยเช่นกัน ไม่ใช่คิดเอง เออเอง ทำเองกันไปเรื่อย ๆ ไม่ดีก็ทำใหม่ไปเรื่อย ๆ
  • ทีมจะต้องมีความเข้าใจใน product ร่วมกัน นั่นคือตั้งแต่ business -> development -> deployment -> ลูกค้า จะต้องเห็นภาพเดียวกัน เปิดเผยให้เห็น ทั้งสถานะของ product และ feature ต่าง ๆ ที่จะมี
  • ทีมทำงานเป็นชิ้นเล็ก ๆ ให้เสร็จภายในหนึ่งสัปดาห์หรือน้อยกว่านั้น เป้าหมายหลักคือการแบ่งงานใหญ่ ๆ ออกเป็นงานเล็ก ๆ เพื่อให้ส่งมอบงานได้อย่างต่อเนื่อง รวมทั้งเป็นการเรียนรู้จาก feedback อย่างต่อเนื่องอีกด้วย
  • เปิดโอกาสให้ทีมสามารถทดลองบางสิ่งบางอย่างได้ เพื่อลองทำตามแนวคิดใหม่ ๆ โดยไม่ต้องผ่านการ approve จากคนภายนอกทีม ซึ่งจะเอื้อให้เกิดแนวคิดใหม่ innovation ใหม่ ๆ ขึ้นมาอีกมากมาย จะสัมพันธ์กับการทำงานชิ้นเล็ก ๆ การรับ feedback จากผู้ใช้งาน และต้องให้ทุกคนเห็นภาพร่วมกันอีกด้วย

กลุ่มที่ 4 Lean management and Monitoring

ประกอบไปด้วย 5 ข้อคือ
  • ขั้นตอนการทำงาน เช่น approval process ต้องไม่เทอะทะ ล่าช้า แต่ยังคงเรื่องของคุณภาพนะ
  • ต้องมีระบบ monitoring ทั้ง application และ infrastructure เพื่อช่วยในการตัดสินใจทาง business ว่าเรากำลังเดินถูกทางหรือไม่
  • ต้องมีระบบดูแลสุขภาพของระบบด้วยว่าเป็นอย่างไร เช่น การกำหนด threshold ของการใช้งานรวมถึง rate of error/warning เพื่อช่วยทำให้รู้ว่าระบบงานกำลังจะเกิดปัญหา อย่าทำแบบ reactive คือ รู้ตอนระบบงานพังแล้ว มันไม่ดีนะ
  • ปรับปรุงขั้นตอนการทำงาน โดยจัดการงานแบบ Work-In Process (WIP) limit ซึ่งทำแนวคิดนี้มาจาก Lean
  • แสดงการทำงานต่าง ๆ ออกมาในรูปแบบของ visualization เช่น dashboard และ physical board เป็นต้น เพื่อช่วยให้เห็นว่าสถานะของงานเป็นอย่างไร การพัฒนา ทดสอบ และส่งมอบเป็นอย่างไร ช่วยทำให้ทีมเห็นสถานะของงานตรงกัน
  มาอ่านหนังสือกันครับ

แนะนำหนังสือ online :: Learn Go with Tests

$
0
0

มีหนังสือ online สอนเกี่ยวกับการพัฒนาระบบงานด้วยภาษา Go ที่น่าสนใจเพียบ ยกตัวอย่างเช่น แต่ก็มีอีกเล่มที่น่าสนใจนั่นคือ Learn Go with Tests เนื้อหาของหนังสือเล่นนี้นั้น จะเป็นการอธิบายความสามารถต่าง ๆ ของภาษา Go ตั้งแต่เริ่มต้น โดยแต่ละเรื่องนั้นจะขับเคลื่อนด้วย Tests หรือชุดการทดสอบ หรือทำการศึกษาภาษา Go ตามแนวคิด Test-Driven Development (TDD) เป็นอีกหนึ่งแนวทางของการศึกษาภาษาโปรแกรมใหม่ ๆ ที่ผมชอบด้วย จึงขอแนะนำให้ลองอ่านและศึกษากันดู เนื้อหาก็เหมาะสำหรับคนเริ่มต้นเลย ตั้งแต่การติดตั้ง การเริ่มเขียนโปรแกรมด้วยภาษา Go เรื่องของ Data type, Iteration (for-loop), Array และ Slice จากนั้นลงเรื่องยากขึ้นเช่น Struct, Interface, Pointer, Error และ Concurrency ยังไม่พอยังไม่เรื่องของ Testable application ด้วยทั้ง Dependency Injection (DI) และการ Mocking ปิดท้ายด้วยการพัฒนาระบบจริง ๆ เช่น HTTP Server, การจัดการกับ JSON และเรื่องของ I/O เป็นต้น ซึ่งจะขับเคลื่อนด้วยชุดการทดสอบอีกนั่นเอง ทำให้เราเห็นว่า จะทดสอบ code ที่เราเขียนขึ้นมาอย่างไร รวมทั้งจะทำให้ code ที่เขียนทดสอบง่ายได้อย่างไร น่าจะทำให้เรามีความเชื่อมั่นต่อ code สูงขึ้นนะ
ปล. ว่าง ๆ ก็มาลองแปลภาษาไทยกันได้นะ หนังสือยังไม่สมบูรณ์แต่เราช่วยได้นะ เพราะว่า เขาให้เราเข้าไป contribute ได้อีกด้วย
มีคนรวบรวมหนังสือเกี่ยวกับภาษา Go ไว้ด้วย ลองศึกษาเพิ่มเติมกันดู น่าจะมีประโยชน์ ขอให้สนุกกับการ coding ครับ

[Part 1] ว่าง ๆ มาลองพัฒนาระบบด้วยภาษา Python ตามแนวคิด 12 Factor กัน

$
0
0

ช่วงหลังมีการพูดถึง The Twelve -Factor App กันเยอะ แต่ไม่ค่อยบอกหรือแสดงให้ดูว่ามันทำอย่างไรบ้าง ? ดังนั้นเราลองมาพัฒนาระบบงานแบบง่าย ๆ ตามแนวคิดนี้กันดู (ตามความเข้าใจที่มีนะ ผิดถูกก็ตามข้างล่างนี้) มาเริ่มกันดีกว่า
ปล. ยิ่งรู้ว่าผิดเร็ว ก็จะทำถูกได้ไว

ข้อที่ 1 Codebase

One codebase tracked in revision control, many deploys ทุกสิ่งอย่างเริ่มที่ source code นั่นเอง ดังนั้นเก็บ source code ใน Version Control System ซะ เช่น Git, Mercurial และ Subversion เป็นต้น อย่ามา backup ด้วย folder หรือ thumb drive กันละ !! ส่งผลให้ง่ายต่อการ deploy source code เหล่านี้ ไปยัง environment ต่าง ๆ ได้ เช่น dev server, test/QA server, staging server และ production server เป็นต้น แต่เรื่องการจัดการ source code ใน Version Control System นั้นก็ไม่ง่าย ต้องเอื้อประโยชน์ต่อทีม ต้องเอื้อประโยชน์ต่อระบบงาน ต้องเอื้อประโยชน์ต่อองค์กร นั่นคือเรื่องของ Branch strategy นั่นเอง ทั้ง Single branch, multiple branch, integration หรือ feature branch นี่คือเรื่องที่สำคัญ ถ้าสิ่งที่เลือกทำให้ช้าลง แย่ลง ก็น่าจะผิดนะ ยังไม่พอนะ โครงสร้างของ source code ก็สำคัญ ทั้งการแยก folder/package ตามหน้าที่การทำงาน ช่วยให้จัดการและดูแลรักษาง่ายขึ้น ดังนั้นมาเขียน code กันดีกว่า อย่าไปเขียนให้ยาก เขียนง่าย ๆ เป็น code สำหรับสร้าง RESTful API ด้วยภาษา Python และเชื่อมต่อ MySQL database (เขียนภาษา Go บ่อยแล้ว เปลี่ยนภาษากันบ้าง) [gist id="4eb6786209e5318ea0ce404239340558" file="api.py"] จากนั้นทำการ run ด้วยคำสั่ง [code] $python api.py [/code] ผลการทำงานเป็นดังนี้ [gist id="4eb6786209e5318ea0ce404239340558" file="1.txt"]

ข้อที่ 2 Dependencies

Explicitly declare and isolate dependencies พวก dependency หรือ library ต่าง ๆ ที่ใช้งานในการพัฒนา ควรถูกแยกออกมาจาก source code โดยเราสามารถนำเครื่องมือเข้ามาช่วย ยกตัวอย่างเช่น
  • Gem bundler สำหรับภาษา Ruby
  • Apache Maven/Gradle สำหรับภาษา Java
  • Pip สำหรับภาษา Python
ในระบบตัวอย่างพัฒนาด้วยภาษา Python จึงใช้งานผ่าน Pip ซึ่งทำการประกาศ dependency หรือ library ที่ใช้งาน ในไฟล์ requirements.txt ดังนี้ [gist id="4eb6786209e5318ea0ce404239340558" file="requirements.txt"] จากนั้นทำการติดตั้ง dependency ด้วยคำสั่ง [code] $pip install -r requirements.txt [/code] ยังไม่พอนะ เรื่องของ depenedncy มันยังลามไปถึง System dependency ด้วย ทั้งเรื่องของ version ของ python และ pip ที่ใช้งาน ซึ่งแก้ไขด้วยการใช้งาน virtualenv การใช้งานก็ไม่ได้ยากเลย ดังนี้ [code] $virtualenv env --no-site-packages $source env/bin/activate [/code] แต่ถ้าต้องการแยกตั้งแต่ระบบปฏิบัติการไปเลย คงต้องมาใช้พวก Containerization แล้วเช่น Docker เป็นต้น แต่ตอนนี้ยังไม่ถึงเวลา เดี๋ยวค่อยนำมาใช้กัน

ข้อที่ 3 Config

Store config in the environment ระบบงานที่พัฒนาควรทำการจัดเก็บ configuration ต่าง ๆ ใน environment variable ซะ เพื่อทำให้สามารถ deploy source code เดียวกันได้ในทุก ๆ enviroment เช่น dev, test/qa และ production เป็นต้น จาก source code จากข้อที่ 1 นั้น เราสามารถแยก configuration ที่เกี่ยวกับ database ออกมา แล้วไปเก็บไว้ใน environment variable ได้
ปล. คิดว่าคงไม่มีใครทำการ hard code หรอกนะ อย่างน้อยก็น่าจะเก็บไว้ในไฟล์ configuration แน่นอน
มาลองเขียนกันหน่อย ไม่ได้ยากเลย [gist id="4eb6786209e5318ea0ce404239340558" file="api2.py"] จากนั้นตอน run ก็กำหนดค่าต่าง ๆ ตามที่ใจต้องการ มันทำให้ระบบงานมีความยืดหยุ่นมากยิ่งขึ้น [gist id="4eb6786209e5318ea0ce404239340558" file="run.sh"]
ถ้าเป็นพวก Docker และ Kubernetes นี่ง่ายมาก ๆ  Docker ไปใช้ environment ได้เลย ส่วน Kubernetes ไปใช้งาน ConfigMap แบบชิว ๆ

ข้อที่ 4 Backing services

Treat backing services as attached resources ในแต่ละส่วนที่ทำงานกับระบบงานของเรานั้นต้องไม่ผูกมัดกันแบบแน่น ยกตัวอย่างเช่น Database, External storage, Message queue ต้องสามารถเปลี่ยนได้ง่าย โดยไม่ทำการแก้ไข code เลย หรือเพียงแค่เปลี่ยน configuration เท่านั้น นั่นคือการเปลี่ยนแปลงต้องไม่กระทบการทำงาน นั่นคือมองสิ่งต่าง ๆ เหล่านี้เป็น service หรือจำเป็นต้องมี abstraction layer/interface เข้ามากั้น ถ้ามองไปยังโลกของ containerization นั้นง่ายมาก ๆ ต้องการเปลี่ยน database จาก MySQL ไปเป็น PostgreSQL ทำได้ง่าย ๆ ด้วยการสร้าง container ใหม่ที่ทำหน้าที่จัดการข้อมูลผ่าน PostgreSQL จากนั้นก็ทำการ rollout ใหม่ หรือทำการ restart container ที่เกี่ยวข้อง ก็เท่านั้นเอง หรือถ้าเพียงแค่เปลี่ยน configuration ใน environment variable ได้ก็จบเลย (อย่าลืม restart ด้วย) กลับมามองที่ระบบงานตัวอย่างของเราบ้าง ถ้าเราต้องการเปลี่ยน database จาก MySQL ไปเป็น database อื่นละ เราจะทำอย่างไรดี ? จากที่ทำมานั้น พบว่ามี 3 แบบที่พอเป็นไปได้คือ
  • 1. ถ้า database ที่เราเลือกใช้ ทำการกำหนดค่าเหมือน MySQL ก็จบ (ไม่ค่อยมี) ไม่ต้องแก้ไข code
  • 2. ทำการแยกส่วนของการจัดการข้อมูลจาก database ไปเป็น service ใหม่เลย แล้วคุยกันผ่าน HTTP protocol เช่น RESTful API จากนั้นถ้าต้องการเปลี่ยน database ก็ไปสร้าง service ใหม่เลย จากนั้นเปลี่ยน configuration ของผู้ใช้งานให้ไปเรียก service ใหม่ เพียงเท่านี้ก็จบ
  • 3. ถ้าการเปลี่ยน database ยังคงเป็น RDBMS เหมือนเดิม เราสามารถใช้งานพวก Object Oriented Mapping (ORM) มาใช้ได้นะ เช่น SQLAlchemy เป็นต้น  จากนั้น URL ของการเชื่อมต่อ database ต่าง ๆ จะเหมือนกันเลย เพียงย้ายมากำหนดผ่าน environment variable ก็เรียบร้อย
อยากใช้แบบไหน ก็เอาที่ถนัดและเอาอยู่นะครับ เพราะว่าแบบแรก ถ้าได้ก็โชคดีไป เพราะว่าแบบที่สองและสามนั้น เราต้องไปแยก service ออกมา จาก 1 เป็น 2 ก่อน จากนั้นจึงค่อยสร้างและเปลี่ยนใหม่ มาดูตัวอย่างในแบบที่ 3 กันหน่อย แก้ไขง่าย ๆ ด้วยการใช้งาน Flask SQLAlchemy [gist id="4eb6786209e5318ea0ce404239340558" file="api3.py"] ทำการง่าย ๆ ด้วยการกำหนด DATABASE_URL ก็พอ [code] $export DATABASE_URL=mysql+mysqlconnector://user:password@localhost/demo $python api.py [/code] จากนั้นถ้าต้องการเปลี่ยน database ก็เพียงเปลี่ยน DATABASE_URL เท่านั้น แต่ต้องเป็น database ที่ SQLAlchemy สนับสนุนเท่านั้นนะ
เขียนไปเขียนมาเริ่มยาวเกินไปแล้ว ดังนั้นเอาไว้ต่อที่เหลืออีก blog ก็แล้วกัน
ตัวอย่าง source code อยู่ที่ Github::Up1::Demo 12 Factor App ขอให้สนุกกับการ coding ครับ

[Part 2] มาต่ออีก 4 ข้อ สำหรับการพัฒนาระบบตามแนวคิด 12 Factor

$
0
0

หลังจากที่ลองพัฒนาระบบด้วยภาษา Python ตามแนวคิด The Twelve Factor App มาแล้ว 4 ข้อคือ
  1. Codebases
  2. Dependencies
  3. Configs
  4. Backing services
ซึ่งยังเหลืออีก 8 ข้อ ดังนั้นมาต่อกันให้จบ โดยทั้ง 8 ข้อนี้จะเข้ากันมาก ๆ กับโลกของ Containerization ในตัวอย่างจะเน้นไปที่ Docker เป็นหลัก มี Kubernetes มาผสมบ้างเล็กน้อย
ปล. เขียนไปเขียนมาทำไมมันยาว ดังนั้นเพิ่มแค่ 4 ข้อเป็น 8 ก็แล้วกัน ที่เหลืออีก 4 ข้อ เอาไว้อีก blog
มาเริ่มกันเลย

ข้อที่ 5 Build, release, run

Strictly separate build and run stages ขั้นตอนการ deploy source code ไปยัง environment ต่าง ๆ เป็นอย่างไรกัน ? ทำการ copy หรือ FTP หรือ Rsync ขึ้นเองไหม หรือแก้ไฟล์เดียว ก็เอาขึ้นไฟล์เดียว !! ตามแนวคิดนี้ จะทำการแบ่งขั้นตอนการนำ source code ไป deploy เป็น 3 ขั้นตอน ขั้นตอนที่ 1 Build ทำการแปลงจาก source code จากข้อหนึ่ง ตาม commit หรือ version ที่กำหนดไว้ กับ dependency จากข้อสอง ไปเป็น executable ไฟล์ ยกตัวอย่างเช่น dll, exe, JAR, WAR, ZIP หรือ binary file อื่น ๆ เป็นต้น ขั้นตอนที่ 2 Release นำผลที่ได้จากขั้นตอนการ build มารวมกับข้อสามคือ Config ซึ่งพร้อมที่จะเริ่มทำงานทันที ขั้นตอนที่ 3 Run หรือ Runtime ทำการ run หรือสร้าง process การทำงานของระบบงานจากขั้นตอนที่สอง จากการทำงานที่มี 3 ขั้นตอนนั้น เราไม่สามารถทำการแก้ไขแบบข้ามขั้นตอนได้ ยกตัวอย่างเช่น ไม่สามารถไปแก้ไขในขั้นตอนการ Run ได้ ถ้าไม่ผ่านขั้นตอนของการ Build และ Release โดยเด็ดขาด สิ่งที่ได้รับกลับมาคือ เราสามารถทำการ rollout หรือ rollback ระบบงานได้ตามที่ต้องการ กลับมายังระบบงานตัวอย่างของเราบ้าง ที่พัฒนาด้วยภาษา Python เราจะทำอย่างไรดี ตามแนวความคิดนี้ สิ่งที่ง่ายขึ้นคือ เราใช้งาน Docker ดีกว่า เพียงแค่สร้าง Docker Image จาก Dockerfile เท่านั้น (มันเป็น Immutable อีกด้วย นั่นคือไม่สามารถแก้ไขได้) ก็สามารถทำการ build image ที่พร้อมจะ release และ run ได้เลย ซึ่งมีการทำงาน 3 ขั้นตอนดังนี้
  1. ทำการสร้าง Docker Image จาก Dockerfile
  2. ทำการสร้าง Docker Image ตาม environment ที่ต้องการ
  3. ทำการสร้าง Container จาก Docker Image ที่ต้องการ
ขั้นตอนที่ 1 สร้าง Dockerfile สำหรับการ build กันก่อน [gist id="4eb6786209e5318ea0ce404239340558" file="Dockerfile.build"] คำอธิบาย ใช้ base image ของ python ไปเลย ง่ายดี ทำการเพิ่ม source code และ dependency ต่าง ๆ เข้าไป จากนั้นทำการสร้าง Docker Image ของการ build ด้วยคำสั่ง [code] $docker image build -t demo:0.1.0 -f Dockerfile.build . [/code] ขั้นตอนที่ 2 สร้าง Dockerfile สำหรับการ release จะใช้ Docker Image จากขั้นตอนที่ 1 พร้อมกับกำหนด config ของ Database ที่ใช้งาน [gist id="4eb6786209e5318ea0ce404239340558" file="Dockerfile.release"] จากนั้นทำการสร้าง Docker Image ของการ release ด้วยคำสั่ง [code] $docker image build -t demo_release:0.1.0 -f Dockerfile.release . [/code] ขั้นตอนที่ 3 ทำการ run หรือสร้าง container จาก Docker Image ที่ได้จากขั้นตอนที่ 2 ใช้คำสั่งดังนี้ [code] $docker container run -p 8000:8000 demo_release:0.1.0 [/code] ถ้าเป็น Kubernetes ก็เอาที่สบายใจเลยว่า จะ run แบบไหนทั้ง Deployments, ReplicaSets และ DaemonSets เป็นต้น

ข้อที่ 6 Processes

Execute the app as one or more stateless processes ถือว่าเป็นหัวใจหลักของ Cloud Native Application ระบบงานจะมี process ที่เป็นแบบ stateless จำนวนตั้งแต่ 1 process ขึ้นไป นั่นคือแต่ละ process จะไม่มีการ share state เลย (ไม่มี session นะ) ตามแนวคิดนี้ ทำให้ง่ายต่อการ scale out (Horizontal scaling) แต่ถ้าจำเป็นต้องเก็บข้อมูล ก็จะต้องใช้ Backing service ตามแนวคิดข้อ 4 ซึ่งทำงานแบบ stateful หรือถ้าใน Kubernetes ก็สามารถใช้งาน StatefulSets ได้เช่นกัน ระวัง process ตายด้วยละ !! เป็นอีกคำพูดหนึ่งที่น่ากลัวใช้ได้เลย แน่นอนว่า เราต้องมีคำตอบให้ด้วย โดยใน Docker และ Kubernetes มีตัวจัดการมาให้พร้อมอยู่แล้ว เพื่อทำให้แน่ใจว่า process ยังทำงานตามจำนวนที่กำหนดไว้เสมอ

ข้อที่ 7 Port binding

Export services via port binding หมายความว่า service ที่เราทำการพัฒนาขึ้นมานั้น ไม่ว่าจะทำงานบน Application/Web server อะไรก็ตาม เช่น Java อาจจะทำงานบน Apache Tomcat Python อาจจะทำงานบน Flask ซึ่งล้วนมี port การทำงานที่แตกต่างกัน แต่ service ของเรานั้นต้องไม่ผูกติดกับ port ของเครื่องมือที่ใช้ในการพัฒนา ถ้าเป็นการพัฒนาปกติ เราสามารถกำหนด port ของ service ด้วยการ configuration ผ่าน environment variable ได้เลย ยกตัวอย่างเช่น [gist id="4eb6786209e5318ea0ce404239340558" file="app4.py"] ทั้ง Docker และ Kubernetes นั้น สามารถทำงาน binding port ของ service ต่าง ๆ ได้ โดยไม่ขึ้นอยู่กับ Application/Web server ที่ใช้งาน

ข้อที่ 8 Concurrency

Scale out via the process model เนื่องจาก process ของ service ต่าง ๆ เป็นแบบ stateless อยู่แล้ว ดังนั้นการ scale out ก็ทำได้ด้วยการเพิ่ม process เข้ามานั่นเอง ( scale out over scale up ) แน่นอนว่า ในระบบงานมี service จำนวนมาก ดังนั้นแต่ละ service ก็มีการ scale ที่แตกต่างกันไป และเป็นอิสระแก่กัน ซึ่งทั้ง Docker และ Kubernetes ล้วยสนับสนุนแนวคิดนี้ด้วยเช่นกัน ไม่ต้องพยายาม
มาถึงตรงนี้น่าจะพอทำให้เข้าใจแนวคิดของ The Twelve -Factor App มากขึ้นมาบ้าง ใน blog ต่อไปจะเป็น 4 เรื่องสุดท้ายแล้ว

[Part 3] ภาคจบสำหรับการพัฒนาระบบตามแนวคิด 12 Factor

$
0
0

มาทำความรู้จักกับ 4 ข้อสุดท้ายสำหรับ The Twelve-Factor App โดยในส่วนนี้จะเป็นส่วนของผู้ดูแลระบบ ประกอบไปด้วย
  • Disposability
  • Dev/prod parity
  • Logs
  • Admin processes
มาดูในรายละเอียดกัน

ข้อที่ 9 Disposability

Maximize robustness with fast startup and graceful shutdown การทำงานของ process นั้น ควรเริ่มทำงานได้อย่างรวดเร็ว รวมทั้งเมื่อต้องการปิดหรือ shutdown จะต้องเป็น graceful shutdown ด้วย คำถามคือ graceful shutdown มันคืออะไร ? อธิบายง่าย ๆ คือ ใช้อะไรอยู่ ก็ต้องคืนอย่างถูกต้อง ก่อนที่จะทำการปิดหรือ shutdown นั่นเอง ยกตัวอย่างเช่น resource ต่าง ๆ เช่น Database connection และ Queue เป็นต้น รวมไปถึงถ้ายังมีการทำงานค้างอยู่เช่น Data processing ก็ต้องรอหรือทำให้เสร็จแบบถูกต้อง ไม่ส่งผลเสียต่อระบบ เช่น ข้อมูลหายหรือการประมวลผลที่ไม่ถูกต้อง หรือ Database connection ไม่ถูกคืนให้กับระบบ ความซวยบังเกิดแน่นอน
ดังนั้นระบบงานหรือ service หรือ process ของเรา ต้องมีคุณสมบัติทั้งสองอย่างเสมอ คือ เริ่มต้นได้เร็วและจบได้สวย
ตัวอย่างของการทำงานของ Graceful shutdown ของ Web server
  1. Web application ได้รับคำสั่งให้หยุดหรือ kill process (ได้รับผ่าน SIGTERM)
  2. ถ้าระบบ Web application รับงานผ่าน Load Balance แล้ว ก็จะทำการแจ้งไปยัง Load Balance ว่าไม่ต้องส่ง request มาให้นะ
  3. ส่วน Web application เครื่องอื่น ๆ ก็ทำงานปกติไป
  4. ระบบ Web application ทำการคืน resource ต่าง ๆ รวมทั้งทำงานที่ค้างไว้ให้เสร็จ ทั้ง Database connection และ Queue เป็นต้น
  5. เมื่อทุกอย่างในข้อ 4 เรียบร้อยแล้ว Web application จึงจะหยุดทำงานและส่งค่าสถานะ success ออกไป
มาดูระบบตัวอย่างที่พัฒนาด้วยภาษา Python กันบ้าง เราจะทำ Graceful shutdown อย่างไร ? ไม่ต้องคิดมากนะ แค่ค้นหาก็เจอ เจอหลายแบบด้วย มาดูตัวอย่างกัน เป็นตัวอย่างการทำงานดักจับในกรณีที่ต้องการปิด process [gist id="4eb6786209e5318ea0ce404239340558" file="api5.py"] ถ้าอยู่ในแนวทางของ Containerization เช่น Docker swarm และ Kubernetes แล้ว หมายความว่า เมื่อ container และ Pod ตายไป จะต้องไม่ส่งผลกระทบต่อการทำงานนั่นเอง โดยที่ Containerization นั้นถูกสร้างขึ้นมาตามแนวทางนี้อยู่แล้ว แต่ source code ของเราละ เขียนมาเพื่อสนับสนุนหรือไม่ ? ถามใจดูเอานะ

ข้อที่ 10 Dev/prod parity

Keep development, staging, and production as similar as possible แนวคิดนี้มีเป้าหมายเพื่อลดความต่างของ environment ต่าง ๆ กับ production environment ให้เหลือน้อยที่สุด ทั้งในแง่ของเวลา นั่นคือนักพัฒนาใช้เวลาในการพัฒนาบน development server นานหรือไม่ กว่าจะ deploy ไปยัง production server ทั้งในแง่ของ process การทำงาน นั่นคือทีมพัฒนาก็เขียน code กันไป ส่วนการ deploy เดี๋ยวให้อีกทีมทำให้ รอกันไปมา โยนกันไปมา ทั้งในแง่ของเครื่องมือ นั่นคือทีมพัฒนาอาจจะใช้ server เล็ก ๆ ทุกอย่างกองรวมกัน database ไม่เหมือนจริง web server ก็ configuration ไม่เหมือน production เช่น พัฒนาบน Windows OS แต่การ deploy ทำบน Linux !! ดังนั้นจะทำอย่างไร เพื่อให้สามารถนำการเปลี่ยนแปลงต่าง ๆ จากการพัฒนาให้ไป deploy ยัง production environment ให้เร็วและมีคุณภาพที่ดี บางครั้งเราจะเรียกกระบวนการนี้ว่า Continuous Integration และ Continuous Deployment เพื่อทำให้เรามั่นใจว่า สิ่งต่าง ๆ ที่พัฒนาขึ้นมายังคงทำงานได้ถูกต้องตามที่คาดหวัง และเกิดปัญหาให้น้อยที่สุด หรือ ให้รู้ปัญหาได้อย่างรวดเร็ว แน่นอนว่าในโลกของ Containerization เกิดมาเพื่อสิ่งนี้เลย ทั้ง Docker ที่สามารถใช้งานได้ในระบบปฏิบัติการหลัก ๆ ได้ แถมยัง compatible กันอีก ดังนั้นจึงหมดหรือลดปัญหาเรื่อง environment ไปได้เลย ตัวอย่างเช่น การใช้งาน docker compose สามารถที่จะสร้างไฟล์ docker-compose.yml จากนั้นก็สั่งด้วย $docker-compose up ได้เลย จะได้ระบบงานที่มีรูปแบบเหมือนกันในทุก ๆ  environment ที่มี Docker engine อยู่ ยิ่งพวก Kubernetes นั้น สามารถแยก environment ต่าง ๆ ด้วย namespaces ได้ง่าย ๆ อีกด้วย

ข้อที่ 11 Logs

Treat logs as event streams ปกติเราดู log กันอย่างไร ? ยังเก็บลง log file และคอยดูแบบนี้ไหมนะ ? $tail -f access_log ไหมนะ ? ถ้ายังทำอยู่ เปลี่ยนเถอะนะ เนื่องจากข้อมูล log ต่าง ๆ มันคือ event ที่เกิดขึ้นตามช่วงเวลาต่าง ๆ ดังนั้นแนะนำให้ทำการพ่น log ออกมายัง stdout หรือ Standard Output จากนั้นให้ทำการจัดเก็บข้อมูล log เหล่านี้ และส่งไปยังระบบจัดการต่อไป ยกตัวอย่างการใช้งานเช่น แต่ระบบ Logs ที่ดี ควรดูได้ง่าย เข้าใจง่าย แจ้งการทำงานที่ผิดปกติ ก่อนที่มันจะทำร้ายระบบ รวมทั้งทีมต้องเข้าใจด้วยว่า มันคืออะไร มีประโยชน์อะไร ดูอย่างไร มิเช่นนั้นมันจะสวยอย่างเดียว แต่จูบไม่หอมนะ

ข้อที่ 12 Admin processes

Run admin/management tasks as one-off processes แนวคิดนี้ต้องการให้แยกงานส่วนการดูแลรักษาระบบออกจาก app ซะ ยกตัวอย่างเช่น การ migrate database การ scale service/process ของระบบ แต่ยังคงทำงานใน environment, source code และ configuration เดียวกัน โดยถ้าใช้ docker แล้ว เราสามารถทำการเข้าถึง container ด้วยคำสั่ง [code] $docker container exec -i --entry-point container_name path_of_entry_point [/code] ซึ่ง entry point ของไฟล์ที่ใช้สำหรับจัดการงานต่าง ๆ

จบซะทีสำหรับ The Twelve-Factor App ทั้ง 12 ข้อ

จะเห็นได้ว่า แนวคิดทั้ง 12 ข้อนั้น ไม่ได้ใช้ได้กับ Cloud application เท่านั้น ยังสามารถนำมาประยุกต์ใช้กับการพัฒนาระบบทั่วไปได้ ทั้ง web application, desktop application ได้อีกด้วย การนำไปใช้งาน ไม่จำเป็นต้องใช้ครบทั้ง 12 ข้อ เพียงนำบางข้อมาใช้เพื่อแก้ไขปัญหา หรือ ปรับปรุงระบบให้ดียิ่งขึ้นก็ได้ แต่เหนือสิ่งอื่นใด เมื่อเรานำแนวคิดมาใช้งานต้องจำไว้ว่า
  • Declarative setup ช่วยทำให้เวลาในการ setup ระบบเร็วขึ้น
  • Clean contracts ทำให้ส่วนงานต่าง ๆ ไม่ผูกมัดกันแน่น นั่นคือเปลี่ยนแปลงได้ง่าย
  • Deploy practices ช่วยทำให้การ deploy และ scale out สะดวกขึ้น
  • Minimize divergence สนับสนุนเรื่องของ Continuous Deployment
สุดท้ายมันคือ การปรับปรุงอย่างต่อเนื่อง แต่ว่าปัญหาของคุณคืออะไร เรื่องต่าง ๆ เหล่านี้มันช่วยคุณได้หรือไม่ ลองพิจารณาดูก่อนนะ

อ่านแนวคิดนี้ข้ออื่น ๆ ได้จาก blog ด้านล่างนี้

Part 1 :: การพัฒนาระบบตามแนวคิด 12 Factor
  • Codebases
  • Dependencies
  • Configs
  • Backing services
Part 2 :: การพัฒนาระบบตามแนวคิด 12 Factor
  • Build, release, run
  • Processes
  • Port binding
  • Concurrency
ขอให้สนุกกับการ coding ครับ

ปรับปรุง productivity ด้วย code ที่ดีกันหน่อย

$
0
0

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

Code ที่เขียนทดสอบหรือไม่ ? ถ้าไม่ทดสอบมีโอกาสพังสูงนะ

การทดสอบแบบไหนก็ได้ ไม่จำเป็นต้องเป็นแบบอัตโนมัติ แต่ขอให้ทุกการเปลี่ยนแปลง ต้องทำการทดสอบทั้งหมด (regression test) ในกรอบเวลาที่เร็วและชัดเจน การทดสอบมีหลายรูปแบบ จากเล็ก ๆ ในระดับ Unit test ไปจนถึงระดับ End-to-End test เวลาก็จะสูงขึ้นเริ่ม ตามระดับที่สูงหรือใหญ่ขึ้น ถ้าทำได้ก็ควรทำในทุกกระดับ เริ่มตั้งแต่ระดับเล็ก ๆ เพื่อทำให้มั่นใจว่า แต่ละส่วนการทำงานยังคงทำงานถูกต้อง จากนั้นเริ่มสูงขึ้นมา เช่น integrate test เพื่อนำส่วนการทำงานต่าง ๆ มาทำงานร่วมกัน รวมกันไปเรื่อย ๆ จนถึง End-to-End test มันจะช่วยให้เรารู้ปัญหาได้อย่างรวดเร็ว ไม่ต้องมา debug กัน

เลือกใช้ชื่อที่เหมาะสมและสื่อความหมายในสิ่งที่ต้องการ

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

ลูกอีช่าง Log ...

ใครบ้างที่เขียน code สำหรับเก็บ log มากกว่าเขียน code ของระบบอีก ? Log เป็นสิ่งที่ดี เพราะว่า มันช่วยทำให้เรารู้ว่า มีอะไรเกิดขึ้นในระบบบ้าง แต่ก่อนที่จะเขียน log นั้นช่วยสรุปก่อนว่า เราต้องการจะถามหรือรู้อะไรจากระบบ เช่นเหตุการณ์ต่าง ๆ ขั้นตอนการทำงานหลักของระบบ และ error ที่เกิดขึ้น เป็นต้น บ่อยครั้งพบว่าเราเก็บ log มากจนเกินไป รวมทั้งชอบเขียนลงไฟล์ แล้วมา tail -f log กันอีก แบบนี้ไม่น่าช่วยทำให้ productivity ดีขึ้นเลย กลับแย่กว่าเก่า ดังนั้นเปลี่ยนมาเขียน log ลงระบบที่ช่วยจัดการดีกว่าไหม ? เช่นระบบ centralize log ที่มีการจัดการที่ดี มีระบบ dashboard มีระบบ alert เมื่อมีสิ่งที่แปลก ๆ เกิดขึ้นมา

เรื่องของ Single Responsibility Principle (SRP) ของแต่ละ class และ method สำคัญมาก ๆ

แต่ละ class และ method ควรมีหน้าที่การทำงานที่เฉพาะเจาะจงไปเลย ชื่อของ class และ method ก็จะต้องสื่อถึงการทำงานที่เจาะจง ส่งทำให้จำนวน code น้อยลง นั่นทำให้การอ่านง่าย หา bug ได้ง่าย แก้ได้ง่าย เพื่อความปลอดภัย อย่าลืมดัก exception/error ที่ไม่คาดฝัน หรือ ไม่ต้องการไว้ด้วย เนื่องจาก code ที่เราพัฒนาขึ้นมานั้น มันอาจจะเกิดสถานการณ์ที่เราไม่คาดฝัน หรือไม่ต้องการขึ้นมาได้ การทดสอบอาจจะยากมาก ๆ ดังนั้นสิ่งที่ควรทำคือ การดัก exception เหล่านั้นซะ แต่ถ้าเราสามารถจำลองสถานการณ์ได้ ก็จัดการมันซะ อย่าปล่อยไว้ ส่วนสิ่งอื่น ๆ ที่อาจจะเกิดขึ้นแต่ไม่สามารถจำลองได้ ก็ต้องดักไว้เช่นกัน เพื่อช่วยให้ระบบงานไม่พังง่ายจนเกินไป
วันนี้ code ที่เราเขียนอยู่เป็นอย่างไรบ้าง ? มันช่วยทำให้เรามี productivity ที่สูงขึ้นหรือไม่ ?

ใส่สีให้กับการทดสอบสำหรับภาษา Python

$
0
0

ปัญหาและความต้องการ

หลังจากที่ทำการ run test ที่พัฒนาด้วยภาษา Python ซึ่งใช้งานผ่าน module unittest เมื่อทำการ run ได้แล้วพบว่า ผลลัพธ์ที่ออกมามันไม่สวย นั่นคือไม่มีสีสันอะไรเลย ดูลำบาก [code] $exportPYTHON_PATH=.:$(pwd)/src:$PYTHONPATH $python -m unittest discover -s tests -p "*_unittest.py" [/code]

การแก้ไขปัญหา

ไปค้นหาเจออันแรก Green ดังนั้นลองใช้งานกัน ติดตั้งกันเลย [code] $pip install green [/code] การใช้งานก็ง่ายมาก ๆ [code] $green -v tests/*.py $green -vv tests/*.py [/code]
เพียงเท่านี้ก็สบายแล้ว Source code ตัวอย่าง Github::Demo Python

ว่าด้วยเรื่องของ Goroutine และ Channel

$
0
0

ไปฟังเรื่อง Goroutine, Channel และ Parallelism จากงาน Go Get # 2 จากกลุ่ม Golang Thailand ก็เลยกลับมานั่งสรุปกันนิดหน่อย เพราะว่าเป็นเรื่องที่มีโอกาสใช้งานน้อยมาก ๆ ตั้งแต่ทำ project ด้วยภาษา Go มาเคยใช้เพียง project เดียวเอง เลยกลับมาสรุปเพื่อทำความเข้าใจกันหน่อย
โดยเริ่มจากเรื่องง่าย ๆ ก่อนคือ Goroutine และ Channel ซึ่งเป็นเรื่องพื้นฐานสุด ๆ แต่ก็ไม่ง่ายเลยนะ มาเริ่มกันเลย

ในการศึกษาภาษา Go นั้น ช่วงแรก ๆ จะเจอรูปแบบภาษาง่าย ๆ เข้าใจง่าย

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

เริ่มจาก Goroutine

[gist id="a6ee1c4f93dea97af1590ec91406922b" file="demo1.go"] ทำการ run ดังนี้ [gist id="a6ee1c4f93dea97af1590ec91406922b" file="1.txt"] คำอธิบาย สังเกตุว่าจะมี keyword ว่า go สำหรับการ run Go routine ขึ้นมาอีก 1 ตัว ทำให้มีการทำงาน 2 ส่วนแยกกันดังรูป โดยที่จาก code นั้น main() ไม่สามารถเข้าถึงผลการทำงานจาก hello() ได้เลย และทำการ hack ในส่วนของ main นิดหน่อย เพื่อให้รอการทำงานของ hello() ด้วยการให้ main() รอด้วยการ sleep เพราะว่าทั้งสองส่วนทำงานแยกกันอย่างชัดเจน

แต่ถ้าเราต้องการผลการทำงานจาก Hello() ละ จะทำอย่างไร ?

สิ่งที่ต้องทำคือ การเพิ่ม channel ระหว่างทั้งคู่เข้าไป โดยสิ่งแรกที่ต้องการคือ รับผลการทำงานจาก Hello() กลับมาดังรูป เขียน code ได้ดังนี้ [gist id="a6ee1c4f93dea97af1590ec91406922b" file="demo2.go"] ทำการ run ดังนี้ [gist id="a6ee1c4f93dea97af1590ec91406922b" file="2.txt"] คำอธิบาย ทำการสร้าง channel ชื่อว่า result โดยชนิดข้อมูลที่ส่งใน channel คือ string จากนั้นทำการส่งไปยัง hello() ใน hello() จะพบว่า ผลลัพธ์ของการทำงานจะถูกส่งเข้าไปยัง channel ที่ส่งมา สุดท้ายใน main() จะรอผลการทำงานจาก channel ด้วย <-result ทำให้ไม่ต้องใช้ sleep() รออีกต่อไป ดังนั้นถ้าจะเขียนรูปให้ถูกมากยิ่งขึ้นจะเป็นดังรูป ซึ่งเป็นการทำงานแบบ unidirection หรือ ทางเดียวเท่านั้น

แต่ถ้าเราต้องการให้ main() และ hello() คุยกันแบบสองทาง หรือ Bidirection ละ ทำอย่างไร ?

โดยตรงนี้จะยิ่งเพิ่มความมึนงงมากยิ่งขึ้น นั่นคือจะสร้าง 2 channel ขึ้นมา
  1. Channel ที่ 1 ทำการส่ง input จาก main() ไปยัง hello()
  2. Channel ที่ 2 ทำการส่งผลการทำงานจาก hello() ไปยัง main()
แสดงดังรูป สังเกตุว่าใน function hello() นั้นจะมี channel สองตัวที่ต่างกัน
  • <-chan string คือ input ที่ส่งเข้ามาใน channel ซึ่งตัวอย่างส่งมาจาก main()
  • chan<- string คือ output ที่จะส่งผลการทำงานจาก hello() ออกไป ซึ่งจากตัวอย่างนี้ main() ก็จะรอรับข้อมูลนี้อยู่
น่าจะทำให้เข้าใจเรื่องของ Go routine มากยิ่งขึ้น ซึ่งยังมีเรื่อง multi-channel อีก ซึ่งมันคือเรื่องของ concurrent ที่ไว้อธิบายต่อไป แต่สิ่งที่น่าสนใจคือ ก่อนการจะเขียน code นั้น จำเป็นต้องวาดภาพอธิบายสิ่งที่ต้องการก่อนนะ ขอให้สนุกกับการเขียน code ครับ Reference Websites https://gobyexample.com/goroutines https://www.sohamkamani.com/blog/2017/08/24/golang-channels-explained/ https://abronan.com/introduction-to-goroutines-and-go-channels/ https://notes.shichao.io/gopl/ch8/ https://medium.com/@tilaklodha/concurrency-and-parallelism-in-golang-5333e9a4ba64 https://stackoverflow.com/questions/39826692/what-are-golang-channels-used-for/39831976 https://medium.com/@trevor4e/learning-gos-concurrency-through-illustrations-8c4aff603b3

สิ่งที่ทำให้นักพัฒนาไม่พอใจ !! สุดท้ายก็ …

$
0
0

นั่งคุยกับนักพัฒนามาพอสมควร ได้รับรู้ปัญหาเกี่ยวกับสิ่งที่ทำให้นักพัฒนาไม่พอใจ สุดท้ายทำให้นักพัฒนาเหล่านั้นต้องเปลี่ยนที่ทำงาน !! เหมือนเป็นศาลาคนเศร้าเลย มาดูกันว่ามีอะไรบ้าง

เจอแต่เทคโนโลยีเก่า ๆ

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

ขาดการ training หรืออบรมในเรื่องใหม่ ๆ

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

ไร้ซึ่งอนาคตในองค์กร

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

ทำงานหามรุ่งหามค่ำ

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

ใช้เครื่องมือที่ไม่เหมาะกับงาน

เครื่องทำงานก็ช้า ก็ยังทนใช้ เครื่องมือที่ใช้กิน resource เยอะ ทั้ง CPU และ Memeory ก็ยังใช้อยู่อีก เครื่องมือที่ใช้งานช้ามาก ๆ ก็ยังใช้ เครื่องมือที่ใช้มีขั้นตอนการใช้งานที่เยอะและวุ่นวาย ก็ยังใช้ ยังไม่พอนะ process การทำงานก็ยังเทอะทะอีก
การเลือกเครื่องมือนั้น ควรมาจากคนทำงาน ไม่ใช่เอาเครื่องมือมาตั้ง แล้วจึงมาบังคับให้ใช้งาน
ลองถามตัวเราเองสิว่า เคยบ่นเรื่องของเครื่องมือที่ใช้พัฒนาหรือไม่ ? ถ้าเคยบ่นและแจ้งไปแล้ว มีใครแก้ไขให้หรือไม่ ? หรือไม่ก็ ทน ๆ ใช้กันไป !!
ไม่มีโอกาสในการเสนอแนวคิดต่าง ๆ ไม่มีใครเชื่อ มีปัญหา ก็หาคนผิดก่อนเสมอ IT โดนด่าตลอด ทำดีแค่เสมอตัว แต่เมื่อพลาดจะ ...
องค์กรของเราเป็นอย่างไรนะ ? มาเขียน code กันเถอะ

มา Vue.js Thailand Meetup เลยมา TDD กันหน่อย

$
0
0

มาร่วมงาน Vue.js Thailand Meetup #4 ของกลุ่ม Vue.js Thailand บอกตามตรงว่า ไม่เคยใช้งานมันเลย ดังนั้นเพื่อให้เข้าใจมากขึ้นมาลองศึกษากันบ้าง เริ่มด้วย TDD with Vue.js กันหน่อย มาเริ่มกันเลย

ขั้นตอนแรก เพื่อความง่ายต้องติดตั้ง Vue CLI 3 ก่อน

[code] $yarn global add @vue/cli $yarn global add @vue/cli-init $vue —version 3.0.4 [/code]

ขั้นตอนที่สอง ทำการสร้าง project ที่มี test กันสิ

ทำการสร้าง project ด้วย template ชื่อว่า webpack ดังนี้ [code] $vue init webpack hello-tdd [/code] จากนั้นก็เพิ่ม unit test และ e2e test เข้าไปใน project ด้วย จากตัวอย่างผมใช้ Jest ในการเขียน unit test แสดงดังรูป

ขั้นตอนที่ 3 ทำการ start server ทดสอบสิ

[code] $yarn run dev [/code] จากนั้นเปิด browser ไปยัง url = http://localhost:8080 แสดงผลการทำงานดังรูป

ขั้นตอนที่ 4 เมื่อทุกอย่างพร้อมทำการเขียน test กันดีกว่า

หลังจากที่สร้าง project ด้วย Vue CLI แล้ว จะทำการสร้าง test มาให้ แน่นอนว่า มี HelloWorld ให้ด้วย แสดงดังรูป มาลอง run unit test กันหน่อย [code] $yarn run unit [/code] ผลที่ได้คือ Error สิครับ ไม่พอ warning เกี่ยวกับ Jest config อีก สงสัยไม่ค่อยมีใครใช้ Jest ไหมหว่า ผลการทำงานเป็นดังนี้
ดังนั้นมาแก้ไข 2 ปัญหานี้กันหน่อย (จะได้เขียน code กันไหมเนี่ย)

ปัญหาแรกคือ SecurityError: localStorage is not available for opaque origins

ทำการแก้ไขปัญหาด้วยการแก้ไขไฟล์ jest.conf.js ด้วยการเพิ่ม testURL: 'http://localhost' เข้าไป จากนั้นทำการ run unit test ใหม่ได้ผลการทำงานดังนี้

ปัญหาที่สอง ก็คือ coverage ของ Jest อีกแล้ว

นั่นคือ Option "mapCoverage" has been removed, as it's no longer necessary mapCoverage จะมีค่า true โดย default ดังนั้นลบออกไปจากไฟล์ jest.conf.js เท่านั้นก็เรียบร้อย
Run unit test ผ่านแล้วววววว นี่แหละชีวิต ...

ขั้นตอนที่ 5 มาดู Unit test กันหน่อย

เป็นตัวอย่าง code ที่ถูกสร้างขึ้นมาจาก Vue CLI ดังนี้ 27a66c49a37adf931d8fb6b376f3d72d Test.js [gist id="27a66c49a37adf931d8fb6b376f3d72d" file="test.js"] คำอธิบาย ทำการตรวจสอบค่าใน tag h1 ซึ่งเป็น tag ลูกที่อยู่ภายใต้ tag ที่ใช้ class ชื่อว่า hello

เย้ ๆ เพียงเท่านี้น่าจะพร้อมแล้วววว มาเขียน test กัน

นี่แหละ First impression กับการเขียน test สำหรับระบบที่พัฒนาด้วย Vue.js มาเขียน code กัน ปล. Source code ตัวอย่างอยู่ที่ Github::Up1::TDD with Vue

มาดูผลการสำรวจเรื่อง High-performing DevOps 2018 จาก DORA กัน

$
0
0

จากบทความเรื่อง New research: what sets top-performing DevOps teams apart ทำการสรุปผลการสำรวจเรื่อง Accelerate: State of DevOps 2018: Strategies for a New Economy ว่าด้วยเรื่องของผลของการนำแนวคิด DevOps มาประยุกต์ใช้ ว่า deploy ระบบได้บ่อยไหม ว่า lead time ของการทำงานลดลงหรือรวดเร็วขึ้นไหม ว่าข้อผิดพลาดจากการเปลี่ยนแปลงต่าง ๆ มันลดน้อยลงไหม ว่าสามารถ recovery ระบบงาน จากความผิดพลาดได้รวดเร็วขึ้นไหม ดังนั้นมาดูผลสรุปจากแบบสำรวจนี้กัน น่าจะพอมีประโยชน์สำหรับใครที่นำแนวคิด DevOps เข้ามาใช้ในองค์กร

จากบทความข้างต้นอธิบายเรื่อง DevOps ได้น่าสนใจ

แนวคิดและแนวปฏิบัติของ DevOps ได้เข้ามาเป็นส่วนหลักในองค์กร มีเป้าหมายเพื่อพัฒนาระบบที่มีความน่าเชื่อถือและยืดหยุ่น นั่นคือ สามารถ scale ได้ง่ายตามการใช้งาน นั่นคือ ส่งมอบประสบการณ์ที่ดีให้ผู้ใช้งานและลูกค้า รวมทั้งนำ feedback จากผู้ใช้งานและลูกค้ามาปรับปรุงให้รวดเร็วที่สุด ดังนั้นขั้นตอนการพัฒนาระบบงาน ตั้งแต่การ requirement -> analysis -> design -> develop + test -> deploy -> maintain -> feedback from user/customer และวนไป ต้องรวดเร็วและมีคุณภาพ และที่สำคัญมาก ๆ คือ
"DevOps is an important component of fast-moving businesses and IT teams. "
ไม่ว่าขั้นตอนการพัฒนาระบบงานจะเป็นแบบไหน ก็สามารถนำแนวคิดและแนวปฏิบัติของ DevOps มาใช้เพื่อปรับปรุงได้

ผลจากการสำรวจสามารถสรุปได้ดังนี้

เริ่มจากการลงมือทำ แต่ต้องลงมือทำจากปัญหา การลงมือทำไปนั้นมันทำให้ดีขึ้นหรือไม่ ต้องค่อย ๆ ทำ ค่อย ๆ เก็บผล ค่อย ๆ ปรับปรุงแก้ไข เพื่อทำให้เห็นว่า แนวปฏิบัติอะไรที่เหมาะสมและทำให้เราวิ่งไปข้างหน้าได้อย่างรวดเร็วและมั่นคง ยกตัวอย่างจากผลการสำรวจ การเพิ่มเรื่องของ continuous testing, monitoring และการจัดการข้อมูลใน database เข้าไปยัง deployment pipeline หรือขั้นตอนการ deploy แบบอัตโนมัตินั่นเอง เพื่อช่วยปรับปรุงการส่งมอบให้เร็วและมีคุณภาพมากยิ่งขึ้น แนวปฏิบัติตาม DevOps นั้นจำเป็นต้องเปลี่ยนวิธีการวัดผล การวัดผลนั้นสำคัญมาก ๆ แต่ถ้าเรายังใช้การวัดผลแบบเดิม ๆ สำหรับแนวคิดใหม่ มันก็ไม่น่าจะถูกต้องใช่ไหม ? ต่อมาสิ่งที่สำคัญมาก ๆ คือ Focus outcome, not output นั่นคือให้สนใจคุณค่าที่ได้ส่งมอบออกไปให้ทาง business และลูกค้า มากกว่าจะให้ความสนใจไปกับปริมาณของสิ่งที่ทำ อีกสิ่งที่สำคัญคือ ความผิดพลาดมันเกิดขึ้นได้เสมอ แต่เรากลับพบว่า ถ้าเมื่อเกิดข้อผิดพลาดขึ้นมาแล้ว มักจะส่งผลให้เราเพิ่มขั้นตอนการทำงานมากขึ้น มักจะส่งผลให้เรา deploy ได้ช้าลง มักจะส่งผลให้เรา deploy ได้น้อยลง เพราะว่าเราต้องทำการตรวจสอบและทดสอบ เพื่อความถูกต้องมากยิ่งขึ้น จากผลการสำรวจพบว่า ระบบที่มีความผิดพลาดสูงนั้น มักจะมาจาก การ deploy แต่ละครั้งมีขนาดที่ใหญ่ และไม่สามารถ deploy ได้บ่อย แต่องค์กรที่มีการนำ DevOps ไปใช้แล้วได้ผลเชิงบวกนั้น แต่ละครั้งในการ deploy จะมีขนาดไม่ใหญ่ สามารถ deploy ได้ตามความต้องการ ในแต่ละวันสามารถ deploy ได้หลายครั้ง ผลที่ตามมาคือ ข้อผิดพลาดจากการ deploy ก็น้อยลงอีกด้วย เมื่อเปรียบเทียบกับกลุ่มที่ทำการ deploy ประมาณสัปดาห์หรือเดือนละครั้ง ตรงนี้น่าจะทำให้เห็นแนวทางดี ๆ บ้างนะ
ลองไปดูรายงานเพิ่มเติมดูนะครับ [PDF]
Viewing all 1997 articles
Browse latest View live