傳三菱汽車將重啟PHV生產並擴增產能

據日經新聞今(19)日報導,汽車大廠三菱汽車(Mitsubishi Motors)將重啟已停擺長達約5個月的插電式油電混合車(PHV)「Outlander PHEV」的生產作業,且為了出口「Outlander PHEV」至歐洲市場,三菱汽車也計畫倍增其產能。

三菱汽車於今年1月開賣「Outlander PHEV」,之後於3月時宣佈因「Outlander PHEV」所搭載的鋰離子電池出包,故將停止生產及出貨。

報導指出,三菱汽車將利用名古屋製作所月產2,000台的規模重啟「Outlander PHEV」生產、之後並計劃於2014年5月底前將其月產能倍增至4,000台。

目前「Outlander PHEV」積壓的訂單約1.8萬台。而搭載出包鋰離子電池的電動車「i-MiEV」等其他車種也一度被迫停止生產,惟「i-MiEV」已於8月上旬前重啟生產。

據日本的調查報告指出,2012年全球插電式油電混合車(PHV)市場規模預估較2011年暴增500%至6萬台,預估2030年時將增至194萬台,將較2012年跳增約31倍。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

有趣的條漫版 HashMap,25歲大爺都能看懂

我是風箏,公眾號「古時的風箏」,一個兼具深度與廣度的程序員鼓勵師,一個本打算寫詩卻寫起了代碼的田園碼農!
文章會收錄在 JavaNewBee 中,更有 Java 後端知識圖譜,從小白到大牛要走的路都在裏面。回復「666」有高清學習路線圖。

因為寫文章的過程中畫了不少的圖,所以,我想,能不能用長圖的形式展現一次呢,結果圖片熬夜做了半天,最後出來的效果不是很好,哎,審美缺失吧。之後會有詳細的文字源碼解析版放出,敬請各位看官關注。

在 Java 中,最常用的數據類型是 8 中基本類型以及他們的包裝類型以及字符串類型,其次應該就是 ArrayList和HashMap了吧。HashMap存的是鍵值對類型的數據,其存儲和獲取的速度快、性能高,是非常好用的一個數據結構,每一個 Java 開發者都肯定用過它。

而且 HashMap的設計巧妙,其結構和原理也經常被拿去當做面試題。其中有很多巧妙的算法和設計,比如 Hash 算法、拉鏈法、紅黑樹設計等,值得每一個開發者借鑒學習。

先來看一下整個 Map家族的集成關係圖,一看東西還不少,但其他的可能都沒怎麼用過,只有 HashMap 最熟悉。

壯士且慢,先給點個贊吧,總是被白嫖,身體吃不消!

我是風箏,公眾號「古時的風箏」。一個兼具深度與廣度的程序員鼓勵師,一個本打算寫詩卻寫起了代碼的田園碼農!你可選擇現在就關注我,或者看看歷史文章再關注也不遲。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

日產結盟三菱 衝刺北美及新興電動車市場

日產和三菱汽車周二(5)宣布策略結盟,將藉由共同開發電動車,共享工廠、產能和技術,並提升北美和新興市場汽車銷量。日產在聲明中表示,「日產已與三菱達成策略結盟,此舉將擴大雷諾與日產的盟友關係。」

三菱加入後,雷諾與日產的盟友將增加至5名,還包括德國戴姆勒和俄羅斯的AvtoVAZ,共同抵禦德國福斯和日本豐田的競爭。此外,雷諾的本國對手標緻雪鐵龍(PSA Peugeot Citroen)也與通用結盟,以節省成本。

2011年,日產和三菱成立合資公司NMKV,共同研發迷你車,本次的聲明表示,「預期現有的NMKV公司將共同研發新款小車,其中包括預計在全球銷售、特定版本的電動車。」

雷諾、日產和三菱表示,結盟後的首批新車之一,將是由雷諾子公司-雷諾三星汽車在南韓生產的大型車,該車款將掛上三菱的品牌在北美市場販售。第2款較小型的車款也是為三菱設計,係由雷諾研發,生產地點尚未決定。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

馬來西亞麥當勞 下月不主動提供塑膠吸管

摘錄自2018年7月29日蘋果日報馬來西亞報導

馬來西亞麥當勞連鎖速食店追上環保潮流,將於下月起不再主動向顧客提供塑膠吸管,發起「向吸管說不」的運動。

