Java後端技術概覽

颯然Hang發表於2018-05-14

一個合格的Java後端工程師需要掌握哪些技能呢?掃描下面的二維碼可以看到Java後端技術概覽圖

file

軟體開發的核心原則

此處所說的是軟體開發應該遵循的一些核心原則:

  • Don't Repeat Yourself: 這是軟體開發的一個基礎原則,即不要做重複性勞動。也是現在所說的“極客文化”的一種。程式碼重複、工作重複在軟體開發中都是不合理的存在。利用各種手段消除這些重複是軟體開發的一個核心工作準則。
  • Keep it simple stupid:即KISS原則。在做軟體設計的工作中,很多時候都不要想得過於複雜,也不要過度設計和過早優化,用最簡單且行之有效的方案也就避免了複雜方案帶來的各種額外成本。既有利於後續的維護,也利於進一步的擴充套件。
  • You Ain’t Gonna Need It: 即YAGNI原則。只需要將應用程式必需的功能包含進來,而不要試圖新增任何其他你認為可能需要的功能。因為在一個軟體中,往往80%的請求都花費在20%的功能上。
  • Done is better than perfect: 在面對一個開發任務時,最佳的一個思路就是先把東西做出來,再去迭代優化。如果一開始就面面俱到,考慮到各種細節,那麼很容易陷入牛角尖而延誤專案進度。
  • Choose the most suitable things: 這是在做方案選擇、技術選型時候的一個很重要的原則。在面對許多技術方案、開源實現的時候,務必做到的是不能盲目求新,要選擇最合適的而非被吹得天花亂墜的。

軟體過程

一個軟體的生命週期中,除了開發還有很多其他步驟,也都是需要掌握的一些技術。

  • 專案管理:專案管理對於一個軟體的開發是非常重要的,能夠保證專案進度有條不紊地進行,在可控的時間內以一定的質量交付。瀑布開發模型、螺旋開發模型是傳統的專案管理模型。在網際網路的開發工作中,敏捷開發則是比較受推崇的開發方式。所謂敏捷開發即快速實現原型,然後快速迭代。Scrum是目前普遍流行的敏捷開發方式之一。
  • 測試驅動開發:在平時的開發過程中,目前比較流行也是行之有效的一種方式就是Test Driven Develop,即測試驅動開發。此種方式的核心就是編寫單元測試。簡單來講,就是先完成某一個功能的單元測試用例,然後在逐步消除測試用例的編譯錯誤的過程中完成功能的開發。
  • 持續整合:某一個軟體功能完成開發之後,後續還有測試、預釋出、部署等過程。整個過程稱之為整合,而持續整合指的是無需人工干預可以不斷地進行這個過程。Jenkins、Quick Build都是比較典型的持續整合工具。

日常開發

日常開發指的是一些日常需要掌握的技能、工具等。

  • 編輯器:開發中現在用的比較多的編輯器包括Emacs、Vim和SublimeText。筆者用的最多的就是SublimeText,基本能夠滿足自己的開發需求,包括編寫指令碼程式碼、檢視程式碼檔案等。Vim和Emacs這兩款編輯器相對SublimeText來說需要記住很多命令,有一定的上手門檻。
  • 原始碼版本管理:程式碼的版本管理工具由CVS到SVN再到現在的Git,已經在事實上形成了以分散式版本管理為主的版本管理方案。基於Git,可以採用Git Flow做為原始碼管理模型。
  • 專案工具:Github是一個第三方Git中央倉庫,目前是世界最大的開原始碼庫,也能夠做為私人的程式碼管理軟體;Facebook開源的Phabrictor提供了非常強大的任務管理、Bug管理、測試、程式碼管理等,但其上手門檻相對較高;禪道是國人開發的一款專案管理工具,但是其免費版功能有限;以Tower.im為代表的第三方專案管理服務也是一個可選擇的方案,風險在於資料都不再是私有的。

執行環境

