北馬其頓首都 歐洲空污最嚴重城市

摘錄自2020年2月14日公視報導

北馬其頓的首都斯科普里,因為當地民眾習慣在冬天燒柴取暖,再加上老舊車輛偏多,盆地地形導致髒空氣不易排出。現在變成了全歐洲空污最嚴重的城市,估計每年有3500多人死於空氣汙染的相關疾病。

斯科普里空污嚴重,除了因為特殊的盆地地形,不利空氣流通之外,工地施工造成塵土飛揚、太多自歐洲進口的二手老舊汽車排放廢氣,還有許多民眾以燒柴的火爐取暖,甚至有街友以焚燒垃圾代替。這種種因素導致當地空氣中懸浮微粒往往比歐盟國家超標10倍以上。

北馬其頓當局則表示,斯科普里的空污有一半是因為焚燒薪柴所引起,承諾逐步擴大天然瓦斯網絡,更新暖氣設備。此外北馬其頓政府也正在考慮以提高關稅等措施,限制歐洲老舊汽車進口。

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

時尚界吹環保永續風 二手店進駐高檔百貨

摘錄自2020年3月2日公視報導

全球吹起永續環保風潮,時尚界也開始為高端的奢侈品,開發更長久的生命線。精品二手店陸續進駐高檔百貨公司。此外包括線上出租平台,修復再利用也獲得越來越多認同。

美國高端時尚百貨公司Nordstrom,推出名叫「See You Tomorrow」的計劃,在網路商店和紐約的旗艦店販賣二手精品,也鼓勵消費者把自己用不到的精品帶到店裡轉賣。

而英國百年老店Selfridges,更早在去年就引二手精品業者永久進駐,百貨公司裡一手零售跟二手轉售結合的創舉,消費者反應很好。二手精品連鎖業者費希表示,「有一個顧客在這裡幾乎喜極而泣,因為發現一件很久都找不到的外套,如果延長一件衣服的壽命九個月,就能減少它二到三成的碳足跡,所以當你轉賣你手上的物品,對環境也有正面影響。」

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

第九届北京国际纯电动车、混合动力车暨新能源汽车及配套设施展览会

主办单位:中国汽车工程学会电动汽车分会、中国电工技术学会电动车辆专业委员会
承办单位:北京泽安达展览有限公司
支持单位: 北京市人民政府

2013第九届北京国际纯电动车、混合动力车暨新能源汽车及配套设施展览会”已历经8载,是国内最早的已具规模的专业的电动汽车行业年度盛会。将于2013年7月6日-8日在北京-中国国际展览中心(老馆)继续举办。
上届(第八届)展会于2012年7月3日—5日在北京-中国国际展览中心(老馆)取得圆满成功;国内外包括北汽、长安、一汽、长城、时风、益高、韩国LG、美国Remy、日本安川、天能、超威、ITT、英飞凌、中航锂电、玉柴、国电、中国兵器、珠海泰坦、浙江万马等260家整车、零部件、充电站设施及相关企业参展、展出面积13000平方米、专业观众25000多人次。

本届展会预计展出四个馆、20000平方米;参展企业预计300家:专业观众30000人次。展会活动形式多样,主要包括展览会开幕式、论坛、主题会议、颁奖晚宴、热点问题沙龙、电动汽车产业发展研讨会、电动车辆学术年会、电动汽车电池电机专题研讨、电动汽车充电站建设技术设施专题展、节能与新能源车示范推广城市政府职能部门和公交公司领导与整车企业互动等。活动将邀请科技部、发改委、工信部等有关政府部门主管领导和欧洲、美洲、亚太等地区及国家的行业协会组织代表出席。

地 址:北京市东城区安定门外大街208号三利大厦7017室
电 话:86-10-51236248
传 真:86-10-51236249
网 址:www.ievechina.com
邮 箱:bj_evs@sina.com
联系人:刘杰

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

2013自行車展-自行車輛更來電

2013自行車展盛大展出,根據集邦科技旗下綠能事業部EnergyTrend的現場了解,除了汽車廠豐田汽車提出了鋰電池在電動載具的應用看法外,自行車方面,包括了變速器廠以及電池廠也紛紛對於電動自行車提出各自的最新的商品展示,無論是零組件廠以及整車廠,都讓參觀者對於車輛電動化的延伸發展,產生的極大期待,讓電動自行車從過去的代步、健身兼具延伸續航距離,發展到未來將整合隨身電子裝置,讓人們對電動車量的普及充滿樂觀。

豐田汽車鋰電池電動車開賣

雖然全球電動汽車銷售市況不如預期,以Nissan leaf來看,銷量逐步好轉,目前在日本每月銷售約800輛、北美則有1,600輛,截至目前累計約兩萬多輛。根據自行車研討會的演說分享,豐田汽車所寄予厚望的重量級車款Prius α 預計在2013年底上市(全球),並且為首度配置的鋰電池中階車款,電池位置也因為體積輕巧而配置於車室內。豐田目前使用NCA材料做為正極材料,電池芯單元為3.7V, 5Ah,總電池容量約4.4kWh,2014年將推出新款車款IQ,12kWh,預計仍是使用NCA材料(圖一)。
 
圖一 豐田汽車

 
   
變速器、系統整合、電池模組熱鬧參與

作為自行車變速系統龍頭大廠,Shimano也將電子化與變速系統做了創新結合。在Shimano E tube計畫裡頭,將以變速系統Di2做為變速系統電子化為主要訴求,初期將落實在維修體系以及變速資訊的便利性上,未來更有可能藉著電池系統的搭配,提供車主更多的資訊來源(圖二),進而成為讓消費者改變使用習慣的革命。
 
圖二 Shimano E tube應用展示

 
三星SDI做為目前全球第二大的電池芯廠(僅次於合併後的Sanyo + Panasonic),除了在消費型應用的鋰電池產業著墨甚多外,近年也積極切入電動工具以及電動自行車等利基市場,更從過去的電池芯供應,逐步跨足到電池模組(圖三)。

以電動自行車來看,此次展出全方位的自行車電池,可提供後架、坐管、下管等不同位置的應用模組。目前全球各地電動自行車因使用族群不同而衍生出不同擺放位置的設計,中國市場大多以坐管以及後架位置為主要設計,主要訴求在荷重與價格;歐洲則集中在下管及座管位置,用於強調於設計外觀一體性,根據會場的展示DM,目前三星主推2.1Ah以及2.8Ah兩顆自行車專用三元材料電池芯,最大放電率可達到3C(C-rate),已可滿足各種路況的電動自行車的使用需求。
 
圖三 三星自行車電池解決方案展示


   
中華車在配合工業局補助政策,全力推廣電動機車銷售,並且在2012年繳出了六千輛的銷售佳績,未來也將從整車品牌退居幕後,藉著曾經扮演整車零組件整合的豐富經驗,轉型成為關鍵零組件提供者,本次特別展示了關鍵零組件品牌GreenTrans,提供中華車的Power Kit(圖四),包含了扭力感測器、LCD顯示、以及馬達驅動系統,2012年起已與台灣多家自行車廠合作,包括永祺、世同、達生、紹凱、吉安等,都採用中華的Power Kit系統組裝成車。

圖四 中華電動車套件供應分類展示


   
台灣電池模組大廠新普科技也展示了已耕耘三年的電動自行車商品,本次特別針對歐洲市場,與美國品牌Specialize、法國品牌BTwin進行合作(圖五),分別展出下管以及後座電池組產品。

與Specialize合作的登山車,下管產品特色在於電池與車架進行整合,呈現高度客製化,與客戶的關係也將因此而更形緊密。另外BTwin所推出的tilt折疊車系列,目前定位在堅固耐用,為了維持車體的強度,電池模組僅在延伸支架上做結合。新普科技憑藉著對於電池芯的品質掌握度,再加上電源管理的豐富經驗,相信未來在電動自行車市場後市可期。

圖五 新普科技電池模組展示

 
   
另一家作風一向低調的台灣電池模組大廠順達科技也積極跨足各種電池類型應用,於2012年與台達電合作的備用電源產品首次發表即得到設計大獎的殊榮外,此次自行車展也不遑多讓,搭配合作的車廠於現場展出了電動自行車模組的電池模組應用,與中國第一大馬達與控制器廠安乃達做配合,搭配了恪萊博(climbull)各系列整車系統(圖六),這樣的策略合作與全系列搭配的組合,也產生令人期待的商品。

恪萊博的產品策略主打戶外運動客層,屬於高階客群,有別於一般通勤族,由於戶外運動屬於白領階級活動,產品單價較高,且一般通勤族需要載重負荷,容易導致產品壽命偏低,對品牌形象反而產生負面影響,因而改以戶外運動客層為主要訴求對象為主,從應用定位面來扭轉可能造成的問題。而整車產品賣點在於搭配新型中置高速馬達,結合其馬達減速系統,可與外變速系統做最有效益的齒輪比搭配,進而提升產品的壽命與動力表現。

圖六 順達科技電池模組展示

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

中國新能源汽車新一輪補貼或於7月底公布

據上證報報導,中國大陸新能源汽車新一輪補貼政策方向和主體內容已經確定,最快將於7月底公布,以此對接2012年底到期的2009版補貼政策。目前業內普遍流傳的補貼版本為,將不再按技術路線來劃分,而是根據節油率劃分為16個級次,補貼下限為3,000元(人民幣,下同)。

中國近日召開「中央國家機關率先使用新能源汽車專題研討會」,會議透露,將在中央黨校率先並擴大使用新能源汽車,顯示了政府推動新能源車發展的決心。

分析人士指出,在市場和政策的雙重驅動下,新能源汽車產業將邁入商業化大規模推廣階段,其中,作為核心領域的鋰電池可望獲得最快成長。據熟悉鋰電池產業人士透露,工信部和科技部補貼方向的不同影響了新政出台;科技部主張用舊辦法、即按電池容量的節能率來進行補貼,而工信部主張用節油率來補貼。

在此之前,中國於2009年出台的新能源汽車補貼政策並沒達到預期效果。據中汽協數據,截至2012年底,25個城市「十城千輛」示範工程實現新能源汽車銷售2.74萬輛,占總汽車銷售規模的0.1%不到,與預計的10%有很大差距。業內認為,若僅靠政府公共採購,民用市場起不來,則新能源汽車發展空間將極為有限。

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

中國提出2015年節能環保產業總產值到4.5兆元的目標

中國政府網昨(11)日發布《國務院關於加快發展節能環保產業的意見》,其中提出節能環保產業的目標是產值年均增幅超過15%,到2015年,總產值達4.5兆元(人民幣,下同),成為國民經濟新的支柱產業。

意見提出,在北京、上海、廣州等城市擴大公共服務領域新能源汽車示範推廣範圍,每年新增或更新的公交車中,新能源汽車的比例達60%以上。同時開展私人購買新能源汽車和新能源出租車、物流車補貼試點。

至於新能源汽車發展面對的兩大難題安全性及充電設施,意見指出,加快實施節能與新能源汽車技術創新工程,大力加強動力電池技術創新,重點解決動力電池系統安全性、可靠性和輕量化問題,加強驅動電機及核心材料、電控等關鍵零部件研發和產業化,加快完善配套產業和充電設施,示範推廣純電動汽車和插電式混合動力汽車、空氣動力車輛等。

為推廣節能環保產品,政府普通公務員用車需優先採購1.8升或以下燃油經濟性達要求的小排量汽車和新能源汽車,有選擇性優先選用純電動汽車。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

中國電動汽車後碰撞及安全氣囊標准有望于十二五期間建立

據中國汽車技術研究中心標准所高級工程師孫振東近日表示,到十二五末,國家爭取逐步建立起電動汽車後碰撞以及安全氣囊的標准體系。

孫振東在9月8日于天津舉行的中國汽車產業發展(泰達)國際論壇上表示,目前新能源汽車正處於快速發展中,它的安全得到了社會各界的重視。中國汽車技術研究中心標准所也會加緊研究和制定新能源汽車的安全標准。

孫振東介紹,被動安全是指當車輛發生交通事故的時候,車輛對成員提供的有效保護。目前整個中國汽車標准體系中,有關被動安全的共有32項標准。

對於乘用車,國家已經建立了完整有效的體系。但是對於商用車,包括客車和貨車,被動安全標准正在建立和完善的過程中,這也是中國汽車技術研究中心標准所今後的工作重點。目前江淮汽車、長安汽車、比亞迪、福田汽車等車企有涉足電動汽車業務。

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

華夏動力及申沃50億元新能源客車項目入駐山西

9月16日上午,山西省孝義市與山西華夏動力科技、上海申沃客車合作項目-投資50億元的新能源客車聯合研制生產基地項目在太原簽約。該項目規劃五年內生產規模達到5000輛產能,預計年產值可達70億元。

據了解,上述三方將在孝義市建設新能源客車及核心零部件聯合研制生產基地,以發展新能源純電動大客車以及核心零部件聯合為起點,建設首條純電動客車示范運營線路和配套充電設施。

華夏動力農用車電機、電池項目已于2011年落戶孝義市,並于2012年9月正式入駐該市高新科技產業園區。上海申沃客車則擁有年產2500輛城市客車、城郊客車及500輛底盤的生產能力,可生產大型長途客車、柴油發動機公交車、CNG壓縮天然氣公交車以及純電動城市公交車等。

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

Raft共識算法

Raft共識算法在分佈式系統中是常用的共識算法之一,論文原文In Search of an Understandable Consensus Algorithm ,作者在論文中指出Poxas共識算法的兩大問題,其一是難懂,其二是應用到實際系統存在困難。針對Paxos存在的問題,作者的目的是提出一個易懂的共識算法,論文中有單獨一小節論述Raft是一個實用的、安全可用、有效易懂的共識算法。本文描述了Raft共識算法的細節,很多內容描述及引用圖片均摘自論文原文。

Raft概述

我們主要分以下三部分對Raft進行討論:

  • Leader election——a new leader must be chosen when
    an existing leader fails. (領導人選舉)
  • Log replication——the leader must accept log entries from clients and replicate them across the cluster,
    forcing the other logs to agree with its own.(日誌複製)
  • Safety——the key safety property for Raft. (安全性)

正常工作過程中,Raft分為兩部分,首先是leader選舉過程,然後在選舉出來的leader基礎上進行正常操作,比如日誌複製操作等。

一個Raft集群通常包含\(2N+1\)個服務器,允許系統有\(N\)個故障服務器。每個服務器處於3個狀態之一:leaderfollowercandidate。正常操作狀態下,僅有一個leader,其他的服務器均為follower。follower是被動的,不會對自身發出的請求而是對來自leader和candidate的請求做出響應。leader處理所有的client請求(若client聯繫follower,則該follower將轉發給leader)。candidate狀態用來選舉leader。狀態轉換如下圖所示:

為了進行領導人選舉和日誌複製等,需要服務器節點存儲如下狀態信息:

狀態 所有服務器上持久存在的
currentTerm 服務器最後一次知道的任期號(初始化為 0,持續遞增)
votedFor 在當前獲得選票的候選人的 Id
log[] 日誌條目集;每一個條目包含一個用戶狀態機執行的指令,和收到時的任期號
狀態 所有服務器上經常變的
commitIndex 已知的最大的已經被提交的日誌條目的索引值
lastApplied 最後被應用到狀態機的日誌條目索引值(初始化為 0,持續遞增)
狀態 在領導人里經常改變的 (選舉后重新初始化)
nextIndex[] 對於每一個服務器,需要發送給他的下一個日誌條目的索引值(初始化為領導人最後索引值加一)
matchIndex[] 對於每一個服務器,已經複製給他的日誌的最高索引值

Raft在任何時刻都滿足如下特性:

  • Election Safety:在一個任期中只能有一個leader;
  • Leader Append-Only:leader不會覆蓋或刪除日誌中的entry,只有添加entry(follower存在依據leader回滾日誌的情況);
  • Log Matching:如果兩個日誌包含了一條具有相同index和term的entry,那麼這兩個日誌在這個index之前的所有entry都相同;
  • Leader Completeness: 如果在某一任期一條entry被提交committed了,那麼在更高任期的leader中這條entry一定存在;(領導人選舉時會保證這一性質,後面會講到這個問題)
  • State Machine Safety:如果一個節點將一條entry應用到狀態機中,那麼任何節點也不會再次將該index的entry應用到狀態機里;

下面我們詳細討論這幾部分。

Leader選舉(Leader election)

一個節點初始狀態為follower,當follower在選舉超時時間內未收到leader的心跳消息,則轉換為candidate狀態。為了避免選舉衝突,這個超時時間是一個隨機數(一般為150~300ms)。超時成為candidate后,向其他節點發出RequestVoteRPC請求,假設有\(2N+1\)個節點,收到\(N+1\)個節點以上的同意回應,即被選舉為leader節點,開始下一階段的工作。如果在選舉期間接收到eader發來的心跳信息,則candidate轉為follower狀態。

在選舉期間,可能會出現多個candidate的情況,可能在一輪選舉過程中都沒有收到多數的同意票,此時再次隨機超時,進入第二輪選舉過程,直至選出leader或着重新收到leader心跳信息,轉為follower狀態。

正常狀態下,leader會不斷的廣播心跳信息,follower收到leader的心跳信息後會重置超時。當leader崩潰或者出現異常離線,此時網絡中follower節點接收不到心跳信息,超時再次進入選舉流程,選舉出一個leader。

這裏還有補充一些細節,每個leader可以理解為都是有自己的任期(term)的,每一期起始於選舉階段,直到因節點失效等原因任期結束。每一期選舉期間,每個follower節點只能投票一次。圖中t3可能是因為沒有獲得超半數票等造成選舉失敗,須進行下一輪選舉,此時follower可以再次對最先到達的candidate發出的RequestVote請求投票(先到先得)。

對所有的請求(RequestVote、AppendEntry等請求),如果發現其Term小於當前節點,則拒絕請求,如果是candidate選舉期間,收到不小於當前節點任期的leader節點發來的AppendEntry請求,則認可該leader,candidate轉換為follower。

日誌複製(Log replication)

leader選舉成功后,將進入有效工作階段,即日誌複製階段,其中日誌複製過程會分記錄日誌和提交數據兩個階段。

整個過程如下:

  1. 首先client向leader發出command指令;(每一次command指令都可以認為是一個entry,或者說是日誌項)
  2. leader收到client的command指令后,將這個command entry追加到本地日誌中,此時這個command是uncommitted狀態,因此並沒有更新節點的當前狀態;
  3. 之後,leader向所有follower發送這條entry,也就是通過日誌複製AppendEntries消息 (可以是一條也可以是多條日誌項) 將日誌項複製到集群其他節點上,follower接收到后 (這裡有判斷條件的,並不是所有leader發送來的日誌項都無條件接收,而且還可能存在本地與leader日誌不一致的情況,後面會詳細說明,這裏先看正常情況) 追加到本地日誌中,並回應leader成功或者失敗;
  4. leader收到大多數follower的確認回應后,此entry在leader節點由uncommitted變為committed狀態,此時按這條command更新leader狀態,或者說將該日誌項應用到狀態機,然後向client返回執行結果;
  5. 在下一心跳中(這裏也可以是或者說多數情況下是新的日誌複製AppendEntries消息,會帶有相關信息,後面后詳細的字段說明會講到),leader會通知所有follower更新確認的entry,follower收到后,更新狀態,這樣,所有節點都完成client指定command的狀態更新。

可以看到client每次提交command指令,服務節點都先將該指令entry追加記錄到日誌中,等leader確認大多數節點已追加記錄此條日誌后,在進行提交確認,更新節點狀態。如果還對這個過程有些模糊的話,可以參考Raft動畫演示,較為直觀的演示了領導人選舉及日誌複製的過程。

安全(Safety)

前面描述了Raft算法是如何選舉和複製日誌的。然而,到目前為止描述的機制並不能充分的保證每一個狀態機會按照相同的順序執行相同的指令。我們需要再繼續深入思考以下幾個問題:

  • 第一個問題,leader選舉時follower收到candidate發起的投票請求,如果同意就進行回應,但具體的規則是什麼呢?是所有的follower都有可能被選舉為領導人嗎?
  • 第二個問題,leader可能在任何時刻掛掉,新任期的leader怎麼提交之前任期的日誌條目呢?

選舉限制

針對第一個問題,之前並沒有細講,如果當前leader節點掛了,需要重新選舉一個新leader,此時follower節點的狀態可能是不同的,有的follower可能狀態與剛剛掛掉的leader相同,狀態較新,有的follower可能記錄的當前index比原leader節點的少很多,狀態更新相對滯后,此時,從系統最優的角度看,選狀態最新的candidate為佳,從正確性的角度看,要確保Leader Completeness,即如果在某一任期一條entry被提交成功了,那麼在更高任期的leader中這條entry一定存在,反過來講就是如果一個candidate的狀態舊於目前被committed的狀態,它一定不能被選為leader。具體到投票規則:
1) 節點只投給擁有不比自己日誌狀態舊的節點;
2)每個節點在一個term內只能投一次,在滿足1的條件下,先到先得;

我們看一下請求投票 RPC(由候選人負責調用用來徵集選票)的定義:

參數 解釋
term 候選人的任期號
candidateId 請求選票的候選人的 Id
lastLogIndex 候選人的最後日誌條目的索引值
lastLogTerm 候選人最後日誌條目的任期號
返回值 解釋
term 當前任期號,以便於候選人去更新自己的任期號
voteGranted 候選人贏得了此張選票時為真

接收者實現:

  1. 如果term < currentTerm返回 false
  2. 如果 votedFor 為空或者為 candidateId,並且候選人的日誌至少和自己一樣新,那麼就投票給他

可以看到RequestVote投票請求中包含了lastLogIndex和lastLogTerm用於比較日誌狀態。這樣,雖然不能保證最新狀態的candidate成為leader,但能夠保證被選為leader的節點一定擁有最新被committed的狀態,但不能保證擁有最新uncommitted狀態entries。

提交之前任期的日誌條目

領導人知道一條當前任期內的日誌記錄是可以被提交的,只要它被存儲到了大多數的服務器上。但是之前任期的未提交的日誌條目,即使已經被存儲到大多數節點上,也依然有可能會被後續任期的領導人覆蓋掉。下圖說明了這種情況:

如圖的時間序列展示了為什麼領導人無法決定對老任期號的日誌條目進行提交。在 (a) 中,S1 是領導者,部分的複製了索引位置 2 的日誌條目。在 (b) 中,S1崩潰了,然後S5在任期3里通過S3、S4和自己的選票贏得選舉,然後從客戶端接收了一條不一樣的日誌條目放在了索引 2 處。然後到 (c),S5又崩潰了;S1重新啟動,選舉成功,開始複製日誌。在這時,來自任期2的那條日誌已經被複制到了集群中的大多數機器上,但是還沒有被提交。如果S1在(d)中又崩潰了,S5可以重新被選舉成功(通過來自S2,S3和S4的選票),然後覆蓋了他們在索引 2 處的日誌。反之,如果在崩潰之前,S1 把自己主導的新任期里產生的日誌條目複製到了大多數機器上,就如 (e) 中那樣,那麼在後面任期裏面這些新的日誌條目就會被提交(因為S5 就不可能選舉成功)。 這樣在同一時刻就同時保證了,之前的所有老的日誌條目就會被提交。

為了消除上圖裡描述的情況,Raft永遠不會通過計算副本數目的方式去提交一個之前任期內的日誌條目。只有領導人當前任期里的日誌條目通過計算副本數目可以被提交;一旦當前任期的日誌條目以這種方式被提交,那麼由於日誌匹配特性,之前的日誌條目也都會被間接的提交。

當領導人複製之前任期里的日誌時,Raft 會為所有日誌保留原始的任期號。

對Raft中幾種情況的思考

follower節點與leader日誌內容不一致時怎麼處理?

我們先舉例說明:正常情況下,follower節點應該向B節點一樣與leader節點日誌內容一致,但也會出現A、C等情況,出現了不一致,以A、B節點為例,當leader節點向follower節點發送AppendEntries<prevLogIndex=7,prevLogTerm=3,entries=[x<-4]>,leaderCommit=7時,我們分析一下發生了什麼,B節點日誌與prevLogIndex=7,prevLogTerm=3相匹配,將index=7x<-5)這條entry提交committed,並在日誌中新加入entryx<-4,處於uncommitted狀態;A節點接收到時,當前日誌index<prevLogIndexprevLogIndex=7,prevLogTerm=3不相匹配,拒接該請求,不會將x<-4添加到日誌中,當leader知道A節點因日誌不一致拒接了該請求后,不斷遞減preLogIndex重新發送請求,直到A節點index,termprevLogIndex,prevLogTerm相匹配,將leader的entries複製到A節點中,達成日誌狀態一致。

我們看一下附加日誌AppendEntries RPC(由領導人負責調用複製日誌指令;也會用作heartbeat)的定義:

參數 解釋
term 領導人的任期號
leaderId 領導人的 Id,以便於跟隨者重定向請求
prevLogIndex 新的日誌條目緊隨之前的索引值
prevLogTerm prevLogIndex 條目的任期號
entries[] 準備存儲的日誌條目(表示心跳時為空;一次性發送多個是為了提高效率)
leaderCommit 領導人已經提交的日誌的索引值
返回值 解釋
term 當前的任期號,用於領導人去更新自己
success 跟隨者包含了匹配上 prevLogIndex 和 prevLogTerm 的日誌時為真

接收者實現:

  1. 如果 term < currentTerm 就返回 false;
  2. 如果日誌在 prevLogIndex 位置處的日誌條目的任期號和 prevLogTerm 不匹配,則返回 false;
  3. 如果已經存在的日誌條目和新的產生衝突(索引值相同但是任期號不同),刪除這一條和之後所有的;(raft中follower處理不一致的一個原則就是一切聽從leader)
  4. 附加日誌中尚未存在的任何新條目;
  5. 如果 leaderCommit > commitIndex,令 commitIndex 等於 leaderCommit 和 新日誌條目索引值中較小的一個;

簡單總結一下,出現不一致時核心的處理原則是一切遵從leader。當leader向follower發送AppendEntry請求,follower對AppendEntry進行一致性檢查,如果通過,則更新狀態信息,如果發現不一致,則拒絕請求,leader發現follower拒絕請求,出現了不一致,此時將遞減nextIndex,並重新給該follower節點發送日誌複製請求,直到找到日誌一致的地方為止。然後把follower節點的日誌覆蓋為leader節點的日誌內容。

leader掛掉了,怎麼處理?

前面可能斷斷續續的提到這種情況的處理方法,首要的就是選出新leader,選出新leader后,可能上一任期還有一些entries並沒有提交,處於uncommitted狀態,該怎麼辦呢?處理方法是新leader只處理提交新任期的entries,上一任期未提交的entries,如果在新leader選舉前已經被大多數節點記錄在日誌中,則新leader在提交最新entry時,之前處於未提交狀態的entries也被committed了,因為如果兩個日誌包含了一條具有相同index和term的entry,那麼這兩個日誌在這個index之前的所有entry都相同;如果在新leader選舉前沒有被大多數節點記錄在日誌中,則原有未提交的entries有可能被新leader的entries覆蓋掉。

出現網絡分區時怎麼處理?

分佈式系統中網絡分區的情況基本無法避免,出現網絡分區時,原有leader在分區的一側,此時如果客戶端發來指令,舊leader依舊在分區一測進行日誌複製的過程,但因收不到大多數節點的確認,客戶端所提交的指令entry只能記錄在日誌中,無法進行提交確認,處於uncommitted狀態。而在分區的另一側,此時收不到心跳信息,會進入選舉流程重新選舉一個leader,新leader負責分區零一側的請求,進行日誌複製等操作。因為新leader可以收到大多數follower確認,客戶端的指令entry可以被提交,並更新節點狀態,當網絡分區恢復時,此時兩個leader會收到彼此廣播的心跳信息,此時,舊leader發現更大term的leader,舊leader轉為follower,此時舊leader分區一側的所有操作都要回滾,接受新leader的更新。

成員變更

在分佈式系統中,節點數量或者說服務器數量不是一成不變的,我們有可能會隨時增減節點數量,當增加節點時,有可能會出現兩個leader選舉成功的情況,主要是新舊配置不一致造成的,怎麼處理呢?最簡單粗暴的就是把目前所有節點都停掉,更新配置,再重啟所有節點,但會造成一段時間服務不可用,很多情況下這是不能被允許的。raft的解決辦法原論文中是聯合共識(Joint Consensus)的辦法,後來又提出了單節點變更(single-server changes)的方法。我們下面詳細描述一下這個問題。

Raft要求,在任一任期內,只能有一個leader,而成員變更的麻煩就在於,成員變更時可能會出現兩個leader,以一個例子說明:原系統有3個節點,成員為[1,2,3],現新增成員4、5。假設在成員變更時,1、2與3發生分區,此時,[1,2]為一組,1通過1、2兩節點選舉為leader,而5通過3、4、5選舉為leader,就形成了2個leader並存的情況。

因為每個節點新舊配置更新的時間不同,造成了在某一時刻,可能會存在新舊配置的兩個大多數情況的存在,上圖中,舊配置的大多數是兩個節點,而新配置的大多數是三個節點,在圖中紅線頭的時刻存在兩個大多數的情況,如果此時出現網絡分區進行選舉時就會出現兩個leader的情況。

怎麼解決呢?用什麼辦法才能不讓上面兩個大多少情況的出現呢?可通過單節點變更解決,即通過一次變更一個節點實現成員變更。主要思想是利用“一次變更一個節點,不會同時存在舊配置和新配置的兩個大多數”的特性,實現成員變更。比如上面的情況,就可先將3節點集群[A,B,C]變更為4節點集群[A,B,C,D],再將4節點集群變更為5節點集群[A,B,C,D]。

為什麼單節點變更不會造成兩個大多數情況的出現呢?我們可以進行如下推理:假設原節點數為2n+1,則舊配置的大多數major_old=n+1,新加入1個節點,新配置節點數為2n+2,則新配置的大多數為major_new=n+2,同時存在兩個大多數所需節點數目為major=major_old+major_new=n+1+n+2=2n+3>2n+2,也就是兩個大多數所需節點數超出了節點總數,故不存在這種情況,如何是刪除成員,其推理過程類似,結論相同。

