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

บันทึกการใช้งาน Puppeteer สำหรับการทำ End-to-End Testing

$
0
0

Puppeteer เป็น Node library พัฒนาจาก Google เตรียมชุดของ API สำหรับการควบคุม Google Chrome (Headless และ Non-headless) หรือ Chromium ผ่าน DevTool protocol ที่สำคัญไม่ต้องทำงานผ่าน Web Driver อีกต่อไป ซึ่งถ้าใครใช้งานผ่าน Selenium จะรู้ว่ามันน่าเบื่อมาก ๆ เพราะว่าต้อง update version ตาม Google Chrome !! ข้อดีคือ ลด dependency ต่าง ๆ สำหรับการควบคุมหรือจัดการ Google Chrome แต่ก็ต้องแลกมาด้วยการเรียนรู้เพิ่มเติมนะ นั่นคือต้องเขียนชุดการทดสอบด้วย NodeJS แต่งานสายนี้ก็ต้องเรียนรู้อยู่แล้ว ดังนั้นมาเริ่มใช้งานกัน

เริ่มด้วยการติดตั้ง module Puppeteer เข้า project

[code] $npm i puppeteer [/code]

จากนั้นมาเริ่มเขียนชุดการทดสอบดีกว่า

เริ่มด้วยสิ่งที่ต้องการคือ การค้นหาข้อมูลที่ google
  • ต้องการทดสอบในหน้าจอขนาดต่าง ๆ
  • โดยค่า default จะเป็น headless mode แต่ใน demo จะกำหนด headless = false เพื่อดูการทำงาน
  • ค้นหาข้อมูล สวัสดี Puppeteer (ทำการกรอกคำที่ต้องการและกดปุ่ม Enter)
  • ตรวจสอบผลการทำงาน
  • ทำการ capture หน้าจอของแต่ละขั้นตอนด้วย (บันทึกเป็น PDF ก็ได้)
โดยที่ code เขียนไม่ง่ายไม่ยาก ดังนี้ (เขียนให้ทำงานได้เฉย ๆ นะ) [gist id="dbd7e7127b93dd69f48bf248fb7bce30" file="google-spec.js"] มาดูการทดสอบกันดูนะ เร็วมากมาย (เครื่องผมมันช้านะ) https://www.youtube.com/watch?v=HSickS5wTD0&width=640&height=480 ตัวอย่างของ code อยู่ที่ Github :: Up1 เพื่อความสนุกสนานมีให้ลองใช้งานผ่าน web browser ด้วยนะที่ Puppeteer Playground โดยที่ Puppeteer เป็นอีกหนึ่งทางเลือกสำหรับการทดสอบ ลองใช้งานกันดูนะ มันสนุก ๆ ในอีกรูปแบบนะ ขอให้สนุกกับการ coding นะครับ

สวัสดีภาษา Golang ใน AWS Lambda

$
0
0

ทาง AWS Lambda ได้ประกาศสนับสนุนภาษา Go แล้ว ดังนั้นเรามาเรียนรู้กันหน่อยว่า จะเริ่มต้นอย่างไร มีอะไรให้ลองใช้งานกันบ้าง ? ในการเริ่มศึกษาและใช้งาน AWS Lambda แน่นอนว่าทาง AWS ได้เตรียมชุด library และเครื่องมือไว้ให้แล้ว ซึ่งเรียกว่า AWS Lambda Go ทำให้การพัฒนาง่ายขึ้นเยอะ ว่าแล้วมาลองใช้งานกันดีกว่า

จากเอกสารสร้างตัวอย่างของระบบง่าย ๆ

นั่นคือ ทำการสร้าง service สำหรับรับข้อมูลในรูปแบบ JSON เข้ามา จากนั้นทำการสร้างผลลัพธ์กลับไปในรูปแบบ JSON ซึ่งสามารถเขียน code ง่าย ๆ ได้ดังนี้ [gist id="f09b7cf4e8d4011c7c6fa481d11a6359" file="main.go"] ทำการ build ด้วยคำสั่ง [code] $go get github.com/aws/aws-lambda-go/lambda $GOOS=linux go build -o main [/code]

ต่อจากนั้นทำการ deploy ไปยัง AWS Lambda

ซึ่งทำได้ทั้ง command line และผ่าน Web UI ใน blog นี้จะทำการ deploy ผ่าน Web UI ให้ดู มีขั้นตอนดังนี้

ขั้นตอนที่ 1 สร้าง Function ใน AWS Lambda แน่นอนว่าเลือก Runtime เป็น Go 1.x

ขั้นตอนที่ 2 ทำการ deploy ระบบที่พัฒนาด้วยภาษา Go

ทำได้ด้วยการสร้าง zip file ของ binary ที่ได้จากการ build ของระบบงาน เลือก runtime และกำหนดชื่อ handler ชื่อ main และทำการ save ดังรูป

ขั้นตอนที่ 3 สร้างส่วนการทดสอบ function ของเรา

จากนั้นทำการบันทึก

ขั้นตอนที่ 4 ทำการทดสอบ

ได้ผลการทดสอบดังรูป

ขั้นตอนที่ 5 ทำการเพิ่ม API Gateway เพื่อให้สามารถเรียกใช้งาน function ได้

ทำการ configuration API Gateway ดังนี้ API Name = hello-go Deployment stage = prod Security = Open จากนั้นทำการบันทึก จะได้ URL ของ function ดังนี้

ขั้นตอนที่ 6 ทดสอบใช้งาน function ที่เราสร้าง

[code] $curl -XPOST --data '{"id":1,"value":"Hello”}’ <url of api gateway> { "message" : "", "ok": true } [/code]

เพียงเท่านี้ก็สามารถพัฒนา AWS Lambda หรือ Function as a Service ด้วยภาษา Go ได้แล้วนะ

สามารถอ่านเอกสารเพิ่มเติมได้ที่ Official Documentation ขอให้สนุกกับการ coding ครับ

สร้างระบบ Distributed Tracing ของระบบที่พัฒนาด้วย Spring Boot

$
0
0

Tracing เป็นอีกเรื่องหนึ่งที่ service หรือระบบงานต่าง ๆ ต้องมีเสมอ และมันมีประโยชน์ต่อระบบและทีมพัฒนาอย่างมาก แต่เราพบว่าระบบงานส่วนใหญ่ไม่มี หรือ มีน้อยมาก ๆ ดังนั้นเรามาลองสร้างระบบงานที่มีการ tracing การทำงานของระบบ สิ่งที่ใช้ในการพัฒนาประกอบไปด้วย
  • Tracing server ใช้ Zipkin
  • พัฒนา Service ด้วย Spring Boot และ Spring Cloud
  • สร้าง Service 1 และ Service 2
  • โดยที่ Service1 จะเรียกใช้งาน Service 2
โครงสร้างของระบบงานที่ต้องการเป็นดังนี้ มาเริ่มพัฒนาระบบงานกันดีกว่า

1. สร้าง Zipkin service

ขั้นตอนการพัฒนา Zipkin service เป็นดังนี้ ทำการสร้าง Zipkin Service ด้วย Spring Boot [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="1.java"] จากนั้นทำการ package และ run service โดยค่า port default ของ service คือ 8080 เข้าใช้งานดังนี้ ซึ่งบอกว่า Zipkin server พร้อมใช้งานแล้ว

2. สร้าง Service 2

ความต้องการของ service 2 คือ
  • พัฒนา service ด้วย Spring Boot
  • มี endpoint ชื่อว่า /sleep/[time]
ขั้นตอนการพัฒนา Service 2 เป็นดังนี้ ขั้นตอนที่ 1 สร้าง Service จะมี annotation NewSpan สำหรับกำหนดให้สร้างกลุ่มการทำงานใหม่ ที่จะจัดเก็บใน Zipkin จากตัวอย่างถ้าไม่กำหนดชื่อ จะเป็นชื่อของ service คือ service2 นั่นเอง [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="2.java"] ขั้นตอนที่ 2 ทำการ configuration URL ของ Zipkin server ในไฟล์ application.properties [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="2.properties"] และกำหนดชื่อของ service ไว้ในไฟล์ bootstrap.properties [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="bootstrap2.properties"] จากนั้นทำการ package และ run service เมื่อเราทำการเรียกใช้งาน endpoint ของ service 2 แล้ว ข้อมูลการทำงานถูกส่งไปยัง Zipkin service ด้วย ผลการทำงานเป็นดังนี้ เข้าไปดูรายละเอียดของแต่ละกลุ่มของ request หรือ Span ในรายละเอียดของแต่ละ Span มันลงรายละเอียดของการทำงานเลยทีเดียว ทั้ง class และ method

3. สร้าง Service 1 เพื่อเรียกใช้งาน Service 2

ความต้องการของ service 1 คือ
  • พัฒนา service ด้วย Spring Boot
  • มี endpoint ชื่อว่า /service1/
ขั้นตอนการพัฒนา Service 1 เป็นดังนี้ ขั้นตอนที่ 1 สร้างส่วนการเรียกใช้งาน service 2 ผ่าน Feign Client [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="Service2Client.java"] ขั้นตอนที่ 2 สร้าง Service [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="service1.java"] ขั้นตอนที่ 3 ทำการ configuration URL ของ Zipkin server ในไฟล์ application.properties [gist id="0dc2fa11d8cf397b33a105faa24f99ab" file="2.properties"] จากนั้นทำการ package และ run service เมื่อเราทำการเรียกใช้งาน endpoint ของ service 1 แล้ว ข้อมูลการทำงานถูกส่งไปยัง Zipkin service ด้วย ผลการทำงานเป็นดังนี้ เข้าไปดูรายละเอียดของแต่ละกลุ่มของ request หรือ Span ในรายละเอียดของแต่ละ Span มันลงรายละเอียดของการทำงานเลยทีเดียว ทั้ง class และ method เพียงเท่านี้เราก็ได้ระบบ tracing ของ service ต่าง ๆ ที่พัฒนาด้วย Spring Boot แล้วนะ น่าจะช่วยทำให้นักพัฒนาเห็นการทำงานที่ชัดเจน รวมทั้งหาปัญหาได้ง่ายขึ้น ตัวอย่าง source code อยู่ที่ Github:Up1 ขอให้สนุกกับการ coding ครับ

สวัสดี Go-kit ชุดเครื่องมือสำหรับพัฒนา Microservices ด้วยภาษา Go

$
0
0

ในช่วงที่ผ่านมาได้มีการพูดถึง Go-kit กันพอสมควร ทั้งในเรื่องของรูปแบบการเขียนที่ดี ทั้งในเรื่องของชุดเครื่องมือสำหรับการพัฒนา Microservices บางคนก็บอกว่าเหมือน Netflix เลย บางคนก็บอกว่าเหมือน Finagle ของ Twitter เลย แต่ไม่ว่าจะเหมือนอะไรก็ช่างมัน เป้าหมายของ Go-kit ต้องการให้นักพัฒนาสนใจไปที่ business logic เท่านั้น ส่วนเรื่องอื่น ๆ ที่ในแต่ละระบบ service ควรมีก็ให้ Go-kit จัดการให้ ยกตัวอย่างความสามารถที่ service ต่าง ๆ ควรมี
  • Rate limit การใช้งาน
  • Logging
  • Metric
  • Tracing
  • Circuit breaker
  • Service discovery
  • Serialization
  • Authentication
ดังนั้นเราลองมาเริ่มต้นทำความรู้จัก Go-kit กันหน่อย เริ่มด้วยการเขียน code ดีกว่า มาเริ่มกันเลย

ขั้นตอนที่ 1 ทำการสร้างส่วนการทำงานหลักหรือ business logic ก่อน

สิ่งที่ควรสร้างคือ กำหนด interface ของ service ก่อน จากนั้นจึงลงมือในส่วนของ implementation ต่อไป ตัวอย่างเป็น Counter Service สำหรับการบวกเลขง่าย ๆ แน่นอนว่า ในส่วนนี้ไม่ได้ใช้อะไรเกี่ยวกับ Go-kit เลยดังนี้ [gist id="a4006a1925e1bb2a61c0039318cafb4e" file="service.go"]

ขั้นตอนที่ 2 สร้างส่วนของ Endpoint ของ service ที่สร้าง

ในส่วนของ Endpoint นั้น Go-kit ได้เตรียมไว้ให้ใช้งาน สิ่งที่เราต้องกำหนดและสร้างขึ้นมาคือ รูปแบบของ request และ response ของการใช้งาน Counter Service ที่สร้างไว้ รวมไปถึงการจัดการข้อมูลในรูปแบบ JSON ดังนั้นจำเป็นต้องมีการ decode request และ encode response ด้วยดังนี้ [gist id="a4006a1925e1bb2a61c0039318cafb4e" file="counter_endpoint.go"]

