創(chuàng)業(yè)技術團隊要不要追求技術的“高大上”?
創(chuàng)業(yè)公司招工程師難,招來水平也參差不齊。在編碼上,不僅要考慮整體安全、規(guī)范,還要快,實在不易。
本篇為大家介紹創(chuàng)業(yè)型公司在技術團隊開發(fā)方面的一些觀點,告訴大家如何避免成本浪費,提高時間效率及管理的一些技巧。
對于一個互聯網創(chuàng)業(yè)公司來說,有以下這幾個特點:
- 什么都要求快,這個快也許并非來自用戶,而來自于自己,比如恨不得開發(fā)一天就開發(fā)一個新功能。
- 變化快,比如一個想法落實到開發(fā),可能會有很多變化。
- 資源稀缺性,資源就是時間、金錢和人力成本,對于創(chuàng)業(yè)公司來說,有效的花費資源本身就很重要,看看多少創(chuàng)業(yè)公司都是胡亂花錢而撐不下去的,而對應的技術上就是能省則省。
針對以三個主要特點,創(chuàng)業(yè)公司在技術使用的策略上有什么準則呢?
個人認為就是“簡單化“,當然這個簡單是建立在理性分析的基礎上的。技術人員有個通病,認為技術實現越復雜,越膨大,越全面就越能體現技術水平。
這是非常錯誤的一個觀點,衡量技術水平的唯一標準其實就是“是否有效支撐業(yè)務發(fā)展”,要看結果論,比如說開發(fā)速度快,后期問題少,假如能做到這些,那么這個技術團隊就是牛逼的。
而提倡簡單化的理論,就會讓你從另外一個角度去審視技術本身,下面的一些技術使用建議也許看上去并不高大上,好像每個人都能明白,但假如能有效的實行,在創(chuàng)業(yè)初期能夠解決大部分的技術問題。
使用云服務器
對于創(chuàng)業(yè)團隊來說,并不知道未來用戶有多少,需要使用多少服務器資源(Web 服務器,DB 服務器等等)不好衡量。
而云服務器的可擴容性則能很好的滿足這個需求,換句話說創(chuàng)業(yè)初期使用云服務器可以有效節(jié)省成本。
云服務器的特點還不止這么多,它代表了一種開發(fā)模式,即分層架構。比如云服務器的類型有很多(云服務器、云緩存服務器、云數據庫服務器、云存儲服務器)。
正因為有了這樣的分層模式,讓你有了更好的選擇,假如自建服務器,很多技術團隊可能會把 Web 服務器和 DB 服務器放一塊,從而帶來很多問題。
另外云服務器也有沙箱功能,在安全性上也有很好的保證。雖然可能很多人覺得現在云廠商做的不好或不安全,不過說句實話你自己搞可能更差。
當然使用云服務器也并不能說明一定就省錢,這取決于你是是否真正了解系統以及其背后需要的資源。
重視數據存儲
先入為主,推薦使用 MySQL來存儲數據。在設計上要盡量規(guī)范化,索引利用合理一點,因為數據有個特點,假如前期設計不好,后期想重新調整結構是非常痛苦的一件事情。
原來公司某個產品,最重要的博文數據庫表(blog 表)有個字段存儲的是文章的具體內容(content 字段),從而導致這個表非常龐大,查詢性能和內容非常不好控制。
就我了解到的情況是目前 content 字段還是沒有從 blog 表中拆分,這不僅僅是技術的問題,對于一個在線的服務,數據量很大的服務,做表結構的調整是非常困難的,所以前期盡量設計好。
MySQL 主要的作用還是存儲,雖然可以通過 SQL 完成很多復雜的查詢,但是建議盡量少使用,否則性能會急劇下降。
我?guī)啄昵傲私獾揭粋€爆款的產品,用戶量上來后,***個壓垮它的就是數據庫,***的原因就在于查詢非常不合理,做了非常多的聯合查詢。
假如不合理使用 MySQL,很多人會質疑性能不行,其實這都是錯覺,我一直相信的一個原則就是,既然這么多人用,說明必然有它的優(yōu)勢,我們要做的就是學會使用而不是抱怨。
對于 MySQL 這樣的數據庫,很重要的觀點就是備份和安全性,剛工作的時候領導說過這樣一句話,“代碼可以重構,但是數據不能丟,所以在寫操作數據程序的時候一定要慎重”,而 MySQL非常成熟,備份和安全性上有很多選擇。
另外一個觀點就是假如你并不知道數據量和訪問量是多少,開始不要選擇分庫分表策略,也不要搞很多路由策略,盡量簡單點。單表數據量在一***別,只要設計和使用上保持穩(wěn)健性,性能不是問題。
MySQL 的主輔同步本來是做備份用的,但是現在很多人多當分布式查詢使用,也能分擔很多查詢壓力。
現在很多 NoSQL 服務特別多,比如 Redis ,對于創(chuàng)業(yè)公司來說建議不要使用,原因有兩點:
- 這些服務并不完全成熟,在使用上需要有很多經驗,尤其在備份和安全性上,在運維上并不簡單,需要有極大的成本。
- 雖然它有很多優(yōu)點是數據庫比不了的,但是還是那句話,它能做的 MySQL 也能做。
對于創(chuàng)業(yè)團隊來說,上手簡單和維護簡單,成本是優(yōu)先要考慮的。當然假如應用場景非常需要用 NoSQL 這樣的服務,還是要大膽的使用。
統一開發(fā)框架
開發(fā)框架在我看來有兩個最主要的作用,分別是規(guī)范和***實踐。
所謂規(guī)范就是框架定義了一些制度,框架理論上不應該讓你隨意寫代碼,尤其在 PHP 語言中,由于太靈活了,假如沒有一套框架去制約開發(fā)者,那么寫出來的系統會很脆弱。
***實踐就是框架集成了很多優(yōu)秀的思想和功能,要做的就是去合適的用,框架能夠解決分層的問題,能夠解決安全性的問題。
創(chuàng)業(yè)團隊一定要有一套開發(fā)框架,但是在選擇上必須謹慎,不要選擇太難以理解的框架。
比如說 PHP 框架 Laravel ,對于使用者來說需要具備很強的設計模式和 OOP 理解能力,沒有經驗就選擇簡單易學的框架。
第二個選擇框架不要選擇封裝太多的框架,舉 JQuery 的例子,很多人可能會 JQuery 但不會 JavaScript,所以選框架應該選用接近開發(fā)語言本質的框架。
另外框架沒有絕對的好壞,一個創(chuàng)業(yè)團隊能夠快速上手的框架就是好框架,使用框架 20% 的功能即可,開發(fā)人員喜歡過度的使用軟件。
說到開發(fā)框架,不要強迫開發(fā)人員使用統一的 IED,只要最終代碼輸出標準一樣即可(比如 PHP 語言重點符合 PSR-2 即可)。
使用 Cache 并配合 Cache 管理工具
在互聯網產品中,可以說 Cache 為王,很多人不管三七二十一必須要使用 Cache。
可我個人覺得系統假如沒有瓶頸(這個詞需要好好理解),不一定需要使用 Cache,首先有容量資源成本,另外也會增加系統的復雜度,導致開發(fā)維護成本提高。
假如實在需要使用 Cache,一定要充分理解應用場景,是 pull 式的 Cache,還是 push 式的 Cache ,如何衡量 Cache 的效果。
假如必須要使用 Cache ,一定要有一個 Cache 管理器,什么意思呢?對于技術人員來說,代碼在寫的時候,意識不到 Cache 的存在,全部優(yōu)雅的封裝了,而封裝能帶來開發(fā)和維護成本的減低。
最重要的一點就是不要過度追求***率這一指標,從而把代碼搞的非常復雜。
比如使用 Memcached,可以基于 SQL 查詢語句做 Cache ,多采用 pull 的方式,過期時間可以設置短一點(意思就是不要主動的去更新 Cache)。
另外一種使用方式就是將數據庫的聯合查詢的結果主動放入到 Cache 中。
盡量異步化
異步化是一種開發(fā)策略,對于創(chuàng)業(yè)團隊的產品來說,資源有限的情況下,沒有必要每個功能追求及時響應。
比如說現在很多 SNS 社交產品,沒有必要評論數、點贊數及時更新,排行榜也不用及時更新,假如什么功能和需求都要做到***,對于開發(fā)和時間是極大的挑戰(zhàn)。
所以對于創(chuàng)業(yè)團隊來說,請有效使用異步化。舉幾個例子:
- 比如說用戶點贊,沒有必要程序實時響應這個用戶有沒有點贊,直接將這個請求放入隊列,這樣這個接口的響應和吞吐能力就提升了。
- 每天文章訪問的排行榜,沒必要查詢數據庫,每天或者每個設定的間隔時間從數據庫中查詢出結果放入緩存即可,會減少很多數據庫的查詢。
日志系統
在互聯網應用中,日志無處不在,如操作系統運行的日志,服務器日志,軟件的運行日志,數據庫操作的日志,應用程序日志,產品業(yè)務日志。
這些日志是了解服務運行狀況的***的來源,在創(chuàng)業(yè)團隊,最忌諱系統出了問題不知道如何分析問題,產品人員需要一些數據卻拿不出,系統的歷史運行狀況也完全一摸黑。
所以對于創(chuàng)業(yè)團隊來說,一定要重視日志。對于開發(fā)人員來說,在開發(fā)框架中一般都有日志模塊,良好的定義好日志格式和含義。
假如服務器眾多,可以使用一些分布式日志系統來搜集和壓縮日志,其實 Linux 發(fā)行版自帶的 Syslog 其實是非常好的一款軟件。
這樣從側面說明我們不用尋找多少高大上的軟件,用好操作系統自帶的工具就很不錯了。
監(jiān)控系統
有了日志,下個話題就是監(jiān)控,因為監(jiān)控都是基于日志的分析,確定合適的閥值,選擇是否報警,所以對于技術團隊來說,有了日志就要充分的分析。
而一套完善的監(jiān)控系統很重要,能夠對系統的運行狀況有更好的了解,主動的去發(fā)現問題,而不是等待用戶去投訴。
監(jiān)控的維度可以有很多,比如系統慢查詢日志、資源調用的錯誤率、數據庫更新頻率突然飆升,某個接口訪問數異常,寫代碼其實很容易,難的是如何知道系統出現異常背后的原因。
監(jiān)控軟件有很多,在使用的時候一定要精確定義閾值和閾值背后的含義。
比如說我們公司也有監(jiān)控系統,可問題出了后還是沒有通過監(jiān)控系統發(fā)現,***發(fā)現報警短信太多了,忽略了,運維和開發(fā)人員對于報警短信也麻木了,所以說使用監(jiān)控系統很簡單,正確使用則有難度。
WIKI 系統
WIKI,知識管理系統,個人理解其實就是提倡寫文檔。文檔的作用很多,如何寫不重要,重要的是這個文檔的作用是干嘛的?能讓人明白嗎?
假如一個新員工來了,看了文檔后,就知道系統包括了什么模塊,自己如何快速開發(fā),如何上線,這就是一個好文檔。
假如要優(yōu)化一個原有的服務,開發(fā)人員不是通過代碼去找邏輯,而是通過文檔去了解大概的邏輯和包含的模塊,當然文檔也不需要太詳細。
文檔是開發(fā)人員和運維人員之間的協作工具,比如服務器的 IP 是多少,系統中資源的路徑和 IP 是多少(比如數據庫的域名、外部 API 的地址)。
說個簡單的笑話,原來公司運維人員維護了一百多個 Memcached 端口,***發(fā)現找不到使用方是誰了,***不得不發(fā)郵件讓大家認領,可大部分***也沒人認領,有了文檔這些問題就能解決了。
文檔是開發(fā)人員之間的協作工具,在創(chuàng)業(yè)團隊,變化太快了,大部分都是通過人與人之間的溝通,可溝通假如總是變化,***發(fā)現雙方理解的有偏差,浪費了很多開發(fā)時間,而約定的文檔能在一定程度上解決這問題。
上面舉得例子就簡單解釋了文檔的重要性,其實文檔代表了一種開發(fā)思維,可以這么說沒有文檔,代表開發(fā)混亂,有了文檔從側面也能大概看出代碼實現的是否合理,這才是文檔最重要的作用。
寫文檔應該避免的幾個誤區(qū):
- 不要太遵循寫作規(guī)則,能夠說清楚就行。有些開發(fā)人員不想寫文檔的原因之一就是寫文檔比寫代碼還要求嚴格。
- 文檔一定要保持更新,比如說一個功能上線初期是有文檔的,后來代碼一直在迭代,***開發(fā)人員發(fā)現文檔和代碼的邏輯完全不一樣,大家也就失去了看文檔的動力,所以文檔最重要的就是要持續(xù)更新。
- 文檔不要強制開發(fā)人員去寫,也不用及時讓大家去更新,約束少一點可能效果更好。
代碼構建,部署&發(fā)布系統
對于創(chuàng)業(yè)團隊來說,假如一個新員工來了,需要快速能夠讓其進行開發(fā),所以需要有一套集成化的環(huán)境,主要包括:代碼協作工具,代碼構建,代碼部署(開發(fā)環(huán)境、仿真環(huán)境、線上環(huán)境)。
為什么需要這套環(huán)境呢?有兩個目的:
- 為了縮短產品上線時間,讓技術人員專注于業(yè)務開發(fā),而不是被其他的一些因素困擾。
- 為了產品的質量。
在很多開發(fā)團隊,有的時候出現問題,都是開發(fā)人員直接線上修改代碼,從而導致潛在的問題;還有任何開發(fā)人員都有線上的服務器的權限,導致安全性得不到保障。
在產品上線后,測試人員說怎么測試的時候沒有問題,一上線就有問題,開發(fā)人員說測試人員測試的環(huán)境不是線上環(huán)境;新來一個員工,一個星期都沒法搭建自己的開發(fā)環(huán)境。
反正很多此類問題,從而也導致了時間的浪費和質量的下降,而更大的危害就是失去別人的信任。
所以有這樣一套環(huán)境很重要,不用特別的高大上。下面就簡單說說:
- 首先要有一個代碼版本控制系統,這個現在大部分都會使用,也不用特別介意用 SVN 還是用 Git。
- 讓運維人員寫一個腳本,能夠配置開發(fā)環(huán)境、仿真環(huán)境、線上環(huán)境(環(huán)境一定要隔離),說真的,簡單的 Shell 腳本就能完成。
這里的環(huán)境不僅僅是服務器,包括數據庫資源等等,這時候大家也意識到 WiKi 的重要性了,假如沒有文檔,不可能能搭建這樣的系統。
- 代碼構建系統,在 PHP 這樣的高級語言中,本質上不存在代碼構建這一說,假如有特殊需要,也可以通過 Shell 腳本來實現。
- 代碼部署系統,在開發(fā)環(huán)境中,完全可以借助 IDE 和 FTP 將實時變動的代碼同步到開發(fā)環(huán)境中。
假如代碼需要部署到線上,可以借助于 SVN 和 rsync 這樣的工具將有差異的代碼快速發(fā)布到線上,有問題也支持快速的回滾。
開發(fā)人員也要做運維
運維這個崗位其實需要了解網絡,Linux ,Shell 等相關知識,而開發(fā)人員本身也應該掌握這些知識。
假如開發(fā)人員不了解這些,而只是會編碼,那代表他并不真正會編碼,了解這些知識開發(fā)人員可以更好的理解一個系統,當系統出現問題的時候能夠從多方面去排查,更好的維護。
在我工作的這么多年中,開發(fā)崗位和運維崗位總是不能很好的協作,出現問題的時候開發(fā)人員說這是網絡問題,是運維的服務器不夠,或者說數據庫響應慢。
而運維人員則更痛苦,你開發(fā)人員寫的什么程序啊,數據庫全是聯合查詢,導致數據庫性能嚴重下降。
或者說上線一個項目我們啥也不知道,你讓我們怎么運維?出現這些問題的原因在于雙方對于對方掌握的技術領域不了解,互相不理解或者不明白對方的職責,而這些會導致整個產品和系統的穩(wěn)定性出現很大的問題。
所以對于創(chuàng)業(yè)團隊來說,假如技術能力足夠,運維工作盡量由開發(fā)人員來做,當然這里的運維可能更多的是產品運維的角色(在大企業(yè),運維崗位的分工也越來越明確)。
具體的工作比如說安裝軟件開發(fā)包,進行 Nginx、PHP 配置,切割日志,這些工作本身也不復雜,開發(fā)人員假如能夠掌握好,對于系統的維護是有極大的好處的。
另外,潛意識告訴開發(fā)人員,出現問題沒有人能依賴,代碼和環(huán)境需要你
如開發(fā)人員素質,協作能力),大家只要遵守就能很好的完成。
而完成這些,就能解決軟件開發(fā)中的大部分問題,讓你的系統更穩(wěn)健,讓你的開發(fā)更快速,讓你的成本更低。
對于創(chuàng)業(yè)團隊開發(fā)人員來說,不要高度追求技術的高大上,有效解決問題很重要。