馬來西亞《新海峽時報》報導,雖然麥當勞仍未發出正式公告,但在吉隆坡孟沙和檳州的分店,已經在準備告示,預料在8月1日起,推行「向吸管說不」的運動,不再主動提供塑膠吸管,要用吸管的顧客要向櫃面人員索取。

根據數據,馬來西亞每日使用和丟棄3100萬支塑膠吸管,數量驚人,每支吸管需要200年時間才能分解。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

東南大學研發出中國首輛無線充電電動汽車

據悉,東南大學近日研發出中國首輛無線充電電動汽車,這一技術還可以應用在家用電器、醫療設備等方面。無線電能傳輸技術即擺脫電力傳輸線路的束縛,直接通過空間磁場實現電力傳輸,為設備進行充電或供電。

電動汽車尾部安裝了一個接收端,而在地面的停車位上,裝了一個磁共振發射源,汽車通過磁共振接收能量,進而轉化為電能。東大研發的這輛3000瓦的無線充電電動汽車,慢充充滿電需要7—8小時,充滿可以跑180多公裏。

據東南大學電氣工程學院院長黃學良介紹,目前電動汽車無線充電有兩種方式,一種方式是電磁感應。只要在路面下面每隔幾英尺埋一段金屬線圈,就能利用磁場以無線方式傳輸大量電能,來驅動電動汽車。不過,這種技術對磁路設計要求苛刻,傳輸距離比較短,在大功率無線電能傳輸中有局限性。

直到另一種方式磁共振技術出現,無線電能傳輸技術才有了新的飛躍。東大研發的無線充電電動汽車用的正是磁共振技術。和電磁感應方式相比,這種方式輻射小,方向性要求不高,傳輸距離更長,傳輸效率高。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

架構設計 | 高併發流量削峰,共享資源加鎖機制

本文源碼:GitHub·點這裏 || GitEE·點這裏

一、高併發簡介

在互聯網的業務架構中,高併發是最難處理的業務之一,常見的使用場景:秒殺,搶購,訂票系統;高併發的流程中需要處理的複雜問題非常多,主要涉及下面幾個方面:

  • 流量管理,逐級承接削峰;
  • 網關控制,路由請求,接口熔斷;
  • 併發控制機制,資源加鎖;
  • 分佈式架構,隔離服務和數據庫;

高併發業務核心還是流量控制,控制流量下沉速度,或者控制承接流量的容器大小,多餘的直接溢出,這是相對複雜的流程。其次就是多線程併發下訪問共享資源,該流程需要加鎖機制,避免數據寫出現錯亂情況。

二、秒殺場景

1、預搶購業務

活動未正式開始,先進行活動預約,先把一部分流量收集和控制起來,在真正秒殺的時間點,很多數據可能都已經預處理好了,可以很大程度上削減系統的壓力。有了一定預約流量還可以提前對庫存系統做好準備,一舉兩得。

場景:活動預約,定金預約,高鐵搶票預購。

2、分批搶購

分批搶購和搶購的場景實現的機制是一致的,只是在流量上緩解了很多壓力,秒殺10W件庫存和秒殺100件庫存系統的抗壓不是一個級別。如果秒殺10W件庫存,系統至少承擔多於10W幾倍的流量衝擊,秒殺100件庫存,體系可能承擔幾百或者上千的流量就結束了。下面流量削峰會詳解這裏的策略機制。

場景:分時段多場次搶購,高鐵票分批放出。

3、實時秒殺

最有難度的場景就是準點實時的秒殺活動,假如10點整準時搶1W件商品,在這個時間點前後會湧入高併發的流量,刷新頁面,或者請求搶購的接口,這樣的場景處理起來是最複雜的。

  • 首先系統要承接住流量的湧入;
  • 頁面的不斷刷新要實時加載;
  • 高併發請求的流量控制加鎖等;
  • 服務隔離和數據庫設計的系統保護;

場景:618準點搶購,雙11準點秒殺,電商促銷秒殺。

三、流量削峰

1、Nginx代理

Nginx是一個高性能的HTTP和反向代理web服務器,經常用在集群服務中做統一代理層和負載均衡策略,也可以作為一層流量控制層,提供兩種限流方式,一是控制速率,二是控制併發連接數。

基於漏桶算法,提供限制請求處理速率能力;限制IP的訪問頻率,流量突然增大時,超出的請求將被拒絕;還可以限制併發連接數。

高併發的秒殺場景下,經過Nginx層的各種限制策略,可以控制流量在一個相對穩定的狀態。

2、CDN節點

