現在市面上的編程語言以面向對象為主流。面向對象先要從一些最基本的做起。比如我24歲就結婚了,不然怎麼面向對象編程。然後剛結婚就生娃了,不然對象跑了咋辦?new一個?創建銷毀開銷很大的,還是生個娃持續持有對象的引用的好。 為啥有些人開口說話能說很久,有些人說話有一搭沒一搭的?據我觀察發現,動手幹活差不 ...
現在市面上的編程語言以面向對象為主流。面向對象先要從一些最基本的做起。比如我24歲就結婚了,不然怎麼面向對象編程。然後剛結婚就生娃了,不然對象跑了咋辦?new一個?創建銷毀開銷很大的,還是生個娃持續持有對象的引用的好。
為啥有些人開口說話能說很久,有些人說話有一搭沒一搭的?據我觀察發現,動手幹活差不多的兩個人,會說的將來發展的會更好。原因從具體實例來感受一下。
和朋友聊天,真的,好幾年前人人網出來的總有點技術極客精神,聊天我們聊技術。人家問我你們視頻是怎麼存儲怎麼播放的。我說我就是做內容,meta的,其他和我無關。天兒就聊死了,自己的格局就下來了。如果說我做的有開發平臺的東西,裡面有上傳視頻的。先調用雲存儲的介面進行一個初始化,他們返回給我們一個視頻介質上傳url。JS端將介質分片的方式上傳到url上。如果網路中斷或者瀏覽器關閉啥的,可以調用續傳介面用新返回的url繼續傳。續傳介面帶著總文件大小和目前已經收到的文件的大小,JS可以依據這個判斷從哪個分片繼續傳。雲存儲在另一個部門,他們負責和雲轉碼部門進行通信,雲轉碼將介質轉成各種格式,至於從原始高清文件轉成各種碼率,怎樣取樣的,DRM數字版權管理又是怎麼做的,由雲轉碼部門負責。他們內部是用什麼策略分發到各個DNS節點上的。調度部門又是怎樣調度來節約視頻網站最寶貴的帶寬的,具體細節我不是很清楚。雲轉碼部門將轉換好的各種碼率和視頻url通過MQ的形式傳給我們,我們存到資料庫里。
那人家就又問了,MQ你們用的啥呀?我說apache的qpidd。額~~,人家不知道,聊天就聊死了。所以得說MQ都差不多的,和rabbit mq一樣都是基於AMQP高級消息隊列協議的。這是公司統一的集群,說是安裝部署挺方便的。主流的編程語言也都支持,所以就用了。因為主要是跨部門的通信,主要以方便,節約溝通成本為主,所以我們的消息體也就是json先壓縮再base64。也沒用protobuf那些二進位的,因為萬一遇到問題,二進位可讀性差,缺乏自描述,不容易排查。
高併發服務必須有一些緊急方案,比如服務熔斷,降級,隔離,限流,非同步RPC等。服務熔斷,降級,隔離大家比較傾向於用netflix開源的分散式服務彈性框架Hystrix。Hystrix也可以限流。但是我們服務用的guava的RateLimiter這種成熟的令牌桶演算法來實現。
服務限流是個很簡單的事情。我們的代碼也就幾百行,但是裡面有一套比較完整的設計思想,目的是根據一定的策略(如:url, 平臺來源,url+平臺來源)來做一個業務細粒度的限流。
所有的請求都要走這個攔截器,這個攔截器里定義了一個單例的限流持有者,這個限流持有者按照配置的策略和配置的每個或者每種請求的限額來構成的map來返回給攔截器請求對應的key和RateLimiter。攔截器里判斷超限則直接返回錯誤不交給控制器處理。一個請求類型,如url一個RateLimiter細粒度限流。
當然,除了這種應用級別的限流,在nginx層面也可以做一些對IP的session空間,請求頻率,併發量的限制。如果遇到網路攻擊,儘量先從運維層面去解決問題,因為越往上層,對服務的影響能降到最低。
一個好的軟體架構能夠滿足系統的品質,使受益人達成一致的目標,能夠支持計劃編製過程,對系統開發的指導性,能夠有效的管理複雜性,為復用奠定了基礎,能夠降低維護費用,能夠支持衝突分析。
絕大多數架構或者編程語言的產生都是來源於項目。比如C++的發明者Stroustrup設計這個語言的初衷是看到C語言由於不合理的初始化參數導致至關重要的編程問題,這種bug很難發現。這種問題在清理的時候同樣出現。做了堅持了,確實就成功了。然而任何一個東西都有一個形成和發展的階段。java在老一些的版本中一直被吐槽性能問題,而它的每一個版本都要伴隨著性能的提升,所以升級JVM就能帶來免費的性能福利。細節處想到final關鍵字,在早期的版本中,final關鍵字的部分會內聯調用,直接將函數展開,而不用不斷的參數入棧出棧而引起性能開銷。但是這個在函數體大的時候會有空間上比較大的開銷。JVM在1.5開始進行了優化,final關鍵字性能上的作用就不再那麼大了。原來公司有個同事,人很好,也很有想法。他說:“我總是會將自己的一些想法記錄在一個本子上,然後過一段時間再看就會發現,我那篇只堅持了當時的其中一個想法,去做了,都成功了。”我認為他離成功比自己想象的要遠很多。因為他有的只是想法,並沒有去做。就好像只有JDK1.0的想法,但是路程離成功至少有離jdk1.5的距離。
Python以代碼量小,維護成本低,編程效率高著稱。但是哪有幾個編程語言不是以維護成本低,編程效率高作為優化點的呢?所以人家問我搜索引擎已是一片火海,你將來真的能打造出自己的優勢嗎?我只能說不試怎麼知道。“人生苦短,我用python”。Python的這些特點可以騰出更多的時間去把妹了,可不就人生苦短了嘛。Python作者的廣告詞給了Python生命力。實際上Python的簡單性從它的記憶體回收就可見一斑,它用的是引用計數法,可見不存在迴圈引用問題。我在人人的時候做過一個python的項目。有段時間我們領導說我一個人做了8個人的活兒。除了整個網站所有的維護工作之外,各種新活兒我都接。就是這個性格,別人實在沒辦法來找我了,我只為難自己,不為難別人。那時候工作不到四年,編程時間不到兩年,我說過工作頭兩年是當日語翻譯的。之所以能去人人。話說一日我剛來北京,和學長正在逛頤和園,突然接到人人網面試電話,電話那頭問我各種技術問題,我的回答都是不會。結果那頭非常nice的說沒關係。最後電話那頭換了一個面試官,用日語給我講話,問我做了啥,她對我的回答非常滿意,滿意主要是發現我日語非常好。結果我就成了人人網的橋梁工程師。記得我前面寫的文章里個人簡介里寫憑藉自己的語言天賦被網友吐槽了,但是我在東軟的時候人人都說我有語言天賦,我自己也就習慣這麼認為了,我只是理所當然的認為自己在陳述一件事情,並沒有標榜的意思。我也不會python,我也根本不知道啥是開放平臺。但是我一個人接手負責整個開放平臺的維護,因為開放平臺的老大跳槽去美團了。話說這個老大真是個牛人,清華的,創過業,來了人人,又去美團做到了P4,現在又自己創業去了。有一天我家男神拿著一個清華校友會的照片問我:“這個人好像是你原來同事吧”。我說:“嗯呢”。他說:“他旁邊坐的是我們老闆”。好吧,看來我家男神可進步的空間不是一般的大。
我硬著頭皮維護這個開放平臺。然後泡泡魚游戲要接入一個日本平臺。這個游戲是python寫的。那時候這款游戲非常火,這個游戲公司超級忙,沒時間給接入,給錢找我們幫忙。我們只能自己把代碼拿過來接入。那時候人人網喜歡搞內部創業,我們是海外事業部,本來就是不賺錢的。我做了那個接入,游戲方給了我們10萬接入費,剩下的就是游戲分成,收入我就不知道有多少了。但是這是我們那時候唯一賺錢的一個項目了。Python真是非常好學,我白天維護網站,所有的人都來找我,晚上做接入,研究python和接入文檔,1周時間把支付接入部分搞定了。測試環境可以充錢了。但是上線有問題,運維MM搭建的正式環境跑的時候有一塊怎麼都不對。晚上所有人都回家了,我自己在那裡弄線上環境。後來終於發現安裝的一個部分一個工具的版本不對,具體怎樣不記得了。6年前的事情了。所以我做過python,但是不會python。
Java與C++之間有一堵由記憶體動態分配和垃圾收集技術所圍成的高牆,牆外面的人想進入,牆裡面的人卻想出來。Java上不能那麼隨意,也就是優化一下記憶體分配參數,說起JVM參數優化,其實最常用覺得人人都知道不當回事的就是堆的初始最大值和最小值設置成相同的值,這樣避免堆自動擴展,調整新生代和年老戴的大小的full gc造成的吞吐量降低和延遲。話說JVM的幾乎所有gc操作,包括minor gc都要stop the world.
最後給大家推薦一個國外的網站http://blog.takipi.com/。經常會介紹一些實用工具和調優技巧,註重分析。代表作有http://blog.takipi.com/7-new-tools-java-developers-should-know/和http://blog.takipi.com/how-to-instantly-improve-your-java-logging-with-7-logback-tweaks/