Skip to main content

Posts

Showing posts with the label go

Đọc code Go Traefik xem router ưu tiên match theo độ dài rule

Traefik là gì Traefik (pronounced traffic) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components (Docker, Swarm mode, Kubernetes, Consul, Etcd, Rancher v2, Amazon ECS, ...) and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the only configuration step you need. Traefik là một HTTP reverse proxy và load balancer giúp triển khai microservices dễ dàng. Traefik có tính năng tương tự NGINX, với điểm mạnh lớn nhất là khả năng tích hợp, cấu hình tự động với hệ thống đã chạy như Kubernetes, Docker, ... Traefik được viết bằng Go, về hiệu năng chưa có gì vượt trội so với NGINX, nhưng có nhiều tính năng hiện đại như: tích hợp HTTPS dễ dàng, hỗ trợ sẵn dashboard, metrics, rate limit,... Build Traefik từ source Tạo file build.sh git clone https://github.com/traefik/traefik --depth 1 --branch v3.5 cd traefik touch webui/static/index.html make ...

Prometheus căn bản

Căn bản không nghĩa là đơn giản hay dễ. Điều này càng đúng khi nói về time series database (TSDB) như Prometheus. Time series là 1 nhánh của toán học, mà chỉ có 1 thứ dễ khi nói về toán, đó là dễ sai. Thời gian là 1 khái niệm không được định nghĩa rõ ràng, chỉ có trong trí tưởng tượng của con người https://en.wikipedia.org/wiki/Time . Chú ý: vì vậy bài viết này, giống mọi bài viết khác, có thể sai. Bài viết giúp trả lời các câu hỏi: Time series là gì Metric và label là gì Các kiểu metric Các kiểu dữ liệu trong PromQL Instant vector khác gì range vector Instant vector selector khác gì range vector selector Instant query khác gì range query Operator khác gì function [bài sau] Cài và chạy Prometheus Xem bài trước . Các khái niệm trong Prometheus Data model - Timeseries Data model Prometheus fundamentally stores all data as time series: streams of timestamped values belonging to the same metric and the same set of labeled dimensions. Prometheus chứa tất cả dữ liệu n...

[go] Viết test code prometheus xem delta và rate tính thế nào

Bài trước đã dùng mắt để chạy code funcDelta và funcRate của Prometheus để xem code chạy qua những dòng nào, những phép tính nào được tính trong extrapolatedRate . Bài này sẽ sử dụng go test coverage để xem code nào được chạy. Viết test Prometheus Code của funcDelta và funcRate đều nằm trong file promql/functions.go , theo quy ước chung của Go, test sẽ nằm trong promql/functions_test.go , nhưng file này chỉ chứa có 2 test: $ grep ^func -c functions*_test.go functions_internal_test.go:1 functions_test.go:2 Lý do là PromQL tự tạo ra 1 kiểu/ngôn ngữ test riêng cho ngôn ngữ PromQL, nằm trong thư mục promqltest/ chứ không phải Golang test thông thường. file promqltest/README.md viết: The PromQL test scripting language This package contains two things: an implementation of a test scripting language for PromQL engines a predefined set of tests written in that scripting language $ find promql/promqltest promql/promqltest promql/promqltest/README.md promql/promqltest/test...

[go] Đọc code prometheus xem vì sao delta tính sai kết quả

Prometheus là gì The Prometheus monitoring system and time series /ˈsɪr.iːz/ database. Prometheus, a Cloud Native Computing Foundation project, is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts when specified conditions are observed. Prometheus là tên phần mềm metric monitoring tiêu chuẩn ngày nay. 10 năm trước là graphite. Stack phổ biến thời cloud: Prometheus lưu trữ time series, hiển thị biểu đồ dùng grafana, gửi cảnh báo alert dùng alertmanager. Prometheus viết bằng Go, bắt nguồn từ SoundCloud, code xem tại https://github.com/prometheus/prometheus Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud. Since its inception in 2012, many companies and organizations have adopted Prometheus, and the project has a very active developer and user community. It is now a standalone open source project and main...

[Go] nil không là duy nhất, cap(map) = ?