後端應用開發完成之後是需要部署到伺服器上對外提供服務的。從最開始的直接在物理機上部署服務到後來的虛擬環境、雲環境再到現在火熱的容器,直至最近興起的無伺服器技術。都是為了讓服務的執行環境能夠更加便於建立、更容易維護、更容易擴充套件。

  • Linux: 說到後端伺服器肯定繞不過Linux。至少現在網際網路的後端服務絕大多數都是部署在Linux的各種伺服器版本中的。其中CentOS、Ubuntu以及Debian是用的比較多的版本。對於Linux,需要熟練掌握的就是很多常用Shell命令如ps、netstat、lsof、ss、df、dh等等。此外,很多效能分析命令如top、vmstat、iostat、sar等也需要熟練使用。
  • 應用伺服器:就Java來講,很多時候開發的都是Web應用,以HTTP協議對外提供服務。除了對效能要求比較苛刻的情況下會自己構建HTTP服務之外,大部分情況是需要依賴於支援Java程式的應用伺服器的。目前最為常用的有:Tomcat、Jetty。嚴格來講,這兩者只是Servlet容器,真正的JavaEE應用伺服器如Jboss、Weblogic在網際網路領域很少使用。當然,這些軟體並沒有提供URL重寫、請求委託等Web伺服器功能,還不足以擔當完整Web伺服器的角色。Nginx則是目前最為流行的Web伺服器。
  • 負載均衡:在高併發流量環境下,後端服務會以叢集的模式對外提供服務。在叢集的前面,需要負載均衡器將請求分配到叢集的各個結點上。LVS是最為流行的四層負載均衡軟體,HAProxy是另一個即支援四層又支援七層負載均衡的軟體,Nginx則是七層負載均衡最為流行的解決方案。當然,效能最為好的負載均衡方案是以F5為代表的硬體負載均衡,但由於其昂貴的成本因此在網際網路團隊中很少使用。此外,這裡需要補充的是為了保證同等角色的服務的高可用,如LVS經常作為流量的入口,因此會部署多個LVS結點互為主備防止一個掛掉的時候造成服務不可用。而實現互為主備的技術目前用的最多的就是Keepalived。
  • 虛擬化:虛擬化技術是前幾年經常用來做私有云的一種技術。即將自己的物理主機通過虛擬化技術分裂為多個虛擬主機,能夠隔離資源。其中,VPS(虛擬專用伺服器)的代表技術包括:微軟的Virtual Server、VMware的ESX Server、SWsoft的Virtuozzo。此外,OpenStack提供的構建私有IIAS的功能、Cloud Foundry提供的構建私有平臺執行環境以及Docker帶來的容器服務都是虛擬化技術的一種。

第三方服務

