加州簽了! 2045年100%乾淨能源目標入法

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:ENS

加州州長布朗10日簽署參議院100號法案(SB 100),將「100%乾淨電力」正式設立為法定目標。

繼提早四年達成「2020年減排13%、經濟成長26%」目標後,「SB 100」將使加州的再生能源比例標準更加積極,2025年必須達到50%電力由再生能源供應,2030年要達到60%,2045年實現零碳電網。

加州州長布朗簽署參議院100號法案(SB 100)。圖片來源:Office of the Governor

州長訂定碳中和目標  減碳不涉核電

為了確保全球暖化對策不只侷限於電業(佔加州溫室氣體排放量的16%),布朗還發布了一項行政命令,指示加州要在2045年實現碳中和,之後則要實現淨負排碳。

目前全球有20多個國家和40多個地方政府宣布,最晚要在本世紀中實現碳中和。

為了實現目標,加州將持續減少碳污染,同時增加森林、土壤和其他自然地景的碳儲存和空氣品質及公共衛生改善計畫,尤其是在該州受影響最嚴重的社區。

加州也將陸續實施一系列因應暖化的長期行動。上週,布朗簽署了另一項法案,禁止加州沿海進行新的聯邦海上石油鑽探活動,並宣布加州反對聯邦政府擴大加州公共土地上石油鑽探的計畫。1968年至今,加州都沒有開放沿海地區的新石油和天然氣租賃。

雖然加州政府定義的乾淨能源有三種,州政府在其網站上的指出,加州正在逐步淘汰核電,現階段也並不考慮新建核電廠。

減碳聯盟「Under2 Coalition」 規模跨六大洲、佔全球經濟四成

原本加州計畫於2020年達成減排13%、同時經濟成長26%,結果此目標提早四年達成。從2015到2016年,加州減排量大約等於減少240萬輛汽車上路,省下15億加侖的汽柴油燃料。

此外,布朗幫助建立全美和全球的減碳合作聯盟「Under2 Coalition」。該聯盟起源於加州與德國巴登-符騰堡州之間的合作關係,現在已納入橫跨六大洲的206個各級政府,共代表13億人口和30兆美元的GDP,相當於全球人口的17%和全球經濟的40%。

聯盟成員做出了一些重要承諾,包括減少相當於1990年水準80%至95%的溫室氣體排放,以及2050年加州每人每年碳排少於2公噸。

California Passes 100 Percent Clean Electricity Bill SACRAMENTO, California, September 10, 2018 (ENS)

Putting his stamp of approval on California’s global climate leadership, Governor Jerry Brown today signed Senate Bill 100, which sets a 100 percent clean electricity goal for the state. The governor also issued an executive order establishing a new target to achieve carbon neutrality – both by 2045.

With Governor Brown’s executive order, California establishes the most ambitious carbon neutrality commitment of the more than 20 countries and at least 40 cities, states and provinces planning to go carbon neutral by mid-century or sooner.

SB 100 advances the state’s existing Renewables Portfolio Standard, which establishes how much of the electricity system should be powered from renewable energy resources, to 50 percent by 2025 and 60 percent by 2030.

It also puts California on the bold path to implement a zero-carbon electricity grid by 2045.

To ensure California is combating global warming beyond the electric sector, which represents 16 percent of the state’s greenhouse gas emissions, the governor’s executive order directs the state to achieve carbon neutrality by 2045 and net negative greenhouse gas emissions after that.

The state will reach its goals with continued reductions of carbon pollution and increased carbon sequestration in forests, soils and other natural landscapes and programs focused on improving air quality and public health, especially in California’s most impacted communities.

These actions are the latest in a long series of actions by California to deal with the warming climate. Late last week, Governor Brown also signed legislation to block new federal offshore oil drilling along California’s coast and announced the state’s opposition to the federal government’s plan to expand oil drilling on public lands in California. The entirety of the state’s coast has been off-limits to new oil and gas leases for more than 30 years, and the state has not issued a lease for offshore oil or gas production since 1968.

The state has met its 2020 target four years early, reducing emissions 13 percent while growing the economy 26 percent.

From 2015 to 2016, emissions reductions were roughly equal to taking 2.4 million cars off the road, saving 1.5 billion gallons of gasoline and diesel fuel.

In addition, Governor Brown has helped establish and expand coalitions of partners across the nation and globe committed to curbing carbon pollution.

The Under2 Coalition, which originated from a partnership between California and the German state of Baden-Württemberg, now includes 206 jurisdictions on six continents that collectively represent 1.3 billion people and $30 trillion in GDP – equivalent to 17 percent of the global population and 40 percent of the global economy.

Members of the Under2 Coalition have made a number of key commitments, including reducing greenhouse gas emissions equivalent to 80 to 95 percent below 1990 levels or to less than two annual metric tons for each person in California by 2050.

※ 全文及圖片詳見:

作者

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

延伸閱讀

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

創新減廢 啤酒公司淘汰塑膠套環 改用可回收膠

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

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