Trong Python, None là giá trị duy nhất thể hiện sự "không có gì", sự "null", thì trong Go, nil lại là nhiều thứ khác nhau. Go nil có kiểu Mỗi giá trị nil có kiểu cụ thể. package main func main() { var s []int var m map[string]int println(s == nil) println(m == nil) // println(x == y) // Compile error: ./nil.go:9:15: invalid operation: s == m (mismatched types []int and map[string]int) } s và m đều bằng nil , nhưng không bằng nhau. nil map không phải là vô dụng var m map[string]int Khi 1 map chưa được khởi tạo, nó có giá trị là nil . Map là kiểu reference , như pointer hay slices. nil map vẫn đọc giá trị bình thường (giá trị là zero value của kiểu int tức 0): var m map[string]int v := m["password"] println(m)// 0x0 println(v)// 0 nil map không thêm được giá trị. var m map[string]int m["age"] = 8 Panic với nội dung panic: assignment to entry in nil map goroutine 1 [running]: main.main() /home/hvn/me/fami...

[Go] any chứa được int nhưng []any không chứa được []int

Theo go tour An interface type is defined as a set of method signatures. A value of interface type can hold any value that implements those methods. Một kiểu interface định nghĩa một bộ các method. Một giá trị kiểu interface có thể chứa bất kỳ giá trị nào có đủ các method trong interface. The interface type that specifies zero methods is known as the empty interface: An empty interface may hold values of any type. (Every type implements at least zero methods.) Một kiểu interface không chỉ định method nào được gọi là empty interface : interface{} Một empty interface có thể chứa giá trị của bất kỳ kiểu nào. any trong Go là gì Từ Go phiên bản 1.18 giới thiệu cách viết khác cho interface{} là: any . Photo by Andrew Wulf on Unsplash function nhận any , nhận mọi giá trị package main import "fmt" func doThing(x any) { fmt.Print(x) } func main() { n := 5 doThing(n) s := "hello" doThing(s) } function doThing nhận đầu vào kiểu a...

[Go] := đôi khi không gán giá trị

Tạo variable (biến) trong Go Go có 2 cách để khai báo và khởi tạo giá trị cho variable: var x int // declare x = 42 // init có thể viết gọn lại var x int = 42 Hoặc cú pháp ngắn "short declaration": x := 42 Short declaration rules Short declaration := ngắn hơn, được ưa chuộng, nhưng cũng kèm theo không ít chú ý mà ít ai để ý. package main import ( "fmt" "os" ) func main() { i, err := os.Open("/etc/passwd") i, err := os.Open("/etc/passwd") fmt.Printf("i %v err %v\n", i, err) } Code này không compile với error: no new variables on left side of := , bên trái := luôn phải có variable mới. Code này compile ok: func main() { i, err := os.Open("/etc/passwd") f, err := os.Open("/etc/passwd") fmt.Printf("i %v f %v err %v\n", i, f, err) } ở đây có var f mới, còn var err cũ được gán cho giá trị mới. Bằng chứng err cũ có thể test: func main() { i, _ := os....

[Go] Đôi khi 0.1 + 0.1 + 0.1 == 0.3

Trong cuộc sống, những thứ đúng là đúng, sai là sai thật dễ dàng, còn những thứ đôi khi thế này, đôi khi thế nọ, thì tùy. Như các học viên của https://pymi.vn đều biết vì sao 0.1 + 0.1 + 0.1 != 0.3 trong Python và hầu hết các ngôn ngữ khác, thì với Go, thực hiện 1 phép tính cộng đơn giản theo 2 cách khác nhau, cho ra 2 kết quả khác nhau. Cách giống các ngôn ngữ khác func main() { x := 0.1 fmt.Printf("%v + %v + %v == 0.3? %t\n", x, x, x, x+x+x == 0.3) fmt.Printf("%f\n", x+x+x) fmt.Printf("%.17f\n", x+x+x) } Kết quả giống như Python và các ngôn ngữ khác, 0.1 + 0.1 + 0.1 != 0.3 do kết quả vế trái là 0.30000000000000004 0.1 + 0.1 + 0.1 == 0.3? false 0.300000 0.30000000000000004 https://go.dev/play/p/eDe3szlFyi7 Cách của riêng Go Nếu viết khác đi một chút, sử dụng từ khóa const , hay viết trực tiếp mà không gán cho biến x , kết quả lại là đúng: func main() { const x = 0.1 fmt.Printf("%v + %v + %v == 0.3? %t\n", x,...

Go value receiver method vẫn thay đổi được giá trị?!

Bài viết đầu tiên của nhiều bài viết sẽ bán than về "Go" - ngôn ngữ lập trình non trẻ (since 2010) nhưng khá hot trên toàn cầu. Go is simple Go thường được nhìn nhận là "đơn giản", không phủ nhận việc làm xong gotour https://go.dev/tour/ khiến người học có thể bắt đầu viết code go, sau 1 tháng có thể tham gia code production (và viết bug). Có hẳn cuốn sách giá cả triệu đồng bán rất chạy về những mistake khi dùng ngôn ngữ đơn giản này 100 Go Mistakes and How to Avoid Them . Không dùng thì thôi, sao phải chê, thích chiến à? Có một sự thật đi làm khá lâu mới nhận ra, rằng 99.99% BẠN không phải người quyết định công ty/dự án dùng cái gì. Những người/thứ quyết định sẽ là: công nghệ có sẵn của công ty công nghệ quen thuộc của team bên trên chỉ xuống (CTO/architect...) khách hàng yêu cầu vậy nên thích hay không vẫn phải dùng. Mà dùng không sướng thì phê bình thôi. Go pointer receiver vs value receiver Go receiver có 2 loại là pointer và value. Trích từ Go...

[vim] Dùng Go font với Gvim

vim dùng trên terminal chỉ có thể dụng font mà terminal đang dùng. Gvim hay macvim thì khác, chúng hỗ trỡ set font tuỳ ý. Đặt font cho gvim Câu lệnh set font trong gvim là: set guifont=FONTNAME:hSIZE Nếu tên font có dấu space, hãy escape nó bằng dấu backslash  ``\``. Để xem guifont đang dùng giá trị gì, gõ: set guifont Để hiện ra giao diện chọn font (đã test trên macvim), gõ set guifont=* Ví dụ, dùng lệnh sau để set Courier font, size 14:  set guifont=Courier:h14

[Golang] fix Go 1.7 panic

Nếu như mới build lại Go bản 1.7 và chạy một lệnh chuẩn nào đó mà bị panic (như go vet chẳng hạn): go vet ./... panic : inconsistent import :      var os . Stderr * os . File previously imported as :      var Stderr * os . File [ recovered ]      panic : inconsistent import :      var os . Stderr * os . File previously imported as :      var Stderr * os . File goroutine 1 [ running ]: panic ( 0x2734a0 , 0xc42028a540 )      / Users / hvn / FOSS / golang / src / runtime / panic . go : 500 + 0x1a1 go / types .(* Checker ). handleBailout ( 0xc4200d21c0 , 0xc42004d8d8 )      / Users / hvn / FOSS / golang / src / go / types / check . go : 213 + 0xae panic ( 0x2734a0 , 0xc42028a540 )      / Users / hvn / FOSS / golang / src / runtime / panic . go : 458 + 0x243 Đừng khóc, vì lúc khóc trông rất ng...

[Golang] ba chấm

Trong Go có một ký hiệu khá đặc biêt: ba chấm (...) Ba chấm, thêm vào mỗi cuối câu, để lại một sự miên man trong suy nghĩ. Như "Anh ... em"... Và có vẻ như bác Rob Pike cũng hiểu 3 chấm có ý này nọ kiểu vậy, nên lấy nó làm ký hiệu cho "wildcards". Tức dấu ... sẽ "match" với tất cả mọi thứ (gần giống ký hiệu * trong shell). Khi viết "github.com/hvnsweeting/pika/..." nó sẽ match với tất cả các sub package trong package "pika" cũng như chính package "pika". Để làm gì?  Một ứng dụng đơn giản là để test tất cả các package / subpackage trong 1 package, Ví dụ: cần test toàn bộ package github.com/labstack/echo chỉ cần chạy go test github.com/labstack/echo/...

[Programming] Closure

Closure /ˈkləʊʒə/ sự đóng kín (Việt sub: cờ lâu giơ) Là một khái niệm phổ biến ở các ngôn ngữ lập trình hàm ( functional programming language như LISP, Scheme, ...) nhưng cũng có thể thấy ở Javascript,Ruby, Go, Object C, hay hỗ trợ 1 phần ở python2 và hỗ trợ hoàn toàn ở python3... (nhưng không có trong C, Java). Các ngôn ngữ nào cho phép trả về giá trị là một function thì có thể sẽ hỗ trợ closure. Để tránh sử dụng wikipedia, sau đây là các định nghĩa closure từ document chính thức của một số ngôn ngữ lập trình: Go đưa ra khái niệm ở dạng mô tả như sau trong gotour : Một closure là một function (hàm) mà reference (tham chiếu) đến các biến ở ngoài body của nó. Function này có thể truy cập và thay đổi các biến mà nó đã reference. Có thể nói function "bound"(đã gắn) đến các biến. EMACS LISP : Một closure là function mà nó "mang theo" một bản ghi về "môi trường lexical" đã tồn tại khi hàm đó được định nghĩa. Javascript : Closure là function...

Vài sai lầm hay mắc phải khi lập trình viên Python code Go

1. Quên compile =)) Thường nếu chỉ code các script nhỏ, code xong ra python filename.py chạy luôn. Nhưng Go là một compiled-language, code xong phải compile, compile xong mới chạy được. 2. Dùng '' thay vì "" Trong Go, string nằm giữa dấu ngoặc kép "", trong Python dấu ngoặc '' hay "" đều dùng được cả. Và lỗi về việc này sẽ thường xuyên đập vào mặt: "illegal rune literal". 3. Quên không return khi định nghĩa function Python là dynamic type language, khi viết function không cần / không thể ghi là nó sẽ trả về giá trị nào, thuộc type gì. Golang hay bất cứ static type language nào cũng cần khai báo giá trị sẽ trả về và kiểu (type) của nó. Có nên học Go?