雖然從根本上講所有的軟體服務都是可以自己開發的或者部署到自己伺服器上的。但是受限於成本、週期或者其他客觀因素,很多服務還是需要使用第三方的。

  • IAAS:Infrastructure As A Service, 是雲端計算最開始的一種模式,現在基本上所有的雲服務商都有IAAS的服務。其中,全球最強大的雲服務提供商是亞馬遜的AWS,國內的則當屬阿里雲。就目前來看,即使是強如AWS也會出現一些運維故障,因此國內的這些雲端計算提供商很多時候的服務健壯性、運維響應更是經常被人吐糟。就筆者自己的經歷來看。2010年左右,盛大雲的雲服務其實做的還不錯,但後來由於種種原因現在基本已經沒啥份額了。國內除了阿里雲,UCloud算是專注做雲端計算的一個比較靠譜的公司了。此外,還有一個青雲,做的東西略顯高大上,也是一個不錯的選擇。當然,現在這些雲服務商早就不僅僅是IAAS了,也做了很多PAAS的服務。
  • PAAS:Platform As A Service,即只需要提交程式碼到指定的執行環境,其他的諸如程式碼打包、部署、IP繫結都由平臺完成。除了可以使用Cloud Foundry構建自己的PAAS平臺以外,現在最為流行的第三方PAAS服務有:新浪的SAE、百度的BAE以及Google的GAE。
  • 域名:有個可以提供服務的應用後,那麼域名也是一個必須的基礎設施。一個好的域名不僅僅代表企業的形象,也能夠更加方便使用者的記憶與傳播。目前購買域名可以通過國外的name.com、godaddy以及國內的萬網等。有了域名之後下一步就得進行備案,域名提供商一般都提供了配套服務或者去找一些代理也可以辦下來。此外,對於域名的解析,域名提供商一般會內建解析功能,也可以使用獨立的dns服務,如dnspod。
  • CDN: 內容分發網路,即就近請求的一種技術實現。服務提供方將會被大量訪問的內容在全國的多個結點都做快取,這樣當使用者訪問時就能夠就近選擇,從而減少網路傳輸延時,提高訪問速度。國內目前七牛和又拍都提供了不錯的cdn服務,當然像阿里雲、UCloud這種綜合雲服務商也都有cdn服務。
  • 郵件傳送:這個主要需要依賴郵件伺服器,然後通過SMTP協議就可以實現傳送。可以選擇自己搭建,也可以選擇注入騰訊郵箱、網易郵箱等。
  • 簡訊傳送:使用簡訊傳送驗證碼、營銷簡訊是很常見的應用場景。由於簡訊是需要運營商支援的,所以這一塊基本上都是需要依賴第三方代理的。市面上也有很多簡訊閘道器代理。
  • 訊息推送:在移動應用上,推送已經成為一個標配功能。目前個推應該是第三方推送服務中的佼佼者,而且由於其客戶很多,在聯盟喚醒上有很大的優勢。
  • 開放平臺:通過開放平臺,可以使用OAuth等協議獲取使用者在第三方平臺上的資訊實現第三方平臺登入等。目前,微博、微信、QQ是最常見的第三方登入方式,基本上都是使用OAuth協議為第三方開發者提供服務的。
  • 支付介面:支付介面是很多內建購買功能軟體的必備元件。目前,接入最多的無非是支付寶和微信,都提供了開放平臺供商家接入。當然,也有直接繫結銀行卡支付的,此時需要走的就是銀行或者銀聯的閘道器介面。

計算機基礎科學知識

對於像資料結構、演算法、計算機網路、作業系統、計算機組成原理這些電腦科學基礎知識,不管是後端還是其他領域都是必須的技能,也是所有軟體開發的基礎。紮實的電腦科學基礎才能讓你在學習、使用某種技術開發軟體、除錯軟體、排查問題時能夠心裡有底、有據可循。

  • 資料結構:資料結構是組成程式的基礎。經典的資料結構包括:字串、陣列、連結串列、雜湊表、樹(二叉樹、平衡樹、紅黑樹、B樹)、堆疊、佇列、圖。
  • 演算法: 經典的排序和查詢演算法在平時的開發工作中經常會用到,如:氣泡排序、插入排序、選擇排序、歸併排序、快速排序、希爾排序、堆排序以及二分查詢等。此外,在函式/方法的演算法實現中要注意遞迴和迭代各自的優缺點。而衡量演算法效能無外乎空間複雜度和時間複雜度。
  • 業務相關演算法:除了上面的基本演算法之外,業務中還會經常涉及到一些更為複雜的演算法,如:壓縮演算法、LRU快取演算法、快取一致性、編譯原理中的狀態機等。此外,目前越來越火的機器學習中有很多演算法也是在很多業務場景中有很大用途的,如:用於文字分詞的結巴分詞和中科院ICTCLAS;用於關鍵詞提取的TF-IDF和TextRank;用於計算文字相似度的主題模型、Word2Vec、餘弦相似度以及歐幾里得距離;用於文字分類的樸素貝葉斯;用於推薦的聚類、協同過濾、使用者畫像、隱語義模型等。
  • 計算機網路: TCP/IP協議是網路最根本的協議,其七層/四層協議棧的設計都是非常精華的東西,連線的建立、斷開以及連線的各種狀態的轉換都是排查、解決網路問題的根本依據。從TCP/IP往上,HTTP協議是現在絕大多數後端應用對外提供的協議,發展到現在已經將要步入HTTP2.0時代,帶來了持久連線、連線複用等令人振奮的新特性。此外,基於HTTP的HTTPS協議由於其安全性在逐漸的成為後端服務對外開放的主流協議。業務層面,基於HTTP協議的RESTful規範正成為對外介面的主流規範,而OAuth2.0協議也在成為開放平臺對外的主流協議。除了HTTP之外,SMTP是另一個基於TCP/IP的應用協議,主要用在傳送郵件上。
  • 設計模式: 在軟體開發中,前人的經驗形成了很多經典設計模式供我們使用,能夠使得軟體的實現可服用、可擴充套件、可維護。經典的工廠模式、簡單工廠模式、單例模式、觀察者模式、代理模式、建築者模式、門面模式、介面卡模式、裝飾器模式在日常的很多開發場景下都具有很重要的意義。

