摘要:最近在維護一個三年前的舊代碼,用的是框架。單元測試和語言并發(fā)控制實際上是個蛋疼的問題,夸張一點說,當(dāng)時的并不能特別輕松地實現(xiàn)并發(fā),甚至不能實現(xiàn)并發(fā)。語言的功能之一就是自帶單元測試。用語言之前,我的習(xí)慣是不寫單元測試。
最近在維護一個三年前的舊代碼,用的是laravel框架。
從某些方面來講,這個代碼算是比較標(biāo)準(zhǔn)為了實現(xiàn)“在規(guī)定的時間內(nèi)完成相關(guān)功能”,同時“程序員水平不高”、“經(jīng)過大量優(yōu)化”之后,變地特別爛的。但是其中,程序員的水平和態(tài)度是最主要的,其他相對于而言都是次要的。
當(dāng)然,我就是那幾個程序員之一,所以我可以放心大膽地說自己的壞話。
另外本文會多次提到語言間的對比,當(dāng)然本文的目的并不在此。
框架之爭無論是當(dāng)年來看還是現(xiàn)在來看,Laravel框架思想還是結(jié)構(gòu),都算得上是“Modern PHP”的典范。
Laravel之于php,就相當(dāng)于springboot之于java。
Laravel針對http請求引入了中間件,稍微配置一下便可以很方便地使用類似servlet的攔截器,功能還遠(yuǎn)比servlet強大。
針對ORM類的需求,自創(chuàng)了eloquent框架,使用的簡潔性上也算得上是一流。
至于安裝、配置、部署、依賴等等,laravel也都提供了完全通用的方案,這就很可怕了。
可以這么說,如果我們完全按照laravel的架構(gòu),完全遵照laravel的文檔,寫出來的代碼即便不會很優(yōu)雅,但是也絕對不會特別坑。
當(dāng)然,laravel缺點也是很明顯的。最重要的一個缺點,性能。
作為PHP框架,laravel的性能無意識特別拖后腿的地方。我們這里已經(jīng)沒有詳細(xì)數(shù)據(jù),但是大概的數(shù)據(jù)我們可以提供一下:一個最簡單的路由,里面只有Redis::set這一個操作,并且沒有任何中間件或者計算邏輯,24C64G的機器,只能支撐到大約300+QPS,即便開了opcache等也沒有質(zhì)的提升。至于php7,第一個7.0版本是發(fā)布在15年12月,項目上線四個月后,不要說還要等laravel支持PHP7,更不要說php7也滿足不了性能需求。
這也就是我們第一版代碼就已經(jīng)是兩種語言異構(gòu)的原因。
PHP部分用于處理正常業(yè)務(wù)請求,Go部分用于處理心跳等其他請求。
技術(shù)和能力在后續(xù)的幾年內(nèi)我們也在反思這個問題。
如果我們當(dāng)初做的是采用tcp協(xié)議進行傳輸數(shù)據(jù),服務(wù)端也用Go,那么我們還可以做很多“看上去很酷”的事情,例如:我們可以實現(xiàn)并到處宣揚C10K、C100K,可以到處宣揚實現(xiàn)了十萬百萬MPS(Message per second),可以將所有的任務(wù)結(jié)果流式傳輸?shù)椒?wù)端,可以做到同步返回結(jié)果,可以讓用戶體驗上更好。
但是如果這樣做的話,無狀態(tài)、流量、日志存儲等便是要考慮的新問題。這可能會把我們培養(yǎng)成技術(shù)流,但是也可能把我們的項目變成新的“技術(shù)瘤”。
現(xiàn)在回想起當(dāng)年,更重要的問題在于,我們確定當(dāng)時參與者沒有人敢提出這種方案,更沒有人能駕馭住這個方案。
維護成本維護成本無疑是后期最大的成本。
早期我們依賴supervisord,在最早期我們經(jīng)歷過supervisord和docker的supervisord沖突的故障,后期我們也經(jīng)歷過其他項目也依賴supervisord、因為配置原因?qū)е缕渌椖勘煌V沟墓收稀9收厦?,自己的鍋自己背,也沒什么好說的。
但是其他的維護成本是比較多的。
你所能想到的,例如agent的?;?,算是比較常見的問題,幾十上百個agent總會有一兩個出問題,這個我們也都習(xí)以為常了,甚至自己做一做自動修復(fù)也能解決問題。
你所不能想到的,有些人將環(huán)境相關(guān)的任務(wù)也給算到你的頭上。有些人會因為“你這個系統(tǒng)怎么在這個環(huán)境出現(xiàn)了這個問題”,查了半天,對方端口沒有打開。
這點在我們中間件相關(guān)的項目比較常見。通常他們會上來就問這個中間件怎么出這種問題了,實際上呢,讓他們把堆棧完整地發(fā)出來之后,告訴他們“caused by里寫明了,unknown host,就是你的XXX域名沒配嘛”。每天都有四五個人問這種問題,也會給答疑方帶來很大的壓力。
在我們的其他工作中,也在不斷地探索如何減少教育成本,F(xiàn)AQ、培訓(xùn)似乎收效都不高。
假裝噴人似乎有效,例如“你XX的是不是又開遠(yuǎn)程調(diào)試了(此處請腦補意大利炮)”,但是這種操作也不能每天都能做的。
如何降低教育成本、讓開發(fā)者自己擁有自己解決問題的能力,一直是我們工作的重點。但是目前看起來,我們在這方面收效甚微。
需求、功能、BUG和變遷這個項目我們也算是頂住了很大壓力,沒有接新的需求,也沒有再去增加新的功能。
我們當(dāng)時的理由是“他僅僅是個任務(wù)的服務(wù)端”,“你只要如此這般寫這個任務(wù)便可以實現(xiàn)這個功能了”。
但是后續(xù)系統(tǒng)變遷是我們當(dāng)時所沒有考慮的。
后續(xù)我們有了一個新的任務(wù)管理界面,有了新的統(tǒng)一登錄接口,CMDB的接口也幾經(jīng)變化。
最終這個系統(tǒng)只剩下API每天任勞任怨地工作著。
按理來說沒人訪問的接口和界面就應(yīng)該直接下掉??墒侵辽龠@也是親生的bug,我也心軟,沒辦法下手。
根據(jù)其他系統(tǒng)的經(jīng)驗,有時候我們是不得不添加部分功能的,而這部分功能我們可能會引入很多問題。
舉個例子,某些人吐槽為什么大公司的代碼如此之爛,一個項目中httpclient就有四個版本。
這件事情可以理解,例如早期可能只用了HttpURLConnection進行g(shù)et請求,中期為了支撐post請求,支持參數(shù),支持超時,分別對HTTPClient了封裝,后期因為引入JWTs,又封裝了一次。代碼冗余度變高,但是既然“系統(tǒng)跑得很好”,也就“沒有精簡的必要”。
可以理解,但是不代表可以接受。
代碼冗余一直是內(nèi)部項目重構(gòu)時常見的問題,通常表現(xiàn)為為了不影響原有代碼的執(zhí)行,把現(xiàn)有的代碼拷貝一份,換個名稱,修改一下交給新接口來調(diào)用。
Java等靜態(tài)語言合并冗余代碼比較簡單,編譯成功即可保證大部分功能可用。但是php等動態(tài)語言我們則不敢這么做。PHP做不到“編譯成功便保證基本沒問題”。
就這個例子來看,一方面是開發(fā)對HttpClient的認(rèn)知不足,另一方面則是開發(fā)對代碼的抽象能力不夠,也未留下適當(dāng)?shù)慕涌跐M足未來的需求,才會出現(xiàn)“一個項目中httpclient就有四個版本”的噩夢。
有些內(nèi)部系統(tǒng)也會和早期的我們一樣,首先為了做出成果,然后才是追求更高層次。
但是這并不是一個做技術(shù)的人應(yīng)該有的態(tài)度。
優(yōu)秀程序員的價值,不在于其所掌握的幾招屠龍之術(shù),而是在細(xì)節(jié)中見真著。
如果我們可以一次把事情做對,并且做好,在允許的范圍內(nèi)盡可能追求卓越,為什么不去做呢?
成果是要有的,但是一個做技術(shù)的人,應(yīng)該有對職業(yè)的自我尊重、對自我價值的追求和對卓越的理解和渴求。
完美有多遠(yuǎn)?不知道,但是我以后肯定會多走幾步。
單元測試和語言并發(fā)控制實際上是個蛋疼的問題,夸張一點說,當(dāng)時的PHP并不能特別輕松地實現(xiàn)并發(fā),甚至不能實現(xiàn)并發(fā)。我們目前的服務(wù)端實際上只是做了任務(wù)轉(zhuǎn)發(fā),采用了一些取巧的方法實現(xiàn)并發(fā)(curl_multi),但是我們并不能實現(xiàn)并發(fā)控制等功能。至于說多線程(pthreads)和多進程(pcntl)的方案,實測下來也并不穩(wěn)定,測試階段便會產(chǎn)生coredump。
并且經(jīng)過多次調(diào)優(yōu),我們也最終解決了curl_multi的性能問題,可以達到成千上萬的并發(fā),并且性能還算可以。
現(xiàn)在復(fù)盤一下,如果用的是Go的話,可以很輕松地用5-6行代碼增加并發(fā)控制。Go語言自身性能不錯,并發(fā)也很好。
Go語言的功能之一就是自帶單元測試。這點和maven差不多,但是Go是少數(shù)幾個語言層提供測試工具鏈的語言之一。
相比于動態(tài)語言,靜態(tài)語言的優(yōu)勢之一便是安全。
可以稍微夸張點講,靜態(tài)語言一旦編譯成功,除非有RuntimeExcetion,不然基本不會出問題。
而PHP這種動態(tài)類型的語言,就比較蛋疼了:不僅寫的時候可能會有問題,很多IDE也無法意識到你到底是不是寫了個bug,甚至過幾年回來閱讀代碼,即便是自己參與過的項目,讀起來代碼也很蛋疼。PHP也意識到了這一點,從PHP7引入了類型聲明,也能緩解這個問題。
用Go語言之前,我的習(xí)慣是不寫單元測試。用了Go語言之后,我開始養(yǎng)成對所有函數(shù)都寫單元測試的習(xí)慣。
我們本文中提到了很多次Go語言,實際上語言對項目的影響并不大,真正起主導(dǎo)作用的,還是人。
規(guī)范運維規(guī)范對本項目的影響并不大,主要是開發(fā)規(guī)范。
后續(xù)的工作中,我不止一次·告誡業(yè)務(wù)開發(fā),我們目前所有的規(guī)范,無論是運維規(guī)范、數(shù)據(jù)庫開發(fā)規(guī)范,或者任何代碼開發(fā)規(guī)范,都是我們一次一次地踩坑鋪出來的路。
如果當(dāng)初我們有數(shù)據(jù)庫開發(fā)規(guī)范的話,表結(jié)構(gòu)也不會這么坑。就像laravel框架一樣,我們按照規(guī)范來寫,不至于讓代碼上升一側(cè)層次,但是也不至于讓代碼爛出水平。
在此我們強烈對小公司和開發(fā)人員推薦《阿里巴巴Java開發(fā)手冊》,不僅有開發(fā)規(guī)范、還有表結(jié)構(gòu)規(guī)范,無論是對開發(fā)或是對公司都有好處。
語言對項目的影響并不大,真正起主導(dǎo)作用的,還是人。
如果人的平均素質(zhì)并不能達到優(yōu)秀的話,那么完善的流程和規(guī)范將能很大程度上影響一個項目的質(zhì)量。
總結(jié)教育成本是后期維護的主要成本之一,我們也一直嘗試賦予開發(fā)者自己解決問題的能力,雖然很難。
人的素質(zhì)無疑能直接決定一個項目的質(zhì)量。
當(dāng)然,對于普通公司、新人這種平均素質(zhì)達不到優(yōu)秀的情況,完善的流程和規(guī)范將很大程度上保障一個項目的質(zhì)量。
靜態(tài)語言、單元測試等手段是保障項目穩(wěn)健性的重要方式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/29336.html
摘要:爆款車?yán)遄拥淖杂少u相好看色澤鮮艷的車?yán)遄诱谴汗?jié)期間討喜的送禮熱門貨之一。智利農(nóng)業(yè)部樂觀預(yù)計,本次出口季銷售成績有望實現(xiàn)的增長,而中國人的春節(jié)消費成了智利果農(nóng)今年最大的期盼。 本博客 貓叔的博客,轉(zhuǎn)載請申明出 前言 本系列主要是貓叔對互聯(lián)網(wǎng)相關(guān)產(chǎn)品(兼任產(chǎn)品經(jīng)理)路上的視野擴展與信息記錄,每日三篇,記錄分享。 爆款車?yán)遄拥淖杂?賣相好看、色澤鮮艷的車?yán)遄诱谴汗?jié)期間討喜的送禮熱門貨之一...
摘要:作為文科專業(yè)畢業(yè),無名校背景,無任何關(guān)系,沒有接受過任何專業(yè)培訓(xùn),完全靠自學(xué)和看書看視頻做了五年前端,在外包公司,創(chuàng)業(yè)公司,級公司再到新型互聯(lián)網(wǎng)公司都呆過,想結(jié)合自己的經(jīng)歷談?wù)剬τ谧詫W(xué)前端的一些看法學(xué)習(xí)大綱關(guān)于技術(shù)棧學(xué)習(xí),網(wǎng)上總會有各種討論 作為文科專業(yè)畢業(yè),無名校背景,無任何關(guān)系,沒有接受過任何專業(yè)培訓(xùn),完全靠自學(xué)和看書看視頻做了五年前端,在外包公司,創(chuàng)業(yè)公司,BAT級公司再到新型互...
摘要:我們在平時的工作中,總是會遇到老舊的系統(tǒng)以及老舊陳的代碼。弊端就是需要維護兩套代碼,理解兩套技術(shù)選型。那么問題就來了新的代碼如何和舊的代碼解耦新代碼我們當(dāng)然是用新倉庫,新選擇,新打包工具。。。 我們在平時的工作中,總是會遇到老舊的系統(tǒng)以及老舊陳的代碼。他們是業(yè)務(wù)長年累月的積累,以及因為是三、四年前的技術(shù)選型造成的系統(tǒng)架構(gòu)的不合理以及繁瑣的代碼。維護這些代碼總是很頭疼,程序員遇到這樣的代...
閱讀 923·2023-04-26 01:34
閱讀 3356·2023-04-25 20:58
閱讀 3258·2021-11-08 13:22
閱讀 2107·2019-08-30 14:17
閱讀 2521·2019-08-29 15:27
閱讀 2673·2019-08-29 12:45
閱讀 2996·2019-08-29 12:26
閱讀 2810·2019-08-28 17:51