[Vim] vim-pathogen

Nếu bạn đã dùng nó, hãy bỏ qua bài này. Nếu chưa, hãy dành 5 phút đọc và dùng ngay. vim-pathogen là một vim-plugin cho phép cài đặt các vim-plugin khác một cách dễ dàng. Đại khái là "khó một lần rồi thôi", sau lần này sẽ dễ. Mà thực chất thì lần này cũng chả khó gì ~.~ English pathogen /ˈpaθədʒ(ə)n/ mầm bệnh (sub Việt : "PÁT thơ giờn") Cài đặt Chạy lệnh sau: mkdir -p ~/.vim/autoload ~/.vim/bundle && \ curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim   Github repo: https://github.com/tpope/vim-pathogen Sau đó thêm dòng

[Go] select và giao thông

Bài viết này giải thích cách hoạt động của câu lệnh "select" trong Go , sử dụng ví dụ trong tutorial "A tour of Go" 1. function fibonacci (Xem code ở dưới). - Nhận input là 2 channel kiểu int. (channel sẽ chỉ "truyền" dữ liệu có kiểu "int"). "for { }" => tương đương với "while true" trong khác ngôn ngữ khác, ở đây lặp vô hạn. Trong ví dụ này, câu lệnh ``select`` có chứa 2 case, theo phần giới thiệu của tutorial : ``select`` lets a goroutine wait on multiple communication operations.  ``select`` cho phép một goroutine chọn hướng chạy dựa trên kết quả của các hoạt động giao tiếp (truyền data trong channel) câu lệnh ``select`` sẽ block cho đến khi một trong các ``case`` của nó có thể chạy (channel hoạt động - không bị block), khi đó nó sẽ chạy các câu lệnh trong ``case`` ấy, nếu có nhiều ``case`` đều có thể chạy cùng lúc thì nó sẽ chọn ngẫu nhiên một ``case``. Để dễ hiểu, ở ví dụ dưới tưởng tượng 2 channel là 2 ...

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG