蝗蟲入侵肆虐 農民籲政府與國際伸援

摘錄自2019年12月22日中央社、ETToday報導

聯合國糧農組織(FAO)18日表示,蝗蟲入侵已摧毀索馬利亞與鄰邦伊索比亞境內7萬公頃農地,危及兩國糧食供應,這是兩國過去70年來最嚴重蝗蟲入侵事件。索馬利亞農民敦促索國政府以及國際社會,協助保護他們的農作物。

由於先前在東非地區發生了大雨以及大洪水,造成數百人喪生,讓今年的蟲災比FAO預期的還要糟,而且可能蔓延到「非洲之角」的其他國家,包括肯亞、吉布地、厄利垂亞、南蘇丹以及蘇丹。專家指出,氣候變遷是該地區天氣快速變化的主因。

更糟的是,FAO地區專員菲里(David Phiri)指出,由於氣候條件適合蝗蟲生長,牠們很可能會繼續繁殖,直到明年3到4月。

▼一名記者拍下蝗災的嚴重程度

Video: Huge locust swarm over Adado town today. Somalia faces the worst Desert Locust outbreak in over 25 years according to

— Harun Maruf (@HarunMaruf)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

Saft將供應61輛龐巴迪電車電池系統

世界級電池製造商Saft(帥福得)與法國龐巴迪(Bombardier)公司達成合作,將由Saft提供122組MX鎳鎘電池系統供龐巴迪61輛FLEXITY有軌電車運行於瑞士巴爾塞市。電池之生產與供貨將在2017年之前完成。

龐巴迪的FLEXITY有軌電車採低地板式設計,結合傳統的底盤結構,創造出更適合城市機動性要求的車體。2012年,龐巴迪與巴爾塞市交通部簽訂合約,巴爾塞市將出資1.84億歐元採購61輛FLEXITY有軌電車,用於取代既有的101輛有軌電車。

每輛FLEXITY有軌電車將搭載兩套Saft MSX 24V定制電池系統,為牽引系統提供緊急備用電源。當電纜供電中斷時,FLEXITY電車仍能繼續行駛到有電地段;而在沒有電纜的地區,Saft MSX也能驅動有軌電車短途行駛,增強機動性能。

Saft已在2013年為兩輛行駛於巴爾塞市的FLEXITY電車提供四套電池系統展開營運,而其餘59輛電車的電池將陸續開始交貨,預計在2017年完成。本次合約代表Saft在歐洲輕軌電車領域的業績成長,年成長率來到15%。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

東風計畫擴建新能源基地 但仍按“舊”規劃發展產品

據報導,東風汽車將在旗下東風乘用車公司擴建一處生產基地,用於新能源汽車製造。

實際上,東風的新能源乘用車產能暫時並不存在缺口。目前,東風乘用車武漢生產基地的年產能為16萬輛,東風乘用車的銷量僅為10萬輛。此外,東風乘用車在常州也建有生產基地,可用於新能源汽車生產。

對此,一位接近東風公司的知情人士表示,東風規劃的新能源汽車生產基地,可能將被用於新產品開發和生產。

仍按“舊”規劃發展產品

實際上,東風很早以前就開始電動汽車研發。其內部資料顯示,東風在“九五”規劃期間就開始電動車技術研發,2010年設立了9個整車項目平臺,包括混合動力和純電動,涉及乘用車和商用車。

據瞭解,主營商用車業務的東風股份2015年新能源商用車銷量達到5191輛,同比增長25倍。此外在商用車領域,東風還推出了純電動客車、物流車等產品,在主流市場均有佈局。

然而,與上汽、北汽等已推出多款新能源乘用車相比,東風在這一領域的反應略顯滯後。

2015年被視作新能源汽車發展元年,銷量開始成倍增長,各品牌相繼加入這一領域,然而,東風依然在按照多年前制定的既定產品路線發展。

據瞭解,目前東風自主品牌的新能源乘用車僅有E30、E30L、A60EV三款車型。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

特斯拉MODEL 3三月底發佈 預估售價約合人民幣22.77萬

據報導,特斯拉將於3月31日發佈全新MODEL 3車型,新車將於同期開始接受預訂,最快有望於2017年晚些時候交付客戶。新車的預估售價約為35000美元(約合人民幣22.77萬元)。

發佈當日,特斯拉將同期開始接受現場預訂,訂金為1000美元(約合人民幣6506元),次日(4月1日)起接受線上預訂,而新車實際交付將會於2017年晚些時候進行。根據消息,預售價為35000美元(約合人民幣22.77萬元)的MODEL 3作為入門車型,其電池續航里程或低於定位更高的MODEL S和MODEL X車型。即將發佈的MODEL 3車型為一款三廂轎車,但未來不排除有跨界版本出現的可能。

特斯拉CEO埃隆•馬斯克曾經表示,MODEL 3未來有望在中國投產,而價格預計只有MODEL S的一半。作為特斯拉的入門車型,MODEL 3將是一款肩負走量任務的產品,適合進行當地語系化生產。未來國產後,其價格可能會下降三分之一。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

戴姆勒 2016 年底前擬推出長續航距離電動車

據美國科技部落格 VentureBeat 報導,德國汽車廠商戴姆勒 (Daimler) 將在 2016 年 10 月份舉行的巴黎國際汽車展上,首次推出超長續航距離電動汽車,希望電動 SUV 的市場與特斯拉 Model X 一較高下。   報導中表示,戴姆勒技術研發部門負責人湯瑪斯‧韋伯 (Thomas Weber) 在出席位於德國斯圖加特舉行的記者會時宣布,該公司將會展示續航里程達 500 公里的賓士電動汽車原型車,與特斯拉 Model X 一較高下。不過, Thomas Weber 並未透露這款電動汽車何時上路行駛,只說會在 2020 年前完成這一目標。   目前,戴姆勒和歐洲其他汽車廠商正加緊對電動汽車的投資,以滿足歐盟新的排放標準,並且追趕上美國電動汽車產業的當紅炸子雞──特斯拉 (Tesla) 。另外,戴姆勒在德國本土的競爭對手,福斯旗下子公司包括奧迪與保時捷均已推出續航里程很長的電動汽車原型車,至於 BMW 也正在開發這種車型。   Thomas Weber 表示,戴姆勒將在 2016 年底推出第四代 Smart 電動汽車,包括兩座和四座兩個車型。戴姆勒目前共有 Smart 和 B 系列兩個全電動車型,還有眾多插電式混合動力車,即同時採用電池和汽油引擎驅動的車型。新款混合動力車也在開發之中。據了解,戴姆勒的目標是在 2020 年以前,每年售出超過 10 萬輛電動車。不過,Thomas Weber 拒絕提供 2015 年的銷售資料。   除了長距離續航力的電動車之外,戴姆勒還在開發燃料電池汽車,這種車型使用由氫發的電。該公司原計劃在 2014 年推出燃料電池汽車,但由於價格問題,不得不延遲發表。消息指出,戴姆勒燃料電池汽車 SUV GLC 預計將在 2017 年投產,屆時可能會與豐田 Mirai 展開競爭。   (首圖來源: CC BY 2.0)   (本文授權轉載自《》─〈〉)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

