有一個讀者問我:你認爲一個程序員具有什麼樣的能力,纔算得上是厲害的程序員?html
我答:擁有解決問題的能力的程序員。程序員
這個回答貌似有點抽象,沒關係看下面的文章你會慢慢有所瞭解。spring
不少年前,當我仍是一個小菜鳥的時候,個人領導常常告訴我,解決問題的時候,不要侷限於技術自己,而且形象的給我舉了一個例子。sql
有一次兩個程序員一直討論,如何判斷兩臺服務器之間是否網絡正常,爭爭吵吵了好久。旁邊的一個測試說,Ping 一下不就知道了嗎?就這樣他們用 Java 代碼實現了 Ping 操做解決了這個問題。數據庫
多年之後,雖然我知道有更優雅的方式來解決這個問題,可是我仍然以爲以前的那個測試人員很聰明。後面咱們持續打過一年交道,她能力真的很強,在小公司至關於產品經理+測試的職能。後端
須要給你們說明的是:解決問題的能力和技術能力是兩個能力區間,我見過不少程序員源碼玩得一溜,生產出現問題的時候仍然不知道如何去解決問題。設計模式
生產出現問題的時候,是考驗一個程序員的最高水準,在面對高強度高壓力下,動做不變形,可以冷靜思考、分析、解決問題,能達到這個水平的程序員,這在古代能夠拜爲上將軍。安全
我一直很是喜歡可以快速解決問題的程序員,我也樂於在各類生產出現問題的時候,第一時間去研究去分析。說一句不厚道的話,好程序員都是在解決問題中鍛煉出來的,特別是生產環境出現問題時,可以站出來的程序員。服務器
公司有一個老系統,一個新系統。網絡
老系統使用了不少年,早已經超出了它能支持的極限,最先在2013年上線這套系統的時候,預估天天的交易量在一兩個億,實際上如今天天已經跑出了 40 億的交易量。
從2013-2017年,技術團隊作了不少努力,老系統使用的是 Oracle 數據庫,爲支持最大的交易量,讀寫分離分庫分表+各類最強硬件搞上;系統拆分、重構、優化了不少次,仍然知足不了公司日益增加的交易量。
說實話,團隊能把一個老系統整成這個樣子,也確實不易。最初的架構設計不合理,縫縫補補終究解決不了大問題。研發新平臺成爲公司發展必需要作的一件事情,新平臺一期設計能夠支撐日百億的交易量,最重要的是支持後期日千億的擴展。
通過兄弟們的艱苦奮站,新平臺終於上線了。新平臺上線是成功的一小半,後面的數據遷移纔是最最重點的事情。 運行了好幾年的老系統,使用的是傳統的垂直架構,(架構演進能夠參考這篇文章:從架構演進的角度聊聊Spring Cloud都作了些什麼?),各類業務、政策、活動、風控都揉在了一塊兒。
新平臺使用的微服務架構,光微服務就搞了上百個,數據庫 Mysql HA。兩個系統在架構設計上隔了一代,在設計時爲了兼容老系統的部分功能,還作了部分冗餘設計,反正這兩個系統就不是一個時代的產物。
遷移的要求是,從老平臺遷移到新平臺的時候,不能影響到商戶的正常交易。打個比喻就至關於,你開着車在高速公路上跑,在行駛的過程當中換掉車輪,而這個過程還得讓坐車的你還不能有任何感受。
因而咱們研發了一套遷移系統,原本計劃着一批一批的遷移,給新平臺一次切一兩個億的交易量,慢慢看看效果再根據節奏來走,可是忽然來的一次政策(活動)打亂了這個節奏。
對於第三方支付公司來說,常常會隨着市場環境推出一些新政策(活動),有些政策比較簡單,但大多數政策很複雜,每每須要很大的開發量。
當時新平臺已經切換了一段時間,你們慢慢對新平臺有了必定的信心,就決定在這個新政策在新平臺實施。計劃在執行政策的當天晚上,把其中一個老平臺上剩餘的商戶所有遷移到新平臺。
方案定下來以後,各部門開始各司其職,運營中心對外發通知,咱們要在元旦的時候搞個大動做,可能會有什麼樣的變化;營銷中心負責聯繫各代理進行分批培訓;商務部門開始出公司的紅頭文件,下發各分公司。
咱們提早和客服、運營部門作好溝通,可能會面臨哪些問題提早作預案;公衆號、公司官網、App、郵件對外通知政策變化,公佈開始執行日期;產品中心負責政策落地需求梳理,研發中心開發新政策肯定的方案。
最最最重要的是,要確保元旦晚上能夠把剩餘幾百萬的商戶,一次性平穩的遷移到新平臺。
遷移程序以前已經執行了不少次,因此你們對這塊相對比較放心,但仍然和主要負責遷移的同事確認了好屢次,開發環境提早兩週必須測試完畢,UAT環境須要在遷移一週前測試完畢,研發和測試雙驗證。
直到距離遷移還有三天的時候,我還專門找到負責遷移的那名程序員瞭解進展,問有沒有在生產上進行過模擬測試。確認沒有問題後,根據主負責人反饋的時間預估三四個小時能夠遷移完畢,這樣凌晨 1:00 開始,凌晨 4:00-5:00 之間能夠遷移完畢。
在真正執行遷移的前一天,又拉着各部門作了一次溝通會,你們一塊兒討論可能出現的各類狀況,以及各部門須要留守的人員。開完會以後,你們感受都還不錯,靜等晚上這一場大戰!
當天晚上留下來十幾名開發和兩名測試,以及一些其它部門的同事,大概二十幾人左右,12點以前你們說說笑笑,打打遊戲靜等凌晨 1 刻遷移,由於恰好是元旦,辦公室一片過節的感受。
時間過得很快,凌晨1點的北京,窗外星光點點,辦公室內一片緊張。
十幾名同事都圍在了主要負責遷移的這名程序員旁邊,能明顯感受到這名程序員頗有壓力(哈哈,我估計這種事情放誰身上都會有壓力)。不過他仍是熟練的按照以前屢次測試的那樣,覈查了多遍數據以後,點擊遷移按鈕。
首先在生產環境遷移一個代理商,看看數據是否正確,執行完畢後相關人員開始覈驗數據。運維人員覈查日誌,開發人員確認相關節點正常、數據庫工程師覈對遷移數據;測試人員在運營平臺查詢數據覈驗、測試 Pos 刷卡測試,一切正常!
試了兩個代理商都沒有問題,下面就準備 All In 了,剩下幾百萬商戶,上千個代理商就計劃一把梭了。負責遷移的程序員,將全部代理商編號,配置到執行程序中,點擊了執行按鈕,生產跟蹤了一下日誌,一切正常。
留下幾我的監控數據,其餘人就散了,等遷移完成後再進行後續工做。我也回到了工位,點起了一根菸,想着今晚還比較順利。
凌晨的夜晚比較困,當我點起第三根菸的時候,負責遷移的這位程序員,急匆匆的跑過來找我了。
「強哥,出現問題了!」
心中一驚,猛吸一口煙,把煙掐滅,忙問到:「出現啥問題?」
原來這位程序員在遷移程序執行後,就一直在跟蹤遷移的進展,發現過了半小時才遷移了10萬商戶,老平臺總共幾百萬商戶,按照這個速度,所有執行完須要幾天後。
這個事可大了!
若是在上午8:00 以前不搞定這個事情,那就徹底是重大事故了。
先不說怎麼處理新老平臺數據割裂,若是公司政策推遲執行,怎麼在這麼短的時間內把信息通知到幾百萬商戶、幾千個代理商,就是一個不可能完成的工做量。
能夠想象次日都會出現什麼樣的情況,客服400電話被打爆、運營人員溝通到吐血,因政策推遲執行可能致使的公司損失,針對代理商的補償行爲...
若是這個問題咱們沒有在一個小時內解決掉,就須要馬上上報公司副總經理,而後估計連夜公司全部的管理層,都須要來公司開會商量後續處理方案。
大腦中雖然閃過遷移失敗後的嚴重後果,但眼前還須要壓下全部的想法,先分析究竟是哪裏出現了問題,有沒有什麼樣的降級方案或者補救方法。
分析緣由:
通過查詢日誌、覈對數據基本查明瞭緣由,開發人員在生產測試的時候,都使用的是中小型代理商進行的測試;但忽略了公司不一樣代理商規模之間差別極大,最大的核心代理商一家的數據,可能佔平臺總體交易量的5%-6%。
因此根據中小型代理商評估的時間確定是不許確的,事已至此先不說誰的問題。如何快速解決問題纔是接下來的關鍵,你們都一塊兒想解決方案,有什麼辦法可讓遷移速度更快一點。
補救方案:
好比先同步核心數據,其它內容後續再進行處理,先保障次日的交易;好比可不能夠所有使用人工導表來處理,數據庫工程師聽到這個方案的時候,差點哭暈過去,上千多張表,關係極爲複雜;其它各類各樣的方案..
在你們七嘴八舌討論優化方案的時候,才發現遷移程序的主流程沒有使用多線程來遷移。
遷移程序提供了一個界面,每次遷移的時候開發人員會在頁面填寫須要遷移的代理商編號,後臺接收到頁面傳遞的參數後,開始 for 循環執行遷移。 雖然代理商下的商戶使用了多線程遷移,可是遷移代理商的主程序入口,卻沒有使用多線程,所以你們想是否把代理商這塊也用多線來加快遷移速度。
你們討論以後,以爲多線程來遷移代理商應該是目前比較好的一個方案,可是若是讓現場寫,沒有通過測試直接就生產執行,風險仍是比較大。
那還有什麼不用改程序就能夠實現這種代理商併發遷移的效果嗎?確實有!
你們知道咱們平時開發的 Web 應用,前臺的每一次請求到後端就會分配一個 Servlet 來處理響應,這個 Servlet 其實就是一個獨立的線程。那麼每次多打開幾個頁面,同時執行遷移請求不就實現了多線程遷移代理商的效果嗎?
說幹就幹,把以前的遷移程序停掉以後,選擇十幾個代理商進行多線程遷移測試,同時打開了4個頁面,每一個頁面輸入不一樣的代理商,開始遷移測試,測試後發現一切正常。
開始加大測試量,使用幾十個代理商,在不一樣的頁面輸入後,前後點擊了遷移程序,在第二次併發遷移的過程忽然發現不時的會報一些錯誤。
中止遷移程序,開始尋找緣由,根據報錯的緣由發現是出現共享數據了。
咱們知道 Servlet 是線程不安全的,當出現多線程訪問的時候,若是有全局共享變量就會出現線程安全問題。
這個問題好解決,使用 ThreadLocal 來修飾就行,ThreadLocal 爲每一個使用該變量的線程提供獨立的變量副本,因此每個線程均可以獨立地改變本身的副本,而不會影響其它線程所對應的副本。
這個問題解決以後就繼續打開多個頁面執行,但同一個 Tomcat 並行超過 6 個線程的時候,機器負載就會比較高,由於每一個線程內還會再次調起另外的線程池來處理商戶、業務員的遷移邏輯。
因而就馬上安排運維人員,在生產環境找十臺服務器,在這十臺服務器上都部署上遷移的主調度程序。爲了防止開發人員手抖出現問題,我讓運維給我開了權限。
因而在個人電腦上(我使用了多個屏幕),分別打開了十臺服務器上的遷移程序頁面,把全部須要遷移的代理商按照每次十五個分組,每次在一個頁面輸入一組代理商來遷移,如此循環依次在每臺服務器開始遷移代理商。
當我循環執行了6次的時候,數據庫工程師檢測到明顯數據的遷移速度加快,就這樣我用了兩個小時,在頁面把全部的代理商分別進行了遷移。
大概到凌晨 4 點的時候,個人工做基本上搞完了,剩下的就讓程序慢慢跑了;凌晨 5 點的時候,大部分商戶數據都已經遷移過來,只剩下兩臺服務器還在繼續跑;到了凌晨 6 點的時候,十臺服務器的遷移程序所有跑完。
安排把全部相關數據一一進行了覈對後,你們長長的舒了一口。
早上 7 點一塊兒下來吃早餐的時候,你們還在說,感受昨天晚上差點就過不去了。開玩笑說,若是凌晨二、3點的時候,給咱們老闆打電話,老闆會是什麼樣的感受。
那時候想,出現這麼大的事故,老闆把咱們開除了都是小事,如何收場纔是咱們最關心的。工做丟了能夠再找,事情無論怎樣都是須要咱們這批人來解決處理的。
上午 9 點打開交易後,又陸陸續續出現了一些小問題,但都是小面積的、不影響交易的問題,總體範圍可控,晚上遷移的這幫人,幾乎都堅持到了下午沒有太大問題了纔回去睡覺。
過後回想時,你們都一種劫後餘生的感受。
過後咱們開復盤會的時候,總結了這裏面疏漏的不少點,但這些都不是本文的重點。咱們仍是回到文章的開頭,什麼是厲害的程序員?
你們能夠看到這個問題並非特別的複雜,處理時須要的技術手段也比較簡單,但最關鍵是解決了當時最最緊迫的問題。因此說技術沒有什麼高低之分,學習技術的本質也是爲了解決各類各樣的問題,不要對技術迷之自信,能用起來纔是最好。
技術人要學會享受壓力,由於壓力就是動力,壓力就是讓你去成長的,越早遇到成長得越快。人在高壓高強度的環境中,哪怕很簡單的動做可能都會變形,從而有可能引起更大的二次事故。
在高強度、高壓力的環境下穩定保持一顆冷靜分析的心,只有你本身沉靜下來才能真正的發現問題解決問題。不少技術人,出現問題時你看他在忙,實際上是沒有思路在那瞎操做。
冷靜下來,仔細分析整個鏈條,設想哪一個地方可能會出現問題,而後經過查詢日誌或者相關命令,一步一步去排查、驗證問題的根源在哪裏,只有真正找到了問題的根源,你解決的時候才能夠成竹在胸。
當天晚上留守遷移的程序員,都是我司最核心的一批程序員,可是誰有能力上誰有能力下,在這一夜很容易就能發現,優秀的程序員就像金子同樣,關鍵的時刻它會發光的。
不少人遇到問題就天然的就會後退幾步,有的人遇到問題就喜歡衝上去。無論你平時源碼研究得多牛逼,無論你的 PPT 寫得有多好,公司須要的是遇到問題的時候,有人可以頂上去把問題解決掉。
凡是可以在關鍵時刻頂上去的程序員,基本上後面都很容易走上管理崗位。人和人其實就是在不斷磨合中創建信任的,領導在選擇提拔員工時,主要考慮就是能不能放心把事情交給你。
因此你們平時研究技術的時候,不要走偏,源碼、設計模式這些東西是應該研究,但更應該考慮的是研究後如何去應用,多專一一些實戰型的知識,這些東西關鍵時刻能夠救你的命(職場)。
那麼做爲一名程序員,如何培養本身解決問題的能力呢?**實踐!實踐!實踐!**平時的技術學習只是一種強力輸入,若是不進行實踐,這些能力就會很快流失了。
那如何實踐呢,多作項目,若是公司的項目用不到此技術,能夠本身業餘時間寫寫代碼本身去調試一番;另外同事出現問題的時候多去幫忙解決問題,公司出現問題的時候,主動去幫忙解決問題;解決各類各樣的問題,是提高能力的最快方式。
實踐完成以後,最好還能覆盤總結一番,把總結的內容做爲日誌或者博客記錄下來。記錄下來的內容就會成爲你的一個知識寶庫,之後遇到相似問題的時候,檢索一下便可解決,如此不斷豐富本身解決問題的經驗。
最後,願你成爲一名真正的技術大拿!