ขั้นตอนที่ 3 ทำการสร้างส่วน Middleware

ในส่วนนี้จะทำการสร้าง web server ขึ้นมา และสามารถใส่ความสามารถต่าง ๆ เข้าไป ทั้ง endpoint ทั้ง decode/encode ดังนี้ [gist id="a4006a1925e1bb2a61c0039318cafb4e" file="main.go"]

ขั้นตอนที่ 4 ทำการทดสอบ service ที่สร้าง

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

ขั้นตอนที่ 5 ใส่ความสามารถต่าง ๆ เข้าไปยัง Middleware/Endpoint ของเรา

ยกตัวอย่างเช่น การใส่ rate limit เข้าไป เพื่อกำหนดจำนวนการเรียกใช้ service เช่นกำหนดให้เรียกใช้งานต่อนาทีเพียงครั้งเดียวเท่านั้น ดังนี้ [gist id="a4006a1925e1bb2a61c0039318cafb4e" file="main2.go"] จากนั้นทดลองใช้งานจะเจอ error แบบนี้ [gist id="a4006a1925e1bb2a61c0039318cafb4e" file="2.txt"]

เพียงเท่านี้เราก็สามารถสร้าง service ด้วย Go-kit ได้แล้วนะ

เหมือนกับการต่อ LEGO เลย แต่ยังมีความสามารถอื่น ๆ อีกทั้ง ขอให้สนุกกับการ coding ครับ ตัวอย่าง source code ทั้งหมดอยู่ที่ Github::Up1

สวัสดี Clojure มาเริ่มต้นเรียนรู้กัน ?

$
0
0

จากหนังสือ Getting Clojure ออก beta version มา (Build your functional skills one idea at a time) ซึ่งแบ่งเนื้อหาเป็น 3 ระดับคือ Basic, Intermediate และ Advance พบว่ามีให้อ่านฟรี ๆ 3 บทคือ เนื่องจากไม่เคยเขียนภาษานี้เลย ดังนั้นก็ต้องเริ่มด้วย Hello Clojure สิ เริ่มกันเลย ในบทแรกนี้เป็นพื้นฐานสุด ๆ ของภาษา Clojure ซึ่งในหนังสือใช้คำว่า Very Basic !! ประกอบไปด้วย syntax, data type และ function ไม่ต้องเรียนรู้เยอะ รู้เท่าที่จะเริ่มต้นได้ก่อนก็พอ

ก่อนจะเริ่มต้นอ่าน ผู้เขียนได้บอกไว้ 2 ข้อซึ่งน่าสนใจคือ

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

ดังนั้นมาเริ่มเขียนดีกว่าจาก Very Basic

ก่อนอื่นต้องเตรียมเครื่องมือในการพัฒนาให้เรียบร้อย (Development tool) แต่ว่ามีทางเลือกเยอะเลยนะ แต่ในหนังสือจะใช้เครื่องมือชื่อว่า Leiningen อ่านว่า "LINE-ing-en"

ดังนั้นขั้นตอนแรกก็ติดตั้ง Leiningen ก่อนเลย

ใช้เวลานิดนึงนะครับ ผลที่ได้ก็ตามนี้ [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="1.txt"] เมื่อเครื่องมือพร้อมก็ต้อง Hello World สิ ใช้งานผ่าน REPL ของ Leiningen นั่นเองดังนี้ [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="2.txt"] คำอธิบาย
  • ข้อมูล string จะอยู่ภายในเครื่องหมาย double quote
  • comment ใช้เครื่องหมาย semicolon (;)
  • println คือชื่อ function ที่ถูกสร้างไว้ให้ใช้งานจาก Clojure
  • จะเห็นว่า การเรียกใช้งาน function จะอยู่ใน ( ... ) เสมอ นี่คือรูปแบบการเรียกใช้ function นะ
โดยปกติการเรียกใช้งาน function จะเป็น println(“Hello World”) นี่คืออีกเรื่องที่ นักพัฒนาต้องปรับเปลี่ยนและใช้เวลาในการฝึกพอควร !! มาดูการเรียกใช้งาน function อื่น ๆ บ้าง [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="3.txt"]
มาถึงตรงนี้ทำให้เราน่าจะพอคุ้นเคยกับตัวภาษามันบ้าง บางคนบอกว่า เลิกดีกว่า แต่ทนหน่อยนะ ไปต่อกัน

เรื่องต่อไปก็พวก บวก ลบ คูณ หาร

แน่นอนว่าจะขัดแย้งกับรูปแบบการเขียนแบบทั่วไป ที่มักจะมีรูปแบบเป็น infix นั่นคือ 1 + 2 = 3 แต่ใน Clojure มันคือ (+ 1 2) นี่มัน prefix ชัด ๆๆ !! มาลองฝึกกัน [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="4.txt"] ซึ่งมักจะมีคำถามเกี่ยวกับรูปแบบของภาษา ว่าทำไมต้องเป็น prefix ด้วย ? เหตุผลคือ ลำดับการทำงานต้องเหมือนการพูด ว่าคุณจะทำอะไร ไม่ใช่ 1 บวก 2 แต่ต้องพูดว่า เราจะบวก (+) เลข 1 เลข 2 นี่คือสิ่งที่ Clojure บอกว่ามันคือ Simplicity นั่นเอง

การประกาศตัวแปรต่าง ๆ และกำหนดค่า

ในภาษา Clojure นั้นมีแนวทางที่ต่างออกไป แต่มันดูตรงไปตรงมา มีรูปแบบดังนี้ [code] (def symbol value) [/code] คำอธิบาย
  • symbol เทียบง่าย ๆ คือ ชื่อตัวแปรนั่นเอง
  • value คือ ค่าที่ต้องการจัดเก็บ หรือเป็น expression ก็ได้ ซึ่งจะถูก evaluate หรือประมวลผล
  • def คือการเชื่อมโยงหรือ binding ระหว่าง symbol และ value เข้าด้วยกัน
มาดูตัวอย่างการใช้งาน [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="5.txt"] สิ่งที่น่าสนใจคือ symbol นั่นเอง ปกติชื่อตัวแปรจะมีข้อจำกัดมากมาย แต่ใน symbol นั้นสามารถตั้งชื่อแบบนี้ได้ this&that|other*hellM*re การตั้งชื่อ symbol มีกฏนิดหน่อย ยกตัวอย่างเช่น ไม่สามารถใช้ (, ), [, ], @ และ ^ เนื่องจากถูกใช้ในตัวภาษาไปแล้ว รวมทั้งไม่สามารถนำหน้าด้วยตัวเลขและ colon (:) ได้เนื่องจากคือ keyword [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="6.txt"]
ใน community ของ Clojure นิยมใช้ convention เรียกว่า kebab case ยกตัวอย่างเช่น all-lowwer-case-with-words-separated-by-dashes

การสร้าง function

มาถึงอีกเรื่องที่น่าสนใจคือ การสร้าง function สามารถเขียนได้ดังนี้ โดยกลับมาที่ hello world กัน [gist id="ae5a6338a28c7c619f6dbb279efaf94e" file="7.txt"] คำอธิบาย
  • ในการประกาศ function จะใช้ defn
  • parameter ของ function จะอยู่ใน [ parameter1 parameter2 ]
  • แต่ละ parameter ไม่จำเป็นต้องมีเครื่องหมาย comma คั่น เพียงใช้ spacebar ก็ได้
  • แต่สามารถใส่ comma ไปได้นะ ซึ่ง Clojure จะมองว่า comma คือ whitespace แต่เขาไม่ใส่กันนะ
  • จากนั้นในส่วนต่อมาคือ body ของการทำงาน ซึ่งจะเรียกว่า expression อยู่ในเครื่องหมาย ( expression )
  • จากตัวอย่างสามารถเขียนอยู่ในบรรทัดเดียวกันหรือแยกบรรทัดได้ ซึ่งขึ้นบรรทัดใหม่นั้น จะถูกมองเป็น whitespace
  • ถ้า function มีการทำงานยาว ๆ มักจะเว้นบรรทัด
  • ในแต่ละชั้นของการทำงานจะขึ้นด้วย 2 spacebar (ไม่เป็น tab นะ)
  • อีกอย่าง การ return ค่าออกจาก function จะไม่มี keyword return เหมือนที่เคยเขียนกันมา
  • โดยที่ expression สุดท้ายจะถูก return ออกจาก function นั้น ๆ เอง
ที่สำคัญคือ ไม่มีการประกาศชนิดของตัวแปรใด ๆ เลย นั่นหมายความว่า ชนิดของตัวแปรจะถูกกำหนดเมื่อทำการกำหนดค่าให้ครั้งแรก ซึ่งไม่สามารถเปลี่ยนชนิดได้อีกเลย นี่คือสิ่งที่ Clojure เลือก เพื่อให้มีความยืดหยุ่นและกระชับ

มาถึงตรงนี้ก็จบในเรื่องแรก

สำหรับเริ่มต้นศึกษาภาษา Clojure ในช่วงวันหยุดสุดสัปดาห์ อย่างน้อยก็ Hello World ได้นะ
ชอบประโยคแรกของหนังสือ เลยเอามาใส่ตอนท้ายของการสรุปคือ This is where the FUN starts …
ขอให้สนุกกับการ coding ครับ

สรุป 6 เรื่องน่าคิดสำหรับ Microservices

$
0
0

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

เรื่องที่ 1 Multiple rate of change

คำถามแรกที่ต้องตอบให้ได้ก่อน ในแต่ละส่วนของระบบนั้นมีการเปลี่ยนแปลงอย่างไร ช้า เร็ว บ่อยเพียงใด ? แต่ละส่วนการทำงานมีทิศทางหรือเป้าหมายอย่างไรบ้าง ? เป็นคำถามที่ช่วยเหลือให้เราสามารถแบ่งส่วนการทำงานออกจากกัน ในแต่ละส่วนการทำงานเราจะเรียกว่า Microservices ซึ่งแต่ละ service จะมี lifecycle ต่างและเป็นอิสระแก่กัน ยกตัวอย่างระบบ e-commerce ซึ่งเป็นระบบ monolith เป็นดังนี้ จากคำถามข้างต้น อาจจะตอบได้ดังนี้
  • ระบบ Cart, Inventory, Order และ Account ไม่เปลี่ยนบ่อยนะ
  • ระบบ Recommendation นั่นอยู่ในช่วงการทดลอง ดังนั้นเปลี่ยนบ่อยมาก ๆ
  • ระบบ Search ต้องปรับปรุงระบบอยู่เป็นประจำ
ดังนั้นเราสามารถแบ่งส่วนการทำงานออกเป็น 2 ส่วน ซึ่งส่งมอบคุณค่าทาง business สูงมาก รวมทั้งช่วยให้ทีมพัฒนาพัฒนาได้ง่าย และ ส่งมอบได้บ่อยขึ้นอีกด้วย แสดงดังรูป

เรื่องที่ 2 Independent Lifecycle

แต่ละส่วนการทำงานเป็นอิสระแก่กันนั่นหมายความว่า มี repository สำหรับจัดการ source code แยกออกไป มี CI/CD process แยกออกไป มีการทดสอบแยกออกไป ผลที่ตามมาคือ ขนาดหรือการทำงานของ service หรือส่วนการทำงานนั้นจะน้อยและเล็ก ดังนั้นเวลาในการทดสอบก็จะน้อยลงไป ถ้า service คุณใช้เวลาการทดสอบนาน แสดงว่ามาผิดทางแน่นอน แต่การทดสอบไม่ใช่เหตุผลหลักในแยก service ออกมา แต่สิ่งที่ต้องอให้ความสนใจคือ business value ยกตัวอย่างเช่น ถ้า business ต้องการเพิ่มความสามารถใหม่เข้าไปยังระบบเดิม แต่ business ต้องการทดลองตลาดให้เร็วที่สุด แต่ทางฝั่ง technical/development ตกลับต้องใช้เวลานาน ในการเพิ่มความสามารถใหม่เข้าไปยังระบบเดิม หรือ Monilith พูดตรง ๆ คือไม่ทันกิน ดังนั้นสิ่งที่น่าลองทำคือ ในส่วนของ feature ใหม่ สามารถแยกออกไปเป็น service ใหม่ ที่มีสิ่งต่าง ๆ เป็นของตัวเอง น่าจะทำให้เรียนรู้ได้เร็ว น่าจะทำให้พัฒนาได้เร็ว ถ้าผลการใช้งานพบว่า ไม่เป็นไปตามที่ business คาดคิด ก็สามารถลบทิ้งไปหรือโยนทิ้งไปได้ง่าย ๆ เลย แสดงดังรูป