具體的,我們依舊以這個3節點集群變更為5節點集群為例進行說明。假設現3節點集群[A,B,C],節點A為leader,配置為[A,B,C],我們先向集群加入節點D,新的配置為[A,B,C,D],成員變更通過以下兩步實現:

  • 第一步,leader節點A向新節點D同步數據;
  • 第二步,leader將新配置[A,B,C,D]作為一個日誌項複製到新配置中的所有節點(A,B,C,D)上,然後將新配置的日誌項應用到本地狀態機,完成單節點變更。

在變更后,現有集群的配置項就是[A,B,C,D],添加E節點也是同樣的步驟。上面的描述如果理解的比較模糊的話,其實raft是採用將修改集群配置的命令放在日誌條目中來處理的,其修改配置項,就是一條日誌項,其流程與普通的日誌項相同,只不過最後狀態機執行的結果是配置變更。

日誌壓縮

日誌壓縮主要是為了解決無限增長的日誌與有限的存貯空間的矛盾,可以想一個問題:對於已經committed的日誌項,是否有必要一直保存下去?如果沒有必要的話,是否可以對部分已committed的日誌項刪減或壓縮呢?raft的主要的解決辦法是採用快照進行日誌壓縮。

如上圖所示,對於日誌索引5之前的日誌項可以刪除,只保留一個快照(保存有當前狀態以及一些任期索引號等元信息)即可。

具體工程實現時,一般每個節點獨立打快照,當日誌超過一定量會觸發快照操作,具體實現以及更多細節待以後深究。

Client Protocol

raft共識算法真正工作時還需有一個客戶端協議(client protocol),綜合解決一些列的問題。比如會遇到下面這些問題:client怎麼和集群交互呢?client如果知道leader節點的話,可以直接將command發給leader節點,如果不知道的話,可以隨意發給集群中已知的節點,節點會將client的請求轉給leader。其實上面還有個問題,client發送請求(或者command)給leader,但是leader遲遲不給回應怎麼辦?重試是一個辦法。連接的leader崩潰了client怎麼辦?如果client超時重發command,怎麼保證command不被狀態機執行兩次?client生成command的時候要給加上唯一ID,當server的日誌中已存在相同command時會忽略。

附錄

這裏附加一張論文中的截圖,裏面詳細講明了不同節點需要維護什麼信息,每個消息是怎麼定義的,以及消息該如何處理等,不包含日誌壓縮以及成員變更部分:

這裏補充一點,raft共識算法與pbft共識算法解決的是不同的問題,即raft節點不能存在惡意節點,節點消息可以延遲、丟失,但不能造假或作惡,即不能存在拜占庭節點。

本文對raft共識算法做了一個整體的梳理學習,可能會存在某些細節描述不清晰的地方,在真正工程代碼實現時,還會存在更多的細節問題,同時,這裏缺少證明為什麼raft算法是正確的證明,有待今後更深一步理解共識算法后再行補充。

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

【其他文章推薦】

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

新北清潔公司,居家、辦公、裝潢細清專業服務

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

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

※超省錢租車方案

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

Magicodes.IE在.NET Core中通過請求頭導出多種格式文件

前言

在2.2里程碑中我們增加了一些新的功能,正如標題所寫通過請求頭進行導出我們不同格式的文件.下面我們來看一下如何使用.通過這種方式無論是對我們的數據多用途,還是說對我們的數據校驗都做到了輕鬆易配。

同時我們也將在本周發布2.3版本,另外3.0版本我們將進行一次大的性能提升。3.0版本我們將對Razor引擎以及導出引擎進行更換,包括對所有代碼的重構,這是值得期待的。