資料

現在網際網路的所有業務其實都是圍繞資料來進行的。而資料傳輸、資料儲存、資料分析處理都是關鍵的部分。

  • 快取記憶體:目前用的最為廣泛的快取軟體Redis能夠支援豐富的資料結構,如:字串、列表、有序集合等多種資料的儲存。瞭解快取實現的原理、記憶體淘汰的策略能夠更好地使用快取。此外由於快取的成本較高,在使用快取的時候一定要做好量化和儲存優化工作。
  • 資料庫:掌握資料庫的很大一個關鍵點就在於對索引的使用,可以說,正確地使用索引就基本等於掌握了資料庫的使用。目前絕大多資料庫都是使用B樹做為索引的資料結構,目的就是為了利用磁碟順序讀寫的特性。不同的資料庫由於本身設計目的的不同,都有一些獨特的優勢,如:MongoDB天然支援sharding,但受限於NoSQL,在重事務、有關聯關係的場景下並不適用;HBase使用LSM作為底層資料結構,犧牲了讀效能來換取高速的寫效能。
  • 搜尋引擎:搜尋引擎主要應對全文檢索以及多維度查詢的業務場景。掌握搜尋引擎使用的資料結構、叢集方式、配置的關鍵點有助於更好地使用搜尋引擎服務於業務應用。
  • 訊息佇列:訊息佇列有兩種角色:生產者和消費者,兩種角色對於訊息佇列的需求也不一樣。其中,對於消費者來說,訊息消費的方式包括髮布-訂閱和佇列兩種。訊息佇列在語義保證上分為:At Most Once、At Least Once、Exactly Once三種模式,需要更具特定的業務場景選擇合適的語義保證。此外,訊息佇列對於高可用、訊息安全的保證決定了此訊息佇列的可靠性。
  • 資料儲存和處理:資料儲存下來最終還是要用來做分析和處理的。資料的處理分為離線處理和實時處理。離線處理的優勢在於能夠處理大量資料,但是一般會有T+1的延遲,適用於計算量大但是對於結果允許有延時的場景。但對於離線資料分析,還有一個很關鍵的就是資料傾斜問題。所謂資料傾斜指的是region資料分佈不均,造成有的結點負載很低,而有些卻負載很高,從而影響整體的效能。因此,處理好資料傾斜問題對於離線資料處理是很關鍵的。而實時處理一般是流式處理方式,適用於資料能夠轉換為資料流,對於結果要求及時性的場景。對於實時資料分析,需要注意的就是實時資料處理結果寫入儲存的時候,要考慮併發的問題,雖然對於Storm的Bolt程式來說不會有併發的問題,但是寫入的儲存介質是會面臨多工同時讀寫的。通常採用的方案就是採用時間視窗的方式對資料做緩衝後批量寫入。
  • 資料同步:資料倉儲的資料來源除了直接的日誌外還有一個很關鍵的就是業務資料庫。從業務資料庫到資料倉儲的過程稱為資料同步。有基於SQL的同步方案,也有基於MySQL binglog的增量同步方案。