เรื่องที่ 3 Independent Scalability

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

เรื่องที่ 4 Isolated Failure

ว่าด้วยเรื่องของการทำงานที่ผิดพลาด และ ระบบล่ม ยกตัวอย่างเช่น ถ้ามีส่วนการทำงานที่ใช้งานเกิดข้อผิดพลาดหรือล่ม เราจะจัดการหรือรับมืออย่างไร ? ยกตัวอย่างเช่นการทำงานในส่วนของระบบ Inventory ซึ่งต้องทำงานร่วมกับ Legacy system เช่นระบบ Warehouse ที่เก่า ๆ แน่นอนว่า ระบบนี้อาจจะล่มหรือมีปัญหาบ่อยมาก ๆ (ระบบ monitoring จะบอกเองนะ) ดังนั้นเราสามารถแยกส่วนการทำงานนี้ออกมาเป็น service ใหม่ เพื่อให้ดูแลรักษาง่ายขึ้น ทั้งการทำ redundancy ทั้งการทำ caching

เรื่องที่ 5 ต้องไม่ยึดติดกับ External service/dependency

บ่อยครั้งที่แต่ละ service ต้องทำงานกับ External service/dependency สิ่งที่ควรทำคือ อย่าเรียกใช้งาน service/dependency เหล่านั้นโดยตรง เนื่องจากมันเปลี่ยนแปลงบ่อย เนื่องจากเกิดความผิดพลาดบ่อย ดังนั้นสิ่งที่ควรทำคือ สร้าง layer หรือ abstraction layer ขึ้นมา เพื่อให้ service เรียกใช้งานได้ง่ายขึ้น และยังซ่อนความซับซ้อนต่าง ๆ อีกด้วย และถ้ามีการเปลี่ยนแปลงก็ทำเฉพาะส่วนที่ซ่อนไว้ โดยไม่กระทบต่อผู้ใช้งาน หรือ ให้กระทบน้อยที่สุด

เรื่องที่ 6 Choose the Tech for the Job

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

สุดท้ายเรื่องที่สำคัญมาก ๆ คือ วัฒนธรรมขององค์กร (Culture)

โครงสร้างขององค์กรที่เป็นอยู่ มันเอื้อต่อแนวทางของ Microservices หรือไม่ ? Microservices ว่าด้วยเรื่องการทำงานี่เล็ก คล่องตัว และเปลี่ยนบ่อย ๆ ซึ่งจะไม่มีคำว่า freeze code, big bang, merge code/integrate code !!
ยิ่งถ้านำแนวคิด Microservices มาใช้กับรูปแบบการพัฒนาแบบ Waterfall แล้ว จะยิ่งไม่เห็นผลประโยชน์ใด ๆ จาก Microservies เลย
ยกตัวอย่างเช่นการ Provisioning infrastructure ของระบบงาน ทีมสามารถทำการสร้างหรือเลือกสิ่งที่ต้องการด้วยตัวเอง ซึ่งทำให้ง่ายต่อการพัฒนา ทดสอบ และ deploy มันง่ายและปลอดภัยต่อการทดลองและเรียนรู้สิ่งใหม่ ๆ
ลองคิดดูสิว่า ถ้าการ Provisioning infrastructure ใช้เวลาเป็นสัปดาห์ เป็นเดือน คิดว่าแนวคิด Microservices จะมีประโยชน์อะไร ?

สิ่งที่ควรให้ความสนใจกว่า Microservices คือ

สิ่งที่ทำไปนั้นมีประโยชน์ต่อ business อย่างไร สิ่งที่ทำไปนั้นมีประโยชน์ต่อ technical หรือทีมพัฒนาอย่างไร ? (Delivery team) ถ้าไม่มีประโยชน์อะไรเลย ก็อย่าไปทำ เสียเวลา เสียเงินโดยเปล่าประโยชน์ ขอให้สนุกกับการ coding ครับ

[The Clean Coder] เรื่องของ Test Strategy

$
0
0

จากหนังสือ The Clean Coder นั้น มีเรื่องที่น่าสนใจสำหรับ Professional developer มากมาย หนึ่งในนั้นคือ "Professional developer test their code” การทดสอบ code ที่เขียนเป็นสิ่งที่ดี แต่มันไม่ได้ง่ายแบบที่พูดนะสิ ดังนั้นต้องเขียนแบบไหน เท่าไร ถึงจะดี
ก่อนอื่นต้องเริ่มด้วย Test Strategy ที่ดี มาเริ่มเรียนรู้กัน
หัวข้อแรกคือ QA (Quality Assurance) ในหนังสือบอกไว้ว่า QA should find nothing QA is part of the team QA as specifier QA as characterizer

QA should find nothing

หมายความว่า ถ้ายังแยกทีม Dev และ QA/Tester ออกจากกัน ผลที่ตามมาคือ ความน่ากลัวและสิ้นเปลืองอย่างมาก เหมือนเกมส์แมวจับหนู ซึ่งเป็นขั้นตอนการค้นหา แต่สิ่งที่ควรเกิดขึ้นคือ QA/Tester ควรถามและบอกว่า มีอะไรบ้างที่จะเกิดขึ้น จะทดสอบอย่างไร ขั้นตอนเป็นอย่างไร ก่อนที่จะเริ่มต้นพัฒนา นี่คือสิ่งที่ควรต้องเกิดขึ้น เพื่อป้องกันปัญหานั่นเอง ทำให้เกิด QA should find nothing

QA is part of the team

หมายความว่าทีม Dev และ QA/Tester ต้องทำงานร่วมกัน ไปด้วยกัน ผิดด้วยกัน เพื่อช่วยกันทำให้มั่นใจว่า ระบบมีคุณภาพ ซึ่งหน้าที่ของ QA ในทีมนั้นควรทำตัวเป็น specifier และ characterizer ?

QA as specifier

การที่ต้องทำงานร่วมกับฝ่าย business เพื่อสร้าง automated acceptance test มันก็คือ specification และ requirement ที่แท้จริงของระบบนั่นเอง เป็นการแปลงข้อมูลจาก requirement จากฝั่ง business มาเป็นข้อมูลฝั่งพัฒนา เพื่อทำให้เข้าใจความต้องการและการทำงานของระบบแบบชัดเจน ไม่ต้องเสียเวลามานั่งตีความ ซึ่งในการทำงานจริง ๆ นั้น ฝั่ง business จะเขียน test caseเฉพาะ happy path ส่วนฝั่ง QA จะเพิ่มเติมส่วนที่ขาดหายไปทั้ง unhappy path, edge case เป็นต้น

QA as characterizer

จะใช้แนวปฏิบัติจาก Exploratory Testing สำหรับดูพฤติกรรมการทำงานจริง ๆ ของระบบว่าทำงานอย่างไร จากนั้นทำการสรุปผลไปยังทีมพัฒนาและทีม business QA นั้นไม่ได้มีหน้าที่ในการแปลหรืออธิบาย requirement แต่ต้องทำการระบุให้ได้ว่า ระบบจริง ๆ มันทำงานและมีพฤติกรรมอย่างไร

เรื่องที่ 2 คือ The Test Automation Pyramid

เป็นเรื่องที่คนที่มีความเกี่ยวข้องในการพัฒนา software น่าจะเข้าใจเป็นอย่างดี แม้จะนำไปใช้หรือไม่ใช้ก็ตาม โดยในหนังสือจะเน้นมาก ๆ คือ
  • Professional developer ต้องให้ความสำคัญกับ TDD สำหรับการสร้าง unit test
  • Professional development team ต้องใช้ acceptance test สำหรับระบบการทำงานของระบบ
  • Professional development team ต้องใช้ Continuous Integration สำหรับการทำ regression
แต่ Unit test และ Acceptance test มันเป็นเพียงการทดสอบส่วนหนึ่งเท่านั้นเอง เป้าหมายหลักของเราคือ QA should find nothing ดังนั้นจึงต้องมีการทดสอบอื่น ๆ อีกมากมาย ซึ่งทำการสรุปไว้ใน The Test Automation Pyramid นั่นเอง แสดงดังรูป การทดสอบทั้งหมดนี้ เพื่อช่วยทำให้แน่ใจว่า ระบบงานสามารถตอบรับการทำงานจากผู้ใช้งานได้ และอย่างถูกต้องตามที่คาดหวัง รวมทั้งทำให้เข้าใจการทำงานและพฤติกรรมต่าง ๆ ของระบบ สุดท้ายการทดสอบต่าง ๆ ควรต้องทำงานอยู่อย่างเสมอ ควรทำงานได้อย่างรวดเร็ว เพื่อให้ได้รับ feedback ที่รวดเร็ว เพื่อทำให้แน่ใจว่าระบบงานพร้อมอยู่ตลอดเวลา
วันนี้ QA should find nothing แล้วหรือยัง ?
ขอให้สนุกกับการ coding ครับ

สิ่งที่ได้รับจาก Angular Developers Thailand Meetup ประจำเดือนมกราคม 2018

$
0
0

เมื่อวานตอนเย็นได้ไปร่วมงาน Angular Developers Thailand Meetup January 2018 จากลุ่ม Angular Developer Thailand จัดที่ HANGAR Coworking Space by DTAC โดยครั้งที่มีหัวข้อดังนี้
  • Create package on NPM
  • Make readable code in Angular with Lettable(Pipe) Operator
  • Angular CI/CD with DroneCI
เนื่องจากไปช้าจึงได้ฟังเฉพาะหัวข้อที่ 2 ปลาย ๆ กับหัวข้อที่ 3 และมีการให้ถามตอบคำถามต่าง ๆ จากคนที่เข้ามาพูดและฟัง มีหลายอย่างที่น่าสนใจดังนี้

สิ่งที่ได้รับจาก Make readable code in Angular with Lettable(Pipe) Operator

ซึ่งใน RxJs 6 ขึ้นไปนั้นเปลี่ยนจาก Lettable ไปเป็น Pipeable operator แล้วนะ ความจริงจังของเอกสารคือ Stop trying to make "lettable” happen มาดูรายละเอียดกันหน่อย เนื่องจากไม่เคยเขียนหรือรู้จักเรื่องพวกนี้เลย ดังนั้นก็ทำการจด ๆ ถ่ายรูปเอาไว้ เพื่อนำมาศึกษาต่อ !! หลังจากที่ไปศึกษาเพิ่มเติม ก็ได้เรื่องประมาณนี้ (ไม่แน่ใจว่าถูกหรือไม่ !!) Lettable/Pipeable operator นั้น เป็นแนวทางใหม่ในการ compose observrable ต่าง ๆ เข้าด้วยกัน ซึ่งมีข้อดีทั้งนักพัฒนาและผู้สร้าง library ด้วย
แต่ก่อนอื่นต้องไปดูก่อนว่า วิธีการ compose observrable ก่อนหน้าที่จะเป็น Lettable/Pipeable นั้นเป็นมาอย่างไร ? แล้วทำไมต้องเปลี่ยนและมาใช้วิธีการใหม่ ๆ ด้วย

เริ่มจากการ bundle ทุกอย่างมาใน RxJS library เลย (Bundle All)

นั่นคือ นักพัฒนาเพียงทำการ import rxjs มาเพียงตัวเดียว ก็สามารถใช้ operator ทั้งหมดผ่าน Observable.prototype ไปเลย สามารถทำการ compose การทำงานได้ดังนี้ [gist id="39c3ea6576288c90773a9331cfbc930f" file="1.js"] คำอธิบาย ทำการดึงข้อมูล name มาจาก REST API ที่กำหนด ซึ่งมี 3 ขั้นตอนคือ getJSON, map และ subscribe ข้อเสียคือ เราใช้งานเพียง 3 operator เท่านั้น แต่ดันมีมาให้ใช้ทั้งหมดเลย (ขนาดของระบบหลังจากการ build ด้วยตัว bundler เช่น Webpack) ดังนั้นทำให้ขนาดของ app เรานั้นใหญ่ขึ้นแบบไร้ประโยชน์ แถมส่งผลต่อประสิทธิภาพการทำงาน

ต่อมาเพื่อแก้ไขปัญหาดังกล่าว RxJS จึงเพิ่ม directory ชื่อว่า add เข้ามา (Prototype Patching)

ช่วยทำให้ผู้ใช้งานทำการ import operation เฉพาะที่ต้องการได้ [gist id="39c3ea6576288c90773a9331cfbc930f" file="2.js"] ข้อเสียที่ตามมาคือ นักพัฒนาทำการ import เพียบเลย !!

สิ่งที่เกิดขึ้น ตอน import งงมาก ๆ ว่า operation แต่ละตัวมาจากไหนบ้าง ?

ดังนั้นมาลองเปลี่ยนการ import และการเขียนหน่อยสิ [gist id="39c3ea6576288c90773a9331cfbc930f" file="3.js"] ดูอ่านง่ายขึ้นนะ แต่ทำไมต้องเขียนเยอะด้วย ? ตรงนี้อยู่ที่ความชอบแล้วนะ

ต่อมาถึงคิวของ Lettable หรือ Pipeable operator กันบ้าง

สิ่งที่น่าสนใจคือ ทำการ import operator ต่าง ๆ จาก directory operator ได้เลย ซึ่งไม่ต้องกลัวว่า operator ที่ไม่ได้ใช้จะถูกรวมเข้ามาเหมือนวิธีการแรก เพราะว่าวิธีการนี้สนับสนุนจาก Tree-shaking (Dead code elimination จาก Webpack) นั่นคือมั่นใจได้ว่า มีเท่าที่ใช้แน่นอน และทำให้ขนาดของระบบเล็กลงอีกด้วย ลองอ่านเพิ่มเติมได้จาก RxJS — Reduce Angular app bundle size using lettable operators อีกทั้งยังทำให้อ่านง่ายขึ้นอีกด้วย (Readable) เพื่อความง่ายในการใช้งาน จะมี method pipe() ใหม่มาให้ ซึ่งสามารถรวมหรือเรียงลำดับการทำงานของแต่ละ operator ได้เลย มาดูกัน [gist id="39c3ea6576288c90773a9331cfbc930f" file="4.js"] สิ่งที่น่าแปลกใจหน่อยคือ ทำไมถึงเรียกว่า Lettable operator ด้วย ? นำมาจาก let operator ใน RxJS นั่นเอง ซึ่งมันทำงานคล้าย ๆ กับ map operator แต่ทำเพียงการรับค่าและ return ค่าเป็น observable เท่านั้น อีกทั้งมีประโยชน์ต่อการ compose การทำงานต่าง ๆ เข้าด้วยกันอีกด้วย แต่กลับไม่ค่อยมีใครใช้งานมากนัก !! ชื่อ Lettable แต่ทำไมต้องเรียกใช้ method pipe() ด้วย ? ตรงนี้นี่เองที่ทำให้เกิดความสับสน ระหว่างชื่อและการใช้งาน ดังนั้นจึงเปลี่ยน Pipeable opertaor แทน

สิ่งที่ได้รับจาก CI/CD with DroneCI

เริ่มต้นว่าด้วยเรื่องของ CI (Continuous Integration) แน่นอนว่าเป็นแนวปฏิบัติที่ทีมพัฒนา software จำเป็นต้องมี ซึ่งมันคือแนวปฏิบัติเพื่อ
  • ช่วยหาข้อผิดพลาดได้ทันที ไม่ต้องไปรอนาน
  • ทำให้เราสามารถหาต้นเหตุของปัญหาได้เร็ว
  • ส่งมอบระบบงานได้เร็วและบ่อย
จากนั้นเพื่อทำให้สามารถทำงานได้เร็วตามที่ต้องการ จึงต้องมีเครื่องมือช่วยเหลือ ซึ่งมีให้เลือกมากมายโดยหนึ่งในนั้นคือ DroneCI ทำต้องใช้ DroneCI ?
  • สนับสนุน Git provider ทั้ง Github, Bitbucket, Gitlab, Gogs, Gitea และ Coding เป็นต้น
  • เร็วและง่าย
  • Docker friendly นั่นคือ configuration ต่าง ๆ เหมือน docker เลย พร้อมทั้งทำงานกับ docker ได้ง่าย
  • ง่ายต่อการขยายระบบ
  • ฟรีต่อการใช้งาน ที่สำคัญสามารถนำมาติดตั้งเองได้
ข้อเสียหลัก ๆ คือ เรื่องของการติดตั้ง และ เริ่มใช้งาน ตลอดจนเรื่องของ community ที่ยังเล็ก เนื่องจากอยู่ในช่วงเริ่มต้นของระบบนั่นเอง แต่ก็น่าจะเป็นเรื่องปกติไปแล้ว ใช้ก่อนเจ็บก่อน สิ่งที่สำคัญของระบบ CI/CD คือ Pipeline โดยใน DroneCI นั้นสามารถเขียนในรูปแบบไฟล์ YML (.drone.yml) เหมือนหรือคล้ายกับ docker-compose ของ Docker เลย การ demo เป็นระบบ TODO List ซึ่งพัฒนาด้วย Angular ซึ่งมีขั้นตอนของ pipeline ดังนี้
  1. ทำการ build ในทุก ๆ brach ที่มีการเปลี่ยนแปลง ประกอบไปด้วย Line, test และ build
  2. ทำการ publish ระบบในรูปแบบของ Docker Image และ push ไปยัง Docker Registry (Docker Hub) ต้องกำหนด branch ที่ต้องการ
  3. ทำการ deploy ไปยัง server ที่ต้องการ โดยทำการ pull Docker image มาจาก Docker Registry

ปิดท้ายด้วยช่วงถามตอบ

ก็มีคำถามที่น่าสนใจเช่น
  • รูปแบบ Git commit message ที่ดีควรเป็นอย่างไร
  • การเริ่มต้นศึกษา Angular และ TypeScript
  • การโน้มน้าวใจให้ทีมมาใช้งาน Angular
ขอให้สนุกกับการ coding ครับ

เมื่อเราสามารถนำ Trello board มาแสดงใน Bitbucket ได้

$
0
0

อ่านเจอข่าวว่า Bitbucket นั้นสามารถนำ board จาก Trello มาแสดงได้แล้วนะ ซึ่งทำให้ Bitbucket มีความสามารถพอ ๆ กับ project ใน Github เลยนะ ดังนั้นลองมาใช้ดูกันหน่อย

การใช้งานก็ไม่ยาก

เพียงเข้าไปที่ Repository ใน Bitbucket ซึ่งจะมี menu Board ดังรูป จากนั้นทำการเชื่อมต่อกับ Trello ซึ่งสามารถสร้างหรือเลือก Board ที่มีอยู่แล้วได้ ทำการกำหนดสิทธิ์ในการเข้าใช้งาน Board นั้น ๆ มีทั้ง Admin, Write และ Read ให้เลือก จากนั้นก็จะมี Board สวย ๆ จาก Trello มาแสดงใน Repository ใน Bitbucket แล้วนะ แต่ก็เป็นเพียงการนำ Board มาแสดงเท่านั้นเอง ยังไม่ integrate กันดีเท่าไรนัก ซึ่งตรงนี้ Github ทำได้ดีกว่า แต่ Board ของ Trello มันสวยนะเออ ดังนั้นลองมาใช้กันดูครับ สะดวกขึ้นเยอะ ไม่ต้องเปิดสลับไปมาแล้วนะ พอลองไปใน Card แต่ละใบ จะพบว่า มีความสามารถดังนี้อีกด้วย เช่นการ attach เข้าไปยัง Pull Request/Branch/Commit ใน repository ที่ Bitbucket ได้อีกด้วย

สิ่งที่แอบเห็นใน Bitbucket คือมี Pipelines ให้ด้วย

อาจจะมีมานานแล้ว ก็ผมเพิ่มเคยเห็น นั่นคือ เราสามารถใส่ pipeline ของกระบวนการ build ระบบ ตั้งแต่การ compile -> test -> deploy แบบอัตโนมัติได้เลย ซึ่งใช้งานง่าย ๆ ดังนี้ ที่สำคัญสนับสนุนภาษาโปรแกรมเพียบ ตัวอย่างระบบงานพัฒนาด้วยภาษา Go ก็สามารถทำการเพิ่ม config ได้ดังนี้ จากนั้นทำการ run สิครับ ได้ผลการทำงานดังนี้ เป็นความสามารถที่น่าสนใจ ดังนั้นลองใช้งานกันดูครับ มันง่ายมาก ๆ มาถึงตรงนี้ Bitbucket น่าใช้ขึ้นมาเป็นกองครับ  

เมื่อคุณค่าของ Continuous Integation ถูกทำลาย

$
0
0

ว่าด้วยเรื่อง Continuous Integration นั้น มันช่วยลดปัญหา หรือ ช่วยหาข้อผิดพลาดของระบบ ที่มีการเปลี่ยนแปลงอยู่ตลอดเวลา แน่นอนว่ามีคุณค่า (Value) มากมาย แต่บ่อยครั้งกลับพบว่า คุณค่าเหล่านั้นของ Continuous Integration ถูกลดค่าหรือทำลายลงไป ดังนั้นมาดูกันหน่อย

เริ่มต้นด้วยคุณค่าของ Continuous Integration (CI)

ประกอบไปด้วย ลดความเสี่ยงของการพัฒนา ทั้งการตรวจจับข้อผิดพลาดได้รวดเร็ว นั่นคือต้องมีกระบวนการทดสอบที่ดีและเร็วด้วย ทั้งการวัดค่าต่าง ๆ ของระบบงาน เปรียบเสมือนการตรวจสุขภาพประจำปี แต่สำหรับระบบงาน เราทำการตรวจสุขภาพในทุก ๆ การเปลี่ยนแปลง ทั้งปัญหาจากความไม่แน่ใจ หรือ จากข้อสันนิษฐานต่าง ๆ บ่อยครั้งทีมพัฒนามักจะคิดไปเองว่า สิ่งที่ทำลงไป ไม่กระทบส่วนไหนหรอก เช่นการเปลี่ยนแปลง code การเปลี่ยน configuration การแก้ไข database ลดกระบวนการทำงานแบบ manual ลงไป ซึ่งลดทั้งเวลา ค่าใช้จ่าย และความพยายามต่าง ๆ ดูเหมือนจะดีนะ แต่เรากลับพบว่า ในการพัฒนาระบบงานนั้น มีกระบวนการทำงานที่ซ้ำ ๆ เยอะมาก ทั้งการ compile code ทั้งการแก้ไข database ทั้งการทดสอบ ทั้งการ deployment มันแปลก ๆ นะ สร้างระบบงานหรือ software ที่พร้อม deploy ได้เสมอ ทำให้เห็นภาพรวมที่แท้จริงของระบบว่าเป็นอย่างไร ? ช่วยให้การตัดสินใจเรื่องต่าง ๆ ดีขึ้น รวมทั้งทีมพัฒนามีความเชื่อมั่นต่อระบบที่พัฒนา

แต่เมื่อมีการนำ Continuous Integration มาใช้กลับมีแต่ข้อเสียมากกว่าข้อดี !!

ส่งผลให้ไม่มีใครเห็นประโยชน์ ส่งผลให้เลิกใช้งานไปในที่สุด มาดูตัวอย่างของปัญหากันดู ระบบ Continuous Integration เพิ่มงานเรื่องการดูแลรักษา นั่นคือการเริ่มเปลี่ยนจาก manual process มาเป็น automation process โดยไม่ได้เปลี่ยนแปลง หรือ ปรับปรุง process อะไรเลย process การทำงานมันวุ่นวาย เทอะทะมาก ๆ ผลที่ตามมาคือ ต้องใช้เวลามากมายไปกับ การพยายามทำให้ manual process มาเป็น automation process มีการทำงานที่ช้า !! นั่นคือ ความเข้าใจผิดอย่างมาก เนื่องจากต้องเริ่มด้วยการออกแบบให้ตรงตามกับระบบงาน จากนั้นต้องเน้นไปที่ process ที่มีประสิทธิภาพ ผลที่ตามมาคือ ระบบ Continuous Integration มีความน่าเชื่อถือ มีส่วนการทำงานที่ผิดพลาดเยอะมาก ๆ ยกตัวอย่างเช่น ในระบบ Continuous Integration มีขั้นตอนการทำงานที่ผิดพลาดเยอะมาก ๆ เช่น นักพัฒนาไม่ทำการทดสอบใด ๆ บนเครื่องตนเอง ก่อนที่จะ commit code ไปยัง version control เลย ทำให้เกิดข้อผิดพลาดในส่วนของระบบ Continuous Integration ทั้ง compile ไม่ผ่าน ทั้งทดสอบไม่ผ่าน ถ้าเป็นเช่นนี้ แสดงว่ามีปัญหาในการ Continuous Integration มาใช้อย่างชัดมาก ๆ นั่นคือ ปัญหาเรื่องความเข้าใจในการทำงานของคน ต้องรีบแก้ไขโดยด่วน ยังไม่พอนะ ระบบที่ต้องทำงานด้วยไม่มีความเสถียร ยิ่งส่งปัญหามากมาย ดังนั้นใครละจะมาแก้ไขปัญหานี้ ? มีการเปลี่ยนแปลงที่มากจนเกินไป Continuous Integration นั้นจะมีประสิทธิภาพสูงมาก ๆ ถ้าการเปลี่ยนแปลงเป็นแบบ incremental คือ ค่อย ๆ เปลี่ยนแปลงทีละเล็กทีละน้อย แต่ถ้ามีการเปลี่ยนแปลงแต่ละครั้งที่มากจนเกินไป เช่นเปลี่ยนการทำงานจากหน้ามือเป็นหลังมือเลย ไม่น่าจะส่งผลดีใด ๆ เลย เนื่องจากต้องเสียเวลามาแก้ไขขั้นตอนการทำงานใหม่ทั้งหมด ระบบ Continuous Integration นั้นต้องมีค่าใช้จ่ายเพิ่ม ทั้งเรื่องของ Hardware และ Software ซึ่งหลาย ๆ ครั้งพบว่า กลุ่มคนที่ดูแลค่าใช้จ่ายของระบบงานมักจะไม่เห็นคุณค่า หรือ ลงทุนมากนัก เพราะว่าไม่เข้าใจ และ ไม่เห็นประโยชน์ คุณค่านั่นเอง ทำให้ไม่มีระบบ หรือ มีก็ทำงานช้ามาก ๆ ปัญหาจากนักพัฒนา เป็นเรื่องที่สำคัญสุด ๆ คือ นักพัฒนา นั่นเอง ถึงแม้จะมีข้อตกลงในการทำงานแล้วก็ตาม ทั้งไม่ชอบ commit การเปลี่ยนแปลงบ่อย ๆ ทั้งไม่ทำการทดสอบการเปลี่ยนแปลงใด ๆ เลย ทั้งไม่มีหรือไม่เขียนชุดการทดสอบ หนักไปกว่านั้น ถ้าพบว่าชุดการทดสอบใดทำงานผิดพลาด ก็ไปลบ หรือ ยกเลิก ไปเลย น่ากลัวมาก ๆ ทั้งมีการใช้ environment ต่าง ๆ ที่แตกต่างกัน

