算起來接觸erlang 快四個月來,從零開始看書寫erlang代碼、修改RabbitMQ、業務開發、系統調優,總算是有點入門了。
最難受的是邊學邊修改RabbitMQ,難受只是暫時的,憋過去就海闊天空,最后提交修改2000+行代碼。
說到坑都是自己技術不過關造成,erlang 設計與一般語言很大不同,雖然簡單但還是有不少需要注意點;erlang 是一門非常成熟語言,OTP 也特別穩定,不過要想用好,很不容易。
列舉遇到的注意點:
1. 學習資料少
書:《programing erlang》erlang 作者寫的,通俗簡單 嗯 真的很簡單。。看一遍就夠寫得都差不多
官方文檔: 不夠詳細?湊合看吧,好歹有
博客推薦:(建議有空將他們博客通讀一遍,助你繞過前人走過的彎路)
http://www.cnblogs.com/zhengsyao/ (強推)
http://blog.yufeng.info/
http://www.cnblogs.com/me-sa/
http://wqtn22.iteye.com/
2. error_logger
這是個坑貨, 而且默認crashlog 用這玩意兒記,一旦進程批量crash,因為內部receive-match 寫磁盤方式,越來越慢。
可以選用lager,不過lager 在message_queue_len 超過指定值(50)后采用同步方式,內部依然是receive-match 寫磁盤 方式寫磁盤,
建議實現自己的lager_backend,通過cast 到獨立 gen_server2 寫磁盤,或者cast 到網絡寫到日志服務器上去
3. gen_server receive-match 問題
避免在熱點gen_server 中使用receive-match 方式,或者都使用如rabbitmq 中的gen_server2,一定要防止在message_queue_len可能
比較大的進程中做recieve-match,error_logger就存在這個問題。
4. 熱點進程
erlang 是公平調度,熱點進程在負載稍高時,就會沒機會得到處理,注意設置priority high
5. 單進程處理瓶頸
erlang 中因為進程無法共享數據,往往使用單個gen_server 完成共享邏輯,但erlang CPU計算是很低效的,往往但進程無法完成業務處理。
這個時候需要拆分到多個進程處理,如:server_1, server_2 .... 。
6. ETS
4、5 另一個解決方案是使用ETS,ETS 可以作為全局表,所有進程都可以讀寫,不存在熱點進程,而且減少了進程消息交互成本,效率要高很多。
但是,ETS 是表結構,能夠適合的場景很少,能用那就盡量多使用吧。
7. rpc:call
成本較大:一次調用有3次網絡往返
服務端單進程:服務端有rex 進程處理,容易產生瓶頸,測試最多處理 10w/s 消息
如有必要盡量多使用 Pid ! Msg - receive 方式
8. gen_server:call timeout
timeout 是給call 方返還的,而實際處理一定會被處理,而且reply 也會在timeout 后發回message_queue,要注意。。
9. Pid ! Msg
Pid 不存在時,消息丟失, gen_cast 也一樣;就算is_process_alive 判斷也會存在競態,所有是無法判斷是否send sucess ,只能reply 確認
10. 依賴supervisor
erlang 設計模式,一般不怎么處理異常,非常態錯誤依賴supervisor 重啟。 但如果gen_server 存在數據,重啟瞬間 就會丟失數據。