Java

對於Java方面的技能來說,主要有兩個大的部分,包括Java程式設計和JVM。

先來看一下Java程式設計部分,這也是Java工程師最最基礎的技能。

  • IDE: 目前用的最多的Java IDE當屬Eclipse和Intellij IDEA。前者是老牌IDE,逐步淘汰了Jbuilder以及Netbeans,佔領了大部分Java IDE市場。後者則是後起之秀,由於其增量編譯、智慧分析程式碼等帶來的效能提升,現在已經得到了大規模使用,大有取代Eclipse之勢。
  • 核心語法:目前用的最多的當屬JDK6的Java語法。而到了Java7引入了try with resource、switch string、diamonds等語法。Java8則又引入了lambda、stream等語法。
  • 集合類:集合類是Java語言中非常精華的部分,包括:HashMap、ArrayList、LinkedList、HashSet、TreeSet以及執行緒安全的ConcurrentHashMap、ConcurrentLinkedQueue等執行緒安全集合。瞭解他們的實現原理以及查詢、修改的效能以及使用場景是非常必要的。
  • 工具類:Google Guava、Apache commons、FastJson提供了很多JDK本身沒有的工具類、集合等。此外,ASM位元組碼操作以及CGLIB程式碼生成能夠提供更底層的java程式設計功能。
  • 高階特性:拋開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則同時支援。
  • JavaEE: JavaEE現在是Java應用最為普遍的一個領域。Servlet是JavaEE中最根本的元件之一。而Servlet3.0帶來的非同步Servlet提高了其處理請求的效能。
  • 專案構建:目前用的最多的Java專案構建工具包括Maven和Gradle,提供了原始碼包依賴管理、編譯、打包、部署等一系列功能。
  • 程式設計框架:Spring是Java程式設計中避不開的一個框架,發展到現在除了Spring核心的IOC、AOP之外,SpringMvc、Spring Data、Spring Cloud等等都給Java開發者們帶來了開發上的便利,大大提高了開發效率。除此之外,ORM框架MyBatis也是Java領域比較火的框架之一,實現了資料庫記錄到Java物件的對映操作。此外,Jersey提供了從客戶端到服務端的一整套符合RESTful規範的開發框架。
  • 測試:測試是任何程式設計都需要的一步。黑盒測試主要指的通常進行的功能測試,白盒測試則主要指的對程式碼功能、質量進行的測試。此外,關鍵的單元測試則是開發工程師需要著重注意的地方,“測試驅動開發”的理念也是值得推崇的開發方式。JUnit是目前Java中實現單元測試的主流方案。

一般來說掌握上面所述的Java程式設計技能是能夠應付大多程式設計工作的。但是如果在程式碼層面已經做到最大努力卻還是達不到效能要求的時候,就需要在JVM虛擬機器層面做一些努力了。可以說掌握JVM相關技術是Java開發進階的一個關鍵步驟。

  • 虛擬機器實現: Java的虛擬機器實現除了我們常用的HotSpot外,還有JRockit、J9以及移動平臺的Dalvkit。我們通常鎖描述的JVM優化絕大多是是針對HotSpot虛擬機器來說的。
  • 類載入機制:JVM的類載入機器遵循雙親委派原則,即當前類載入器需要先去請求父載入器去載入當前類,如果無法完成自己才去嘗試進行載入。OSGI框架則打破了此機制,採用了平等的、網狀的類載入機制,以實現模組化的載入方案。
  • 執行時記憶體組成: 程式計數器、堆疊、方法區、堆、堆外記憶體,這些一起組成了JVM的執行時記憶體。
  • Java記憶體模型:Java的主記憶體+執行緒私有記憶體的模型是執行緒安全問題產生的根本。
  • GC原理和調優:與C、C++這些語言相比,GC是Java的優勢,但因為GC的細節被JVM遮蔽了,在對記憶體、效能要求非常苛刻的情況下難以進行自由控制,某種程度這也是劣勢。如果想在某些場景下發揮GC的最大效能,能做的就是對GC的各種引數做優化配置,如新生代和老年代的垃圾回收器選擇、各種垃圾回收引數的配置等。此外,很多時候由於程式碼質量或者外部客觀因素,造成了JVM頻繁GC,需要使用相關的工具快速進行問題定位和解決。
  • 效能調優和監控工具:JDK自帶了很多強大的調優和監控工具,包括jmap、jstack、jcmd、jconsole、jinfo等。此外,btrace是一款非常強大的線上問題動態排查工具,能夠無須重啟Java程式,動態的插入一些程式碼邏輯,從而攔截程式碼執行邏輯列印日誌,從而排查問題。