ซึ่งสิ่งเหล่านี้จะทำลายคุณค่าของ Continuous Integration ไปอย่างมาก

วันนี้ระบบ Continuous Integration ของระบบงานคุณเป็นอย่างไร แต่แนะนำว่า ให้ลองทำตามขั้นตอนนี้นะครับ
  1. Identify ระบบจุดที่ต้องการระบบการทำงานแบบอัตโนมัติ
  2. Build สร้าง script สำหรับการทำงาน
  3. Share โดยที่ script ต่าง ๆ เหล่านี้ต้องถูก share หรือจัดเก็บใน version control
  4. Make it continuous นำ script ต่าง ๆ เหล่านี้ไปอยู่ในขั้นตอนการทำงานในระบบ Continuous Integration เพื่อให้ทำงานทุก ๆ ครั้งเมื่อมีการเปลี่ยนแปลงเกิดขึ้น
  5. วนกลับไปข้อ 1 (Continuous Improvement)
ขอให้สนุกกับการ coding ครับ

บันทึกการติดตั้ง Selenium Grid ในแบบต่าง ๆ

$
0
0

Selenium Grid คือสิ่งที่ช่วยทำให้สามารถ run ชุดการทดสอบแบบอัตโนมัติ บน OS และ browser ต่าง ๆ แบบ distributed และ ขนาน (parallel) ได้ง่ายขึ้น ซึ่งช่วยลดเวลาของการทดสอบระบบลงไปเยอะมาก ๆ ดังนั้นมาดูการติดตั้งกันนิดหน่อย ซึ่งบอกเลยว่า มันไม่ได้ยากเลย แต่ที่เหลือยากหมดเลย !!

เริ่มต้นด้วยโครงสร้างของ Selenium Grid กันหน่อย

ประกอบไปด้วย 2 ส่วนคือ 1. Hub ทำหน้าที่รับ request การทดสอบ และ จัดการส่งไปยัง node ต่าง ๆ 2. Node ทำหน้าที่ทดสอบตาม request ต่าง ๆ ซึ่งแต่ละ node มีความสามารถแตกต่างกันไป ตามความต้องการ แสดงดังรูป
ก่อนติดตั้งให้ทำการ Download Selenium Standalone Server มาก่อน ซึ่งในตัวอย่างจะใช้ selenium-server-standalone-3.9.1.jar

ทำการติดตั้งกันดีกว่า

มาดูขั้นตอนการติดตั้งกัน เริ่มจากทำการสร้าง Hub ก่อน ด้วยคำสั่ง [code] $java -jar selenium-server-standalone-3.9.1.jar -role hub [/code] ต่อมาจึงทำการสร้างและ register node ไปยัง Hub ด้วยคำสั่ง ในตัวอย่าง Hub และ Node อยู่ในเครื่องเดียวกันคือ localhost [code] $java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://localhost:4444/grid/register [/code] แต่สิ่งที่ห้ามลืมสำหรับ Node คือกำหนด Web Driver สำหรับ browser แต่ละชนิดด้วย มิเช่นนั้น Node จะไม่สามารถทดสอบตามที่ต้องการได้ ยกตัวอย่างเช่น ให้ Node ทำการทดสอบผ่าน Google Chrome [code] java -jar selenium-server-standalone-3.9.1.jar -role node -hub http://localhost:4444/grid/register -Dwebdriver.chrome.driver=<path to file chromedriver> [/code] เมื่อทุกอย่างเรียบร้อย สามารถตรวจสอบผ่าน Selenium Grid Web Console ได้ดังนี้ การติดตั้งในรูปแบบนี้นั้น ดูแลรักษาไม่ง่ายเลย ทั้งการ download และติดตั้ง dependency ต่าง ๆ ของแต่ละ node ทั้ง process ของ java ที่อาจใช้ memory จนเกิดปัญหา out of memory ได้ ทั้งการจัดการ node ต่าง ๆ แบบ manual เช่น restart node เมื่อเกิดปัญหา ทั้งปัญหาในการดูแลรักษา ทั้งปัญหาเรื่องของการขยายระบบ

ดังนั้นมาลองติดตั้งด้วย Docker กันบ้าง

โดยที่ Selenium ได้เตรียม Docker image ไว้ให้เรียบร้อย ทั้ง Hub และ Node ชนิดต่าง ๆ เช่น Selenium Chrome และ Selenium Firefox ทำให้ไม่ต้องไปติดตั้งสิ่งต่าง ๆ เองเลย สามารถติดตั้งง่าย ๆ ดังนี้ [code] // Start Hub docker container run -d -p 4444:4444 --name selenium-hub selenium/hub // Start Nodes docker container run -d --link selenium-hub:hub selenium/node-chrome docker container run -d --link selenium-hub:hub selenium/node-firefox [/code] ดูง่ายขึ้นไหมละ ? แต่ปัญหาเรื่องการเพิ่มและลด Node ยังยาก รวมไปถึงการ start/stop/restart Node ก็ยังลำบาก

ดังนั้นมาลองใช้งาน Docker compose กันดีกว่า

โดยทั้ง hub และ node สามารถกำหนดใน services ของ Docker compose ได้เลย ดังนี้ [gist id="0aa82fadbf8f70c157f2ede8e1235e9c" file="docker-compose.yml"] จากนั้นทำการติดตั้งด้วยคำสั่ง [code] $docker-compose up [/code] ถ้าต้องการ scale Node ที่ run Google Chrome ให้เป็น 4 node ทำได้ดังนี้ [code] $docker-compose scale chrome=4 [/code] แสดงผลการทำงานดังนี้ เพียงเท่านี้ก็สามารถติดตั้งและใช้งาน Selenium Grid แบบง่าย ๆ ได้แล้ว ดังนั้นอย่าลืมนำ Selenium Grid ไปใช้งานกันนะครับ Reference Website https://github.com/SeleniumHQ/selenium/wiki/Grid2 https://github.com/SeleniumHQ/docker-selenium/wiki/Getting-Started-with-Docker-Compose

[Kotlin for Android] ว่าง ๆ มาดูจำนวน Method ของ Data Class กัน

$
0
0

หลังดูบอลมานั่งเขียน Android app ด้วยภาษา Kotlin กันหน่อย ซึ่งเป็นภาษาที่มีความสามารถที่ดีมากมาย หนึ่งในนั้นคือ Data Class ที่ Java Developer ถือว่าเป็น killer feature เลยนะ เพราะว่า ไม่ต้องมาเขียนหรือ generate getter/setter method เอง ดังนั้นทุกคนก็จะ convert พวก POJO class มาเป็น Data Class กันหมดเลย รู้กันไหมว่า ความสามารถนี้มันมาพร้อม cost นะ มาลองดูกัน

นักพัฒนา Android app ทุกคนรู้ว่า

ทุกสิ่งอย่างที่นำมาใช้ในการพัฒนา Android app นั้น ล้วนมีค่าใช้จ่ายทั้งนั้น เนื่องจากมันส่งผลต่อ จำนวน method ของ app ซึ่ง Android app มีจำกัดให้ 64K method ถ้ามีจำนวนเกินนี้ก็ต้องเข้าสู่โลกของ Multi-Dex นั่นหมายความว่า ต้องใช้เวลาในการ build มากขึ้น ดังนั้น เราจึงควรต้องจัดการให้ดี
โดยปกติการนับจำนวน method นั้น มักจะใช้งาน plugin ชื่อว่า Dexcount gradle plugin

มาดูกันสิว่า Data Class มันเป็นอย่างไรบ้าง ?

เริ่มด้วยการสร้าง Android project ด้วยภาษา Kotlin ใน Android Studio นับจำนวน method ได้ดังนี้ [code] Total methods in app-debug.apk: 23512 (35.88% used) Total fields in app-debug.apk: 11117 (16.96% used) Total classes in app-debug.apk: 2648 (4.04% used) Methods remaining in app-debug.apk: 42023 Fields remaining in app-debug.apk: 54418 Classes remaining in app-debug.apk: 62887 [/code] จากนั้นสร้าง Data class แบบง่าย ๆ ดังนี้ [code] data class User(val id: Int = 0, val firstname: String = "") [/code] ลองนับจำนวน method ได้ดังนี้ [code] Total methods in app-debug.apk: 23524 (35.90% used) Total fields in app-debug.apk: 11119 (16.97% used) Total classes in app-debug.apk: 2649 (4.04% used) Methods remaining in app-debug.apk: 42011 Fields remaining in app-debug.apk: 54416 Classes remaining in app-debug.apk: 62886 [/code]
สิ่งที่เพิ่มขึ้นมาคือ 1 class 2 field 12 method
มาจากไหนตั้ง 12 method นะ ? เยอะใช้ได้เลยนะ
  1. equals()
  2. hashCode()
  3. toString()
  4. copy()
  5. componentN()
  6. กำหนดค่า default argument
  7. primary constructor

ลองไม่ใช้ default argument หน่อยสิ

[code] data class User(val id: Int, val firstname: String) [/code] ผลที่ได้เป็นดังนี้ [code] Total methods in app-debug.apk: 23522 (35.89% used) Total fields in app-debug.apk: 11119 (16.97% used) Total classes in app-debug.apk: 2649 (4.04% used) Methods remaining in app-debug.apk: 42013 Fields remaining in app-debug.apk: 54416 Classes remaining in app-debug.apk: 62886 [/code] จะเห็นว่า จำนวน method ลดลงไป 2 method แสดงว่าแค่ default argument ของแต่ละ field ก็คือ 1 method นะ

ลองเอา keyword data ออกไปหน่อยสิ ?

[code] class User(val id: Int, val firstname: String) [/code] จำนวน method ลดลงไปอีก 7 method !!! นั่นคือเพิ่มจากเริ่มต้นเพียง 3 method เท่านั้น ดังนี้ [code] Total methods in app-debug.apk: 23515 (35.88% used) Total fields in app-debug.apk: 11119 (16.97% used) Total classes in app-debug.apk: 2649 (4.04% used) Methods remaining in app-debug.apk: 42020 Fields remaining in app-debug.apk: 54416 Classes remaining in app-debug.apk: 62886 [/code]

สุดท้ายแล้ว

ก่อนจะใช้งานต้องรู้และเข้าใจก่อน ใช้เท่าที่จำเป็นเท่านั้น เพราะว่าทุกสิ่งอย่างมันมีค่าใช้จ่ายตามมาเสมอ โดยที่ Kotlin library ก็มีจำนวน method ตามนี้

มาใช้งาน Android KTX กันนะ (Preview version)

$
0
0