CDN靜態文件的代理節點,秒殺場景的服務有這樣一個操作特點,活動倒計時開始之前,大量的用戶會不斷的刷新頁面,這時候靜態頁面可以交給CDN層面代理,分擔數據服務接口的壓力。

CDN層面也可以做一層限流,在頁面內置一層策略,假設有10W用戶點擊搶購,可以只放行1W的流量,其他的直接提示活動結束即可,這也是常用的手段之一。

話外之意:平時參与的搶購活動,可能你的請求根本沒有到達數據接口層面,就極速響應商品已搶完,自行意會吧。

3、網關控制

網關層面處理服務接口路由,一些校驗之外,最主要的是可以集成一些策略進入網關,比如經過上述層層的流量控制之後,請求已經接近核心的數據接口,這時在網關層面內置一些策略控制:如果活動是想激活老用戶,網關層面快速判斷用戶屬性,老用戶會放行請求;如果活動的目的是拉新,則放行更多的新用戶。

經過這些層面的控制,剩下的流量已經不多了,後續才真正開始執行搶購的數據操作。

話外之意:如果有10W人參加搶購活動,真正下沉到底層的搶購流量可能就1W,甚至更少,在分散到集群服務中處理。

4、併發熔斷

在分佈式服務的接口中,還有最精細的一層控制,對於一個接口在單位之間內控制請求處理的數量,這個基於接口的響應時間綜合考慮,響應越快,單位時間內的併發量就越高,這裏邏輯不難理解。

言外之意:流量經過層層控制,數據接口層面分擔的壓力已經不大,這時候就是面對秒殺業務中的加鎖問題了。

四、分佈式加鎖

1、悲觀鎖

機制描述

所有請求的線程必須在獲取鎖之後,才能執行數據庫操作,並且基於序列化的模式,沒有獲取鎖的線程處於等待狀態,並且設定重試機制,在單位時間后再次嘗試獲取鎖,或者直接返回。

過程圖解

Redis基礎命令

SETNX:加鎖的思路是,如果key不存在,將key設置為value如果key已存在,則 SETNX 不做任何動作。並且可以給key設置過期時間,過期后其他線程可以繼續嘗試鎖獲取機制。

藉助Redis的該命令模擬鎖的獲取動作。

代碼實現

這裏基於Redis實現的鎖獲取和釋放機制。

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import javax.annotation.Resource;
@Component
public class RedisLock {

    @Resource
    private Jedis jedis ;

    /**
     * 獲取鎖
     */
    public boolean getLock (String key,String value,long expire){
        try {
            String result = jedis.set( key, value, "nx", "ex", expire);
            return result != null;
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null) jedis.close();
        }
        return false ;
    }

    /**
     * 釋放鎖
     */
    public boolean unLock (String key){
        try {
            Long result = jedis.del(key);
            return result > 0 ;
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null) jedis.close();
        }
        return false ;
    }
}

這裏基於Jedis的API實現,這裏提供一份配置文件。

@Configuration
public class RedisConfig {

    @Bean
    public JedisPoolConfig jedisPoolConfig (){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig() ;
        jedisPoolConfig.setMaxIdle(8);
        jedisPoolConfig.setMaxTotal(20);
        return jedisPoolConfig ;
    }

    @Bean
    public JedisPool jedisPool (@Autowired JedisPoolConfig jedisPoolConfig){
        return new JedisPool(jedisPoolConfig,"127.0.0.1",6379) ;
    }

    @Bean
    public Jedis jedis (@Autowired JedisPool jedisPool){
        return jedisPool.getResource() ;
    }
}

問題描述

在實際的系統運行期間可能出現如下情況:線程01獲取鎖之後,進程被掛起,後續該執行的沒有執行,鎖失效后,線程02又獲取鎖,在數據庫更新后,線程01恢復,此時在持有鎖之後的狀態,繼續執行后就會容易導致數據錯亂問題。

這時候就需要引入鎖版本概念的,假設線程01獲取鎖版本1,如果沒有執行,線程02獲取鎖版本2,執行之後,通過鎖版本的比較,線程01的鎖版本過低,數據更新就會失敗。

CREATE TABLE `dl_data_lock` (
	`id` INT (11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
	`inventory` INT (11) DEFAULT '0' COMMENT '庫存量',
	`lock_value` INT (11) NOT NULL DEFAULT '0' COMMENT '鎖版本',
	PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '鎖機製表';

說明:lock_value就是記錄鎖版本,作為控制數據更新的條件。

<update id="updateByLock">
    UPDATE dl_data_lock SET inventory=inventory-1,lock_value=#{lockVersion}
    WHERE id=#{id} AND lock_value &lt;#{lockVersion}
</update>

說明:這裏的更新操作,不但要求線程獲取鎖,還會判斷線程鎖的版本不能低於當前更新記錄中的最新鎖版本。

2、樂觀鎖

機制描述

樂觀鎖大多是基於數據記錄來控制,在更新數據庫的時候,基於前置的查詢條件判斷,如果查詢出來的數據沒有被修改,則更新操作成功,如果前置的查詢結果作為更新的條件不成立,則數據寫失敗。

過程圖解

代碼實現

業務流程,先查詢要更新的記錄,然後把讀取的列,作為更新條件。

@Override
public Boolean updateByInventory(Integer id) {
    DataLockEntity dataLockEntity = dataLockMapper.getById(id);
    if (dataLockEntity != null){
        return dataLockMapper.updateByInventory(id,dataLockEntity.getInventory())>0 ;
    }
    return false ;
}

例如如果要把庫存更新,就把讀取的庫存數據作為更新條件,如果讀取庫存是100,在更新的時候庫存變了,則更新條件自然不能成立。

<update id="updateByInventory">
    UPDATE dl_data_lock SET inventory=inventory-1 WHERE id=#{id} AND inventory=#{inventory}
</update>

五、分佈式服務

1、服務保護

在處理高併發的秒殺場景時,經常出現服務掛掉場景,常見某些APP的營銷頁面,出現活動火爆頁面丟失的提示情況,但是不影響整體應用的運行,這就是服務的隔離和保護機制。

基於分佈式的服務結構可以把高併發的業務服務獨立出來,不會因為秒殺服務掛掉影響整體的服務,導致服務雪崩的場景。

2、數據庫保護

數據庫保護和服務保護是相輔相成的,分佈式服務架構下,服務和數據庫是對應的,理論上秒殺服務對應的就是秒殺數據庫,不會因為秒殺庫掛掉,導致整個數據庫宕機。

六、源代碼地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent

推薦閱讀:《架構設計系列》,蘿蔔青菜,各有所需

序號 標題
00 架構設計:單服務.集群.分佈式,基本區別和聯繫
01 架構設計:分佈式業務系統中,全局ID生成策略
02 架構設計:分佈式系統調度,Zookeeper集群化管理
03 架構設計:接口冪等性原則,防重複提交Token管理
04 架構設計:緩存管理模式,監控和內存回收策略
05 架構設計:異步處理流程,多種實現模式詳解

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

不能放任蜜蜂死 法國禁五款類尼古丁農藥

摘錄自2018年8月10日中央社報導

法國政府為遏止蜜蜂持續大量死亡,公告自9月1日起禁用五種含類尼古丁的農藥。

法國於2016年實施生物多樣性法規,當時就決定要禁用含類尼古丁(neonicotinoid)的殺蟲劑,這種物質會破壞昆蟲的神經系統,導致蜜蜂等花粉媒介昆蟲迷路及死亡,威脅到生物多樣性和糧食生產。

法國這一波禁用的五種殺蟲劑包括益達胺(imidacloprid)、可尼丁(clothianidin)、賽速安(Thiamethoxam)、賽果培(Thiacloprid)和亞滅培(Acetamiprid)。

法國政府對這類殺蟲劑的禁令比歐盟嚴格。費加洛報(Le Figaro)報導,法國生態部表示,國會正在審議糧食法草案,通過後,應可再增加禁用類尼古丁殺蟲劑的種類。

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

誰再悄咪咪的吃掉異常,我上去就是一 JIO

又到周末了,周更选手申請出站~

這次分享一下上個月碰到的離奇的問題。一個簡單的問題,硬是因為異常被悄咪咪吃掉,過關難度直線提升,導致小黑哥排查一個晚上。

這個美好的晚上,本想着開兩把 LOL 無限火力,在召喚師峽谷來個五殺的~

哎,就這樣沒了啊!我知道,你們一定能理解這種五殺被搶的感覺~

下次,真的,誰再讓我看到悄咪咪的吃掉異常,我真的要上去一 Jio 了!

好了,本文可不是水文,看完本篇文章,你可以學到以下知識點:

  • Arthas 排查技巧
  • 啥是 NoClassDefFoundError
  • Dubbo 異常內部處理方式

好了,同學們,打開小本子,準備記好知識點~

先贊后看養成習慣,微信搜索「程序通事」,關注就完事了

起因

我們有個業務系統,應用之間調用鏈如下所示:

A 應用是業務發生起始應用,在這個應用中將會根據一定規則選擇最後的通訊渠道 C,然後將這個渠道標識傳遞給 B 應用。

B 應用的功能類似網關,這個應用將會根據 A 應用傳遞過來的渠道標識,將會請求路由下發到具體的 C 應用,起到服務路由的功能。

C 應用是與外部應用交互的應用,我們將其稱為渠道通訊機。

假設一次業務中,A 應用根據規則選擇 C2 的渠道標識,然後傳遞給 B 應用。B 應用根據這個標識選擇使用 C2 進行通訊,最後 C2 調用外部應用完成一次業務調用。

上述所有應用都基於 Dubbo 進行遠程通訊,B 應用實現原理在小黑哥之前文章「支付路由系統演進史」中有寫過,感興趣的同學可以查看一下。

介紹完業務的基本情況,現在我們來看下到底發生了啥事。

一次業務需求中,需要改動 C2 應用,這次改動功能點真的很小,很快就完成了。小黑哥想着閑着也是閑着,於是就把之前 C2 應用中打印的日誌中一些沒有脫敏的信息,進行脫敏處理。

由於之前日誌框架脫敏處理存在一些問題,於是就將日誌框架從 Log4j 升級為 LogBack。升級之後,為了防止不同日誌框架中之間的產生衝突,於是使用 IDEA Maven Helper 插件,統一將應用中所有的 Log4j 相關依賴都給排除了。

改動完成之後,將 C2 應用發布到測試環境,再次從 A 應用發起測試, B 應用返回異常提示未找到 C2 應用

B 應用業務代碼類似如下:

public Response pay(Request req) {
    
    try {
        if (!isSupport(req.getChnlCode())) {
            return new Response("ERROR", "未找到相關渠道應用");
        }
        return doPay(req);
    } catch (Exception e) {
        return new Response("ERROR", "未找到相關渠道應用");
    }
}

正常情況下,若是配置存在問題,B 應用將會返回未找到具體渠道,請求也會在 B 應用結束,不會調用到 C2 應用(也沒辦法調用)。

然而此次配置什麼都沒問題, 而且最詭異的是 C2 應用居然收到了請求,並且成功處理了業務請求。

排查問題

由於 B 應用異常處理時,將異常吃掉了,我們沒辦法得知這個過程到底發生了啥事,所以第一要緊的事獲取異常信息。

最簡單的辦法就是,將 B 應用改造一下,加入打印異常日誌。不過當時比較懶,不想改造應用,就想獲取異常信息,於是想到使用 Arthas

Arthas 排錯技巧

Arthas 是Alibaba開源的Java診斷工具,這裏就不再詳細介紹這個工具,主要講下這次排錯用到的命令-watch

watch 命令可以方便觀察指定方的調用情況,可以具體觀察方法的返回值拋出異常入參,另外還可以通過 OGNL表達式查看對應的變量。

這裏我們主要為了查看方法拋出的異常信息,執行命令如下:

watch com.dubbo.example.DemoService doPay -e -x 2 '{params,throwExp}'

上述命令將會在方法異常之後觀察方法的入參以及異常信息。

注意,我們需要查看 doPay 方法,而不是 pay 方法。這是因為 pay方法中我們將異常捕獲,不太可能會拋出異常哦~

異常信息如下所示:

真正引起此次錯誤的異常信息為:

java.lang.NoClassDefFoundError: Could not initialize class xx.xxx.xx.GELogger

由於此次 B 應用不存在改動,所以推測這個異常實際發生在 C2 應用,於是在 C2 應用處再次使用 Arthas watch 命令,同樣觀察到相同的錯誤信息。

NoClassDefFoundError

NoClassDefFound,從名字上我們可以推測是因為類不存在,從而引發的這個錯誤。按照這個思路,我們首先可以簡單查看一下 B 應用中是否存在 GELogger 相關類。

查看 B 應用相關依賴包,從中發現了這個類文件,這說明這個類確實存在。

在 IDEA 反編譯查看 GELogger類相關源碼,從中發現了問題。

private static Logger logger;

static {
    System.out.println("static init");
    logger = Logger.getLogger(NoClassDefFoundErrorTestService.class);
    System.out.println("Logger init success");
}

GELogger存在一個靜態代碼塊,用於初始化一個 org.apache.log4j.Logger日誌類。

然後在上面改動中,全部的 Log4j依賴都被排除了,所以這裏運行時應該會拋出另外一個找到 org.apache.log4j.Logger 錯誤。

執行以下代碼,模擬拋錯過程。

System.out.println("模擬第一次 Error");
try {
    NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
} catch (Throwable e) {
    e.printStackTrace();
}
System.out.println("模擬第二次 Error");
try {
    NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
} catch (Throwable e) {
    e.printStackTrace();
}

異常信息如下所示:

第一次創建 NoClassDefFoundErrorTestService實例時,Java 虛擬機讀取加載時,將會初始化靜態代碼塊時。由於 org.apache.log4j.Logger類不存在,靜態代碼塊執行異常,從而導致類加載失敗。

第二次再創建 NoClassDefFoundErrorTestService 實例時,Java 虛擬機不會再次讀取加載,所以直接返回了以下異常。

java.lang.NoClassDefFoundError: Could not initialize class com.dubbo.example.NoClassDefFoundErrorTestService

找到問題真正原因,解決辦法也很簡單,直接排除 GELogger 所在依賴包。

Dubbo 內部異常處理

雖然問題到此解決了,但是這裏還有一個疑問,為何 C2 應用發生了異常,卻沒有相關錯誤日誌,並且 C2 業務邏輯也正常處理完成。

這就要說到 Dubbo 內部異常錯誤處理方式,上面 GELogger 其實作用在一個 Dubbo 自定義 Filter 中,用來記錄結果,模擬代碼如下:

@Activate(
        group = {"provider", "consumer"}
)
public class ErrorFilter implements Filter {


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        Result result = invoker.invoke(invocation);
        NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
        // 處理業務邏輯
        return result;
    }
}

這個自定義 Filter 中首先執行 invoker 方法,這個方法將會調用真正的業務方法,這就是為什麼 C2 應用邏輯是正常處理完成。

業務方法處理完成之後,然後執行後續邏輯。由於 NoClassDefFoundErrorTestService將會拋出 Error,最終這個 Error,將會在 HeaderExchangeHandler#handleRequest 被捕獲,然後將會把相關異常信息返回給調用 Dubbo 消費者。

而在 Dubbo 消費者接受到服務提供者返回信息之後,將會在 DefaultFuture#doReceived轉化成 RemotingException

RemotingException 最終將會在 FailoverClusterInvoker#doInvoke 轉換成 RpcException返回給業務代碼。

總結

好了,說了這麼多,總結一下本文知識點

  1. 異常捕獲之後,一定要記得打印日誌,並且要記得輸出堆棧信息
  2. 運行時類不存在,將會導致 NoClassDefFoundError,類加載過程失敗,也會導致 NoClassDefFoundError
  3. 對外提供的二方包,最好不要依賴特定日誌框架,如 Log4j,Logback 等,應該使用 Slf4j 框架。

幫助

1、當Dubbo遇上Arthas:排查問題的實踐

2、java.lang.NoClassDefFoundError 的解決方法一例

3、noclassdeffounderror-could-not-initialize-class-error

歡迎關注我的公眾號:程序通事,獲得日常乾貨推送。如果您對我的專題內容感興趣,也可以關注我的博客:studyidea.cn

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

【你來報報】國際間廢棄漁具管理與台灣經驗的對話

文:郭柏秀(國立成功大學海洋科技與事務研究所 博士候選人)

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案

Jmeter系列(27)- 詳解正則提取器

如果你想從頭學習Jmeter,可以看看這個系列的文章哦

https://www.cnblogs.com/poloyy/category/1746599.html

 

有了 JSON 提取器為啥還要用正則提取器?

  • JSON 提取器只針對接口返回的響應內容
  • 如果想提取的是響應頭、請求頭的值,而非響應內容的值呢?
  • 這個時候正則提取器的作用就出來了,它可以提取請求任一部分的值

 

需知

  • 正則表達式很多內容,在這篇文章中不會展開詳細說的哦,主要還是說提取器的使用
  • 想詳細學習正則表達式可以看這篇文章:待補充

 

正則提取器

我們通過實際栗子去講述理論知識點

 

正則提取器界面介紹

 

字段含義

字段 含義
Apply to 應用範圍,選默認的 main sample only 就行了
Field to check

可提取的字段

Names of created variables
  • 接收提取值的變量名
  • 必傳
Regular Expression

正則表達式

Template 從找到的匹配項中創建字符串的模板
Match No.(0 for Random)
  • 取第幾個值
  • 0:隨機,默認
  • -1:所有
  • 1:第一個值
  • 非必傳
Default Value
  • 缺省值,匹配不到值的時候取該值
  • 非必傳
Use empty default value

勾選后,提取不到值時,則返回空字符串

 

Template

  • 如果一條正則表達式有多個提取結果,則提取結果是數組形式
  • 模板 $1$、$2$…..表示把解析到的第幾個值賦給變量,從 1 開始匹配
  • $0$ 表示整個表達式匹配的內容(後續具體看栗子)
  • 若只有一個結果,只能是$1$

 

Field to check

屬性 含義
Body 響應體,不包括響應頭;最常用
Body (unescaped) 響應體,替換了所有HTML轉義符;不建議使用
Body as a Document 從不同類型的文件中提取文本;影響性能
Request Headers 請求頭
Response Headers 響應頭
URL URL
Response Code 響應碼
Response Message 響應信息

 

Body

 

Request Headers

 

Response Headers

 

URL

 

Response Code、Message

 

入門栗子

栗子的前提

這個栗子,我都會以這個地址的接口來完成 JSON 提取器的實戰慄子,大家可以註冊個賬號玩一玩哦

http://api.yesapi.cn/docs.php?keyword=%E4%BC%9A%E5%91%98&channel=api

 

測試計劃樹結構

下面多個栗子都以這個測試計劃為基礎哦

 

提取某個特定的值的栗子

登錄接口響應

登錄是執行其他接口的前置接口,所以要獲取用戶登錄后的 token、uuid

 

提取 token

 

提取 uuid

 

其他接口調用 token、uuid

 

知識點

  • 提其他接口可以通過  ${var}  這種格式,來獲取提取到的值
  •  ( ) 裏面寫匹配規則,用於解析正則表達式
  •  .*? 表示匹配任意長度的任意字符,這也是最常用的正則表達式
  • 一般 (.+?) 和 (.*?) 能夠滿足我們 80%的使用場景

 

一般正則表達式都可以寫成下面兩種

  •  左邊界(.+?)右邊界 
  •  左邊界(.*?)右邊界 

 

舉更多栗子前的一些話

  • 上面講的是使用正則提取器時的一個流程,也是實際工作中最簡單的栗子
  • 在實際項目中,我們可能會出現一條正則表達式有多個提取結果的情況

 

JSON 字符串

下面的栗子都以這個 JSON 字符串為基礎,从里面提取結果

這 JSON 字符串也是某個接口的響應內容,貨真價實,感興趣也可以自己玩一玩:http://api.yesapi.cn/docs-api-App.User.GetList.html

{
    "ret": 200,
    "msg": "V2.5.1 YesApi App.User.GetList",
    "data": {
        "total": 4,
        "err_msg": "",
        "err_code": 0,
        "users": [
            {
                "role": "user",
                "status_desc": "正常",
                "reg_time": "2020-06-22 20:45:05",
                "role_desc": "普通會員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                },
                "uuid": "0564CE592B4CE914365D8922F6FC4CEC",
                "username": "luojunjiess286",
                "status": 0
            },
            {
                "role": "user",
                "status_desc": "正常",
                "reg_time": "2020-06-22 14:27:17",
                "role_desc": "普通會員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                },
                "uuid": "0164DC0680F84DCE40D3DD4A36640ECA",
                "username": "luojunjiessa",
                "status": 0
            },
            {
                "role": "admin",
                "status_desc": "正常",
                "reg_time": "2020-03-23 22:48:32",
                "role_desc": "管理員",
                "ext_info": {
                    "yesapi_nickname": "",
                    "yesapi_points": 0
                    "yesapi_reg_source": ""
                },
                "uuid": "079BF6BB82AFCFC7084F96AECAF0519F",
                "username": "luojunjiess",
                "status": 0
            }
        ]
    }
}

 

一條正則表達式只有一個提取結果的栗子

什麼叫只有一個提取結果

就是正則表達式里只有一個 ( ) ,且  Match No. 不是 -1

 

未填寫模板

提取器

 

測試結果

uuid1=
uuid1_g=1
uuid1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid1_g1=0564CE592B4CE914365D8922F6FC4CEC

 

知識點

如果正則匹配到值,但是沒有填模板,則返回

 

$0$

提取器

 

測試結果

uuid2="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid2_g=1
uuid2_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid2_g1=0564CE592B4CE914365D8922F6FC4CEC

 

知識點

  •  $0$ 模板其實返回的就是 uuid2_g0 的值
  • 返回了整個正則表達式,不只是 ( ) 內匹配到的值

 

$1$

提取器

 

測試結果

uuid3=0564CE592B4CE914365D8922F6FC4CEC
uuid3_g=1
uuid3_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid3_g1=0564CE592B4CE914365D8922F6FC4CEC

 

知識點

  •  $1$  模板其實返回的就是 uuid2_g1 的值
  • 僅返回 ( ) 內匹配到的值

 

$2$

提取器

 

測試結果

uuid4=null
uuid4_g=1
uuid4_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid4_g1=0564CE592B4CE914365D8922F6FC4CEC

 

知識點

 $2$ 模板並不存在,其實就是 uuid4_g2 變量不存在,即使勾了使用空默認值,也返回 null,

 

總結

  • 其實 uuid 在 JSON 字符串中有三個可匹配到的值,如果不填寫匹配数字 Match No. ,則會隨機取一個 uuid 並返回
  • 像上述的幾個栗子,都填了 1 ,所以都返回了第一個匹配到的 uuid

 

一條正則表達式有多個提取結果的栗子

什麼叫有多個提取結果

有兩種情況

  • 一條表達式有多個 ( ) 
  • 一個 ( ) 匹配到多個值,且 Match No 填了 -1

 

一個 ( ) 匹配到多個值 

提取器

 

測試結果

手動分成四部分

uuid1_1=0564CE592B4CE914365D8922F6FC4CEC
uuid1_1_g=1
uuid1_1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC"
uuid1_1_g1=0564CE592B4CE914365D8922F6FC4CEC

uuid1_2=0164DC0680F84DCE40D3DD4A36640ECA
uuid1_2_g=1
uuid1_2_g0="uuid":"0164DC0680F84DCE40D3DD4A36640ECA"
uuid1_2_g1=0164DC0680F84DCE40D3DD4A36640ECA

uuid1_3=079BF6BB82AFCFC7084F96AECAF0519F
uuid1_3_g=1
uuid1_3_g0="uuid":"079BF6BB82AFCFC7084F96AECAF0519F"
uuid1_3_g1=079BF6BB82AFCFC7084F96AECAF0519F

uuid1_matchNr=3

 

知識點

  • 一個 ( ) 匹配到多個值的場景 ,一般會結合 ForEach控制器,可以循環將提取到的值賦予到 HTTP 請求中
  • 可以看看下圖的小栗子,這裏不展開講,後面會再詳細講解

 

結構樹 + ForEach 控制器

 

查看結果樹

 

一條表達式有多個( ),且模板為空

提取器

 

測試結果

info1=
info1_g=2
info1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286"
info1_g1=0564CE592B4CE914365D8922F6FC4CEC
info1_g2=luojunjiess286

 

一條表達式有多個( ),且只有一個模板

提取器

 

測試結果

info2=0564CE592B4CE914365D8922F6FC4CEC
info2_g=2
info2_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286"
info2_g1=0564CE592B4CE914365D8922F6FC4CEC
info2_g2=luojunjiess286

 

知識點

  • info2 拿的就是 info2_g1 的值
  •  $1$ 獲取的是第一個 ( ) 匹配到的值, $2$ 獲取的是第二個 ( ) 匹配到的值,以此類推     

 

一條表達式有多個( ),且有兩個模板

提取器

 

測試結果

info3=0564CE592B4CE914365D8922F6FC4CECluojunjiess286
info3_g=2
info3_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286"
info3_g1=0564CE592B4CE914365D8922F6FC4CEC
info3_g2=luojunjiess286

info4=0564CE592B4CE914365D8922F6FC4CEC,luojunjiess286
info4_g=2
info4_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286"
info4_g1=0564CE592B4CE914365D8922F6FC4CEC
info4_g2=luojunjiess286

 

正則表達式中有多個 ( ) 時的總結

  • 如果其中一個 ( ) 匹配不到元素,那也無法獲取到值
  • 引用名稱、匹配数字、缺省值三個字段也只需要填一個值即可,不需要跟 ( ) 的數量一致
  • 多個模板( $1$$2$ )的時候,可以用空格、, 、. 、  連接模板,最終會显示在變量上,如:info4

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

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

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

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

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

※教你寫出一流的銷售文案?

※超省錢租車方案