系統架構

一個應用從0開始一般會經歷單體應用、垂直應用到分散式服務架構的演化。如下圖所示:

file

  • 單體應用:當應用規模、團隊規模比較小的時候,只需要一個包括了所有功能的應用即可。減少部署結點,也減少了部署成本。此時,對資料庫的ORM操作是架構實現的關鍵點。
  • 垂直應用:當應用的使用者規模越來越大,請求量越來越高的時候。單體應用增加結點帶來的資源浪費會凸現出來,因為絕大多數介面請求量並沒有特別大,根本沒必要擴充到多個結點。此時,就可以將單體應用拆分成互不相關的幾個應用,分別對外提供服務。此時,加速每個應用開發的MVC框架是架構實現的關鍵點。
  • 分散式服務:當垂直應用越來越多,應用之間的互動不可避免。抽離核心業務單獨部署,逐漸形成穩定的服務中心。而隨著團隊規模的相應擴大,服務會隨著團隊的增多變得越來越多,粒度也會變得越來越小,也就逐步形成了分散式服務的架構,而當粒度細到某種程度、服務數量多到一定程度則可以稱之為微服務。即在設計好業務邊界之後將原來的單體應用分解成一個個細粒度的服務,彼此之間通過某種方式進行通訊。微服務架構的關鍵在於如何做好服務的治理、排程、維護工作。目前,Dubbo算是微服務架構中用的比較多的框架,但Dubbo僅僅解決了微服務架構中的一部分問題。Spring Cloud則基本上涵蓋了微服務架構的各個方面。

部署架構

對於Web應用來說,LVS+Nginx+Tomcat+MySQL+Redis即可構成一個簡單通用的部署架構,如下圖所示:

![file](http://springf orall.ufile.ucloud.com.cn/static/img/4245fa956e464e90bff72fdc83aa97281526294)

  • LVS作為最前置的結點,負責在網路第四層轉發流量、負載均衡。
  • 多個LVS使用Keepalived互為主備實現高可用。
  • Nginx作為反向代理,負責在網路第七層轉發流量、負載均衡。
  • Tomcat做為業務容器,主要的應用程式碼都在這裡面。
  • Redis作為快取,隔離高併發請求和後端資料庫。
  • MySQL以主從模式對資料做持久化。

其中,虛線部分是資料庫層,採用的是主從模式。也可以使用Redis Cluster(Codis等)以及MySQL Cluster(Cobar等)來替換。


本文節選自《Java工程師修煉之道》一書。

本書可以看作一本Java工程師的入職指南,也可以看作一本串聯Java後端技能點的參考手冊。通過精心編排的內容,剛入門的Java工程師能夠體系化地學習相關開發技能,有經驗的Java工程師能夠查漏補缺,鞏固自己的相關開發技能,進一步完善自身的Java技術體系。

file

file

購書地址:item.jd.com/12325207.ht…

file

相關文章