上周我們發布了2.2.5版本更新如下:

  • 【Nuget】版本更新到2.2.5

  • 【Excel導出】增加分欄、分sheet、追加rows導出 #74

    - exporter.Append(list1).SeparateByColumn().Append(list2).ExportAppendData(filePath);
    - exporter.Append(list1).SeparateBySheet().Append(list2).ExportAppendData(filePath);
    - exporter.Append(list1).SeparateByRow().AppendHeaders().Append(list2).ExportAppendData(filePath);
    
  • [Excel導出】修復‘IsAllowRepeat=true’ #107

  • [Pdf導出】增加PDF擴展方法,支持通過以參數形式傳遞特性參數 #104

    - Task<byte[]> ExportListBytesByTemplate<T>(ICollection<T> data, PdfExporterAttribute pdfExporterAttribute,string temple);
    - Task<byte[]> ExportBytesByTemplate<T>(T data, PdfExporterAttribute pdfExporterAttribute,string template);
    

主要步驟

1.安裝包

Install-Package Magicodes.IE.AspNetCore

2.開始配置

Startup.cs的Configure()方法中,在UseRouting()中間件之後,註冊如下中間件

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();
    app.UseMagiCodesIE();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

上面這種以中間件形式可以為我們提供導出服務,那麼我們再看一下另一種方式如下所示:

  public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers(options=>options.Filters.Add(typeof(MagicodesFilter)));
            }

上面兩種方式都可以為我們提供導出服務,我們只需要對我們的控制器進行配置我們的特性,在這邊呢 特性主要做的是一個標識作用,標識他的一些相關的內容數據,同時標識他可以當成文件導出。

[HttpGet("excel")]
[Magicodes(Type = typeof(ExportTestDataWithAttrs))]
public List<ExportTestDataWithAttrs> Excel()
{
    return GenFu.GenFu.ListOf<ExportTestDataWithAttrs>(100);
}

上面代碼片段中我們標識這個類允許被導出。同時我們需要通過Type指定我們被導出類的類型。

這樣填寫完后我們可以通過對該地址的調用,但是注意我們必須要添加請求頭以標識被導出的文件類型。如果不添加請求頭,那麼此處將返回的還是json格式的數據。請求頭名稱為Magicodes-Type

       /// <summary>
        ///     XLSX
        /// </summary>
        internal const string XLSXHttpContentMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        /// <summary>
        ///     PDF
        /// </summary>
        internal const string PDFHttpContentMediaType = "application/pdf";
        /// <summary>
        ///     DOCX
        /// </summary>
        internal const string DOCXHttpContentMediaType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        /// <summary>
        ///     HTML
        /// </summary>
        internal const string HTMLHttpContentMediaType = "text/html";

如果說是模板導出word或者pdf甚至說html文件那麼我們也是同樣的操作如下所示:

[HttpGet("Word")]
        [Magicodes(Type = typeof(ReceiptInfo), TemplatePath = ".//ExportTemplates//receipt.cshtml")]
        public ReceiptInfo Word()
        {
            return new ReceiptInfo
            {
                Amount = 22939.43M,
                Grade = "2019秋",
                IdNo = "43062619890622xxxx",
                Name = "張三",
                Payee = "湖南心萊信息科技有限公司",
                PaymentMethod = "微信支付",
                Profession = "運動訓練",
                Remark = "學費",
                TradeStatus = "已完成",
                TradeTime = DateTime.Now,
                UppercaseAmount = "貳萬貳仟玖佰叄拾玖圓肆角叄分",
                Code = "19071800001"
            };
        }

我們還是需要對其指定Type,然後通過TemplatePath進行指定模板地址即可

同樣的我們還可以通過請求頭進行標識本次請求是否是文件格式導出。


        [HttpGet("pdf")]
        [Magicodes(Type = typeof(BatchPortraitReceiptInfoInput), TemplatePath = ".//ExportTemplates//batchReceipt.cshtml")]
        public BatchPortraitReceiptInfoInput Pdf()
        {

            var input = new BatchPortraitReceiptInfoInput
            {
                Payee = "湖南心萊信息科技有限公司",
                SealUrl =
                @"data:image/jpeg;base64,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",
                LogoUrl =
                @"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAAAYCAYAAACY5PEcAAAaPUlEQVRogY15eZxdVbHuV2vt+Yzdp8f0mM4cAySBBEOAgEHCoIKggIIXZFJ5IMPjPhwAEQdUFHmAE6hccLqoQDDMDhBCCBDIBBnI2N3puU/36TPuaQ3vj+QBvuvTW7/f+mvtqlr17Vq1a39FWkv8V2EAYm+095ObZcz9+mlfOoUb2byMpqAVAEQgrkFMwHIWglgC0BMAtUDrKkqjvwSjOhj2nFShb+PN5eEDJ2iZHm+Zf9pNqZY5u7ibhqgVERaGQdwAlAaZDMw1Aa0Pn0HDTnVhaMdvMbrnj5j/oa9jZM8v4KZnoWnm1QAApSdAIBDVQ4rdEHEvwtoe2O7RsN25qJbWI6rtBVESWgE6rsKrXwEnNQ9+cSuC6hZ42WNgOtOgVQ1x1AfGOAANEAMjC1LtgqYSlAxgWatgGEcAegoAB4hBK4XYPwgR1jC+5xHUd5yMOIhR6NsCbmTQvuQSMAKY4aB3/eMoD+yHAbwXJECHjCFmkyOXrAtrG2cr0YLxA3duy3VcfZrlztgW+0N4T+cfiQYz09CxbBnb9eCG0sjBbhVm4RcHUJsondq28MxLcrOWPKKVBBH9Ezv/P/nv6BBA7J88+8/2/ju+2fuW+tdaRMD7YmVa1XBo+dAQAICp/LXPV4u/XWzZH4BptyIOB1pHdn93q1/cdqbptQF0OBv+oYMkoFVj4eATm8Nyf7fttcBwM/Dq2zA1sNuZ2LftWhHWQCAwywEzTDDDBDF+KCgiQCvYqZbDQR4KjnELjFlghvfe4SkHovpDfpkLIgYiG9zIAkiDcQ/ELDDugHEbxExwMwPAADfTIGYCZICYC25kYVit4GYruNEGbnSBsRz+Pin54SDTACUAuADUuz5ABGIGQAStFYg4DDsJslIAs0GMQ2sFg8g9bIgBAMLqroyTOPX7fmnNShGPgKETpt2CqFrG8K67n8x1XXR9tvXEu0U8CujK++A+VKa0DptKo7/fIsKgxbA7IQICtEZ1YhCtC05cP3vV5adx20NtrG9mXJ06yC071FLCztTD8hLQUoK4jdHdz19M3OlVosSVLF0ZB5ULQn/wAaWK48mGJV/hpgcRv3EF414fM+c+r8U4lIq4VpUllcKTC2T8nx8nlvohNHypfGhFgFIo59c3ivCZyznXv2Ym64UKNsbBXhn5O072Sy/cZjrN+xmXQso9s233mOtMd9lmjSKIAKWnUC7c820ZDCeA1LWmMx2J7LnQKoIS1YyW8c+0FBcQOAwrAYJCNb+fCn1vrfbSDZ+VUW3SclOgQzWdABAmDz58S2H4W9d2Ln7oA4SEGDtw5XDsByax6YAwEdZ8yMhHrvPD99V1nHONVkUYZjeIpQBY0HqqJX/wvFdr+dEuiPmQgQkR2KiMl+Fm5m6cecIVx5qZNh1MjR49vvPlE9MtPXdrJTWRgSAYQBxPgnEbpl2PTU9fp5tnnPCraXOWr+3dfO/P5xz/HRrZ98P9WvtW4/Tz2hU2I45Wa9NtedGwjjuZs7kgSqRrxaeLQXk34qAAy14AwAPgBVCcpIjsOKggqg7A9rLw6mYh07IiY3rTSyIaWxxWt14cBc99EZSHlznjHm61/VLJNT/UNNmgJAfnp98Vlnb9m1/ceCxjTYls65eQqDsP43vu+mFp+LUzlEzM5izzhpXo+rk/MboirFaPEhHSYSVoZzDHmZkZJzjVwzWdoTT26hkHNt14e6qphInBT4w0tj/V1dT9q87RfV/cFlT6Gg1jFgwzBYKNqaEnrtYY68i2nf8JYklxCPD9HVP5j78S+v3t3DoJUmiACGF1HF62e1v7UauWGV5KA8DYzr99yU40POI1dmoVB2DcRP/6P6IwuAWWlwORAYDyIL47qE6OMzMBxi1wI/GaENVlhtkAr/4GFPMHxg0zV0lmroLWPrSmKjfretxUfm5UO3iu6XR837K7/aDS/zmtlLa99vtFFDSGlYHPWV7mYdNtGLLcjmrkv4M4HAyJWJ4buQMgI0nk5rWaiKQc4JomoGIJRmVws7PPsMYaiepgOjMAACIqzIiDfJNhpSCico/hRM0aelgr2Wi5uSLjql0J1a8ln5K+HxgAh1/snfvWc+c95WVNOMlFIBrAaN8pfXVNP/9A4/TvHzW29+tb/VJvI+czQNyGYbWjkn/uLCm2TrbO/nMaAIqFGf1RBJjWKsTRoY9kWBmEk577Vq7rlGPNRKMkM43S0KbPFAc3nj3rQ9d/UoQlQCloFaF9welonbMCjNvghoOtz/V6pp0ShulCyxjEGLiZGhfxUE5rhcjfCugoL9VEKozWIa4NA9KQUXTgVmi7U0vywuquhxklKQqCIyEZqkbiVCkkTKsxFmH/bSiJraZVdwO3GIjC9jjce4ZGuYW474b+8x8znZ7H3eTdKzTFgAa0IkS1R75ARBxgqBWfheUejfruT30sUbdscX7fmjcbpp+Ws5PdkJEP0grcbcWeFx7WXQtXHCdjRLEfwAjKQ01vPv7JDUrXYCdnQasQShZhOcsGGGtMWnbXjqYZNy8eeeeb6/ypoW7DbgNA0DqEmz7pWSnyjSIcneYmr7gtjh64TchhEM1AUN6HRG7F9raFtxzHrWSgVQhAYWDzg790Us3PAxGiyigMK4lqoQ+jB14CMx0wMHDDQ1SbtEwnM8EMm2slQCBwMzUCwGWkIWUeGgJM20pLAdOaB8amgRvThmullx3DmiUSmY8wKXwdj67uATORajzzHYJNfultJcJBM1m3LM/NDNzMUSCu36gWVv8kDtdfqVWBbG/RPaZzNIMeWAE9klXKBKOe7UTuqNY6YZj1CKobUJv6C7zsKeA8F6jdj8RhdfQG4Ueb/cLQFVJgdlQL6msTAxjZ9eb+qOK/2rH0I/ca25696TfF8bezzbOOhFYhtA616SxZm2n8xhmmsdSPgtdhmB0DrbO+ctTQrns2+KXB+YKNINf9b7/Ptnz1/P6t1+xk5p/mTpu3xsg2nLRhwv/yc0FpK9zMyr0di7+zBMR9QICYi6n+x77hT2412k743v8kzmF6aRhWEkaYgtQEKEAzBiVCaJAIK+NxnE4S4xaUliCyR7QKuAbgJU6CiP9WArGclzoXSk0B2oKIDnxFisnHvWznbYbVstXLzkBU3fu0htLJ3PKLYn8AKh49PihuvprI+LZXtxDMcBCUX10UlF69n9vmLpBRkPHebzPu/SiOf3SdwlCHjAHbuuwbjNf3E7FurcvgfBqi2gg434KwPDxbxiGf7Hv5B5nW46+Jw3IAuIMy9v3MtJ7XiVgLcWPJnj//5kVj4uAbp6Qa5kArAa0DECCzTfdeQSzlx+FWcKMVcXAQjDulljk3Lhza/u29ljc3bui8+fz8wZtW1ybfmlvXHWL8wJlhwtnQkq7/+hk6WnNXc893lx4CXAIwoFWxfnjHPTdn2z+4P9E8a5eMiuCWC00adqIe3UedBcZNMG5Ca6LR3medRP30kuVmSckYh7Idk4CCBqFafg4yHq4RE8ni5DdAaIaWlKhOPvGcltbywuAvzg5rAzsY1cOwZ0yHBPYePGu7jAJYbud8Qg0T/T/pVKrvw056flWKEQJkrxLFGjNMCxBVxpsGbfOmBUrt5cqywGhmIQ5ff1LrSINMMOoCFGFs90/eLo/u+IBpz9D1PSuPb5zzmfXj76y5vZo/EM8746azwon9sDMt2PHUw2tNJ9FkJLLto0H5rWYv2wkiD0oXjFL+S8+5qQs+Ztsf3i5FHlJNAWiBlpW4bcGXF8qwMXnw7fPWaVp/vOWeDm4WoNQY3/3XG8db5l31kWnHPDQPMKF1CCITADDR/72no2ofGmdedydxBjB9uI9NYO9rD2N091o4qaZ3e/XYL6GS318xzK4McQ4iQqrxuI2Tww9BK//ibMNVD02Nvi6UHHa8xKehVQAty1pnKvmwuu9hIJlxkovSWjOEldF2ECHTfMKolgQRlfZA+yWvbmbazRyjlJiACAe0lEXNUCDD7NZaFxiRp2z3YyWlBqC1AwAUFF+sA8iua7vdIpWMwvImw071PGpY3Wv9qcErTdt6C6ihrnvln/te//xLSvDGrqXnX7zzmQd/N9m748RlV/1oljF7+dWXb332ijUiLIEoA8bqEfkv90T+jjca2pZ9kPHUViIbhtWMoLwNptteIEoXtCq3k+EC0NBaQUsNt76uzGFUdRiD7BBEaQAMgf/INcWRnx2bavpIlGyY8xsZ5aFlADCG2K8hUdeB9iM+Cm7ah36/mamrr+9EpuUDsJOuoWUErSJkWj862FjZ9GC+9+7/cNPTH1JqcgDMW0jcBnQN3JxZs5zq1UF55xPZ1s8crXUEL70U4/vuf0EDurH70g/5xS2QUehMDj76kps97ljijdqfehpx0CeIuZooZBpScd48JuIdmajw7XdA47OVMqCjGZBxDCkCROWdP0jkzrqGGUI42YVfk7Fq7nvt1qu0jrvLw+u3efVL1y06725r26NfjV795Ssfd5LT9LGXfoupuKaNho4PPtm54FOfGznw8595WQ1iGXCzEyIqOPn+q15P5a5cYXsLXyViULKC2B+Dk25F55HPTB/tveTF2tjAChENwrTqxppnn7PIMpqG/MpemDBh2guh9CvHlguX3qNEDrn2Vfc62dllEU2AWxkQNyGCMupa58OwXGitYbkZlMb2dUd+AYaZ2BeU+psifxJKBWZU3R43dF58aSIz/0FmpEHMC0S8p1HJIrTyASoh8nfdqmRhMRHAeRMIDZCi5IIMzXgLDLsTjFeYjCaWBOVdN7hM/IDzZmhbcxHubACza1qLCDpKEiUCUNutIK8RzCbwRhCrXgOVT4HkIwBQyb8OOzkLcVBdLoIJcCtTEWGM/O6nesJq+UJuJmAnDZ8Yc4a3rbuKiD9mKABdi66+P9Uy1xrff/u9IoxAVAfDakdQ6rPG+7++oaXngeOcZOcGrQRMpxkyrABMI9Vw5klx+W8vGma2zqtbeno0IYZi2glDcdhsIQL/5fmBf+ZflajBSZ6CdOsp38Xh7gTEQGSiNLoZ/tQgDDsJAHBTrdi38eEHTacO9Z0f3FebymlmuNjz2i2Rl8nCsGNheTScrD96XablultKkzd+oTr109tNe+mtWu2rrxWfuyJZd8HvLGcBDrFzMaQoziLmagCwvelQKq6lGlc+Uxx+/PuGdfqD2dbrJv3S384pT070cu5XZNx/HDGYduKjjmku/XUUrgbpNMA7IKN1VzFjKBP6L74sRkYBmUNp6Llbxvc9c3u66aS93O7cP7Ljd8mgOLJPxSaa5q76QtOs5fcPb3/5xuGtG+4DrPv4N751J0w3h3TTktdtr6NYnvzP0+wUA1gShHqoKEatsOUy05n2oum09RH3oGUVQzueQlQrIztt8X+Y7tyfmtbssjbK4LYJw2hBHA6cWhq75UUy9rgyBlJ1t97hZj+4Roo8AAmChlY+8gc2IiiNQ8YB4qCMsDqJqDpR6Fhw1h0NPSvGvOysgu01rSbooVzHhzYn6o/aaljpvbbX/kYie8HzzGj4q199/qBpzTngOMsTGuHWTNP/uI0bTWA8BYCDG+a46TT9wbQ7d2koMJ6GV7f4NyoeGfEyS3cZdldNq/Ko6XTezgx3kFvtW0xn7hrLXrTeNE8Yl/I1yHgMprEIhLhClFmrdbyR83p42ZMRVXvbSWN/x5I7LjKtXBiXDySTTQs2Nc0++cJ06/zXtdY61dS1PtnYdgcxcztprfB+xq049qMvVYr/fodhz4SKm6CFi6AyBRUzNE2//ox089nPyHAEB7c80VGe3Dy7Y9HytcxcJ0zrRFPrppxfPHhMUOy9TESvnW2lpmClNoIZPZPZ3L4ckQ+ta+/SDkQexva8iPLIHphu6l0OyJ8aQqqxC02zV6Ba2A6/2Ida6S1wM0Zjz0XwMksAGAAE/OpqlEsPwUuciWT68/Crf4aTOAEiHEdU2QniGWg5jtL4SwgqIwwQqrH7SjiZeZDhICy3AyIeRFh7C6H/JpK5s0DEAQiY5gwQ60IQ3g8tAc4XQIRvIw6noEQI05oHL7sStck3IPw8Mu3nQAsfKhhEFElE1SkooaHiGMzwoIWGEgLG+xlCrQKkcp/4Doy3ncrkQ18jnQDgwLQbEIkSxvY+8LRhTzvXyy59rGnm6ar46itfHdxx01+aZmfzYW1URBUnFxRDU4QR3KwHjV4Qc5FteOQkAgAtQXAOg2tAiQiGaSLR0AbObYAArTVkXEO67WgoGWOi7yUoXUTk964Nypv2FEdfubzjyOvh1bVAyF6Y9nwkEp9EpfBrxLUhEEuiOvlXVKdegxYGHG8hQNQVlPc9HwcTq0y3tbeafwnl8Wdhp2ZCkw+oPJQYPxsq+Clj6TatlVRyL2B2AYhgWxeAKA2/9nv45RegZT1ErQJKpaB1CICDuIHS8F9guZ2wEq3Qfh9qEwcQ12pQsQK0CcPKINncA37bbV97L9O1ABDDcpe9yHgL90svrNDKgVYuOEshDqsoja4938vOfNOrm/Wmm+5+iHPdoWnj8XE4lBSBwSGTgHZANAg7HUbZph8vI7VyMxAzaNLQHNAMxGwExUGEpYOwvTowboAZNggaIAO57uMh4wkQS6Ku/SRwbm5wktPXtc66dtJJt8OvrAPjMVzvAlj2QpTz/xu1yssQwUGE1XdA5AGagZsNsOxpLXGYv0nJ6BfNs67PG1YWfmkzQFWkch+F5R4Nratj3GhabTlzRoil3sWC8U4Q2Yd4VLEPfukv0MKEVhqW0w43cxy08KFVBUqEsFM9MN1pYKRQGd99qLxZSUAqaA3UdR3xfzNdH77ZzruZmMrecCtUysr3f+cmxlwAJkynCbE/iaEdN6/J9Xz8Ki+78CfJhusvj6MT76xOvXCLL0ZWRSEaGDemErljfl/ffuE1pd5gieVuOiPRMu8ZLYLDd4oBWiCq5aHJhBSHp1ekwYwEjex5/KFEfc8NWk86UyNv3NXe8Knz8n1PrYzDvSOZaSv3RrU9d1YKT53gpIRgzNlkmSu/yLjXwI3mLkLiEGeuTIi4BlA8TJyXZVya9OqOHjCshllj/X/8sVaRE1X6jWphw5/STR+5I/S3t8bB7gstb/pXoLXSKkCsD4AZPWBUD62nMkH51w8oOTKNoV5LEQHcvToOhrdPDT3z26g20RZVyoaM2EO5GV0/Lo/tPrvQv+16rSzGeErISJv+5CTjdt2jh2v6/yvv1fipkTvvnRj49dWcTYcSHrQ2QCiAjAkkcp1rE/XLfmB7x6/RmiGq7UdUq8Cy28ANC/k9a3/CeH13y4JLztHK9w/P+kDEQYyhOjkIKcLDA4xDXk23Hnteue8xvzI6ZbuUNN1krmXWqpX9b92xi/Hw+dY5n/lyUPlbxXCCTxtuFDAz8Zhtndztl15ZHovCT6E9QHJoxRGHAbz0wjtMu+27+b7VfbmOz3RIoX9VGnl6VbJ+3pVxPDJPxn23p5tWmoblnBn4m5/MNF9uQENqnYeiAqAJGhoieuWKuPbm/bb7hXNFOKygPTBqemGq75nLRRx8v2X+1z8RFPYsze978rrOY65zhrY+PRqWJ/7kZnuerBUmH+fM+SIzM2FtIv8j4x8g/j4RyLZcck0cFhLFobWfJWoBiIPxBLjJENX2rZDy7RVO8ldDpme8BNb5Cjd6gqD8zvLCgQ0Xc2N2pWvZjS2Mu77W1rsvk4gjDgqQcRnETbw7AAFATKOubeEvhl745pOGGWH+yV87lzEDgB4m7ozaiZluHL7Rb3tLfmemmhD5f9lrOUcuF0KsVv7Wlxg1H2IEJYEZEbiVKykZt0FFxK0cuGknuZV5wq07YrUqlFaLEOfEwRAMa3pIZA1BA0QWiNWB4EIjRhxvh4h2ZW335J3J7GWPTRy8CkAS/lQvwsrB2Vai689ajD6aaVv66NTAy2dF5T4OqFJd+/yH63tWvLR//aPDDZ1zf1Y384Ro+5oHrvsXoAeQoohUw8pLRRDo0ujWS4licPdQn82NHBgVIcXuaRRNXiDlaxeEU/PgT4Tg1oLelrmXz2HcjQ4Bbf6dZRlXwQwXzHDeG0YTgZiDkb0vfG/m0i98zrDiusmB1+5rW3DuY1F1sIlFIqdEGdCiEzA4GJdKTsxkPJtOZD5WC/23alpHYORCE0BkQEZlkOZtxM02EY5BRnEo49KHuZE8yTAb5/hy4zFuevE0sKlYRAenARJC9EOIbcdptf9S0z72Ss7blGHOrMTRpnlTI9ceUZtao1Scg5M8dY+bnd8vwuKVlfyWVcWhTYug0WYmpiklN3cpGc2QcfCSCGutSsluEVQLWorp/wJ0glYhRDSOTPOHL3OSSzdP9v/pDhGOJMEUuKkBKBC5AAFKAoCBbNuFv7SchZcp+f5xnn7XZmnkbUz0vgI70QCt35u1EuOQInJEUN2Sapj5W8aFXRzbcrRWEo09n3ocqO7mZjbUWj8CUpogwFjiN1JO7bLdpUjXfwql8UehGQc0gbEsOMtA66hgWI2/j/yDPFl/wjfjoP++6sSmu0BKeJkjX7S8OfPA4rekqP2RG21ayjFI0T8Hav9lkjd83k18Vjn2aX+YGr/841Hw+oN28gQlAgW37oirGqZ/6K6xd36xuDy++d/jqs+b51z0v9y62Yqxp/5A3NpHYDBt91FivKShA27Zv/0XoB8GXoZQqCKVO/Y+w6r/o1988xIp+1YSH5tNrFBHrK7GWKbPdhe96rmn/slyFv81KO2HEtX/YgsAiiPvYOSddXAzrX+/SwxxWIs4T1wYVcfhZRsrlps7z7KzmH7Md28GgKi6E0qEFxAZIDJALHURHe4HLGceGE9CKwFoA8xIgxt1UKo2YtqN5xMRuenZb1tey0m220pKFHUcjcByZoF4HWx3+ScBwGE2DLPxQU3yQcZsMNYEovq8l7n6VJkYTWrBCFLBsLoibraFyYZjz61O7EKibhbSLYuhlYRpJz9tWAkww4LlJD/BLAdEBiwncdn/AYw6MEDPFpZRAAAAAElFTkSuQmCC",
                ReceiptInfoInputs = new List<BatchPortraitReceiptInfoDto>()
            };

            for (var i = 0; i < 500; i++)
                input.ReceiptInfoInputs.Add(new BatchPortraitReceiptInfoDto
                {
                    Amount = 22939.43M,
                    Grade = "2019秋",
                    IdNo = "43062619890622xxxx",
                    Name = "張三",
                    PaymentMethod = "微信支付",
                    Profession = "運動訓練",
                    Remark = "學費",
                    TradeStatus = "已完成",
                    TradeTime = DateTime.Now,
                    UppercaseAmount = "貳萬貳仟玖佰叄拾玖圓肆角叄分",
                    Code = "1907180000" + i
                });
            return input;
        }


        [HttpGet("Html")]
        [Magicodes(Type = typeof(ReceiptInfo), TemplatePath = ".//ExportTemplates//receipt.cshtml")]
        public ReceiptInfo Html()
        {
            return new ReceiptInfo
            {
                Amount = 22939.43M,
                Grade = "2019秋",
                IdNo = "43062619890622xxxx",
                Name = "張三",
                Payee = "湖南心萊信息科技有限公司",
                PaymentMethod = "微信支付",
                Profession = "運動訓練",
                Remark = "學費",
                TradeStatus = "已完成",
                TradeTime = DateTime.Now,
                UppercaseAmount = "貳萬貳仟玖佰叄拾玖圓肆角叄分",
                Code = "19071800001"
            };
        }

Reference

https://github.com/dotnetcore/Magicodes.IE

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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