Android KTX คืออะไร ? คือ เป็นชุดของ API สำหรับการพัฒนา Android application ด้วยภาษา Kotlin ที่อยู่บน Android framework และ Support library ต่าง ๆ มีเป้าหมายเพื่อ ให้สามารถเขียน Kotlin ถูกต้องและกระชับตามหลักของภาษา (Less code, More fun) ดังนั้นมาลองใช้งานกันดู เริ่มด้วยการติดตั้ง Library เข้าไปใน project [code] repositories { google() } dependencies { implementation 'androidx.core:core-ktx:0.1' } [/code] โดยใน Android KTX library นั้นครอบคลุมหลายส่วนเลย เช่น
  • Graphic
  • Annimation
  • Content
  • Database
  • Network
  • Text
  • Time
  • View
ลองใช้งานตามตัวอย่างหน่อยสิ [gist id="be420775789bdf028a7c426d68a92ac0" file="demo.kt"] คำอธิบาย ใช้ package เป็น androidx.* นะ นั่นคือแยกออกมาจาก android โดยสิ้นเชิง โดย library ชุดนี้มี method ทั้งหมด 527 method และในอนาคตของทีมพัฒนาคือ นำ Android KTX ไปใส่ใน Android Suport Library ต่อไป ดังนั้นลองใช้เถอะนะ Reference Websites https://android-developers.googleblog.com/2018/02/introducing-android-ktx-even-sweeter.html https://medium.com/exploring-android/exploring-ktx-for-android-13a369795b51

แปลและสรุปเรื่อง 10 Tips for developers

$
0
0

อ่านเจอบทความที่น่าสนใจเรื่อง 10 Tips for developers ประกอบไปด้วย 10 แนวทางสำหรับมีคุณภาพชีวิตที่ดีขึ้น ซึ่งจำเป็นมาก ๆ สำหรับนักพัฒนา software จึงทำการแปลและสรุปไว้นิดหน่อย 1. Specialize ให้เชื่อว่า งานที่คุณทำนั้นมันเป็นความเชี่ยวชาญเฉพาะทาง มิใช่กรรมกร IT (อันนี้ผมใส่เอง) บริษัทต่าง ๆ จ่ายเงินให้คุณเพราะว่า คุณทำสิ่งที่บริษัทต้องการได้ดี สิ่งที่คุณมีความรู้คือ ความรู้ในเชิงลึก แน่นอนว่า มันดีว่ารู้แบบเป็ด ๆ ไปเสียทุกอย่าง 2. Practice การอ่านหนังสือดี ๆ เป็นส่ิงที่ดี การเรียน course online เป็นสิ่งที่ดี ลองคิดดูถ้าเพียงอ่าน ถ้าเพียงฟัง แต่ไม่ได้ลงมือทำและฝึก ไม่น่าจะดีนะ ดังนั้นการฝึกฝนและลงมือทำเป็นสิ่งที่สำคัญมาก ๆ 3. Personal project เมื่อการลงมือทำและฝึกฝนเป็นสิ่งที่สำคัญ แนะนำให้คิดหรือทำ project ใหม่ ๆ เพื่อให้การฝึกฝนมันสนุกและน่าสนใจ ถ้าไปฝึกในระบบที่ข้อจำกัดเยอะ มันจะน่าเบื่อมาก ๆ รวมทั้งไม่ได้ฝึกฝนอะไรเท่าไร นอกจากแก้ไขปัญหาไปวัน ๆ 4. Read great people การอ่านเป็นสิ่งที่สำคัญมาก ๆ ทั้งการอ่านจาก blog ต่าง ๆ ทั้งการอ่านจาก tweet ใน Twitter ทั้งจากการอ่าน code ใน Github.com ต่อมาก็ลงมือทำนะ 5. Analyze before writing code สำหรับนักพัฒนานั้น ก่อนจะเริ่มเขียน code ควรเริ่มต้นด้วยการวิเคราะห์ และ ทำความเข้าใจก่อนเสมอ บ่อยครั้งพบว่า เราลงมือเขียน code ก่อนทำความเข้าใจ ผลที่ตามมาคือ ทำงานได้เร็ว แต่ข้อผิดพลาดเยอะมาก ๆ 6. Refactor your code การปรับปรุง code ให้ดีขึ้นอย่างสม่ำเสมอ เพื่อทำให้ code นั้นอ่านและทำความเข้าใจได้ง่ายขึ้น เนื่องจากพบว่า นักพัฒนาใช้เวลาในการอ่าน code มากกว่าเขียนเสมอ 7. Meet people พบปะพูดคุยกับคนอื่น ๆ เพื่อแลกเปลี่ยนประสบการณ์ รวมทั้งการไปร่วมงาน ไปพูดในงานต่าง ๆ อีกด้วย 8. Share your knowledge ยิ่งคุณแบ่งปันมากไปเท่าไร ก็ยิ่งได้กลับมาเท่านั้น การสอนก็เช่นเดียวกัน มันทำให้เรียนรู้ได้อย่างรวดเร็ว ทั้งการเขียน blog ทั้งการไปพูด ทั้งการสอน course online 9. Have a normal life คุณไม่ควรนั่งอยู่หน้า computer หรือ electronic device ตลอด 24 ชั่วโมง คุณควรต้องจัดการเวลาให้ดี ทั้งเวลาทำงาน ทั้งเวลาพักผ่อน ทั้งเวลาออกกำลังกาย ทั้งเวลางานอดิเรก ไม่จำเป็นต้องเรียนรู้ทุกสิ่งอย่าง 10. Enjoy สนุกไปกับการเรียนรู้ สนุกไปกับการทำงานในหน้าที่ของตนเอง สนุกกับสิ่งที่ได้ทำ ไม่ใช่เรียนรู้เพราะเงิน แต่เงินมันจะมาจากการเรียนรู้นี่แหละ
ลองถามตัวเองนะว่า วันนี้คุณได้เรรียนรู็อะไรเพิ่มจากเมื่อวานบ้าง ?
ขอให้สนุกกับการ coding ครับ

คำแนะนำสำหรับการเขียน code ในโลกของ Data Science

$
0
0

มีโอกาส review code ของชาว Data Science หรือบางที่เรียกว่า Data Science Team/Project ซึ่ง code ต่าง ๆ ที่เขียนขึ้นมานั้นมันทำงานได้ดีตามที่ต้องการ เขียนจากทั้งนักพัฒนาจริง ๆ และ ไม่ใช่จากสายนักพัฒนา แน่นอนว่า มันไม่แปลกอะไรเลย แต่พบว่า code ส่วนใหญ่มันส่งกลิ่นแปลก ๆ มากพอควร ถ้าเรายังอยู่กับ code แบบนี้ต่อไป คิดว่า ไม่น่าจะส่งผลดีต่อทีม และ บริษัทเลย ดังนั้นจึงให้คำแนะนำไปนิดหน่อย น่าจะพอมีประโยชน์ หรือ อาจจะทำให้เสียกำลังใจก็เป็นไปได้
Make it Work ก่อน แต่อย่าลืม Make it Right นะ

อย่างแรกแยก code ให้เป็นกลุ่มงาน หรือ Modular หน่อยนะ

ให้แยกตามหน้าที่การทำงานไป เช่น
  • การ pre-processing data เช่น clean up, outlier และ null value เป็นต้น
  • การ analyze data
  • การ training data
  • การ visualize data
เนื่องจาก code ที่เจอส่วนใหญ่นั้น ยาวเป็นหางว่าวเลย ไม่พอยังมีการเขียน comment ไว้ด้วยนะ ว่าแต่ละส่วนทำอะไร อย่างไรบ้าง มันคือสิ่งที่บ่งบอกว่า ควรแยกการทำงานได้แล้วนะ
พูดง่าย ๆ แยกการทำงานต่าง ๆ เป็น function ย่อย ๆ ก่อน จากนั้นทำงานจัดกลุ่ม function อีกที จะได้ modular แบบเป็นธรรมชาติมาก ๆ

ต่อมาเรื่อง readability ของ code มันอ่านยากมาก ๆ (อ่านยากฉิบหาย)

ยกตัวอย่างเช่น มันคืออะไรครับ ลูกพี่ ใกล้จะครบแล้วนะ a-z !! [gist id="74251a4f25623b35c1339cbd9673cefc" file="1.py"] ดังนั้นอย่างน้อย code นั้นควรทำให้อ่านเข้าใจง่าย ๆ หน่อย ทั้งตัวเราเอง และ เพื่อนร่วมงาน มิเช่นนั้น การดูแลรักษามันจะนรกมาก ๆ ทีมควรมีข้อตกลงร่วมกันและ review code บ่อย ๆ ทั้งการตั้งชื่อตัวแปร ทั้งการตั้งชื่อ function ไล่ให้ไปอ่านหนังสือ Clean Code ก่อนเลย ยิ่งถ้าเขียน code ด้วยภาษา Python ก็ช่วยเขียน Doc string ไปด้วยนะ เพราะว่า ใช้ทั้งเขียนคำอธิบาย ใช้ทั้งเขียนตัวอย่างการใช้งาน ใช้ทั้งทดสอบได้อีกด้วย ดังนั้นเขียนเถอะครับ เพื่อลดภาระให้ลูกหลาน

เรื่อง Logging ของการทำงานอย่าให้ขาด

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

ปัญหาที่เจอคือ ต้องไป integrate กับระบบงาน

พบว่า เปลี่ยนเมื่อไร กระทบเมื่อนั้น ดังนั้น interface หรือข้อตกลงกับระบบอื่น ๆ นั้น เป็นสิ่งที่จำเป็นมาก ๆ รูปแบบของ input และ output ต้องชัดเจน ถ้าแก้ไข ต้องรู้ว่า ใครบ้างที่ใช้งาน กระทบอะไรบ้าง กระทบกับใครบ้าง
ดังนั้นเรื่องของการทดสอบจึงเป็นสิ่งที่สำคัญมาก ๆ ยิ่งเป็น Automation testing เลยยิ่งดี แต่พบว่าในโลกของ Data Science ไม่เขียนกัน (Software Development ยังน้อยเลยนะ)

เรื่องเพิ่มเติมคือ

มีปัญหาว่า ทำไม code ชุดนี้มันช้าลง ทั้ง ๆ ที่มันเคยเร็ว !! ตอบยากสุด ๆ กลับไปดูเรื่อง Logging และผลบันทึกในแต่ละขั้นตอนก็จะช่วยได้มา กับเรื่องที่หนักหน่อยคือ Big-O ของ algorithm ต่าง ๆ หรือขั้นตอนการทำงานว่าเป็นอย่างไร

สุดท้ายจริง ๆ คือ ใช้ Version Control ที่ดี ๆ เถอะครับ

code จะได้ไม่ทับกันไปมา ตอนนี้แก้ปัญหา code ทับกันด้วย เขียนคนละไฟล์ คนละ folder ไปเลย ซึ่งไม่ขอแนะนำนะครับ !! ขอให้สนุกกับการเขียน code ครับ

[Clojure] ว่าด้วยเรื่องของ Vector และ List

$
0
0

หลังจากที่ทำความรู้จักกับภาษา Clojure ไปบ้างเล็กน้อยแล้ว ต่อมาก็เริ่มไปดู Data structure พื้นฐาน ทั้ง Vector, List, Map, Keyword และ Set โดยครั้งนี้จะเรียนรู้กับ Vector และ List กัน มาเริ่มกันเลย

Vector เป็น data structure ที่ใช้เยอะมาก ๆ ในภาษา Clojure

ซึ่งในแต่ละ item นั้นมีชนิดที่แตกต่างกันได้ รวมทั้งสามารถมี Vector ซ้อน Vector ได้แบบสบาย ๆ โดยที่รูปแบบ syntax ของ Vector นั้น จะอยู่ในเครื่องหมายก้ามปู [] แต่ละ item คั่นด้วยช่องว่าง (space bar) สามารถใส่ comma (,) ได้นะ แต่ตัว compiler จะ ignore ไปเอง มาดู code ตัวอย่างกัน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="1.txt"] แต่ตัวภาษาก็มี function ชื่อว่า vector มาใช้สำหรับสร้าง Vector ให้ด้วย ซึ่งน่าจะช่วยเพิ่มทางเลือกให้ใช้งานอีกด้วย แต่ส่วนใหญ่จะใช้แบบแรกกันนะ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="2.txt"] มาดู function อื่น ๆ สำหรับทำงานกับ Vector กันบ้าง
  • count สำหรับนำจำนวน item ใน Vector
  • first สำหรับดึงค่าในตำแหน่งแรกของ Vector
  • rest จะแสดงข้อมูลตั้งแต่ในลำดับที่สองเป็นต้นไป แต่ return ออกมาไม่ใช่ Vector นะ แต่มันคือ sequence ?
Sequence มันคืออะไร ? ชีวิตยากอะแล้ว พักไว้ก่อน
มาดูตัวอย่างการใช้งาน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="3.txt"] ถ้าต้องการเข้าถึงข้อมูลแต่ละตำแหน่งละ ? ในภาษา Clojure จะมี function ชื่อว่า nth ให้ใช้งาน โดยจะเริ่มตำแน่งที่ 0 ของ Vector ใช้งานดังนี้ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="4.txt"] nth มันคืออะไรนะ ? ชื่อมันแปลกดี ไม่เคยพบเห็นมาก่อน ดังนั้นจึงลองไปค้นหาดู พบว่ามันคือ คำที่มีความหมายทางคณิตศาสตร์ ดังนี้ [code] nth enTH/Submit adjective MATHEMATICS denoting an unspecified member of a series of numbers or enumerated items. "systematic sampling by taking every nth name from the list" [/code] ถ้าต้องการเพิ่มข้อมูลเข้าไปยัง Vector ทำอย่างไร ? จะใช้ function ชื่อว่า conj ซึ่งย่อมาจาก conjunction หรือการเชื่อมต่อหรือเชื่อมโยง ซึ่งจะทำการเพิ่มข้อมูลไปยังตำแหน่งสุดท้ายของ Vector แต่ถ้าต้องการเพิ่มข้อมูลไปยังตำแหน่งแรกสุดของ Vector สามารถใช้ function cons ซึ่งย่อมาจาก construct มาดูตัวอย่างการใช้งาน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="5.txt"] สิ่งที่แตกต่างระหว่าง conj และ cons คือ cons จะทำการ return ข้อมูลเป็นชนิด sequence อีกแล้วนะ !!
ปล. สิ่งที่ควรจำไว้คือ ทุก ๆ function ที่กระทำกับ Vector นั้น จะไม่ไปแก้ไขหรือเปลี่ยนแปลง Vector ต้นฉบับเลย เพียงแค่ return value กลับมาเท่านั้น ซึ่งเป็นพื้นฐานของภาษา Clojure นั่นคือ immutability

มาดู List กันบ้าง ว่าเป็นอย่างไร ?

มันเหมือนกับ Vector มาก ๆ แต่การใช้งานมีรูปแบบที่ต่างกัน มาดูการสร้าง List กัน โดยใช้เครื่องหมายวงเล็บ และ execute list ด้วยเครื่องหมาย single qoute (‘) หรือใช้ function ชื่อ list ก็ได้ ส่วน function อื่น ๆ ใช้เหมือน Vector เลยครับ ไม่ต้อมาจำให้วุ่นวาย
แต่สิ่งที่ต่างคือ function conj และ cons ให้ผลเหมือนกัน !! คือเป็นการเพิ่มไปยังตำแหน่งแรกของ List
ดังนี้ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="6.txt"]

มีคำถามว่า ทำไมต้องมีทั้ง Vector และ List ด้วยละ ทั้ง ๆ ที่เหมือนกันมาก ๆ ?

สิ่งที่ Clojure อธิบายไว้อย่างน่าสนใจคือ มองจากภายนอกนั้นจะเหมือนกันมาก (External) แต่เมื่อดูการทำงานภายในแล้วต่างกัน (Internal) โดยที่ Vector นั้นมองเหมือนกับ array ข้อมูลแต่ละตำแหน่งอยู่ในหน่วยความจำที่ต่อเนื่องกันดังรูป แต่ List จะตรงข้ามกับ Vector เลย เพราะว่าคือ Linked List แสดงดังรูป ส่งผลให้การเข้าถึงข้อมูลในแต่ละตำแหน่งต่างกัน โดยการเข้าถึงของ Vector จะเร็วกว่า List เพราะว่าใช้การคำนวณทางคณิตศาสตร์ ส่วน List ต้องไปตามลำดับที่ link กันไว้ แต่การใช้งานต้อดู use case ด้วยว่าอะไรที่เหมาะกับ Vector หรือ List
สิ่งที่ Clojure ให้ความสำคัญมาก ๆ ของ data structure ต่าง ๆ คือ เรื่องของ performance ในการทำงาน
ซึ่งในโลกของ Clojure นั้น จะมีการใช้งาน Vector มากกว่า List มาก ปล. การทำงานภายในของ Vector และ List น่าสนใจมาก มีทั้งเรื่องของ caching และ การจัดการ memory ซึ่งไว้ต้องศึกษาเพิ่มเติมอีก

สรุปสิ่งที่ไปแบ่งปันในงาน WordCamp Bangkok 2018

$
0
0

ในวันที่ 18 กุมภาพันธ์ 2561 ที่ผ่านมามีโอกาสไปแบ่งปัน เรื่อง ก้าวแรกสู่สังเวียนการใช้งาน Wordpress ที่งาน Wordcamp Bangkok 2018 ซึ่งเป็นคำแนะนำสำหรับการเริ่มต้นใช้งานแบบพื้นมาก ๆ จนจมดินก็ว่าได้ ตลอดจนประสบการณ์และคำแนะนำในการเขียน blog มาดูรายละเอียดกันนิดหน่อย

เริ่มด้วยคำแนะนำในการใช้งาน Wordpress ขั้นพื้นฐาน

ตั้งแต่การเลือกใช้งาน plugin ที่เหมาะสมกับระบบของเรา อย่าติดตั้งเยอะเกินความจำเป็น เนื่องจากในโลกของ wordpress นั้นมี plugin เยอะมาก ๆ พวก Top 5, 10, 20 ,50 ของแต่ละปีมันเยอะมาก ๆ ดังนั้นลองดูทั้ง ความนิยม จำนวนการใช้งาน การ update ล่าสุด เอกสารการใช้งาน ขนาดของ community รวมไปถึงเรื่องของ security ซึ่งพบว่า กว่า 20% ของ plugin ที่ได้รับความนิยมมักจะไม่ผ่านด้าน security ลองดู Guideline เพิ่มได้
การใช้งาน Plugin ก็ใช้แต่พอดีพองาม อย่าเยอะ เช่น Analytic ก็ไปใช้ Google Analytic เถอะ ไม่ต้องติดตั้ง plugin อะไร
การใช้งานทั่วไปที่ขอแนะนำ เช่น Revision ของแต่ละ post/page ให้ระวังด้วย เพราะว่าจะทำให้ขนาดของ database ใหญ่ขึ้นอย่างมาก การเขียน blog อย่า draft เกิน 1 เรื่อง นั่นหมายความว่า เขียนเสร็จก็ให้ทำการ publish เลย เป็นกฏที่ขอแนะนำ ดังนั้นแต่ละ blog ที่เขียนให้มีเป้าหมายเดียว
การเขียน blog เป็นการบอกว่า ในแต่ละวันเราเรียนรู้อะไรบ้าง ในแต่ละวันเราทำอะไรไปบ้าง ให้ทำการจดบันทึกไว้ ไม่ใช่เพื่อใคร แต่เพื่อตัวเราเอง
ปล. น่าจะมีหัวข้อการติดตั้งด้วยนะ มันง่ายแต่ก็มีเทคนิคดี ๆ เยอะมาก ส่วน slide อยู่ที่นี่ครับ [slideshare id=88259940&doc=sck-wordpress-newbie-180219040623&w=640&h=480] ขอให้สนุกกับการเรียนรู้ครับ มาเขียน blog กันเถอะ เป็นช่วยบันทึกสิ่งที่เราได้เรียนรู้และลงมือทำ

ภาษา Golang 1.10 ออกแล้วนะ

$
0
0

เมื่อวันที่ 16 กุมภาพันธ์ 2561 ที่ผ่านมา ทีมพัฒนาภาษา Go ได้ปล่อย version 1.10 ออกมาแล้ว ตามแนวคิดปกติของภาษาคือ เรื่องหลัก ๆ ของตัวภาษาไม่มีอะไรเปลี่ยนแปลง ส่วนเรื่องที่ปรับปรุงมาก ๆ ก็คือ ประสิทธิภาพของการทำงาน และ เครื่องมือต่าง ๆ มาดูรายละเอียดกันนิดหน่อย ในตัวภาษามีเพิ่ม shift operation เข้ามา [gist id="ef38c40ddf04c191cd6bf0d878eee49c" file="1.go"] ปล. ใน Go Playground ยังเป็น Go 1.9 อยู่นะ ใน Go 1.10 จะเป็น version สุดท้าย ที่สนับสนุน Windows XP และ Windows Vista โดยที่ใน version ต่อไปจะทำงานบน Windows 7 ขึ้นไปเท่านั้น เช่นเดียวกันกับ OS X จะทำงานบน OS X 10.10 Yosemite ขึ้นไปเท่านั้น GOROOT เป็น optional เหมือน GOPATH แล้วนะ เพิ่ม GOTMPDIR เข้ามาสำหรับระบุ PATH ของไฟล์ caching ปรับปรุงประสิทธิภาพการทำงาน go tool ทั้ง go build และ go test ซึ่งจะสร้าง caching การทำงานไว้ให้อัตโนมัติ ทำให้ build และ test เฉพาะสิ่งที่เปลี่ยนแปลงเท่านั้น แต่ถ้าไม่ต้องการก็ใส่ parameter ปิดได้ จัดว่าเป็นความสามารถเล็ก ๆ แต่สำคัญมาก ๆ ผมเคยเขียนไว้ที่ blog Go 1.10 with Testing มีสิ่งที่น่ารักคือ Unicode จาก 9.0 เป็น 10.0 ซึ่งเพิ่มอักขระมาอีก 8,518 ตัว ซึ่งมีทั้ง Bitcoin currency และ Emoji 56 ตัวอีกด้วย ส่วนพวก Library อื่น ๆ ที่เปลี่ยนก็เช่น
  • bytes
  • strings
  • net/url
  • bufio
ไป Download มาใช้งานกัน จากนั้นก็ run ชุดการทดสอบเลยครับ
ยังไม่พอนะ Docker Image ก็พร้อมแล้วด้วย
แล้วในไทยจะมีการจัด Go 1.10 Release Party ไหมนะ ?

ว่าด้วยเรื่องของ Fast Data

$
0
0

โดยปกตินั้นข้อมูลมีการเปลี่ยนแปลงอยู่เสมอ ยิ่งในปัจจุบันอัตราการเปลี่ยนแปลงสูงมาก ๆ ทั้ง Volume, Velocity และ Variety ทำให้เครื่องมือต่าง ๆ ที่มีอยู่อาจจะไม่เพียงพอต่อความต้องการ ทั้งการจัดเก็บ ทั้งการรวบรวม ทั้งการวิเคราะห์ ประมวลผล ซึ่งมีความซับซ้อน และต้องการให้ทำงานแบบ realtime ดังนั้นเราต้องการวิธีการใหม่ เครื่องมือใหม่ ๆ architecture ใหม่

ขนาดของข้อมูลนั้นกลายเป็นเรื่องปกติไปแล้ว

ทั้งจาก business transaction, operation, logging และ IoT แต่สิ่งที่สำคัญมากกว่าคือ ความเร็วของระบบให้ทันต่อความต้องการ เพื่อใช้ในการวิเคราะห์และตัดสินใจต่อไป ยิ่งระบบสมัยใหม่ ทำการจัดเก็บข้อมูลการใช้งานเยอะมาก ๆ ทั้งสถิติการใช้งาน เช่นการ click การ view และ การดู เพื่อเรียนรู้พฤติกรรมการใช้งาน และ ปรับปรุงระบบได้อย่างทันท่วงที ดังนั้นจำเป็นต้องมีกระบวนการจัดเก็บ ทำความสะอาด วิเคราะห์ และแสดงผลได้เร็ว ดี ละเอียดและเข้าใจได้ง่าย

มีทางเลือกสำหรับระบบจัดการสิ่งต่าง ๆ เหล่านี้คือ

ซื้อ ทำเอง ให้คนอื่นทำให้ เลือกเอาเองนะครับ

แต่ในบทความนี้เราลองมาดูว่า โครงสร้างที่น่าจะเหมาะสมกับ Fast data เป็นอย่างไรบ้าง ?

ซึ่งต้องการให้การประมวลผลเร็ว ๆ ดังนั้นน่าจะต้องคิดใหม่ ทำใหม่กัน เพราะว่า จะมาประมวลผลแบบ batch หรือ offline คงไม่เพียงพอต่อความต้องการ โดยในการจะสร้างระบบนั้นต้องพิจารณาในเรื่องของ
  • การนำข้อมูลเข้าที่มีประสิทธิภาพ
  • การจัดเก็บข้อมูลและการดึงข้อมูลที่ยืดหยุ่น
  • การวิเคราะห์ข้อมูลที่สะดวกและหลากหลาย
  • การแสดงผล