FB行銷專家,教你從零開始的技巧

聚甘新

2017第八屆廣州國際新能源汽車工業展覽會

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

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

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

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

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

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

※超省錢租車方案

聚甘新

台電動車廠凱勝新廠動土,打造綠能產業聚落

台灣本地的電動車大廠凱勝綠能科技正式於嘉義縣馬稠後工業區破土興建新廠房。馬稠後廠房共分三廠,總投資額達新台幣60億元,首期一廠工程預計在2018年完工,將成為台灣規模最大的電動車生產基地,並將進一步投入綠能相關產業的研發製造。

凱勝綠能的招牌產品為電動巴士,是目前台灣最大的電動巴士生產商。為深耕台灣在地電動車產業,凱勝綠能看上馬稠後工業區的地理區位,規劃興建三個廠房。投資新台幣25億元的一廠工程於11月1日正式動土,預計在2018年完工,屆時電動巴士產能可提高到1,000餘輛,年產值新台幣300億元以上,並可創造當地就業和10億餘元的地方稅收。

凱勝綠能董事長陳怡仁表示,馬稠後工廠一廠除將進行電動車研發生產外,更將投入太陽能綠電與儲能系統的開發和應用,如提升電池儲能功能等。到了二、三廠陸續完工後,還將投入各式電動載具與相關產品的研發製造,屆時馬稠後工廠不僅會是全台規模最大的電動車建案,也將形成完整的電動車與綠能產業研發基地。

陳怡仁指出,電動車是「零排放、零汙染、零噪音」的「三零」產業,將有助守護台灣與地球環境。嘉義縣長張花冠亦蒞臨破土典禮,並親自試乘凱勝綠能的電動車。

(照片:嘉義縣長張花冠試乘電動車。來源:嘉義縣政府)

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

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

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

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

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

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

※超省錢租車方案

聚甘新

中國第四季電動車市場需求回溫,全年挑戰55萬輛

2016年中國電動車市場雖有取締騙補政策影響原成長力道,但在預期2017年補貼將降低而刺激消費者提前購車的情況下,今年第四季仍有很大的銷售成長空間。TrendForce旗下拓墣產業研究所最新研究顯示,今年1~9月的中國電動車市場銷售已近35萬輛,超越去年總量,預估2016年將挑戰55萬輛,引領全球電動車邁向近百萬輛市場規模。

拓墣車輛電子分析師張仙平表示,中國2014及2015年已連續兩年以超過300%的銷售成長率,超越日、美,成為全球最大電動車區域市場,2015年更占據了全球逾半的銷售量,因此中國電動車市場已成為全球電動車銷售引擎。

張仙平指出,外界持續看好中國電動車市場,然而,在2016年初中國政府積極取締騙補,以及從2016年起逐年遞減的購車補貼政策下,使得中國雖然在乘用車市場仍能維持快速成長力道,但在商用車市場上,包含電動巴士與電動專車的銷售狀況均受到衝擊,銷量呈現衰退。而中國政府也在騙補事件後,提高廠商申請生產許可證的資格,因此在補助減少而門檻提高的影響下,2017年中國電動商用車銷量仍可能衰退。

在預期2017年中國電動車購車補貼將降低的情況下,拓墣預估市場需求將集中在2016第四季,拉升中國市場電動車全年銷售達55萬輛,其中主要受惠於乘用車市場的高速成長動能。除中國市場外,美國與日本市場也一掃去年銷售頹勢,在2016年維持成長。美國市場在特斯拉Model S與Model X的熱銷下,有望締造近15萬輛的銷售佳績。拓墣預估2016年全球電動車市場將在中國市場領頭的情形下,突破95萬輛的銷售量。

全球市場研究機構TrendForce將在2016年11月10日,於臺大醫院國際會議中心舉辦「集邦拓墣2017年科技產業大預測」研討會。活動網址:

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

【其他文章推薦】

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

※別再煩惱如何寫文案,掌握八大原則!

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

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

聚甘新

台北萬豪酒店首設Tesla充電站,即日啟用

美商特斯拉(Tesla)於今年9月正式進軍台灣,在台引發電動車熱。台北萬豪酒店宣布與Tesla合作設置充電站,同時推出限時活動,鼓勵民眾響應環保行動。

繼在台灣科技大學校區內設置充電站後,Tesla正式宣布與台北萬豪酒店合作,於飯店內設置6組充電站,成為全台首家提供Tesla電動車充電服務的飯店。車主只要於飯店內消費,就可免費享有充電服務。

台北萬豪酒店主管表示,萬豪國際的核心理念是「擁抱改變」,不但要跟著時代進步,還要勇於創新,與Tesla的形象相輔相成。藉由與Tesla合作設置電動車充電站,希望能提供客戶更便捷的服務,並推動現代科技。

萬豪酒店同時也推出相關活動,凡是11月30日前佩戴紅色配件到萬豪酒店消費的顧客,就可享有9折優惠。

Tesla主管表示,Tesla進入台灣市場後,將提供銷售、服務、充電等全方位服務,未來將繼續加速布建「目的地充電站」的腳步,以為台灣的Tesla車主提供更綿密的充電網絡。

除了萬豪酒店之外,台北晶華酒店也與BMW合作設置了i公共充電站,可供i3、i8等車款使用。

(照片來源:)

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

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

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

※超省錢租車方案

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

網頁設計最專業,超強功能平台可客製化

聚甘新

BMW 2017年目標售出10萬輛電動車

德國媒體報導,汽車廠商BMW CEO Harald Krueger 在接受採訪時表示,電動車的時代即將到來,這一市場還有巨大的潛力,BMW 將在2017 年力爭把電動車的銷量提升到10 萬台,目前該公司2015 年電動車和混合動力車的銷量大約為6 萬台。

BMW CEO Harald Krueger 表示,該公司希望能夠在2017 年大幅提升電動車的銷量,至少提升六成,達到年銷量10 萬台。BMW 2016 年電動車和混合動力車的銷量合計大約為6 萬台,自2013 年發售電動車以來,BMW 電動車的雷軍銷量已經超過了10 萬台。

Harald Krueger 認為電動車的時代即將到來,這一市場還有很大的潛力,需求還沒有完全被發掘。

BMW 旗下唯一的純電動車車款i3 上市以來市場反響不如預期,2015 年i3 僅售出了2.5 萬台,為了提升這款產品的競爭力,BMW 將在2016 年的升級中把i3 系列電動車的續航里程提升50%。

在高階汽車市場中,BMW 的產品銷量已經落後於Benz,該公司希望在2025 年前將電動車和混合動力車的銷量提升到15%-25%。

(本文由《》授權提供。照片來源:)

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

電動車有害道路安全?美國規定汽車不能太安靜!

根據外電報導,美國政府正式通過一則汽車行駛新規定,也就是未來一些「安靜的汽車」,如電動汽車或混合動力汽車等,在行駛速度超過時速18.6 英里 (約30 公里)的情況下,必須增加噪音警報裝置,以避免傷及行人、盲人和騎車的路人。

根據美國國家公路交通安全管理局(NHTSA)發布的這則新規定表示,該規定將在2019 年9 月1 日起生效。屆時,包括特斯拉 (TESLA)、日產汽車 (Nisson) 和豐田汽車 (TOYOTA) 等廠商都需要為所有汽車增加噪音裝置。美國政府希望通過此規定,能夠防止每年多達2,400 件的行人受傷事故,並為53 萬輛汽車增設噪音專制。

NHTSA 指出,這項新規每年約會給汽車廠商增加3,900 萬美元的花費。因為,他們要為汽車增設一個外設防水喇叭。但是,能夠透過降低交通事故而每年節省約2.5 億到3.2 億美元的醫療費用。

該規定未來將適用於全美各地區,並且涵蓋路上行駛的電動汽車和混合動力汽車等。另外,包括帶有4 個輪子、總重量低於10,000 磅的車輛,也都必須在向後或向前行駛時,在速度達到每小時30 公里之際發出聲響,以警告周遭的路人與騎車的民眾。不過,NHTSA 也認為,規定汽車喇叭可有可無,因為輪胎和風也可以製造出足夠的噪音聲響,只要該聲響能達到警告的標準即可。

該項新的規定雖然受到全美盲人主組織的歡迎,但是卻讓汽車廠商表示擔憂。因為噪音也許會太大,並且實施起來將可能相當複雜。因為,新規只規定了最低的聲音要求,卻沒有制定必須發出什麼聲音。

(本文由《》授權提供。照片來源:特斯拉)

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

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

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

FB行銷專家,教你從零開始的技巧

聚甘新

.Net Core微服務入門全紀錄(五)——Ocelot-API網關(下)

前言

上一篇【.Net Core微服務入門全紀錄(四)——Ocelot-API網關(上)】已經完成了Ocelot網關的基本搭建,實現了服務入口的統一。當然,這隻是API網關的一個最基本功能,它的進階功能還有很多很多。

服務發現

首先需要解決的就是服務發現的問題,服務發現的優點之前講過,就不說了。
上一篇中我們的服務地址都是寫在ocelot.json配置文件里,現在我們需要結合之前的Consul來實現服務發現。

  • 改造代碼:

首先NuGet安裝Ocelot.Provider.Consul

修改Startup.cs:

        public void ConfigureServices(IServiceCollection services)
        {
            //添加ocelot服務
            services.AddOcelot()
                .AddConsul();//添加consul支持
        }

修改ocelot.json配置:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

這個配置應該很好理解,就是把我們上次的DownstreamHostAndPorts節點去掉了,然後增加了ServiceDiscoveryProvider服務發現相關配置。
注意,Ocelot除了支持Consul服務發現以外,還有Eureka也可以,Eureka也是一個類似的註冊中心。

好了,代碼修改就差不多了,下面運行程序測試一下:

客戶端正常運行。

至此我們就實現了服務註冊與發現和api網關的基本功能。接下來就要提到:服務治理

服務治理

其實服務治理也沒有一個非常明確的定義。它的作用簡單來說,就是幫助我們更好的管理服務,提升服務的可用性。——緩存,限流,熔斷,鏈路追蹤 等等。。。都屬於常用的服務治理手段。
之前講的負載均衡,服務發現也可以算是服務治理。

  • 緩存:

在Ocelot中啟用緩存,需要NuGet安裝一下Ocelot.Cache.CacheManager

修改Startup.cs中的ConfigureServices()方法:

//添加ocelot服務
services.AddOcelot()
    //添加consul支持
    .AddConsul()
    //添加緩存
    .AddCacheManager(x =>
    {
        x.WithDictionaryHandle();
    });

修改ocelot.json配置文件:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

在Routes路由配置中增加了FileCacheOptions。TtlSeconds代表緩存的過期時間,Region代表緩衝區名稱,這個我們目前用不到。

好了,代碼修改完需要編譯重啟一下網關項目,然後打開客戶端網站測試一下:

可以看到,5秒之內的請求都是同樣的緩存數據。Ocelot也支持自定義緩存。

  • 限流:

限流就是限制客戶端一定時間內的請求次數。
繼續修改配置:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      },
      "RateLimitOptions": {
        "ClientWhitelist": [ "SuperClient" ],
        "EnableRateLimiting": true,
        "Period": "5s",
        "PeriodTimespan": 2,
        "Limit": 1
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      },
      "RateLimitOptions": {
        "ClientWhitelist": [ "SuperClient" ],
        "EnableRateLimiting": true,
        "Period": "5s",
        "PeriodTimespan": 2,
        "Limit": 2
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "too many requests...",
      "HttpStatusCode": 999,
      "ClientIdHeader": "Test"
    }
  }
}

在Routes路由配置中增加了RateLimitOptions。ClientWhitelist代表客戶端白名單,在白名單中的客戶端可以不受限流的影響;EnableRateLimiting代表是否限流;Period代表限流的單位時間,例如1s,5m,1h,1d等;PeriodTimespan代表客戶端達到請求上限多少秒后可以重試;Limit代表客戶端在定義的時間內可以發出的最大請求數。
在GlobalConfiguration配置中也增加了RateLimitOptions。DisableRateLimitHeaders代表是否禁用X-Rate-Limit和Retry-After標頭(請求達到上限時response header中的限制數和多少秒后能重試);QuotaExceededMessage:代表請求達到上限時返回給客戶端的消息;HttpStatusCode:代表請求達到上限時返回給客戶端的HTTP狀態代碼。ClientIdHeader可以允許自定義用於標識客戶端的標頭。默認情況下為“ ClientId”。
最重要的就是Period,PeriodTimespan,Limit這幾個配置。

重新編譯啟動看一下效果:

  • 超時/熔斷

超時很好理解,就是網關請求服務時可容忍的最長響應時間。熔斷的意思就是當請求某個服務的異常次數達到一定量時,那麼網關在一定時間內就不再對這個服務發起請求了,直接熔斷。
Ocelot中啟用 超時/熔斷 需要NuGet安裝一下Ocelot.Provider.Polly

修改Startup.cs中的ConfigureServices()方法:

//添加ocelot服務
services.AddOcelot()
    //添加consul支持
    .AddConsul()
    //添加緩存
    .AddCacheManager(x =>
    {
        x.WithDictionaryHandle();
    })
    //添加Polly
    .AddPolly();

同樣的在ocelot.json路由配置中增加QoSOptions:

"QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 10000,
        "TimeoutValue": 5000
      }

ExceptionsAllowedBeforeBreaking代表發生錯誤的次數,DurationOfBreak代表熔斷時間,TimeoutValue代表超時時間。
以上的配置意思就是當服務發生3次錯誤時,那麼就熔斷10秒,期間客戶端的請求直接返回錯誤,10秒之後恢復。
這個不太好模擬,就不演示了,應該也挺好理解的。

。。。。。。

關於服務治理的學問還有很多,不繼續了。。。就到此為止吧。
想要更深入了解Ocelot的,請看官網:https://ocelot.readthedocs.io/en/latest/
或者看源碼:https://github.com/ThreeMammals/Ocelot

下一篇準備說一下:事件總線。

代碼放在:https://github.com/xiajingren/NetCoreMicroserviceDemo

未完待續…

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

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

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

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

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

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

※超省錢租車方案

聚甘新

重學 Java 設計模式:實戰責任鏈模式「模擬618電商大促期間,項目上線流程多級負責人審批場景」

作者:小傅哥
博客:https://bugstack.cn – 原創系列專題文章

沉澱、分享、成長,讓自己和他人都能有所收穫!

一、前言

場地和場景的重要性

射擊需要去靶場學習、滑雪需要去雪場體驗、開車需要能上路實踐,而編程開發除了能完成產品的功能流程,還需要保證系統的可靠性能。就像你能聽到的一些系統監控指標;QPSTPSTP99TP999可用率響應時長等等,而這些指標的總和評估就是一個系統的健康度。但如果你幾乎沒有聽到這樣的技術術語,也沒接觸過類似高併發場景,那麼就很像駕駛證的科目1考了100分,但不能上路。沒有這樣的技術場景給你訓練,讓你不斷的體會系統的脾氣秉性,即便你有再多的想法都沒法實現。所以,如果真的想學習一定要去一個有實操的場景,下水試試才能學會狗刨。

你的視覺盲區有多大

同樣一本書、同樣一條路、同樣一座城,你真的以為生活有選擇嗎?有時候很多選項都是擺設,給你多少次機會你都選的一模一樣。這不是你選不選而是你的認知範圍決定了你下一秒做的事情,另外的一個下一秒又決定了再下一個下一秒。就像管中窺豹一樣,20%的面積在你視覺里都是黑色的,甚至就總是忽略看不到,而這看不到的20%就是生命中的時運!但,人可以學習,可以成長,可以脫胎換骨,可以努力付出,通過一次次的蛻變而看到剩下的20%!

沒有設計圖紙你敢蓋樓嗎

編程開發中最好的什麼,是設計。運用架構思維、經驗心得、才華靈感,構建出最佳的系統。真正的研發會把自己寫的代碼當做作品來欣賞,你說這是一份工作,但在這樣的人眼裡這可不是一份工作,而是一份工匠精神。就像可能時而你也會為自己因為一個niubility的設計而豪邁萬丈,為能上線一個扛得住每秒200萬訪問量的系統會精神煥發。這樣的自豪感就是一次次壘磚一樣墊高腳底,不斷的把你的視野提高,讓你能看到上層設計也能知曉根基建設。可以把控全局,也可以治理細節。這一份份知識的沉澱,來幫助你繪製出一張系統架構藍圖。

二、開發環境

  1. JDK 1.8
  2. Idea + Maven
  3. 涉及工程三個,可以通過關注公眾號bugstack蟲洞棧,回復源碼下載獲取(打開獲取的鏈接,找到序號18)
工程 描述
itstack-demo-design-13-00 場景模擬工程;模擬一個上線流程審批的接口。
itstack-demo-design-13-01 使用一坨代碼實現業務需求
itstack-demo-design-13-02 通過設計模式優化改造代碼,產生對比性從而學習

三、責任鏈模式介紹

擊鼓傳雷,看上圖你是否想起周星馳有一個電影,大家坐在海邊圍成一個圈,拿着一個點燃的炸彈,互相傳遞。

責任鏈模式的核心是解決一組服務中的先後執行處理關係,就有點像你沒錢花了,需要家庭財務支出審批,10塊錢以下找閨女審批,100塊錢先閨女審批在媳婦審批。你可以理解想象成當你要跳槽的時候被安排的明明白白的被各個領導簽字放行。

四、案例場景模擬

在本案例中我們模擬在618大促期間的業務系統上線審批流程場景

像是這些一線電商類的互聯網公司,阿里、京東、拼多多等,在618期間都會做一些運營活動場景以及提供的擴容備戰,就像過年期間百度的紅包一樣。但是所有開發的這些系統都需要陸續的上線,因為臨近618有時候也有一些緊急的調整的需要上線,但為了保障線上系統的穩定性是盡可能的減少上線的,也會相應的增強審批力度。就像一級響應、二級響應一樣。

而這審批的過程在隨着特定時間點會增加不同級別的負責人加入,每個人就像責任鏈模式中的每一個核心點。對於研發小夥伴並不需要關心具體的審批流程處理細節,只需要知道這個上線更嚴格,級別也更高,但對於研發人員來說同樣是點擊相同的提審按鈕,等待審核。

接下來我們就模擬這樣一個業務訴求場景,使用責任鏈的設計模式來實現此功能。

1. 場景模擬工程

itstack-demo-design-13-00
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                └── AuthService.java
  • 這裏的代碼結構比較簡單,只有一個模擬審核和查詢審核結果的服務類。相當於你可以調用這個類去審核工程和獲取審核結構,這部分結果信息是模擬的寫到緩存實現。

2. 場景簡述

2.1 模擬審核服務

public class AuthService {

    private static Map<String, Date> authMap = new ConcurrentHashMap<String, Date>();

    public static Date queryAuthInfo(String uId, String orderId) {
        return authMap.get(uId.concat(orderId));
    }

    public static void auth(String uId, String orderId) {
        authMap.put(uId.concat(orderId), new Date());
    }

}
  • 這裏面提供了兩個接口一個是查詢審核結果(queryAuthInfo)、另外一個是處理審核(auth)。
  • 這部分是把由誰審核的和審核的單子ID作為唯一key值記錄到內存Map結構中。

五、用一坨坨代碼實現

這裏我們先使用最直接的方式來實現功能

按照我們的需求審批流程,平常系統上線只需要三級負責人審批就可以,但是到了618大促時間點,就需要由二級負責以及一級負責人一起加入審批系統上線流程。在這裏我們使用非常直接的if判斷方式來實現這樣的需求。

1. 工程結構

itstack-demo-design-13-01
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                └── AuthController.java
  • 這部分非常簡單的只包含了一個審核的控制類,就像有些夥伴開始寫代碼一樣,一個類寫所有需求。

2. 代碼實現

public class AuthController {

    private SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 時間格式化

    public AuthInfo doAuth(String uId, String orderId, Date authDate) throws ParseException {

        // 三級審批
        Date date = AuthService.queryAuthInfo("1000013", orderId);
        if (null == date) return new AuthInfo("0001", "單號:", orderId, " 狀態:待三級審批負責人 ", "王工");

        // 二級審批
        if (authDate.after(f.parse("2020-06-01 00:00:00")) && authDate.before(f.parse("2020-06-25 23:59:59"))) {
            date = AuthService.queryAuthInfo("1000012", orderId);
            if (null == date) return new AuthInfo("0001", "單號:", orderId, " 狀態:待二級審批負責人 ", "張經理");
        }

        // 一級審批
        if (authDate.after(f.parse("2020-06-11 00:00:00")) && authDate.before(f.parse("2020-06-20 23:59:59"))) {
            date = AuthService.queryAuthInfo("1000011", orderId);
            if (null == date) return new AuthInfo("0001", "單號:", orderId, " 狀態:待一級審批負責人 ", "段總");
        }

        return new AuthInfo("0001", "單號:", orderId, " 狀態:審批完成");
    }

}
  • 這裏從上到下分別判斷了在指定時間範圍內由不同的人員進行審批,就像618上線的時候需要三個負責人都審批才能讓系統進行上線。
  • 像是這樣的功能看起來很簡單的,但是實際的業務中會有很多部門,但如果這樣實現就很難進行擴展,並且在改動擴展調整也非常麻煩。

3. 測試驗證

3.1 編寫測試類

@Test
public void test_AuthController() throws ParseException {
    AuthController authController = new AuthController();  

    // 模擬三級負責人審批
    logger.info("測試結果:{}", JSON.toJSONString(authController.doAuth("小傅哥", "1000998004813441", new Date())));
    logger.info("測試結果:{}", "模擬三級負責人審批,王工");
    AuthService.auth("1000013", "1000998004813441");  

    // 模擬二級負責人審批                                 
    logger.info("測試結果:{}", JSON.toJSONString(authController.doAuth("小傅哥", "1000998004813441", new Date())));
    logger.info("測試結果:{}", "模擬二級負責人審批,張經理");
    AuthService.auth("1000012", "1000998004813441");    

    // 模擬一級負責人審批
    logger.info("測試結果:{}", JSON.toJSONString(authController.doAuth("小傅哥", "1000998004813441", new Date())));
    logger.info("測試結果:{}", "模擬一級負責人審批,段總");
    AuthService.auth("1000011", "1000998004813441");            

    logger.info("測試結果:{}", "審批完成");
}
  • 這裏模擬每次查詢是否審批完成,隨着審批的不同節點,之後繼續由不同的負責人進行審批操作。
  • authController.doAuth,是查看審批的流程節點、AuthService.auth,是審批方法用於操作節點流程狀態。

3.2 測試結果

23:25:00.363 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待三級審批負責人 王工"}
23:25:00.366 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬三級負責人審批,王工
23:25:00.367 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待二級審批負責人 張經理"}
23:25:00.367 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬二級負責人審批,張經理
23:25:00.368 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待一級審批負責人 段總"}
23:25:00.368 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬一級負責人審批,段總
23:25:00.368 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:審批完成

Process finished with exit code 0
  • 從測試結果上可以看到一層層的由不同的人員進行審批,審批完成後到下一個人進行處理。單看結果是滿足我們的訴求,只不過很難擴展和調整流程,相當於代碼寫的死死的。

六、責任鏈模式重構代碼

接下來使用裝飾器模式來進行代碼優化,也算是一次很小的重構。

責任鏈模式可以讓各個服務模塊更加清晰,而每一個模塊間可以通過next的方式進行獲取。而每一個next是由繼承的統一抽象類實現的。最終所有類的職責可以動態的進行編排使用,編排的過程可以做成可配置化。

1. 工程結構

itstack-demo-design-13-02
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                ├── impl
                │    ├── Level1AuthLink.java
                │    ├── Level2AuthLink.java
                │    └── Level3AuthLink.java
                ├── AuthInfo.java
                └── AuthLink.java

責任鏈模式模型結構

  • 上圖是這個業務模型中責任鏈結構的核心部分,通過三個實現了統一抽象類AuthLink的不同規則,再進行責任編排模擬出一條鏈路。這個鏈路就是業務中的責任鏈。
  • 一般在使用責任鏈時候如果是場景比較固定,可以通過寫死到代碼中進行初始化。但如果業務場景經常變化可以做成xml配置的方式進行處理,也可以落到庫里進行初始化操作。

2. 代碼實現

2.1 責任鏈中返回對象定義

public class AuthInfo {

    private String code;
    private String info = "";

    public AuthInfo(String code, String ...infos) {
        this.code = code;
        for (String str:infos){
            this.info = this.info.concat(str);
        }
    }
    
    // ...get/set
}
  • 這個類的是包裝了責任鏈處理過程中返回結果的類,方面處理每個責任鏈的返回信息。

2.2 鏈路抽象類定義

public abstract class AuthLink {

    protected Logger logger = LoggerFactory.getLogger(AuthLink.class);

    protected SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 時間格式化
    protected String levelUserId;                           // 級別人員ID
    protected String levelUserName;                         // 級別人員姓名
    private AuthLink next;                                  // 責任鏈

    public AuthLink(String levelUserId, String levelUserName) {
        this.levelUserId = levelUserId;
        this.levelUserName = levelUserName;
    }

    public AuthLink next() {
        return next;
    }

    public AuthLink appendNext(AuthLink next) {
        this.next = next;
        return this;
    }

    public abstract AuthInfo doAuth(String uId, String orderId, Date authDate);

}
  • 這部分是責任鏈,鏈接起來的核心部分。AuthLink next,重點在於可以通過next方式獲取下一個鏈路需要處理的節點。
  • levelUserIdlevelUserName,是責任鏈中的公用信息,標記每一個審核節點的人員信息。
  • 抽象類中定義了一個抽象方法,abstract AuthInfo doAuth,這是每一個實現者必須實現的類,不同的審核級別處理不同的業務。

2.3 三個審核實現類

Level1AuthLink

public class Level1AuthLink extends AuthLink {

    public Level1AuthLink(String levelUserId, String levelUserName) {
        super(levelUserId, levelUserName);
    }

    public AuthInfo doAuth(String uId, String orderId, Date authDate) {
        Date date = AuthService.queryAuthInfo(levelUserId, orderId);
        if (null == date) {
            return new AuthInfo("0001", "單號:", orderId, " 狀態:待一級審批負責人 ", levelUserName);
        }
        AuthLink next = super.next();
        if (null == next) {
            return new AuthInfo("0000", "單號:", orderId, " 狀態:一級審批完成負責人", " 時間:", f.format(date), " 審批人:", levelUserName);
        }

        return next.doAuth(uId, orderId, authDate);
    }

}

Level2AuthLink

public class Level2AuthLink extends AuthLink {

    private Date beginDate = f.parse("2020-06-11 00:00:00");
    private Date endDate = f.parse("2020-06-20 23:59:59");

    public Level2AuthLink(String levelUserId, String levelUserName) throws ParseException {
        super(levelUserId, levelUserName);
    }

    public AuthInfo doAuth(String uId, String orderId, Date authDate) {
        Date date = AuthService.queryAuthInfo(levelUserId, orderId);
        if (null == date) {
            return new AuthInfo("0001", "單號:", orderId, " 狀態:待二級審批負責人 ", levelUserName);
        }
        AuthLink next = super.next();
        if (null == next) {
            return new AuthInfo("0000", "單號:", orderId, " 狀態:二級審批完成負責人", " 時間:", f.format(date), " 審批人:", levelUserName);
        }

        if (authDate.before(beginDate) || authDate.after(endDate)) {
            return new AuthInfo("0000", "單號:", orderId, " 狀態:二級審批完成負責人", " 時間:", f.format(date), " 審批人:", levelUserName);
        }

        return next.doAuth(uId, orderId, authDate);
    }

}

Level3AuthLink

public class Level3AuthLink extends AuthLink {

    private Date beginDate = f.parse("2020-06-01 00:00:00");
    private Date endDate = f.parse("2020-06-25 23:59:59");

    public Level3AuthLink(String levelUserId, String levelUserName) throws ParseException {
        super(levelUserId, levelUserName);
    }

    public AuthInfo doAuth(String uId, String orderId, Date authDate) {
        Date date = AuthService.queryAuthInfo(levelUserId, orderId);
        if (null == date) {
            return new AuthInfo("0001", "單號:", orderId, " 狀態:待三級審批負責人 ", levelUserName);
        }
        AuthLink next = super.next();
        if (null == next) {
            return new AuthInfo("0000", "單號:", orderId, " 狀態:三級審批負責人完成", " 時間:", f.format(date), " 審批人:", levelUserName);
        }

        if (authDate.before(beginDate) || authDate.after(endDate)) {
            return new AuthInfo("0000", "單號:", orderId, " 狀態:三級審批負責人完成", " 時間:", f.format(date), " 審批人:", levelUserName);
        }

        return next.doAuth(uId, orderId, authDate);
    }

}
  • 如上三個類;Level1AuthLinkLevel2AuthLinkLevel3AuthLink,實現了不同的審核級別處理的簡單邏輯。
  • 例如第一個審核類中會先判斷是否審核通過,如果沒有審核通過則返回結果給調用方,引導去審核。(這裏簡單模擬審核後有時間信息不為空,作為判斷條件)
  • 判斷完成后獲取下一個審核節點;super.next();,如果不存在下一個節點,則直接返回結果。
  • 之後是根據不同的業務時間段進行判斷是否需要,二級和一級的審核。
  • 最後返回下一個審核結果;next.doAuth(uId, orderId, authDate);,有點像遞歸調用。

3. 測試驗證

3.1 編寫測試類

@Test
public void test_AuthLink() throws ParseException {
    AuthLink authLink = new Level3AuthLink("1000013", "王工")
            .appendNext(new Level2AuthLink("1000012", "張經理")
                    .appendNext(new Level1AuthLink("1000011", "段總")));

    logger.info("測試結果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date())));

    // 模擬三級負責人審批
    AuthService.auth("1000013", "1000998004813441");
    logger.info("測試結果:{}", "模擬三級負責人審批,王工");
    logger.info("測試結果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date())));

    // 模擬二級負責人審批
    AuthService.auth("1000012", "1000998004813441");
    logger.info("測試結果:{}", "模擬二級負責人審批,張經理");
    logger.info("測試結果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date())));

    // 模擬一級負責人審批
    AuthService.auth("1000011", "1000998004813441");
    logger.info("測試結果:{}", "模擬一級負責人審批,段總");
    logger.info("測試結果:{}", JSON.toJSONString(authLink.doAuth("小傅哥", "1000998004813441", new Date())));
}
  • 這裏包括最核心的責任鏈創建,實際的業務中會包裝到控制層; AuthLink authLink = new Level3AuthLink("1000013", "王工") .appendNext(new Level2AuthLink("1000012", "張經理") .appendNext(new Level1AuthLink("1000011", "段總"))); 通過把不同的責任節點進行組裝,構成一條完整業務的責任鏈。
  • 接下里不斷的執行查看審核鏈路authLink.doAuth(...),通過返回結果對數據進行3、2、1級負責人審核,直至最後審核全部完成。

3.2 測試結果

23:49:46.585 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待三級審批負責人 王工"}
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬三級負責人審批,王工
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待二級審批負責人 張經理"}
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬二級負責人審批,張經理
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0001","info":"單號:1000998004813441 狀態:待一級審批負責人 段總"}
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:模擬一級負責人審批,段總
23:49:46.590 [main] INFO  org.itstack.demo.design.test.ApiTest - 測試結果:{"code":"0000","info":"單號:1000998004813441 狀態:一級審批完成負責人 時間:2020-06-18 23:49:46 審批人:段總"}

Process finished with exit code 0
  • 從上述的結果可以看到我們的責任鏈已經生效,按照責任鏈的結構一層層審批,直至最後輸出審批結束到一級完成的結果。
  • 這樣責任鏈的設計方式可以方便的進行擴展和維護,也把if語句幹掉了。

七、總結

  • 從上面代碼從if語句重構到使用責任鏈模式開發可以看到,我們的代碼結構變得清晰乾淨了,也解決了大量if語句的使用。並不是if語句不好,只不過if語句並不適合做系統流程設計,但是在做判斷和行為邏輯處理中還是非常可以使用的。
  • 在我們前面學習結構性模式中講到過組合模式,它像是一顆組合樹一樣,我們搭建出一個流程決策樹。其實這樣的模式也是可以和責任鏈模型進行組合擴展使用,而這部分的重點在於如何關聯鏈路的關聯,最終的執行都是在執行在中間的關係鏈。
  • 責任鏈模式很好的處理單一職責和開閉原則,簡單了耦合也使對象關係更加清晰,而且外部的調用方並不需要關心責任鏈是如何進行處理的(以上程序中可以把責任鏈的組合進行包裝,在提供給外部使用)。但除了這些優點外也需要是適當的場景才進行使用,避免造成性能以及編排混亂調試測試疏漏問題。

八、推薦閱讀

  • 1. 重學 Java 設計模式:實戰工廠方法模式「多種類型商品不同接口,統一發獎服務搭建場景」
  • 2. 重學 Java 設計模式:實戰原型模式「上機考試多套試,每人題目和答案亂序排列場景」
  • 3. 重學 Java 設計模式:實戰橋接模式「多支付渠道(微信、支付寶)與多支付模式(刷臉、指紋)場景」
  • 4. 重學 Java 設計模式:實戰組合模式「營銷差異化人群發券,決策樹引擎搭建場景」
  • 5. 重學 Java 設計模式:實戰外觀模式「基於SpringBoot開發門面模式中間件,統一控制接口白名單場景」

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

【其他文章推薦】

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

※別再煩惱如何寫文案,掌握八大原則!

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

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

聚甘新