Nikola 氫電皮卡概念車 Badger 登場,續航將近一千公里,你信嗎?

電動車新創 Nikola 推出全新電動皮卡概念車 Badger,同時採用電池動力與氫燃料電池,續航里程高達 960 公里,零到一百加速只要 2.9 秒,問題是還有多少人相信他們?

超狂電動車新創 Nikola Motor(尼古拉)再次發出豪語,他們全新的皮卡車 Badger,將可以擁有傲視全球的 600 英哩續航力(約 960 公里),並且輸出高達 906 馬力,扭力也是兇猛的 1328 牛頓米。而且這台新車將採用雙動力模式,能夠以電池動力行駛,里程就已經有 300 英哩(約 480 公里),還可以再用氫燃料電池行駛額外的 300 英哩(480 公里),來吸引沒辦法充氫氣的族群。

Badger 的官方數據非常嚇人,完全樂勝競爭對手。

這輛新車的規格完全足以跟 Tesla Cybertruck、Rivian R1T 和電動悍馬車相抗衡,同時還有超越對手的續航力,Nikola 將在今年 9 月的技術大會上展示這輛全新的 Badger。

然而,Nikola 最不缺乏的就是漂亮的數據與規格,他們最需要的是一款真正能夠銷售的「產品」。Nikola 跟 Tesla 同樣用偉大科學家為名,也同樣喜歡講大話,但是 Tesla 在 2004 年到 2007 年總共進行了 3 輪募資,總金額約 6,500 萬美元。2006 年 Tesla 推出第一台原型車 Roadster,並且開始接單,2008 年第一季交車。儘管在初期有許多瑕疵,但至少他們把產品做出來也賣了出去。

但是 Nikola 的吸金功力遠遠超越它的前輩,他們光是 2017 年第一輪就募到 1.1 億美元後,目前已經進行了四輪募資,最新一輪的投資者包含 Bosch(博世)、Hanhwa(韓華技佳) 和 CNH(凱斯紐環球),金額超過 5 億,也讓它的募資總金額超過十億美元。

大廠領投加上跨時代的高科技,或許還要感謝 Tesla 的成功故事,讓這家連原型車都還沒做出來的車廠,就能拿下超過十億美元的資金。

Nikola 氫燃料電池卡車頭 TRE,直接和 Tesla Semi 打對台。

今年 9 月,Nikola 將舉辦 Nikola World 2020 大會,原先預定在這場大會上展示的,是他們新的氫燃料電池,根據之前官方釋出的消息,將能夠讓電動車續航力高達 1,200 公里,卡車甚至能高達 1,600 公里,讓所有人都嚇傻了。如今又新增這台氫電皮卡車 Badger 也要在 9 月展示,到底真相如何,屆時就能分曉。

如果 Nikola 真的掌握了革命性的技術,那麼未來發展很有機會超越特斯拉,成為商用市場的電動車小霸王;相反的,如果 Nikola 沒辦法兌現這些承諾,那就成了電動車界的 Theranos,對整體產業發展產生負面衝擊。

(合作媒體:。首圖來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※帶您來看台北網站建置台北網頁設計,各種案例分享

現實生活中的鋼鐵人──Tesla 聯合創辦人 Elon Musk

漫威系列中的鋼鐵人 Anthony Stark 擁有極佳的政治和商業手腕,縱橫在各個領域之間。現實生活中的 Tesla 聯合創辦人 Elon Musk,除了在電動車市場佔有一席之地以外,過往他成立的電子支付平臺 PayPal,或是現在同時經營的太空計畫 SpaceX,甚至是打造未來交通系統全新樣貌的 Hyperloop,其成就都可以和 Anthony Stark 比擬。  
Elon Musk 簡介   1971 年出生在南非,Elon Musk 本身具有多重身分,最廣為世人所知的是 SpaceX 創辦人,以及 PayPal 和 Tesla 的聯合創辦人。他有過兩段婚姻和 5 個孩子,最終都以離婚收場。其投資或創立的公司眾多且跨足各種領域,並能善用之間的脈絡進行技術整合,被喻為鋼鐵人的真人版,也曾在電影《鋼鐵人》客串飾演自己。  

▲ Elon Musk 在鋼鐵人中客串演出自己。(Source:)  
創業的起點-Zip2、PayPal   24 歲那年,Musk 從史丹佛的物理研究所中輟離開學校,開創他的第一家公司 Zip2 Corporation,一家對線上報紙提供地圖和商業指引的公司。4 年後,1999 年 Musk 將公司以 3 億 700 萬美元出售,寫下了當年網路產業有史以來最高的成交價。   出售 Zip2 的同年,Musk 從出售 Zip2 得到的錢中撥出一千萬美元投資成立線上金融服務公司 X.com。他想要利用新科技(例如 email)完成支付,並將自己創立的公司和競爭對手 Confinity 合併,後者正是 PayPay 的前身。然而經歷一些衝突後,Confinity 的共同創辦人將 Musk 從董事會中開除,並將公司名稱改為 PayPal,其後在 2002 年被 eBay 以 15 億美元收購。  

▲ PayPal 的商標。  
顛覆汽車產業的 Tesla   2003 年 Martin Eberhard 和 Marc Tarpenning 砸重金成立 Tesla,Musk 隨後加入公司的董事會。該公司推出的第一輛 Roadste 令人驚豔,不僅因為可以在四秒內從 0 加速到 60 英哩 / 每小時,更可以在單次充飽電後行駛 250 英哩。2008 年金融風暴後,Musk 取得公司主導的地位,並接下了 CEO 的職務。   2016 年 3 月,一輛售價 3.5 萬美元(約新台幣 110 萬元)的 Model 3 在全新預售時吸引了全球 32 萬筆以上的訂單。電動車的市場如火如荼發展下,Tesla 改採直銷的方式站在第一線和客戶交互動,並根據顧客回饋隨時修正市場方向。Musk 放話在 2018 年要達到年度出貨 50 萬輛以上的目標,有別於競爭對手使用的鋰電池,Tesla 電動車的電池是數千個普通電池聚合成,可以在行駛長程路線和短時間內加速等方面表現亮眼,其驚豔程度甚至打破了 Consumer Reports 的評比系統。  

 
▲Medel 3(Source:)    
Tesla 的未來發展關鍵:Model 3 能否在 2017 年如期交貨   Tesla 帶起一股電動車的潮流,自然也會吸引競爭對手的模仿。德國福特執行長對外表示他們正積極研發可以與 Model 3 匹敵的長程電動車,目標是每次充飽電可以行駛高達 200 英哩。不僅汽車大廠紛紛投入長程電動車的研發,電池蓄電能力的提升也是另一大技術關鍵。賓士母公司戴姆勒日前對外公開表示正在生產用於家用儲能的電池組,未來計劃販售給電力供應商或太陽能公司,結合太陽能電池儲存功能。這塊電動車大餅的瓜分潮也延燒到中國,其熱度不輸當年的 2000 年網路泡沫。   不過,Tesla 會帶來的是個實際的未來或是幻想呢?2016 年 Model 3 的預售掀起一股熱潮,一天內湧入了 11 萬筆訂單,預售第一周累積筆數高達 32 萬筆。不過 5 月 4 日公布的 2016 年第一季財報看來,雖然營收比去年同期增加 22%,但因為擴張階段帶來的高營業費用支出,以及 2017 年是否能如期交貨仍是個未知數,公司整體仍呈現虧損狀態。另外,預售時的簽訂合約也是個隱藏版玄機,消費者只要交付 1,000 美元,可在未來無條件解約拿回全額訂金。Tesla 的方面,只在合約中提及「可能在 2017 年交貨」,到時候若延至 2018 年或更更遙遠的時間點,趙文字敘述並未違反合約規定。Tesla 能否具足產能在 2017 年順利出貨,將會直接影響 Tesla 未來的發展。  
SpaceX:一手包辦設計、製造和發射火箭的公司   在 2002 年的最後,Musk 成立了 SpaceX,目標是讓火箭的價格變得平易近人。2012 年,SpaceX 推出的 Dragon 成為了第一個在國際太空站和地球間運送貨櫃的商業宇宙飛船。Musk 最終希望透過 Dragon 將人類送上外太空,並且計劃將人類送到火星殖民地。   經歷了 4 次的失敗,SpaceX 成功讓獵鷹 9 號火箭在發射太空梭到太空後,成功的降落在海上平台。Musk 近日對外宣布要在 2018 年登上火星,回顧 SpaceX 發展的光景,有以下的重大成就:

  1. SpaceX 為一家掌握了設計、製造和發送等製造流程的私人公司,正因為一條龍的供應鏈整合降低了成本,相對於一般需花費 4.6 億美元,SpaceX 的支出僅 9,000 萬美元。
  2. SpaceX 的獵鷹 9 號火箭由9 座 Merlin 1D 引擎建構,即使其中一座引擎在發射期間故障,不過火箭仍順利將運載的貨物成功送上太空完成任務。
  3. 第一家回收火箭的私人公司,完成發射衛星到地球軌道後,還能將獵鷹 9 號成功回收,這可是唯大做到的公司,是可相當大的創新壯舉。

SpaceX 公司員工數從 2002 年創立的 14 人,到現在已有 2,000 人,短時間人力資源速度增加之快令人佩服。近期 SpaceX 也獲得 NASA 的認可,拿下了運送太空人往返國際太空站的權利,預計最快 2017 年就能達成此目標。此外,也打敗了競爭對手聯合發射聯盟(United Launch Alliance)得到了軍事衛星的發射資格。台灣的福爾摩沙衛星五號將由 SpaceX 提供 Falcon 9 火箭,預計 2016 年第二季發射。  
SolarCity:太陽能乾淨能源系統的擁護者   Musk 長久以來就以支持永續和綠能科技聞名。為了讓 Tesla 可以保持在節省能源之流,他投資巨額在 SolarCity,一個由他的表兄弟 Lyndon 和 Peter Rive 成立安裝家戶太陽能的公司,目前 Musk 擔任該公司的主席。   SolarCity 設計和裝設太陽能乾淨能源系統,同時也監管和建構電動車充電站。2015 年 4 月,他宣布SloarCity 和 Tesla 的電池合作,推動太陽能電池後衛系統。同年底,Musk 對外宣稱通過 Renewable Energy Test Center(RETC)的測試,其太陽能板的轉換率高達 22.04%,勝過最大競爭對手 SunPower X 的 21.5% 轉換效率。   SolarCity 看好的前景,吸引 Google 投資 3 億美元協助開拓住宅太陽能市場。SolarCity 也大動作進軍非洲,或者與 Tesla、Nest 結盟,目標在缺乏能源的夏威夷推出自給自足的能源系統。然而,SolarCity 推出的家庭能源儲存系統的 10 Wh 容量 Powerwall 已在 2016 年 3 月悄悄下架,只留下號稱 7 Wh 的 6.4 Wh 版本,不禁讓外界質疑 Powerwall 的前景。  

▲ Powerwall 展示。(Source:)  
Hyperloop :未來交通系統樣貌的超迴路列車   超迴路列車(Hyperloop)是 Musk 著手的新計畫,一項可以加快兩地之間移動速度的交通系統。摩擦力是造成交通工具移動速度快慢的關鍵,Hyperloop 計劃以懸浮的運行方式,利用膠囊型的座艙載客,速度預計可以在 30 分鐘內橫跨越約 350 英里(約 560 公里)的距離,有可能超越飛機的飛行速度。不過這項運輸建設尚在計劃當中,相關的費用估計也存有爭議。

(首圖來源: CC BY 2.0)

(本文授權轉載自《》─〈〉)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!

每賣一輛 Model S 特斯拉得賠超過 4,000 美元

美國豪華電動車廠特斯拉(Tesla)若以營業虧損來結算,每賣出一輛 Model S 電動汽車,就要賠超過 4,000 美元(約新台幣 12.7 萬元),上季特斯拉在豪華車的牛市燒掉 3.59 億美元。   特斯拉第 2 季交貨量為 1 萬 1,532 輛,營業虧損大約 4,700 萬美元,換算成每輛為虧損 4,000 美元左右。   特斯拉 5 日已削減今年與明年的生產目標。執行長馬斯克(Elon Musk)表示,他正在思考擴大募資的選項,且不排除脫手更多股票。  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

從代碼的視角深入淺出理解DevOps

對於DevOps的理解大家眾說紛紜,就連維基百科(Wikipedia)都沒有給出一個統一的定義。一般的解釋都是從字面上來理解,就是把開發(Development)和運維(Operations)整合到一起,來加速產品從啟動到上線的過程,並使之自動化。這個是對DevOps的廣義解釋,而且大多數人都是認可的。但這個解釋太寬泛了,幾乎包括了IT的所有內容,使之沒有太大意義。 而DevOps是近幾年才興起的(2014年才開始流行),它是對某種項目模式的描述,是有着其特定內涵的。任何項目都可以分成開發和運維兩個部分,而開發的一整套流程和工具在DevOps之前早就有了,並沒有改變。

DevOps真正改變的是運維。因此從運維的角度去理解DevOps,才能抓住它的本質。你可以把它理解為用開發的方式做運維(Operation as Development),這就是對它的狹義的理解。 開發的方式就是寫代碼,換句話說DevOps就是通過寫代碼來做運維。運維里一個非常流行的概念叫“Iac()” 基礎設施即代碼,也就是把運行環境的創建用代碼的形式來描述出來,通過運行代碼來創建環境。它是運維領域的一場革命,開創了現代運維技術,它也是DevOps的基石。但基礎設施創建只是運維的一部分,如果我們把這場革命繼續延伸到運維的各個領域,讓代碼覆蓋整個運維,那時就是代碼即運維(Operation as Code),這才是DevOps的精髓。

那麼從一個應用程序項目的角度看,什麼是DevOps呢?它就是把應用程序的代碼和運維的代碼都放到一個源程序庫中,並對它進行版本管理,這樣你就擁有了關於這個項目的所有信息,隨時可以部署這個程序(包括程序本身和它的運行環境),而且可以保證每次創建出來的程序的運行結果是一樣的(因為它的運行環境也是一樣的)。

運維即代碼(Operation as Code):

下面我們就把運維所做的事情一件一件拆分開,看看他們是怎麼用代碼來實現的。

運維的工作通常包括下面幾個方面:

  • 基礎設施:即程序運行環境的創建和維護。
  • 持續部署:部署應用程序,並使整個過程自動化。
  • 服務的健壯性:是指當服務的的運行環境出現了問題,例如網絡故障或服務過載或某些微服務宕機的情況下,程序仍能夠提供部分或大部分服務。
  • 運行監測:它既包含對程序的監測也包含對運行環境的監測。

基礎設施即代碼 (Infrastructure as code)

我們通過一個Go(別的語言也大同小異)微服務程序做例子來展示如何用代碼來創建基礎設施。程序本身的功能非常簡單,只是用SQL語句訪問數據庫中的數據,並寫入日誌。你可以簡單地把它分成兩層,後端數據訪問層和數據庫層。程序的部署環境是基於k8s的容器環境。在k8s中它被分成兩個服務。一個是後端程序服務,另一個是數據庫(用MySQL)服務。後端程序要調用數據庫服務,然後會把一些數據寫入日誌。

在這種新的模式下,運行環境的代碼和應用程序的代碼是存在一個源碼庫中的,這樣當你下載了源碼庫之後,你不但擁有了程序的所有源碼,而且也擁有了運行環境的源碼。這樣當要創建新的運行環境時,只要運行一遍代碼就能創建出整套的運行環境,而且每次創建出來的環境都是一致的。

上面就是這個Go程序的目錄結構,它裏面有一個目錄“script”是專門存放與運行環境相關的文件的,裏面的“kuburnetes”子目錄就是整個運行環境的代碼。除了“script”之外的其它目錄存有應用程序的代碼。這樣,與這個應用程序有關的信息都以代碼的方式保存在了一個源代碼庫。有了它之後,你可以隨時部署出一個相同的程序的運行環境,而且保證是一模一樣的。

“kubernetes”目錄下有兩個子目錄“backend”和“database”分別存放後端程序和數據庫的配置文件。它們內部的結構是類似的,都有三個“yaml”文件:

  • backend-deployment.yaml:部署配置文件,
  • backend-service.yaml:服務配置文件
  • backend-volume.yaml:持久卷配置文件.

另外還有一個“.sh”文件是它的運行命令,當你運行這個shell文件時,它就調用上面三個k8s配置文件來創建運行環境。

kubernetes目錄的最外層有兩個“yaml”文件“k8sdemo-config.yaml”和”k8sdemo-secret.yaml”,它們是用來創建k8s運行環境參數的,因為它們是被不同服務共享的,因此放在最外層。另外還有一個”k8sdemo.sh”文件是k8s命令文件,用來創建k8s對象。

這種源程序結構的一個好處就是使應用程序和它的運行環境能夠更好地集成。舉個例子,當你要修改服務的端口時,以前,你需要在運行環境和源碼里分別修改,但它是分別由開發和運維完成的,這很容易造成修改的不同步。當你把它們放在同一個源碼庫中,只需要修改一個地方,這樣就保證了應用程序和運行環境的一致性。

下面就是後端服務的k8s配置代碼:

apiVersion: v1
kind: Service
metadata:
  name: k8sdemo-backend-service
  labels:
    app: k8sdemo-backend
spec:
  type: NodePort
  selector:
    app: k8sdemo-backend
  ports:
    - protocol : TCP
      nodePort: 32080
      port: 80
      targetPort: 8080

由於篇幅的關係,這裏就不詳細解釋程序了,有興趣的請參見.

基礎設施可以分成兩個層面,一個就是上面講到的k8s層面,也就是容器層面,這個是跟應用程序緊密相關的。還有一個層面就是容器下面的支持層,也就是虛機層面,當然還包括網絡,負載均衡等設備或軟件。當你在阿里雲或華為雲上創建k8s之前,先要把這些構建好才行。它的部署也可以用代碼來完成。Terraform就是一款非常流行的用來完成創建的工具,它是被ThoughtWorks推薦的(詳見 ),它支持用代碼來創建虛機。

代碼如下:

resource "aws_instance" "example" {
  count         = 10
  ami           = "ami-v1"
  instance_type = "t2.micro"
}

但在這一層面,基礎設施的工作與應用程序的關聯並沒有那麼緊密,因此這部分的代碼沒有放在應用程序里,你可以單獨創建一個基礎設施的源碼項目,用來存放這部分代碼。

持續部署(Continuous Deployment)

部署應用程序是運維的一項重要工作。隨着商業競爭的加劇,要求更快的程序更新,從原來的的幾周部署一次,到後來的一天部署十幾次甚至幾十次。這樣手工部署就完全不能滿足需要,於是就要把整個流程自動化,這就是持續部署。

管線(pipeline)是一個很重要的概念,它用來描述持續部署的整個步驟和流程。Jenkin是一款非常流行的持續集成和部署工具,它提出了“管線即代碼”(“Pipeline as code”,詳見)。就是把持續部署的管線也作為程序源碼的一部分,和應用程序一起管理起來,讓它有着和應用程序一樣的版本和複審流程。

下面我們就通過一個具體例子來說明他是怎樣實現的。這個例子用的是和上面一樣的程序。先來看一下程序的目錄結構。

與持續部署相關的文件都在“script”目錄下,他被分成兩部分,一個是“cd”子目錄,它存有Jenkins的管線,另一個是“Kubernetes”下的“jenkins”子目錄,它存有Jenkinsde的k8s配置文件。你如果仔細看一下的話會發現它裏面的文件和前面講到的後端程序和數據庫的k8s配置文件很相似,有了它,你就可以在k8s里創建出Jenkins的運行環境。

這裏我把Jenkins的k8s配置文件也放在應用程序里了,但實際上它是應該放在前面提到的基礎設施項目源碼里。因為Jenkins是被應用程序共享的,而不是屬於單獨的一個應用。這裏為了說明方便放在一起了,真正用的時候要把它抽取出來。

下面就是管線的代碼:

def POD_LABEL = "k8sdemopod-${UUID.randomUUID().toString()}"
podTemplate(label: POD_LABEL, cloud: 'kubernetes', containers: [
    containerTemplate(name: 'modified-jenkins', image: 'jfeng45/modified-jenkins:1.0', ttyEnabled: true, command: 'cat')
  ],
  volumes: [
     hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
  ]) {

    node(POD_LABEL) {
       def kubBackendDirectory = "/script/kubernetes/backend"
       stage('Checkout') {
            container('modified-jenkins') {
                sh 'echo get source from github'
                git 'https://github.com/jfeng45/k8sdemo'
            }
          }
       stage('Build image') {
            def imageName = "jfeng45/jenkins-k8sdemo:${env.BUILD_NUMBER}"
            def dockerDirectory = "${kubBackendDirectory}/docker/Dockerfile-k8sdemo-backend"
             container('modified-jenkins') {
               withCredentials([[$class: 'UsernamePasswordMultiBinding',
                 credentialsId: 'dockerhub',
                 usernameVariable: 'DOCKER_HUB_USER',
                 passwordVariable: 'DOCKER_HUB_PASSWORD']]) {
                 sh """
                   docker login -u ${DOCKER_HUB_USER} -p ${DOCKER_HUB_PASSWORD}
                   docker build -f ${WORKSPACE}${dockerDirectory} -t ${imageName} .
                   docker push ${imageName}
                   """
               }
             }
           }
       stage('Deploy') {
           container('modified-jenkins') {
               sh "kubectl apply -f ${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml"
               sh "kubectl apply -f ${WORKSPACE}${kubBackendDirectory}/backend-service.yaml"
             }
       }
    }
}

由於篇幅的關係,這裏不詳細解釋。如果有興趣並想了解如何運行Jenkins來完成持續部署,請參閱 .

這裏我用的是Jenkins軟件,它另外還有一個子項目叫Jenkins-x,是專門為k8s環境量身打造的,它的主要功能是能夠幫助你自動生成管線代碼(你需要回答他的一些問題)。如果你不想自己寫代碼,那麼你可以試一下它,詳情請見。

服務的韌性(Service Resilience as Code)

又叫服務的健壯性,這部分不像前面兩個部分有着公認的名字,英文叫“Service Resilience”,翻譯成中文就五花八門了,我覺得叫服務的韌性比較合適。

“Service Resilience”是指當服務的的運行環境出現了問題,例如網絡故障或服務過載或某些微服務宕機的情況下,程序仍能夠提供部分或大部分服務,這時我們就說服務的韌性很強。它是衡量服務質量的一個重要指標。

這部分的功能包括下面幾個部分:

  • 服務超時 (Timeout)
  • 服務重試 (Retry)
  • 服務限流(Rate Limiting)
  • 熔斷器 (Circuit Breaker)
  • 故障注入(Fault Injection)
  • 艙壁隔離技術(Bulkhead)

這部分與前面兩個部分略有不同,前面兩個部分都是典型的運維任務,而這部分以前是應用程序的一部分,只是這些年才慢慢開始轉移到運維的。

最開始的時候,這些功能都是和程序的業務邏輯混在一起,對業務邏輯的侵入很大,後來,大家開始把這部分邏輯抽取出來,劃分成單獨的一部分。下面通過一個具體的例子(Go微服務程序)來講解:

上圖是程序的目錄結構,它分為客戶端(client)和服務端(server),它們的內部結構是類似的。“middleware”包是實現服務韌性功能的包。 “service”包是業務邏輯包,在服務端就是微服務的實現函數,在客戶端就是調用服務端的函數。在客戶端(client)下的“middleware”包中包含四個文件並實現了三個功能:服務超時,服務重試和熔斷器。“clientMiddleware.go”是總入口。在服務端(server)下的“middleware”包中包含了兩個文件並實現了一個功能,服務限流。“serverMiddleware.go”是總入口。

注意,這裏的服務韌性的功能是完全從業務邏輯中抽出來了,對業務邏輯沒有任何侵入,它是在一個單獨的包(middleware)里實現的。這裏用的是修飾模式。有關程序實現的詳情,請參閱。

上面講的是用程序來實現這些功能,但從本質上來講這些功能不應該屬於應用程序,而是應該由基礎設施來完成。現在公認的看法是,服務網格(Service Mesh)是完成這些功能的最佳方案。使用服務網格的方式和k8s類似,也是創建配置文件,然後通過運行配置文件來建立服務網格的運行環境。我們這裏用Istio來舉例說明,Istio是一款非常流行的服務網格軟件。

上圖就是下載的Istio軟件的目錄,“bookinfo”是它的一個示例程序,在這個例子里,它展示了多種使用Istio的方式,其中就有如何實現服務韌性的方法。詳情請參見.

運行監測 (Monitoring or Observability)

運行監測是運維的一項重要內容,它通常包含如下幾個方面的內容:

  • 日誌(logging): 記錄的是程序運行過程中的信息
  • 跟蹤(tracing): 記錄的是與一條請求相關的信息,特別是請求的與時間有關的信息。
  • 指標(metrics): 與上面的離散的信息不同,這裏記錄的是可累加的信息,一般是按照時間軸進行累加。

我們經常稱之為觀測的三個支柱(Three Pillars of Observabilty),有一篇很不錯的講解它們之間關係的文章,詳情請見””。

這部分的內容可能會有些爭議。因為前幾個部分都是清清楚楚的運維工作,即使服務韌性, 雖然以前是開發的工作,但現在也已經一直公認是運維的事,而且它們的代碼都能很乾凈的摘出來。但運行監測不一樣,雖然主要工作還是由運維來完成,但它的代碼與業務邏輯代碼混在一起,很難摘得清楚。

日誌:

這部分的代碼都是在應用程序里,但日誌的採集,匯總,分析和展示都是由運維來完成。它的代表就是著名的ELK系列。採用DevOps之後,這裏面的變化不大,頂多就是採集代理(Agent)更好地和服務網格或k8s進行集成,使之變得更為容易。

分佈式跟蹤:

這部分有點像服務韌性,開始的時候是由程序完成,慢慢地把它變成單獨的部分與應用程序隔離開,最終大部分的工作交由服務網格來完成。但它又與服務韌性不太相同。服務韌性可以和應用程序做一個非常乾淨的切割,而分佈式跟蹤取決於跟蹤的顆粒度。如果僅是服務之間的跟蹤,就一點問題都沒有,完全可以由服務網格來完成。但如果是服務內部的跟蹤,服務網格就無能為力了,還是要由程序代碼來完成,就像日誌一樣。但我覺得服務之間的跟蹤是投入產出比最高的,大多數情況下有它就足夠了,不必需要服務內部的跟蹤。

詳細情況請參見

Metrics:

這部分觀測的是累加信息。大多數情況下,只要安裝好工具,就能採集數據進行分析。最流行的工具是Prometheus. 你不需要寫代碼來獲取數據,不過你如果想要快速地找到需要的信息,k8s的配置還是要和Prometheus的設置相匹配,因此你需要做一些詳細的設計。詳細情況請參見。

當然你如果有一些更細緻的監測需求,Prometheus不能直接滿足。這時需要在應用程序里插入一些Prometheus的監測代碼來滿足你的需要。

其他工作

是不是還有其他運維工作被漏掉了?

持續集成(Continious Integration)

很多人都把持續集成(CI)算作DevOps的重要組成部分,那是因為他用的是廣義的定義。按照狹義的理解,DevOps只包括運維的內容。持續集成(CI)與持續部署(CD)有着明顯的不同,持續集成是開發的工作,而持續部署是運維的工作,下圖展示了它們的差異。

如圖所示,整個流程是這樣的:
程序員從源碼庫(Source Control)中下載源代碼,編寫程序,完成后提交代碼到源碼庫,持續集成(Continuous Integration)工具從源碼庫中下載源代碼,編譯源代碼,然後提交到運行庫(Repository),然後持續交付(Continuous Delivery)工具從運行庫(Repository)中下載代碼,生成發布版本,併發布到不同的運行環境(例如DEV,QA,UAT, PROD)。

圖中,左邊的部分是持續集成,它主要跟開發和程序員有關;右邊的部分是持續部署,它主要跟測試和運維有關。持續交付(Continuous Delivery)又叫持續部署(Continuous Deployment),它們如果細分的話還是有一點區別的,但我們這裏不分得那麼細,統稱為持續部署

我並沒有把持續集成放到DevOps裏面,因為本文用的是狹義的解釋,也就是只包含運維的部分。

結論

本文從代碼的視角詮釋了對DevOps的理解,DevOps的精髓就是用寫代碼的方式來做運維,並對運維的各個部分給出了具體的實例,希望能對想採用DevOps的朋友有所幫助。DevOps對開發和運維的改變都是巨大的,尤其是對運維。在不久的將來,就沒有開發和運維之分了,只有一個工作,就是寫代碼,當然也許會細分成開發碼農和運維碼農。運維的工作都是通過寫代碼來完成。應用程序里不但包括業務邏輯的代碼,也包括運維的代碼,它們會被同時存儲在一個源碼庫中。

源碼庫

完整源碼的github鏈接:

索引:

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

Java基礎系列6:深入理解Java異常體系

該系列博文會告訴你如何從入門到進階,一步步地學習Java基礎知識,並上手進行實戰,接着了解每個Java知識點背後的實現原理,更完整地了解整個Java技術體系,形成自己的知識框架。

 

前言:

Java的基本理念是“結構不佳的代碼不能運行”。

“異常”這個詞有“我對此感到意外”的意思。問題出現了,你也許不清楚該如何處理,但你的確知道不應該置之不理;你要停下來,看看是不是有別人或在別的地方,能夠處理這個問題。只是在當前的環境中還沒有足夠的信息來解決這個問題,所以就把這個問題提交到一個更高級別的環境中,在這裏將作出正確的決定。

使用異常所帶來的另一個相當明顯的好處是,它往往能夠降低錯誤處理代碼的複雜度。如果不使用異常,那麼就必須檢查特定的錯誤,並在程序中的許多地方去處理它。而如果使用異常,那就不必在方法調用處進行檢查,因為異常機制將保證能夠捕獲這個錯誤。並且,只需在一個地方處理錯誤,即所謂的異常處理程序中。這種方式不僅節省代碼,而且把“描述在正常執行過程中做什麼事”的代碼和“出了問題怎麼辦”的代碼相分離。總之,與以前的錯誤處理方法相比,異常機制使代碼的閱讀、編寫和調試工作更加井井有條。

 

異常概述:

現在我們需要編寫一個五子棋程序,當用戶輸入下期坐標時,程序要判斷用戶輸入是否合法,如果保證程序有較好的容錯性,將會有如下的代碼(偽代碼):

if(用戶輸入包含除逗號之外的其他非数字字符)
{
	alert 坐標只能是數值
	goto retry
}
else if(用戶輸入不包含逗號) {
	alert 應使用逗號分隔兩個坐標值
	goto retry
}

else if(用戶輸入坐標值超出了有效範圍) {
	alert 用戶輸入坐標應位於棋盤坐標之內
	goto retry
}

else if(用戶輸入的坐標已有棋子)
{
	alert 只能在沒有棋子的地方下棋
	goto retry
}
else {
	.....
}

  

上面代碼還未涉及任何有效處理,只是考慮了4種可能的錯誤,代碼就已經急劇增加了。但實際上,上面考慮的4種情形還遠未考慮到所有的可能情形(事實上,世界上的意外是不可窮舉的),程序可能發生的異常情況總是大於程序員所能考慮的意外情況。

對於上面的錯誤處理機制,主要有以下兩個缺點:

  • 無法窮舉所有的異常情況。因為人類知識的限制,異常情況總比可以考慮到的情況多,總有“漏網之魚”的異常情況,所以程序總是不夠健壯。
  • 錯誤處理代碼和業務實現代碼混雜。這種錯誤處理和業務實現混雜的代碼嚴重影響程序的可讀性,會增加程序維護的難度。

我們希望有這樣一種處理機制:

if(用戶輸入的數據不合法){
    .....
}else{
   處理邏輯
   .....  
}

  

上面偽碼提供了一個非常強大的“if塊”——程序不管輸入錯誤的原因是什麼,只要用戶輸入不滿足要求,程序就一次處理所有的錯誤。這種處理方法的好處是,使得錯誤處理代碼變得更有條理,只需在一個地方處理錯誤。

這就需要用到java異常了。

 

異常是程序中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候是可以避免的。

比如說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤java.lang.Error;如果你用System.out.println(11/0),那麼你是因為你用0做了除數,會拋出java.lang.ArithmeticException的異常。

異常發生的原因有很多,通常包含以下幾大類:

  • 用戶輸入了非法數據。
  • 要打開的文件不存在。
  • 網絡通信時連接中斷,或者JVM內存溢出。

 

Java中的異常有以下三種類型:

檢查異常:最具代表的檢查性異常是用戶錯誤或問題引起的異常,這是程序員無法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。

運行異常:運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常可以在編譯時被忽略。

錯誤:錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中通常被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。

 

異常的體繫結構:

我們先來統觀以下Java的異常體繫結構圖:

 

 

Java的異常被分為兩大類:Checked異常和Runtime異常(運行時異常)。所有的RuntimeException類及其子類的實例被稱為Runtime異常;不是RuntimeException類及其子類的異常實例則被稱為Checked異常。

只有Java語言提供了Checked異常,其他語言都沒有提供Checked異常。Java認為Checked異常都是可以被處理(修復)的異常,所以Java程序必須顯式處理Checked異常。如果程序沒有處理Checked異常,該程序在編譯時就會發生錯誤,無法通過編譯。

 

Throwable

Java異常的頂級類,所有的類都繼承自Throwable

Error:

Error錯誤,一般是指與虛擬機相關的問題,如系統崩潰、虛擬機錯誤、動態鏈接失敗等,這種錯誤無法恢復或不可能捕獲,將導致應用程序中斷。通常應用程序無法處理這些錯誤,因此應用程序不應該試圖使用catch 塊來捕獲Error對象。
在定義該方法時,也無須在其throws子句中聲明該方法可能拋出Error及其任何子類。

 

Exception:

Exception中異常主要分為兩大類,運行時異常和檢查異常。常見的運行時異常有ArrayIndexOutOfBoundsException(數組下標越界)、NullPointerException(空指針異常)、ArithmeticException(算術異常)、ClassNotFoundException(類型找不到),這些異常時非檢查異常,程序可以選擇處理,也可以不處理,編譯器編譯時期並不會報錯。這些異常一般是由於程序邏輯錯誤引起的,所以建議程序員還是處理一下。除運行時異常外的所有異常我們都稱為非運行時異常,也是必須處理的異常,如果不出來,程序編譯會報錯。

 

Error和Exception的區別:

ErrorException的區別:Error通常是災難性的致命的錯誤,是程序無法控制和處理的,當出現這些異常時,Java虛擬機(JVM)一般會選擇終止線程;Exception通常情況下是可以被程序處理的,並且在程序中應該盡可能的去處理這些異常。

 

檢查異常:必須處理的異常

除了RuntimeException及其子類以外,其他的Exception類及其子類都屬於檢查異常,當程序中可能出現這類異常,要麼使用try-catch語句進行捕獲,要麼用throws子句拋出,否則編譯無法通過。

 

非檢查異常:可以不處理

包括RuntimeException及其子類和Error

不受檢查異常為編譯器不要求強制處理的異常,檢查異常則是編譯器要求必須處置的異常。

 

異常處理機制:

Java的異常處理機制可以讓程序具有極好的容錯性,讓程序更加健壯。當程序運行出現意外情形時,系統會自動生成一個Exception對象來通知程序,從而實現將“業務功能實現代碼”和“錯誤處理代碼”分離,提供更好的可讀性。

java異常關鍵字:

  • try – 用於監聽。try后緊跟一個花括號括起來的代碼塊(花括號不可省略),簡稱try塊,它裏面放置可能引發異常的代碼,當try語句塊內發生異常時,異常就被拋出。【監控區域】
  • catch – 用於捕獲異常。catch后對應異常類型和一個代碼塊,用於處理try塊發生對應類型的異常。【異常處理程序】
  • finally – 用於清理資源,finally語句塊總是會被執行。 多個catch塊后還可以跟一個finally塊,finally塊用於回收在try塊里打開的物理資源(如數據庫連接、網絡連接和磁盤文件)。只有finally塊執行完成之後,才會回來執行try或者catch塊中的return或者throw語句,如果finally中使用了return或者throw等終止方法的語句,則就不會跳回執行,直接停止。【使用finally進行清理】
  • throw – 用於拋出一個實際的異常。throw可以單獨作為語句使用,拋出一個具體的異常對象。【拋出異常】
  • throws –用在方法簽名中,用於聲明該方法可能拋出的異常。【異常說明】

 

1、使用try…catch捕獲異常:

語法格式:

try{
   //業務實現代碼
   ...
}catch(Exception e){
  //異常處理代碼
  ...
}

  

如果執行try塊里的業務邏輯代碼時出現異常,系統自動生成一個異常對象,該異常對象被提交給Java運行時環境,這個過程被稱為拋出(throw)異常。

當Java運行時環境收到異常對象時,會尋找能處理該異常對象的catch塊,如果找到合適的catch塊,則把該異常對象交給該catch塊處理,這個過程被稱為捕獲(catch)異常;如果Java運行時環境找不到捕獲異常的catch塊,則運行時環境終止Java程序也將退出。

下面看幾個簡單的異常捕獲的例子:

例1:

public class DivTest {
	
	public static void main(String[] args) {
		try {
			int a=Integer.parseInt(args[0]);
			int b=Integer.parseInt(args[1]);
			int c=a/b;
			System.out.println("您輸入的兩個數相除的結果是"+c);
		}catch(IndexOutOfBoundsException e) {
			System.out.println("數組越界,運行時參數不夠");
		}catch(NumberFormatException e) {
			System.out.println("数字格式異常");
		}catch(ArithmeticException e) {
			System.out.println("算術異常");
		}catch(Exception e) {
			System.out.println("未知異常");
		}
	}

}

  

  • 如果運行該程序時輸入的參數不夠,將會發生數組越界異常,Java運行時將調用IndexOutOfBoundsException對應的catch塊處理該異常。
  • 如果運行該程序時輸入的參數不是数字,而是字母,將發生数字格式異常,Java運行時將調用NumberFormatException 對應的catch塊處理該異常。
  • 如果運行該程序時輸入的第二個參數是0,將發生除0異常,Java運行時將調用ArithmeticException對應的catch塊處理該異常。
  • 如果程序運行時出現其他異常,該異常對象總是Exception類或其子類的實例,Java運行時將調用Exception對應的catch塊處理該異常。

上面程序中的三種異常是我們在編程中經常遇見的,讀者應該掌握這些異常。

例2:

import java.util.Date;


public class Test {
	
	public static void main(String[] args) {
		Date d=null;
		try {
			System.out.println(d.after(new Date()));
		}catch(NullPointerException e) {
			System.out.println("空指針異常");
		}catch(Exception e) {
			System.out.println("未知異常");
		}
	}

}

  

上面程序針對NullPointerException異常提供了專門的異常處理塊。上面程序調用一個null對象的after0方法,這將引發NullPointerException異常(當試圖調用一個null對象的實例方法或實例變量時,就會引發NullPointerException異常),Java 運行時將會調用NullPointerException對應的catch塊來處理該異常;如果程序遇到其他異常,Java運行時將會調用最後的catch塊來處理異常。

catch塊處理異常遵循着:先小后大,即先子類後父類。正如在前面程序所看到的,程序總是把對應Exception類的catch塊放在最後,這是為什麼呢?讀者可能明白原因:如果把Exception類對應的catch塊排在其他catch塊的前面,Java運行時將直接進入該catch塊(因為所有的異常對象都是Exception或其子類的實例),而排在它後面的catch塊將永遠也不會獲得執行的機會。

 

多異常捕獲:

在Java7之前,每個catch塊只能捕獲一個異常,Java7之後,每個catch塊可以捕獲多種類型的異常。

上面的例1可以改成如下代碼實現:

public class Test {
	
	public static void main(String[] args) {
		try {
			int a=Integer.parseInt(args[0]);
			int b=Integer.parseInt(args[1]);
			int c=a/b;
			System.out.println("您輸入的兩個數相除的結果是"+c);
		}catch(IndexOutOfBoundsException|NumberFormatException|ArithmeticException e) {
			System.out.println("數組越界,数字格式異常,算術異常");
		}catch(Exception e) {
			System.out.println("未知異常");
		}
	}

}

  

2、使用throws聲明拋出異常:

使用throws聲明拋出異常的思路是,當前方法不知道如何處理這種類型的異常,該異常應該由上一級調用者處理;如果main方法也不知道如何處理這種類型的異常,也可以使用throws聲明拋出異常,該異常將交給JVM處理。JVM對異常的處理方法是,打印異常的跟蹤棧信息,並中止程序運行,這就是前面程序在遇到異常后自動結束的原因。

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Test {
	
	public static void main(String[] args) throws FileNotFoundException {
		FileInputStream fis=new FileInputStream("a.txt");
	}

}

  

上面程序聲明不處理IOException異常,將該異常交給JVM處理,所以程序一旦遇到該異常,JVM就會打印該異常的跟蹤棧信息,並結束程序。運行上面程序,會看到如下圖所示的運行結果。

 

 

3、使用throw拋出異常:

public class Test {
	
	public static void main(String[] args) throws Exception {
		try {
			int a=Integer.parseInt(args[0]);
			int b=Integer.parseInt(args[1]);
			int c=a/b;
			if(b==0) {
				throw new Exception("除數不能為0");
			}
			System.out.println("您輸入的兩個數相除的結果是"+c);
		}catch(Exception e) {
			System.out.println("未知異常");
		}
	}

}

  

上面程序中粗體字代碼使用throw語句來自行拋出異常。當Java運行時接收到開發者自行拋出的異常時,同樣會中止當前的執行流,跳到該異常對應的catch塊,由該catch塊來處理該異常。也就是說,不管是系統自動拋出的異常,還是程序員手動拋出的異常,Java運行時環境對異常的處理沒有任何差別。

 

4、訪問異常信息:

如果程序需要在catch塊中訪問異常對象的相關信息,則可以通過訪問catch塊的后異常形參來獲得。當Java運行時決定調用某個catch塊來處理該異常對象時,會將異常對象賦給catch塊后的異常參數,程序即可通過該參數來獲得異常的相關信息。

所有的異常對象都包括如下幾個常用的方法:

getMessage():返回該異常信息的跟蹤棧信息輸出到標準錯誤輸出

printStackTrace():將該異常的跟蹤棧信息輸出到標準錯誤輸出。

printStackTrace(PrintStream s):將該異常的跟蹤棧信息輸出到指定輸出流。

getStackTrace():返回該異常的跟蹤棧信息。

 

5、使用finally回收資源:

有些時候,程序在try塊里打開了一些物理資源(例如數據庫連接、網絡連接和磁盤文件),這些物理資源都必須显示回收。

在哪裡回收這些物理資源呢?在try塊里回收?還是在catch塊中進行回收?假設程序在try塊里進行資源回收,根據圖10.1所示的異常捕獲流程—一如果try塊的某條語句引起了異常,該語句后的其他語句通常不會獲得執行的機會,這將導致位於該語句之後的資源回收語句得不到執行。如果在catch塊里進行資源回收,但catch塊完全有可能得不到執行,這將導致不能及時回收這些物理資源。

為了保證一定能回收try塊中打開的物理資源,異常處理機制提供了finally塊。不管try塊中的代碼是否出現異常,也不管哪一個catch塊被執行,甚至在try塊或catch塊中執行了return語句,finally塊總會被執行。完整的Java異常處理語法結構如下:

try{
  //業務實現代碼
  ...
}catch(SubException e){
  //異常處理塊
  ...
}catch(SubException e2){
   //異常處理塊
   ...
}finally{
   //資源回收
   ...
}

  

例如:

public class Test {
	
	public static void main(String[] args) throws Exception {
		try {
			int a=10;
			int b=0;
			int c=a/b;
		}catch(Exception e) {
			System.out.println("未知異常");
		}finally {
			System.out.println("資源回收");
		}
	}

}

  

結果:

未知異常
資源回收

  

 

總結:

 

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!