หรืออาจจะมองไปถึงเรื่องของ Reactive คือ การขยายเข้าหรือออกตามความต้องการได้ Resilient และ Responsive คือ สามารถทำงานได้ แม้จะมีส่วนใด ๆ ที่ล่มไป มาดูในแต่ละส่วนกัน

1. การนำข้อมูลเข้า

โดยข้อมูลเข้ามีที่มามากมาย มีรูปแบบที่แตกต่างกันเช่น plain text, JSON, XML เป็นส่วนที่บอกว่า ข้อมูลจะเข้ามาสู่ระบบมากน้อยเพียงใด โดยปกติจะมีขั้นตอนดังนี้
  • Parsing
  • Validation
  • Cleansing
  • De-duping
  • Transformation
แนวทางที่น่าสนใจของการนำข้อมูลเข้าคือ การทำงานควรเป็นแบบ Asynchronous เช่นการส่งข้อมูลในแต่ละขั้นตอน ถ้ามารอกันคงช้าน่าดู ส่วนพวกการทำ parsing จนถึง transform ข้อมูลนั้นใช้ resource ต่าง ๆ เยอะมาก ดังนั้นก็ควรทำงานแบบขนานกันไปด้วย นั่นคือ ควรมีการนำระบบ Messaging-Oriented Middleware (MOM) มาใช้ ซึ่งมีเครื่องมือต่าง ๆ มากมายเช่น
  • Apache Kafka
  • Akka Stream
  • ActiveMQ
  • RabbitMQ
  • JBoss AMQ
โดยตัวที่แนะนำ คือ Apache Kafka

2. การจัดเก็บข้อมูล

แนะนำให้ทดลองใช้งานหลาย ๆ อย่าง เพื่อให้เข้าใจ เพื่อให้รู้ว่าเหมาะหรือไม่กับระบบงานของเรา ซึ่งเชื่อเถอะว่า ทุก ๆ ปัญหาที่เราพบเจอนั้น มักจะมี solution หรือการแก้ไขไว้แล้ว ดังนั้นไม่จำเป็นต้องสร้างขึ้นมาใหม่จากศูนย์เอง ทั้งปัญหาเรื่องการอ่านข้อมูล ทั้งปัญหาเรื่องการเขียนข้อมูล ทั้งปัญหาเรื่องการแก้ไขข้อมูล โดยที่จัดเก็บข้อมูลที่ดีจะช่วยลด เวลาในการออกแบบ เวลาในการประมวลผล เวลาในการ transfer ข้อมูล ประหยัดที่จัดเก็บ ต่อมาสิ่งที่นำมาใช้งานต้องสามารถ configuration ได้ง่าย และปรับแต่งตามที่ต้องการได้ ทั้งการ replication และ ความถูกต้องของข้อมูล ในส่วนของการออกแบบ data model นั้น มันขึ้นอยู่กับระบบและการนำไปใช้งาน แต่ให้เน้นไปที่ performance เป็นหลัก ในส่วนของเครื่องมือก็มีให้เลือกใช้เพียบ เช่น
  • Apache Cassandra
  • Couchbase
  • Apache Hive
  • Riak
  • Redis
  • MongoDB
  • MariaDB
โดยตัวที่แนะนำ คือ Apache Cassandra

3. การประมวลผลข้อมูล

สำหรับระบบ Fast data นั้นมีการประมวลผลทั้ง Batching และ Streaming รวมกันไป นั่นคือเลือกวิธีการให้เหมาะสมกับงานนั่นเอง ยกตัวอย่างเช่น ระบบงานต้องการการทำงานแบบ realtime คงไม่ใช้วิธีการแบบ batching หรอกนะ หรือถ้ามีระบบ ETL แบบเดิม ๆ อยู่ ซึ่งทำงานแบบ bacthing คงไม่มีใครบ้าระห่ำย้ายมาทำงานแบบ realtime หรือ streaming หมดหรอกนะ โดยที่เครื่องมือบางตัวอาจจะแบ่งการทำงานเป็นส่วนเล็ก ๆ แต่ละส่วนการทำงานจะทำงานแบบ bactching หรือ micro-batching จากนั้นตัวควบคุมการทำงานหลักทำงานแบบ streaming ซึ่งวิธีการทำงานแบบนี้จะเรียกว่า hybrid อีกเครื่องคือ จะทำการบน disk หรือ memory ดีละ ก็เหมือนข้างต้นนั่นเอง ทำงานบน disk ไปหมดก็ไม่ดี มันช้า ทำงานบน memory ไปหมดก็ไม่ได้ มันเปลือง เราพูดถึงความเร็วคือ data locallly มากกว่า นั่นคือ ประมวลผลข้อมูลที่อยู่ใกล้ ๆ ซึ่งเร็วต่อการทำงาน และ transfer ข้อมูล ดังนั้นเครื่องมือหลาย ๆ ตัว จะทำงานแบบการกระจายข้อมูลไปในแต่ละที่ จากนั้นจึงรวมผลการทำงานเข้าด้วยกัน คุ้น ๆ กับวิธีการทำงานหรือไม่ ? โดยเครื่องมือมีให้ใช้เยอะมาก ๆ ยกตัวอย่างเช่น
  • Apache Spark
  • Apache Flink
  • Apache Storm
  • Apache Beam
  • Tensorflow
โดยตัวที่แนะนำ คือ Apache Spark สำหรับ micro-batching และ Apache Flink สำหรับ streaming

4. การแสดงผลข้อมูล

เป็นส่วนที่ใช้อธิบายผลการประมวลผลข้อมูลให้ผู้ใช้งานทั่วไปเข้าใจได้ง่าย เป็นขั้นตอนที่ไม่ง่ายเลย เนื่องจากต้องใช้ศาตร์และศิลป์เยอะสูงมาก ๆ ที่สำคัญต้องโดนใจ ถูกต้อง เข้าใจง่ายและเร็ว ดังนั้น การ process เยอะ ๆ ในขณะแสดงผลเป็นสิ่งต้องห้ามอย่างมาก ข้อมูลก่อนนำมาแสดงผล ต้องเป็นข้อมูลที่สรุปมาแล้ว เช่นข้อมูลตามหมวดหมู และ ตามช่วงเวลาเป็นต้น ข้อมูลแต่ละชุดทำขึ้นมาเพื่อการแสดงผลแบบเฉพาะเจาะจงเท่านั้น อย่านำข้อมูลชุดเดียวแล้วไปแสดงในทุกรูปแบบ มิเช่นนั้นจะช้าอย่างมาก ส่วนของเครื่องมือก็เยอะนะ ยกตัวอย่างเช่น
  • Notebook report เช่น Jupiter notebook และ Apache Zeppelin
  • Tableau
  • D3.js
  • Gephi

แต่ทั้งหมดนี้ ต้องการ infrastructure ที่ดีด้วยเช่นกัน

ดังนั้น operation จำเป็นต้องปรับและเปลี่ยนด้วย จากที่เคยทำแต่ scale-up ต้องเปลี่ยนมาเป็น scale-out รวมทั้งเรื่องการนำ opensource มาใช้งาน แนวคิดและแนวปฏิบัติ DevOps จึงมีความสำคัญอย่างมาก เพื่อลดการ rework ต่าง ๆ ลงไป เช่นทีมพัฒนาสามารถทดสอบระบบ บน environment ที่เหมือนหรือคล้ายกับ production เป็นต้น ส่วนของเครื่องมีในการจัดการก็มีเยอะมากเช่นเดิม
  • Docker
  • Kubernetes
  • Spinnaker
  • Apache Mesos
ทั้งหมดนี้เป็นคำแนะนำเล็ก ๆ น้อย ๆ สำหรับระบบ Fast Data เพื่อช่วยทำให้การจัดการข้อมูลมีประสิทธิภาพที่ดีขึ้นตั้งแต่ การนำข้อมูลเข้า การจัดเก็บข้อมูล การประมวลผลข้อมูล การแสดงผลข้อมูล Reference Websites https://www.oreilly.com/ideas/from-big-data-to-fast-data

สรุปการแบ่งปันเรื่อง Continuous Integration ด้วย Jenkins ที่ SWPark

$
0
0

สัปดาห์ที่ผ่านมามีโอกาสสอนและแบ่งปัน เรื่อง Continuous Integration and Delivery with Jenkins ที่ Software Park เป็นเวลา 2 วัน จึงทำการสรุปสิ่งที่สอนและแบ่งปันไว้นิดหน่อย

อธิบายเกี่ยวกับความสำคัญของ CI และ CD

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

อธิบายเกี่ยวกับแนวปฏิบัติของ CI และ CD

หลัก ๆ คือ 1. Integrate ส่วนการทำงานบ่อย ๆ 2. ค่อย ๆ เพิ่ม feature ต่าง ๆ แบบเล็ก ๆ 3. ต้องทำให้ได้ feedback ที่รวดเร็วจากทุก ๆ การเปลี่ยนแปลง สังเกตได้ว่า แนวปฏิบัติต่าง ๆ จะเกิดจากคนล้วน ๆ ลองคิดดูว่า ถ้าคนทำงานไม่ส่งการเปลี่ยนแปลง หรือ บอกให้คนอื่นรู้โดยเร็ว จะทำการ integrate บ่อยได้อย่างไร แล้วจะรู้ปัญหาได้เร็วได้อย่างไร แสดงว่างานที่ทำมันใหญ่เกินไปไหม ดังนั้นสิ่งต่าง ๆ เหล่านี้ เป็นการปรับปรุงสิ่งที่กำลังทำอยู่ให้ดีขึ้น นั่นคือ ต้องเริ่มจากคนทำงาน (People) จากนั้นคนทำงานคิดขั้นตอนการทำงานหรือปรับให้ดีขึ้น (Process) สุดท้ายคนทำงานจึงหาเครื่องมือที่ดีและเหมาะสม (Tools) เพื่อช่วยให้ขั้นตอนการทำงานมีประสิทธิภาพที่ดีขึ้นอย่างต่อเนื่อง
ปล. อย่าเริ่มด้วยเครื่องมือเด็ดขาด !!

จากนั้นแนะนำให้ผู้เรียนทำการออกแบบขั้นตอนการทำงาน

หรืออาจจะเรียกว่า build process หรือ build pipeline ขึ้นมา ซึ่งจะเน้นในส่วนการพัฒนา software นั่นคือ เริ่มด้วยจาก
  • การจัดการ source code ควรอยู่ใน version control system ที่ดี
  • ยังไม่พอ ต้องคุยและตกลงเรื่องของ Branch strategy อีกด้วย มิเช่นนั้นเละแน่ ๆ
  • ขั้นตอนการ build เป็นอย่างไร เช่น compile, testing, packaging และ deploy
  • เน้นเรื่องของการวิเคราะห์ source code
  • เน้นเรื่องของการทดสอบในชั้นต่าง ๆ เช่น unit, integration, component, API และ User Interface ซึ่งควรเป็นการทดสอบแบบอัตโนมัติให้ได้มากที่สุด
  • เน้นในเรื่องของการจัดเก็บ software package ซึ่งแนะนำให้แยก code กับ configuration ออกจากกัน
  • เน้นในเรื่องของการ deploy ระบบงานแบบอัตโนมัติ

สิ่งเหล่านี้คือ ขั้นตอนที่ทีมควรคิดและสรุปกันก่อนเสมอ

จากนั้นทำการสรุปว่า ในแต่ละขั้นตอนทำอย่างไร ? ในแต่ละขั้นตอนใช้เครื่องมืออะไรบ้าง ? โดยใน workshop นั้นจะใช้เครื่องมือต่าง ๆ ดัง
  • Git และ Github สำหรับจัดการ source code, configuration และชุดการทดสอบ
  • SonarQube, Checkstyle, Lint, PMD, CPD และ FindBugสำหรับการวิเคราะห์ source code
  • JUnit สำหรับการเขียนชุดการทดสอบแบบอัตโนมัติ
  • Robotframework สำหรับการทดสอบ User Interface แบบอัตโนมัติ
  • Postman สำหรับการทดสอบ API แบบอัตโนมัติ
  • Frog Artifactory สำหรับการจัดเก็บ software package ต่าง ๆ

สุดท้ายจึงพาแปลงจากขั้นตอนการทำงานที่สรุปด้วยเครื่องมือที่ชื่อว่า Jenkins

ซึ่งเป็นหนึ่งในเครื่องมือที่ได้รับความนิยม แต่ถามว่า ใช้เครื่องมืออื่นได้ไหม ? ตอบได้เลยว่า ได้ แต่คุณเอาเครื่องมือ หรือ ขั้นตอนเป็นหลัก ไว้เจอกันในรอบต่อ ๆ ไป ขอให้สนุกกับการ coding ครับ
Viewing all 1997 articles
Browse latest View live