[Heroku][Golang] 一些關於筆記關於 Heroku 與 Golang

給自己做個筆記…. 關於 Heroku 以下指令都需要安裝Heroku Toolbelt後登入Heroku. heroku login 查詢Server 目前的log: heroku logs -t 其他更多指令在這裡 Heroku App/Worker crash如何重啟: heroku restart web.1 更多指令 如何在Heroku上面快速的rollback: 到control panel 下 [activity] 選擇你要的change旁邊有[roll back to here]. Performance Status: 可以透過add-on Librato來監測你目前在Heroku的webapp. 關於Golang Golang 的scope是依照package,所以同目錄下面的檔案,只要package一樣都會被歸在一起. init() 跑的順序是依照 alphabet axxx.go bxxx.go …… zxxx.go 關於go import 更多使用要看這(好像是FAQ) import _ “xxx”: 代表的是使用 Init 但是不把整個package 套進來(不會有compiler error if no use) import . “fmt”: 打所有function 不用加上namespace import m “fmt”: fmt.Println 變成 m.Println 參考資料 Stackoveflow: heroku - how to see all the logs Heroku: What to do when your dyno/worker crashes? Heroku: Releases and Rollbacks
繼續閱讀

[Ubuntu][Golang]關於Ubuntu Server連線能力設定

前言: 架設Golang Server選擇可以有兩個方向,大部分的人可能選擇自己架設主機來跑Golang Server如果要能夠達到10k甚至是100k連線數的話.這邊把一些經驗記錄下來. 架設環境 這邊的伺服器主要是架設在以下的設備與軟體: Ubuntu 14.04 X64 MySQL + Apache + Ejabberd 了解主機原先設定的上限與調整 先就不討論硬體架構的連線能力狀況下,還是有一些軟體設定需要調整. MySQL 連線上限調整 首先會遇到的問題就會是MySQL query 卡住的問題,每一次的Query Request 都會卡在MySQL那一端.主要是以下的設定需要調高.max_connections原先設定只有100.設定方式如下:(細節參考這裡) mysql> set GLOBAL max_connections=65536; 可能還是會遇到有一些問題,建議把另外一個max_connect_errors一併也調高 mysql> set GLOBAL max_connect_errors=65536; 改完MySQL 接下來可能出現的會是 Ubuntu 設定 改完了MySQL的設定之後,整個設定就可以變得相當的順暢.但是偶爾會出現一些問題,就得接下去追查原因. 問題: 一次能進入的TCP connection 太少 首先可能去做調整就是去/etc/sysctl.conf來增加TCP連線數,以下是參考設定. net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_max_syn_backlog = 8192 問題: “too many open files” 解決了大量連線數無法接收的問題,卻發生了"too many open files"的error. 根據這個Stackoverlow,由於每一個TCP的Connection在Linux系統本身都被當作是一個file來存取,所以面對到大量connection的時候,可能遇到的問題就是依照前面的方式把TCP connection 打開到65000之後,但是由於每一個TCP connection 會對應到一個檔案的開啟,接下來就是檔案開啟的上限被打爆.於是就會出現…. Too many open files 這個問題可能是關於到Ubuntu原本的設定. ulimit -n //console mode 可以顯示目前可以同時開啟起檔案的最大量. 預設: 1000 修改方式主要是打開 /etc/security/limits.conf * hard nofile 500000 * soft nofile 500000 root hard nofile 500000 root soft nofile 500000 這樣應該可以初步的把server request產生到同時間至少有3000以上. 參考文章 MySQL Parameter Setting Stackoverlow: dial error : ‘too many open files’ Linux Increase The Maximum Number Of Open Files / File Descriptors (FD) Increase “Open Files Limit”
繼續閱讀

[Golang][Martini]在Martini-render上面的layout/template套用

前言: 學習架設Golang Web Services 的時候,也需要有後台網頁管理介面.這時候就需要有樣板來套.才能讓網站架設起來比較快. 筆記: 以下的部分會提到如何使用,我個人使用習慣. 不會將所有的程式碼都貼出來,但是會顯示部份的整理過的資料. 關於Martini的layout: 網頁上的資料部分,可以拆解成兩大部分: 不可以抽換,使用layout替換 (ex: layout.tmpl) 舉例: <HTML><HEAD> 甚至是CSS JS都可以. 需要用程式來表示的部分,用render來顯示 (ex: hello_world.tmpl, layout_hello.tmpl) 舉例: table content或是資料庫裡面的資料. Layout file layout.tmpl <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Layout sample</title> </head> <body style="margin: 20px;"> <h1>This is a layout sample</h1> <!-- 可以被替換的部分放這裡 --> </body> </html> 其中 `` 將你要顯示的tmpl部分全部換到這邊. 接下來要處理的部分拆解到hello_world.tmpl. <CENTER> Hello </CENTER> 接下來另外一個需要處理的到layout_hello.tmpl. <CENTER> This is another layout Hello </CENTER> 接下來就要提到Golang處理layout的部分. 如何使用Layout: 提到Golang處理的部分,先看看在一開始martini啟動的部分 ..... func main() { m := martini.Classic() // 將所有預設的layout都先設定到"layout.tmpl" m.Use(render.Renderer(render.Options { Layout: "layout", })) ..... m.Run() } 這邊要記住,預設的目錄都會在templates下面. 要顯示的時候可以使用以下的方式. // 使用hello_world.tmpl m.Get("/", func(r render.Render, db *mgo.Database) { display_name := "John" r.HTML(200, "hello_world", display_name) }) 如果不同的entry point 要使用不同的layout呢? 有一些時候,網站開始變大之後.layout 的版型也開始變多了.這時候可能需要動態的去變你要套用的layout.原本的martini-render 就提供可以在render.HTML裡面加上 HTMLOptions.其實也就是加上你要指定的layout. // 使用hello_world.tmpl,並且套上layout_hello.tmpl m.Get("/", func(r render.Render, db *mgo.Database) { display_name := "John" r.HTML(200, "hello_world", display_name, render.HTMLOptions{Layout: "layout_hello"}) }) 相關鏈結: GoDoc: martini-render 這一篇是GoDoc不得不看.. GoDoc: template 關於http/template,不過martini-render是架設在他之上.可看可不看. GO TUTORIAL WITH MONGODB ON HEORKU 是一篇tutorial,不過對於martini-render有一些介紹. Hack martini-render 很推薦看這一篇,基本常識都會了解. 初學 Golang 30 天(二十八)Router,...
繼續閱讀

[MongoDB]More study about mongodb and mgo 3 - logical operator and like

Preface When we trying to use MongoDB, the requirement comes more and more complex and diversity. Here is some note during my implement. Multiple condition in MongoDB Query It is very easy to find data in MongoDB, but how about multiple condition such as “AND” and “OR” ? AND OR in MongoDB It is very easy to find “AND” support in MongoDB, but how to apply in mgo (MongoDB driver in Go)? // Find user name is John and Contry is US. var alldb []User UserCollection.Find(bson.M{"$and": []bson.M{bson.M{"name": "John"}, bson.M{"Contry": "US"}}}).All(&alldb) Please note: the $and need combine an array of bson.M. // Find CONDITION_A and CONDITION_B bson.M{"$and": []bson.M{ CONDITION_A, CONDITION_B }} So, it is similar with “OR” ($or), detail doc is here. // Find CONDITION_A or CONDITION_B bson.M{"$or": []bson.M{ CONDITION_A, CONDITION_B }} Make it more clear in code. // Find user name is John or Tom. var alldb []User UserCollection.Find(bson.M{"$or": []bson.M{bson.M{"name":...
繼續閱讀

[Golang]關於Channels的控制一些要注意的事項(二)

##前言 前一篇的一些討論後,接下來有一些更容易出錯的部分可以討論.主要focus Goroutine跟 defer ###Goroutine Closure 主要是這一篇部落格帶出的問題: func main() { done := make(chan bool) values := []string{"a", "b", "c"} for _, v := range values { go func() { fmt.Println(v) done <- true }() } // wait for all goroutines to complete before exiting for _ = range values { <-done } } 根據以上的部分,印出的結果不會是 “a”, “b”, “c”.而是 “c”, “c”, “c” 原因是 goroutine 變數會參照到go func 跑的時候. 如果修改成以下就可以避免這個問題: func main() { done := make(chan bool) values := []string{"a", "b", "c"} for _, v := range values { go func(obj string) { fmt.Println(obj) done <- true }(v) } // wait for all goroutines to complete before exiting for _ = range values { <-done } } 由於他的順序會是 go func(v) 之後才執行,所以其變數內容會先傳過去而不是跑道fmt.Println(v)才取得. 更多跟goroutinem與closure有關的資訊請看這裡Go: FAQ 參考資料 Effective Go: Channels 官方Effective Go文件,一定要熟讀. Go FAQ: hat happens with closures running as goroutines? A Go Gotcha: When Closures and Goroutines Collide
繼續閱讀

[Android]關於JNI的學習筆記

前言 上個禮拜在Android Studio 1.1 把JNI搞定之後,接下來就是把JNI的內容去完成.其中有許多小技巧與眉眉角角的地方需要紀錄一下. 筆記內容 關於Android.mk 與 Application.mk 的部分 (2015/10/21 update) 關於Android Studio與JNI的發生ld.exe crash 如果在Android Studio要去load其他的jni static library,在Windows上面有時候會發生ld.exe crash的問題.這時候只要打開”Build Variants”-> 把”Build All”,改成看你現在需要哪一種(Android 手機就是 arm-Debug,模擬器就是x86-Debug). 就可以解決. (2015/10/20 update) 關於STL部分 如果有用到STL的支援,主要都是修改Application.mk,不是改在Android.mk中. 這樣才能一次改到所有的檔案,避免A檔案過,B檔案不過. APP_STL := stlport_static 參考: Using the STL with Android NDK C++ 增加 C++ 與 CPP11 支援 新增以下到 Application.mk APP_STL := stlport_static APP_CPPFLAGS += -std=c++11 讀取其他資料夾與一次讀取所有的cpp 新增以下到 Android.mk LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../../source/*.cpp) 關於JNI資料的轉換部分 C++ char* 與 JNI jstring 的轉換 *jstring to char ** char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } char* to jstring jstring stoJstring(JNIEnv* env, const char* pat) { jclass strClass...
繼續閱讀