一、軟件開發的核心原則
此處所說的是軟件開發應該遵循的一些核心原則:
1、Don’t Repeat Yourself: 這是軟件開發的一個基礎原則,即不要做重復性勞動。也是現在所說的“極客文化”的一種。代碼重復、工作重復在軟件開發中都是不合理的存在。利用各種手段消除這些重復是軟件開發的一個核心工作準則。
2、Keep it simple stupid:即KISS原則。在做軟件設計的工作中,很多時候都不要想得過于復雜,也不要過度設計和過早優化,用最簡單且行之有效的方案也就避免了復雜方案帶來的各種額外成本。既有利于后續的維護,也利于進一步的擴展。
3、You Ain’t Gonna Need It: 即YAGNI原則。只需要將應用程序必需的功能包含進來,而不要試圖添加任何其他你認為可能需要的功能。因為在一個軟件中,往往80%的請求都花費在20%的功能上。
4、Done is better than perfect: 在面對一個開發任務時,最佳的一個思路就是先把東西做出來,再去迭代優化。如果一開始就面面俱到,考慮到各種細節,那么很容易陷入牛角尖而延誤項目進度。
5、Choose the most suitable things: 這是在做方案選擇、技術選型時候的一個很重要的原則。在面對許多技術方案、開源實現的時候,務必做到的是不能盲目求新,要選擇最合適的而非被吹得天花亂墜的。
二、軟件過程
一個軟件的生命周期中,除了開發還有很多其他步驟,也都是需要掌握的一些技術。
1、項目管理:項目管理對于一個軟件的開發是非常重要的,能夠保證項目進度有條不紊地進行,在可控的時間內以一定的質量交付。瀑布開發模型、螺旋開發模型是傳統的項目管理模型。在互聯網的開發工作中,敏捷開發則是比較受推崇的開發方式。所謂敏捷開發即快速實現原型,然后快速迭代。Scrum是目前普遍流行的敏捷開發方式之一。
2、測試驅動開發:在平時的開發過程中,目前比較流行也是行之有效的一種方式就是Test Driven Develop,即測試驅動開發。此種方式的核心就是編寫單元測試。簡單來講,就是先完成某一個功能的單元測試用例,然后在逐步消除測試用例的編譯錯誤的過程中完成功能的開發。
3、持續集成:某一個軟件功能完成開發之后,后續還有測試、預發布、部署等過程。整個過程稱之為集成,而持續集成指的是無需人工干預可以不斷地進行這個過程。Jenkins、Quick Build都是比較典型的持續集成工具。
三、日常開發
日常開發指的是一些日常需要掌握的技能、工具等。
1、編輯器:開發中現在用的比較多的編輯器包括Emacs、Vim和SublimeText。筆者用的最多的就是SublimeText,基本能夠滿足自己的開發需求,包括編寫腳本代碼、查看代碼文件等。Vim和Emacs這兩款編輯器相對SublimeText來說需要記住很多命令,有一定的上手門檻。
2、源碼版本管理:代碼的版本管理工具由CVS到SVN再到現在的Git,已經在事實上形成了以分布式版本管理為主的版本管理方案。基于Git,可以采用Git Flow做為源碼管理模型。
3、項目工具:Github是一個第三方Git中央倉庫,目前是世界最大的開源代碼庫,也能夠做為私人的代碼管理軟件;Facebook開源的Phabrictor提供了非常強大的任務管理、Bug管理、測試、代碼管理等,但其上手門檻相對較高;禪道是國人開發的一款項目管理工具,但是其免費版功能有限;以Tower.im為代表的第三方項目管理服務也是一個可選擇的方案,風險在于數據都不再是私有的。
四、運行環境
后端應用開發完成之后是需要部署到服務器上對外提供服務的。從最開始的直接在物理機上部署服務到后來的虛擬環境、云環境再到現在火熱的容器,直至最近興起的無服務器技術。都是為了讓服務的運行環境能夠更加便于建立、更容易維護、更容易擴展。
1、Linux: 說到后端服務器肯定繞不過Linux。至少現在互聯網的后端服務絕大多數都是部署在Linux的各種服務器版本中的。其中CentOS、Ubuntu以及Debian是用的比較多的版本。對于Linux,需要熟練掌握的就是很多常用Shell命令如ps、netstat、lsof、ss、df、dh等等。此外,很多性能分析命令如top、vmstat、iostat、sar等也需要熟練使用。
2、應用服務器:就Java來講,很多時候開發的都是Web應用,以HTTP協議對外提供服務。除了對性能要求比較苛刻的情況下會自己構建HTTP服務之外,大部分情況是需要依賴于支持Java程序的應用服務器的。目前最為常用的有:Tomcat、Jetty。嚴格來講,這兩者只是Servlet容器,真正的JavaEE應用服務器如Jboss、Weblogic在互聯網領域很少使用。當然,這些軟件并沒有提供URL重寫、請求委托等Web服務器功能,還不足以擔當完整Web服務器的角色。Nginx則是目前最為流行的Web服務器。
3、負載均衡:在高并發流量環境下,后端服務會以集群的模式對外提供服務。在集群的前面,需要負載均衡器將請求分配到集群的各個結點上。LVS是最為流行的四層負載均衡軟件,HAProxy是另一個即支持四層又支持七層負載均衡的軟件,Nginx則是七層負載均衡最為流行的解決方案。當然,性能最為好的負載均衡方案是以F5為代表的硬件負載均衡,但由于其昂貴的成本因此在互聯網團隊中很少使用。此外,這里需要補充的是為了保證同等角色的服務的高可用,如LVS經常作為流量的入口,因此會部署多個LVS結點互為主備防止一個掛掉的時候造成服務不可用。而實現互為主備的技術目前用的最多的就是Keepalived。
4、虛擬化:虛擬化技術是前幾年經常用來做私有云的一種技術。即將自己的物理主機通過虛擬化技術分裂為多個虛擬主機,能夠隔離資源。其中,VPS(虛擬專用服務器)的代表技術包括:微軟的Virtual Server、VMware的ESX Server、SWsoft的Virtuozzo。此外,OpenStack提供的構建私有IIAS的功能、Cloud Foundry提供的構建私有平臺運行環境以及Docker帶來的容器服務都是虛擬化技術的一種。
五、第三方服務
雖然從根本上講所有的軟件服務都是可以自己開發的或者部署到自己服務器上的。但是受限于成本、周期或者其他客觀因素,很多服務還是需要使用第三方的。
1、IAAS:Infrastructure As A Service, 是云計算最開始的一種模式,現在基本上所有的云服務商都有IAAS的服務。其中,全球最強大的云服務提供商是亞馬遜的AWS,國內的則當屬阿里云。就目前來看,即使是強如AWS也會出現一些運維故障,因此國內的這些云計算提供商很多時候的服務健壯性、運維響應更是經常被人吐糟。就筆者自己的經歷來看。2010年左右,盛大云的云服務其實做的還不錯,但后來由于種種原因現在基本已經沒啥份額了。國內除了阿里云,UCloud算是專注做云計算的一個比較靠譜的公司了。此外,還有一個青云,做的東西略顯高大上,也是一個不錯的選擇。當然,現在這些云服務商早就不僅僅是IAAS了,也做了很多PAAS的服務。
2、PAAS:Platform As A Service,即只需要提交代碼到指定的運行環境,其他的諸如代碼打包、部署、IP綁定都由平臺完成。除了可以使用Cloud Foundry構建自己的PAAS平臺以外,現在最為流行的第三方PAAS服務有:新浪的SAE、百度的BAE以及Google的GAE。
3、域名:有個可以提供服務的應用后,那么域名也是一個必須的基礎設施。一個好的域名不僅僅代表企業的形象,也能夠更加方便用戶的記憶與傳播。目前購買域名可以通過國外的name.com、godaddy以及國內的萬網等。有了域名之后下一步就得進行備案,域名提供商一般都提供了配套服務或者去找一些代理也可以辦下來。此外,對于域名的解析,域名提供商一般會內置解析功能,也可以使用獨立的DNS服務,如dnspod。
4、CDN: 內容分發網絡,即就近請求的一種技術實現。服務提供方將會被大量訪問的內容在全國的多個結點都做緩存,這樣當用戶訪問時就能夠就近選擇,從而減少網絡傳輸延時,提高訪問速度。國內目前七牛和又拍都提供了不錯的CDN服務,當然像阿里云、UCloud這種綜合云服務商也都有CDN服務。
5、郵件發送:這個主要需要依賴郵件服務器,然后通過SMTP協議就可以實現發送。可以選擇自己搭建,也可以選擇諸如騰訊郵箱、網易郵箱等。
6、短信發送:使用短信發送驗證碼、營銷短信是很常見的應用場景。由于短信是需要運營商支持的,所以這一塊基本上都是需要依賴第三方代理的。市面上也有很多短信網關代理。
7、消息推送:在移動應用上,推送已經成為一個標配功能。目前個推應該是第三方推送服務中的佼佼者,而且由于其客戶很多,在聯盟喚醒上有很大的優勢。
8、開放平臺:通過開放平臺,可以使用OAuth等協議獲取用戶在第三方平臺上的信息實現第三方平臺登錄等。目前,微博、微信、QQ是最常見的第三方登錄方式,基本上都是使用OAuth協議為第三方開發者提供服務的。
9、支付接口:支付接口是很多內置購買功能軟件的必備組件。目前,接入最多的無非是支付寶和微信,都提供了開放平臺供商家接入。當然,也有直接綁定銀行卡支付的,此時需要走的就是銀行或者銀聯的網關接口。
七、計算機基礎科學知識
對于像數據結構、算法、計算機網絡、操作系統、計算機組成原理這些計算機科學基礎知識,不管是后端還是其他領域都是必須的技能,也是所有軟件開發的基礎。扎實的計算機科學基礎才能讓你在學習、使用某種技術開發軟件、調試軟件、排查問題時能夠心里有底、有據可循。
1、數據結構:數據結構是組成程序的基礎。經典的數據結構包括:字符串、數組、鏈表、哈希表、樹(二叉樹、平衡樹、紅黑樹、B樹)、堆棧、隊列、圖。
2、算法: 經典的排序和查找算法在平時的開發工作中經常會用到,如:冒泡排序、插入排序、選擇排序、歸并排序、快速排序、希爾排序、堆排序以及二分查找等。此外,在函數/方法的算法實現中要注意遞歸和迭代各自的優缺點。而衡量算法性能無外乎空間復雜度和時間復雜度。
3、業務相關算法:除了上面的基本算法之外,業務中還會經常涉及到一些更為復雜的算法,如:壓縮算法、LRU緩存算法、緩存一致性、編譯原理中的狀態機等。此外,目前越來越火的機器學習中有很多算法也是在很多業務場景中有很大用途的,如:用于文本分詞的結巴分詞和中科院ICTCLAS;用于關鍵詞提取的TF-IDF和TextRank;用于計算文本相似度的主題模型、Word2Vec、余弦相似度以及歐幾里得距離;用于文本分類的樸素貝葉斯;用于推薦的聚類、協同過濾、用戶畫像、隱語義模型等。
4、計算機網絡: TCP/IP協議是網絡最根本的協議,其七層/四層協議棧的設計都是非常精華的東西,連接的建立、斷開以及連接的各種狀態的轉換都是排查、解決網絡問題的根本依據。從TCP/IP往上,HTTP協議是現在絕大多數后端應用對外提供的協議,發展到現在已經將要步入HTTP2.0時代,帶來了持久連接、連接復用等令人振奮的新特性。此外,基于HTTP的HTTPS協議由于其安全性在逐漸的成為后端服務對外開放的主流協議。業務層面,基于HTTP協議的RESTful規范正成為對外接口的主流規范,而OAuth2.0協議也在成為開放平臺對外的主流協議。除了HTTP之外,SMTP是另一個基于TCP/IP的應用協議,主要用在發送郵件上。
5、設計模式: 在軟件開發中,前人的經驗形成了很多經典設計模式供我們使用,能夠使得軟件的實現可服用、可擴展、可維護。經典的工廠模式、簡單工廠模式、單例模式、觀察者模式、代理模式、建筑者模式、門面模式、適配器模式、裝飾器模式在日常的很多開發場景下都具有很重要的意義。
八、數據
現在互聯網的所有業務其實都是圍繞數據來進行的。而數據傳輸、數據存儲、數據分析處理都是關鍵的部分。
1、高速緩存:目前用的最為廣泛的緩存軟件Redis能夠支持豐富的數據結構,如:字符串、列表、有序集合等多種數據的存儲。了解緩存實現的原理、內存淘汰的策略能夠更好地使用緩存。此外由于緩存的成本較高,在使用緩存的時候一定要做好量化和存儲優化工作。
2、數據庫:掌握數據庫的很大一個關鍵點就在于對索引的使用,可以說,正確地使用索引就基本等于掌握了數據庫的使用。目前絕大多數據庫都是使用B樹做為索引的數據結構,目的就是為了利用磁盤順序讀寫的特性。不同的數據庫由于本身設計目的的不同,都有一些獨特的優勢,如:MongoDB天然支持sharding,但受限于NoSQL,在重事務、有關聯關系的場景下并不適用;HBase使用LSM作為底層數據結構,犧牲了讀性能來換取高速的寫性能。
3、搜索引擎:搜索引擎主要應對全文檢索以及多維度查詢的業務場景。掌握搜索引擎使用的數據結構、集群方式、配置的關鍵點有助于更好地使用搜索引擎服務于業務應用。
4、消息隊列:消息隊列有兩種角色:生產者和消費者,兩種角色對于消息隊列的需求也不一樣。其中,對于消費者來說,消息消費的方式包括發布-訂閱和隊列兩種。消息隊列在語義保證上分為:At Most Once、At Least Once、Exactly Once三種模式,需要更具特定的業務場景選擇合適的語義保證。此外,消息隊列對于高可用、消息安全的保證決定了此消息隊列的可靠性。
5、數據存儲和處理:數據存儲下來最終還是要用來做分析和處理的。數據的處理分為離線處理和實時處理。離線處理的優勢在于能夠處理大量數據,但是一般會有T+1的延遲,適用于計算量大但是對于結果允許有延時的場景。但對于離線數據分析,還有一個很關鍵的就是數據傾斜問題。所謂數據傾斜指的是region數據分布不均,造成有的結點負載很低,而有些卻負載很高,從而影響整體的性能。因此,處理好數據傾斜問題對于離線數據處理是很關鍵的。而實時處理一般是流式處理方式,適用于數據能夠轉換為數據流,對于結果要求及時性的場景。對于實時數據分析,需要注意的就是實時數據處理結果寫入存儲的時候,要考慮并發的問題,雖然對于Storm的Bolt程序來說不會有并發的問題,但是寫入的存儲介質是會面臨多任務同時讀寫的。通常采用的方案就是采用時間窗口的方式對數據做緩沖后批量寫入。
6、數據同步:數據倉庫的數據來源除了直接的日志外還有一個很關鍵的就是業務數據庫。從業務數據庫到數據倉庫的過程稱為數據同步。有基于SQL的同步方案,也有基于MySQL binglog的增量同步方案。
九、Java
對于Java方面的技能來說,主要有兩個大的部分,包括Java編程和JVM。
先來看一下Java編程部分,這也是Java工程師最最基礎的技能。
1、IDE: 目前用的最多的Java IDE當屬Eclipse和Intellij IDEA。前者是老牌IDE,逐步淘汰了Jbuilder以及Netbeans,占領了大部分Java IDE市場。后者則是后起之秀,由于其增量編譯、智能分析代碼等帶來的性能提升,現在已經得到了大規模使用,大有取代Eclipse之勢。
2、核心語法:目前用的最多的當屬JDK6的Java語法。而到了Java7引入了try with resource、switch string、diamonds等語法。Java8則又引入了lambda、stream等語法。
3、集合類:集合類是Java語言中非常精華的部分,包括:HashMap、ArrayList、LinkedList、HashSet、TreeSet以及線程安全的ConcurrentHashMap、ConcurrentLinkedQueue等線程安全集合。了解他們的實現原理以及查詢、修改的性能以及使用場景是非常必要的。
4、工具類:Google Guava、Apache commons、FastJson提供了很多JDK本身沒有的工具類、集合等。此外,ASM字節碼操作以及CGLIB代碼生成能夠提供更底層的java編程功能。
5、高級特性:拋開Java核心的基本編程,并發編程、泛型、網絡編程、序列化RPC都屬于java的高級編程特性。其中并發編程需要掌握Executors提供的各種并發工具、Java7帶來的fork/join框架以及CountDownLatch、Semaphore、CyclicBarrier等同步工具;網絡編程要區分好BIO、NIO以及AIO;序列化中除了JDK自帶的序列化實現之外,Protobuf和Kryo是比較高效的第三方實現;RPC的實現中,Thrift、Hessian、Dubbo以及RMI則是比較常用的幾個協議,其中的Hessian是基于Http協議的,Dubbo是基于TCP協議,而Thrift則同時支持。
6、JavaEE: JavaEE現在是Java應用最為普遍的一個領域。Servlet是JavaEE中最根本的組件之一。而Servlet3.0帶來的異步Servlet提高了其處理請求的性能。
7、項目構建:目前用的最多的Java項目構建工具包括Maven和Gradle,提供了源碼包依賴管理、編譯、打包、部署等一系列功能。
8、編程框架:Spring是Java編程中避不開的一個框架,發展到現在除了Spring核心的IOC、AOP之外,SpringMVC、Spring Data、Spring Cloud、Spring Boot等等都給Java開發者們帶來了開發上的便利,大大提高了開發效率;ORM框架MyBatis也是Java領域比較火的框架之一,實現了數據庫記錄到Java對象的映射操作;Jersey則提供了從客戶端到服務端的一整套符合RESTful規范的開發框架。此外,Vert.x、Spring Flux這種非常適用于IO密集型應用的異步響應式編程框架也開始興起。
9、測試:測試是任何編程都需要的一步。黑盒測試主要指的通常進行的功能測試,白盒測試則主要指的對代碼功能、質量進行的測試。此外,關鍵的單元測試則是開發工程師需要著重注意的地方,“測試驅動開發”的理念也是值得推崇的開發方式。JUnit是目前Java中實現單元測試的主流方案。
一般來說掌握上面所述的Java編程技能是能夠應付大多編程工作的。但是如果在代碼層面已經做到最大努力卻還是達不到性能要求的時候,就需要在JVM虛擬機層面做一些努力了。可以說掌握JVM相關技術是Java開發進階的一個關鍵步驟。
1、虛擬機實現: Java的虛擬機實現除了我們常用的HotSpot外,還有JRockit、J9以及移動平臺的Dalvkit、ART(Android4.4后引入)。我們通常鎖描述的JVM優化絕大多是是針對HotSpot虛擬機來說的。
2、類加載機制:JVM的類加載機器遵循雙親委派原則,即當前類加載器需要先去請求父加載器去加載當前類,如果無法完成自己才去嘗試進行加載。OSGI框架則打破了此機制,采用了平等的、網狀的類加載機制,以實現模塊化的加載方案。
3、運行時內存組成: 程序計數器、堆棧、方法區、堆、堆外內存,這些一起組成了JVM的運行時內存。
4、Java內存模型:Java的主內存+線程私有內存的模型是線程安全問題產生的根本。
5、GC原理和調優:與C、C++這些語言相比,GC是Java的優勢,但因為GC的細節被JVM屏蔽了,在對內存、性能要求非常苛刻的情況下難以進行自由控制,某種程度這也是劣勢。如果想在某些場景下發揮GC的最大性能,能做的就是對GC的各種參數做優化配置,如新生代和老年代的垃圾回收器選擇、各種垃圾回收參數的配置等。此外,很多時候由于代碼質量或者外部客觀因素,造成了JVM頻繁GC,需要使用相關的工具快速進行問題定位和解決。
6、性能調優和監控工具:JDK自帶了很多強大的調優和監控工具,包括jmap、jstack、jcmd、jconsole、jinfo等。此外,btrace是一款非常強大的在線問題動態排查工具,能夠無須重啟Java進程,動態的插入一些代碼邏輯,從而攔截代碼執行邏輯打印日志,從而排查問題。
十、系統架構
一個應用從0開始一般會經歷單體應用、垂直應用到分布式服務架構的演化。如下圖所示:
1、單體應用:當應用規模、團隊規模比較小的時候,只需要一個包括了所有功能的應用即可。減少部署結點,也減少了部署成本。此時,對數據庫的ORM操作是架構實現的關鍵點。
2、垂直應用:當應用的用戶規模越來越大,請求量越來越高的時候。單體應用增加結點帶來的資源浪費會凸現出來,因為絕大多數接口請求量并沒有特別大,根本沒必要擴充到多個結點。此時,就可以將單體應用拆分成互不相關的幾個應用,分別對外提供服務。此時,加速每個應用開發的MVC框架是架構實現的關鍵點。
3、分布式服務:當垂直應用越來越多,應用之間的交互不可避免。抽離核心業務單獨部署,逐漸形成穩定的服務中心。而隨著團隊規模的相應擴大,服務會隨著團隊的增多變得越來越多,粒度也會變得越來越小,也就逐步形成了分布式服務的架構,而當粒度細到某種程度、服務數量多到一定程度則可以稱之為微服務。即在設計好業務邊界之后將原來的單體應用分解成一個個細粒度的服務,彼此之間通過某種方式進行通信。微服務架構的關鍵在于如何做好服務的治理、調度、維護工作。目前,Dubbo算是微服務架構中用的比較多的框架,但Dubbo僅僅解決了微服務架構中的一部分問題。Spring Cloud則基本上涵蓋了微服務架構的各個方面。
十一、部署架構
對于Web應用來說,LVS+Nginx+Tomcat+MySQL+Redis即可構成一個簡單通用的部署架構,如下圖所示:
1、LVS作為最前置的結點,負責在網絡第四層轉發流量、負載均衡。
2、多個LVS使用Keepalived互為主備實現高可用。
3、Nginx作為反向代理,負責在網絡第七層轉發流量、負載均衡。
4、Tomcat做為業務容器,主要的應用代碼都在這里面。
5、Redis作為緩存,隔離高并發請求和后端數據庫。
6、MySQL以主從模式對數據做持久化。
其中,虛線部分是數據庫層,采用的是主從模式。也可以使用Redis Cluster(Codis等)以及MySQL Cluster(Cobar等)來替換。
-
工程師
+關注
關注
59文章
1569瀏覽量
68506 -
JAVA
+關注
關注
19文章
2966瀏覽量
104704
發布評論請先 登錄
相關推薦
評論