TopGear主持人全程嚇尿!連英女王都要出來看他漂移

從地上出來之後,遇到一對新人結婚,兩人還摻了一腳,在新郎一臉懵逼之下再度絕塵而去,看他的表情一定是沒看過Topgear吧。接下來鏡頭又給到了兩人,Ken Block通過倫敦塔橋后鑽進了倫敦街頭藝術聖地Banksy Tunnel,眼尖的Matt看到了有人在噴STIG,這套路實在滿分。

距離Ken Block上一部大作已經過去了好一陣子了,對於很多車迷來說他的漂移表演必定是足夠震撼,也非常有個人風格。而最近,Topgear官方就推出了一條他在23季Topgear中的剪輯加長版,今天也讓大家先睹為快。

在片中,Ken Block先是裝在集裝箱內,被軍用運輸機運到目的地,然後開着座駕Hoonicorn Mustang破籠而出。

一路狂甩之下遇到了站在路邊無所事事的Topgear主持人Matt LeBlanc,然後把他兜上車,繼續絕塵而去。

一上車Matt LeBlanc就拿着本導遊手冊開始bb,Ken Block則一路狂漂,又是圍着火車轉,又是繞着拖頭漂,都是很典型的KenBlock戲碼。

隨後的路線就非常有衝擊力了,進入倫敦市中心后在大馬路上任性的跑,最後從升降機跑到地下通道,通過抄小道上演了一出火花四濺的飛車好戲。

從地上出來之後,遇到一對新人結婚,兩人還摻了一腳,在新郎一臉懵逼之下再度絕塵而去,看他的表情一定是沒看過Topgear吧。

接下來鏡頭又給到了兩人,Ken Block通過倫敦塔橋后鑽進了倫敦街頭藝術聖地Banksy Tunnel,眼尖的Matt看到了有人在噴STIG,這套路實在滿分。

兩人一路向白金漢官狂奔而去,雖然Matt一路叨叨讓Ken Block規矩點,但這很明顯是多餘的勸告。最後他們在警察的護送下到達白金漢官,一腳原地轟油轟出了英女王的橋段真是有點讓人尷尬。

至此全片進入尾聲,雖然Matt一再手賤要研究車內手剎上的紅按鈕是什麼東西,但最後Ken Block還是不太想鳥他 。然後直升機徐徐起飛,全片結束。

整個片子單獨剪輯過後確實更加緊湊精彩,所有橋段、鏡頭和路線的設定都是滿屏的Ken Block風格,雖說三賤的離去是沒法挽回了,但至少Topgear在製作 上還是保持了很高的水準。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家公司費用怎麼算?

汽車評測視頻居然是這樣拍出來的

而且AT變速器在換擋的時候因為有液力變矩器的原因,不會有動力中斷的感覺,雖然在換擋速度上和老款雙離合有差距,不過搭配了渦輪發動機后,前段扭矩比較充足,不需要作過多的降檔動作,所以日常開會覺得這套動力總成的平順感要由於老款。

很多網友都很好奇,我們的汽車節目是怎樣拍出來的,也很想知道,我們平時工作用什麼車。

除了平常每天評測拍攝的汽車外,我們還會拿到一些長期測試車輛做一些選題,因為有時候一款車好或不好,或者有沒有一些暗病小問題,不是在一天两天里能試出來的。最近我們視頻部拿了一台新福克斯EcoBoost 180來做長期測試車,看看在每天高強度使用的情況下,這台車的表現如何。

我們對工作車的訴求很簡單:動力好、操控佳、油耗低、空間夠用。也就是和大部分的車主需求一樣。

因為我們拍攝很大一部分內容都是性能車,所以拍攝車的性能必須要跟上,不然速度太慢的話鏡頭就顯得不夠動感;但同時每次拍攝又有油耗預算,相比起The Grand Tour 4000萬一集的預算,我們每一條評測只有200元的油費預算,超過的費用我們要自己補上。分享一下新福克斯這段時間開下來的感受。

動力:

除了幾家日系廠家還在堅持使用自然吸氣外,在這個級別里渦輪增壓已經成為主流。我們常說的動力好,其實除了加速外,更重要是動力的匹配。相比使用自然吸氣匹配雙離合變速器的老款,我更喜歡使用1.5T 發動機匹配6AT的新福克斯。因為新的變速器在換擋邏輯和頓挫表現要大大優於老款,簡單來說就是更聽話。給換擋指令的時候,雖然有一定的延時,但每次的時間基本上都是一樣的,所以會感覺這台發動機很可控。

而且AT變速器在換擋的時候因為有液力變矩器的原因,不會有動力中斷的感覺,雖然在換擋速度上和老款雙離合有差距,不過搭配了渦輪發動機后,前段扭矩比較充足,不需要作過多的降檔動作,所以日常開會覺得這套動力總成的平順感要由於老款。此外,更另外欣慰的是,手動換擋模式的按鈕從老款的檔把換到了方向盤上,覺得這才是一個合乎人類操作的位置。

油耗:

拿到車的時候,是廣東的秋冬季節,我們測得的平均油耗大概在8.7L左右,屬於可以接受的範圍。比較驚喜的是在激烈駕駛時油耗並不會升高太多,在外地賽車場跟拍一天後居然還剩下不少的燃油返回廣州。

空間:

由於經常需要運載不少的拍攝器材,所以兩廂的設計對於我們來說更實用。雖然後排乘坐空間不如一些實用型家轎,但福克斯後排座椅放倒后是一個平整的空間,更方便休息,而且也能放下我們的超長拍攝器材。

懸挂調教:

在市區的路況下懸挂的跳動顯得有點多,家用取向的消費者可能要考慮清楚。不過到了山路或者賽道就會覺得福克斯的動態很可控,車感很好。一台車的操控不在於能在彎中開多快,而是車輛和駕駛者的交流有多少。沒到極限的時候給予司機充足的信心,而將要到極限的時候透響胎等信號告訴駕駛者要減速,這就是所謂的人車交流。

與福克斯相處了一段時間后,覺得這車在各方面的表現都很平衡,非常適合對操控和動力有追求,但又要顧及一定實用性的車主。

作為性能控,現在我更想試試把2.3T EcoBoost發動機壓榨至350馬力的福克斯RS。

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價

中國自主品牌領跑者 長安汽車11月份銷量點評

其實CS15也瓜分CS35一部分銷量,因兩款車型車身尺寸基本相當,而長安CS15卻還要便宜,這也不能忽略自動擋車型的上市,也有效提高長安CS15銷量,畢竟現在城市路況,駕馭自動擋更加舒適而年輕消費群體也更愛自動擋車型。長安汽車-悅翔(系列)11月銷量:10263輛編者點評:悅翔系列與艾瑞澤5以及新遠景相比,悅翔過萬銷量並不算好,其實個人覺得長安不能把重點都放在SUV車型上,如果注重轎車一定會有另外一番作為,長安還是要拿出更多的誠意來打動消費者。

面對現今汽車市場,每個品牌都有所突破,而長安作為中國自主品牌領先者,也為中國車企做了個好榜樣,今年1-10月,長安品牌汽車銷售141.8萬輛,銷量位於自主品牌第一。

日前,長安汽車官方公布了2016年11月產銷快報,其中長安CS75銷量突破了2萬輛,逸動以及悅翔兩大橋車系列在11月份銷量也突破了一萬輛,具體銷量數據如下:

長安汽車-長安CS75

指導價:9.28-15.88萬

11月銷量:21978輛

編者點評:長安CS75面對榮威RX5以及吉利博越的熱銷,絲毫沒有影響其銷量,11月份銷量更是達到了21978輛,這也可以說明消費群體不同,長安CS75更實用外觀設計也偏沉穩。也不能忽略購置稅減半金融政策,臨近年底,也能刺激消費者購車慾望,而長安CS75也最大功臣莫過於1.5T車型,帶動着長安CS75銷量一路攀升。

長安汽車-長安CS35

指導價:7.89-9.89萬

11月銷量:13902輛

編者點評:長安CS35外觀設計比較個性,配置也豐富,底盤調教很紮實,舒適性表現還是相當不錯,長安CS35主要目標也是年輕消費者,而長安CS35面對哈弗H2、瑞風S3等強實力选手,瓜分市場群體銷量份額,這也讓長安CS35銷量下降了26%。

長安汽車-長安CS15

指導價:5.79-7.79萬

11月銷量:10430輛

編者點評:長安CS15可以說取得比較不錯成績,11月份銷量也終於突破了1萬輛。其實CS15也瓜分CS35一部分銷量,因兩款車型車身尺寸基本相當,而長安CS15卻還要便宜,這也不能忽略自動擋車型的上市,也有效提高長安CS15銷量,畢竟現在城市路況,駕馭自動擋更加舒適而年輕消費群體也更愛自動擋車型。

長安汽車-悅翔(系列)

11月銷量:10263輛

編者點評:悅翔系列與艾瑞澤5以及新遠景相比,悅翔過萬銷量並不算好,其實個人覺得長安不能把重點都放在SUV車型上,如果注重轎車一定會有另外一番作為,長安還是要拿出更多的誠意來打動消費者。

長安汽車-逸動

指導價:8.09-24.99萬

11月銷量:10571

編者點評:長安逸動本月銷量同比下跌33%,其實只要原因是,長安品牌車型,更新換代較慢、配置不夠豐富是逸動硬傷,或許長安應該學習下吉利,更新換代快,而且在配置上面是誠意滿滿,綜合實力強。但整體來說逸動綜合能力也不算差。

長安汽車-長安CX70

指導價:6.89-8.49萬

11月銷量:10125

編者點評:長安CX70自打銷量過萬,其一直維持在一萬輛左右的水平。銷量難以突破主要原因,還是因為這款車沒有配備自動車型,畢竟現在成熟路況駕馭自動擋會更舒適,就算是新手駕馭也不會手忙腳亂。其次還是自主品牌車型越來越多,競爭力也越來越強,9月份上市的東風風光580等車車型表現很有競爭力,而CX70面臨的壓力也越來越大,也希望長安能儘快推出自動擋車型,可能會有所改善。

全文總結:

其實在11月份,長安汽車旗下已經有8款車型銷量過萬,這個成績也相當不錯。但長安汽車品牌也不能鬆懈,畢竟競爭力會越來越大,反而長安應該更注重轎車市場,如果在轎車市場更注重,可能會有另一番作為。長安汽車接下來的銷量依然會面臨很大壓力。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※回頭車貨運收費標準

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

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

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

7500億歐元振興案 梅克爾籲歐盟7月底前達協議

摘錄自2020年6月18日中央社報導

德國總理梅克爾今(18日)敦促歐洲聯盟在7月底前,針對7500億歐元(8430億美元)振興方案達成協議,重振受武漢肺炎(COVID-19)疫情重創的歐洲經濟。

歐洲聯盟執行委員會(European Commission)主席范德賴恩提議(Ursula von der Leyen)設立這筆巨額基金,幫助歐盟走出有史以來最嚴重經濟衰退,但她的計畫立即遭到奧地利和荷蘭等財政立場保守成員國強烈反對。提議的振興方案內容包括援助款項5000億歐元和貸款2500億歐元,但需要歐盟成員國無異議通過。

歐洲理事會(European Council)預定6月19日舉行視訊峰會,討論這項引發爭議振興方案,這也是歐盟迄今規模最大經濟振興方案。不過,梅克爾表示,在歐盟各國領導人面對面會談前,預料不會做出決定。德國將於7月接掌歐盟輪值主席國。

國際新聞
歐洲
振興經濟
武漢肺炎
疫情
救經濟靠綠色振興

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家公司費用怎麼算?

疫情改變通勤方式 雅加達自行車需求看漲

摘錄自2020年06月21日中央通訊社印尼報導

受武漢肺炎疫情影響,可健身又可避開大眾運輸人潮的自行車成為通勤最佳選擇。雅加達省政府指出,疫情後自行車族增加,兩大主要幹道每天固定時段都會隔出臨時自行車道。

印尼第一大報羅盤報(Kompas)19日報導,雅加達使用中的自行車道只有25公里,仍在計劃、施工、驗收中的自行車道有63公里。雅加達自6月初逐漸鬆綁為控制2019冠狀病毒疾病(COVID-19,武漢肺炎)疫情實施的管制措施,民眾陸續恢復上班。

雅加達省政府交通局長夏孚林(Syafrin Liputo)指出,雅加達省政府近日已開始與警方合作,每天固定時段會在雅加達中區的蘇迪爾曼大道(Sudirman)和塔林大道(Thamrin)兩條主要幹道,使用路錐,隔出臨時自行車道,方便自行車族使用,全長約14公里。

自行車業者表示,疫情初期業績暴跌,最近業績突然成長,賣最好的是折疊式腳踏車,因為民眾勤於運動,需求大增,他要向供應商調貨也遇到供貨吃緊的問題。

生活環境
能源轉型
國際新聞
印尼
雅加達
自行車
武漢肺炎
疫情下的食衣住行
交通運輸

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

【其他文章推薦】

※回頭車貨運收費標準

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

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

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

深度學習在高德ETA應用的探索與實踐

1.導讀

駕車導航是数字地圖的核心用戶場景,用戶在進行導航規劃時,高德地圖會提供給用戶3條路線選擇,由用戶根據自身情況來決定按照哪條路線行駛。

同時各路線的ETA(estimated time of arrival,預估到達時間)會直接显示給用戶,這是用戶關心的核心點之一。用戶給定起點和終點后,我們的任務是預測起終點的ETA,ETA的準確率越高,給用戶帶來的出行體驗越好。

2.基於深度學習模型的探索和實踐

2.1模型選擇

傳統機器學習模型在ETA中,比較常用的有線性回歸、RF(隨機森林)、GBDT(梯度提升決策樹)等回歸預測類模型。線性模型表達能力較差,需要大量特徵工程預先分析出有效的特徵;RF通過樣本隨機和特徵隨機的方式引入更多的隨機性,解決了決策樹泛化能力弱的問題;GBDT是通過採用加法模型(即基函數的線性組合),以及不斷減小訓練過程產生的殘差來達到回歸的算法。

傳統機器學習模型相對簡單易懂,也能達到不錯的效果,但存在兩個問題:

  • 模型的表達能力跟選取的特徵有關,需要人工事先分析出有效的特徵。
  • 沒有考慮上游對下游路段的影響,產生了如丟失上下游關聯信息、下游受上游影響導致的不確定性等問題。

第一個問題很好理解,深度學習模型能很好地彌補這方面。針對第二個問題,以歷史速度信息選取存在的不確定性為例來說明一下,歷史速度信息是一個區分周一到周日七個工作日、10分鐘間隔的歷史平均時間,可以根據該路段的預計進入時間所在10分鐘區間來選定。如下圖(歷史平均速度)從0:00-24:00的變化曲線,可以看到一天中特別是早晚高峰,速度值存在較大波動。

而在選取歷史平均時間時,依賴的是預計進入時間,這個時間依賴於上游路段的預計通行時間,因此其選取存在不確定性,進而導致ETA計算不準確。

考慮到以上問題的存在,我們選擇利用RNN的時間序列思想將路線中上下游路段串聯起來進行路段ETA的預測。

另外考慮到RNN存在的長依賴問題,且結合實際業務情況,我們選擇使用LSTM模型來進行建模,LSTM的門結構具有的選擇性還能讓模型自行學習選擇保留哪些上游的特徵信息進行預測。

2.2網絡架構

上圖為整個模型的框架圖,主要分為兩部分,使用LSTM模塊對路線中的路段ETA的預測和最終使用N層全連接模塊對累計路段ETA及路線各特徵進行完整路線的ETA預測。

2.3路段ETA預測

上圖為各路段ETA預測使用的LSTM結構圖,Xt為路線中第t個路段的特徵信息,主要包含對應的實時路況信息、歷史路況信息、路段的靜態特徵等。

LSTM本是輸入時間序列數據的模型,我們利用該思想,將路線中各路段序列依次輸入模型。

2.4完整路線ETA預測

在LSTM模塊得到累計路線ETA預測值后,結合該路線的靜態屬性,使用全連接模塊將其整合成最終輸出的完整路線ETA預測值。

路線的屬性特徵主要指一些人工提取的特徵,如該路線的長度、導航規劃發起特徵日、是否早晚高峰時段等,用以加強模型在不同場景下的表達能力。

損失函數選用線性回歸常用的平方形式:MSE,公式如下:

其中,N是路線數量,ETA路線j為路線ETA,即預測值;用戶實走j為用戶在該路線的實走時間,即真值。

3.模型效果

衡量模型效果,即路線上ETA的預測值時,主要考慮的是準確率。一般情況下,用戶對ETA偏長和偏短的容忍度不同,對偏長容忍度更高。比如用戶要去機場,ETA給的時間偏短10分鐘比偏長10分鐘對用戶的損害更大。因此準確度的指標設計傾向於ETA偏長,定義為滿足用戶一定容忍範圍的請求比例,即準確率作為主要衡量指標。

在北京市上的實驗結果显示,ETA準確率得到提升,MSE loss下降比例28.2%,效果有了明顯的提升。

4.小結

本文介紹了引入深度學習模型,幫助建模導航規劃的預估到達時間預測,成功解決了線性模型的不足,也為後續引入更多特徵、進行更多探索打開了空間,如歷史速度信息的不確定度、時效性、周期性、突發事件、路網結構等。

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

※推薦台中搬家公司優質服務,可到府估價

Rust異步之Future

對異步的學習,我們先從Future開始,學習異步的實現原理。等理解了異步是怎麼實現的后,再學習Rust異步編程涉及的2個庫(futures、tokio)的時候就容易理解多了。

Future

rust中Future的定義如下,一個Future可以理解為一段供將來調度執行的代碼。我們為什麼需要異步呢,異步相比同步高效在哪裡呢?就是異步環境下,當前調用就緒時則執行,沒有就緒時則不等待任務就緒,而是返回一個Future,等待將來任務就緒時再調度執行。當然,這裏返回Future時關鍵的是要聲明事件什麼時候就緒,就緒后怎麼喚醒這個任務到調度器去調度執行。

#[must_use = "futures do nothing unless you `.await` or poll them"]
#[lang = "future_trait"]
pub trait Future {  // A future represents an asynchronous computation.
    type Output;
    /* The core method of future, poll, attempts to resolve the future into a final value. This method does not block if the value is not ready. Instead, the current task is scheduled to be woken up when it's possible to make further progress by polling again. */ 
    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>;
}

可以看到執行后的返回結果,一個是就緒返回執行結果,另一個是未就緒待定。

#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
pub enum Poll<T> {
    Ready(T),
    Pending,
}

可能到這裏你還是雲里霧裡,我們寫一段代碼,幫助你理解。完整代碼見:future_study

use futures;
use std::{future::Future, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll, Waker}, thread, time::Duration};

fn main() {
    // 我們現在還沒有實現調度器,所以要用一下futues庫里的一個調度器。
    futures::executor::block_on(TimerFuture::new(Duration::new(10, 0)));    
}

struct SharedState {
    completed: bool,
    waker: Option<Waker>,
}

// 我們想要實現一個定時器Future
pub struct TimerFuture {
    share_state: Arc<Mutex<SharedState>>,
}

// impl Future trait for TimerFuture.
impl Future for TimerFuture {
    type Output = ();
    // executor will run this poll ,and Context is to tell future how to wakeup the task.
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut share_state = self.share_state.lock().unwrap();
        if share_state.completed {
            println!("future ready. execute poll to return.");
            Poll::Ready(())
        } else {
            println!("future not ready, tell the future task how to wakeup to executor");
            // 你要告訴future,當事件就緒后怎麼喚醒任務去調度執行,而這個waker根具體的調度器有關
            // 調度器執行的時候會將上下文信息傳進來,裏面最重要的一項就是Waker
            share_state.waker = Some(cx.waker().clone());
            Poll::Pending
        }
    }
}

impl TimerFuture {
    pub fn new(duration: Duration) -> Self {
        let share_state = Arc::new(Mutex::new(SharedState{completed:false, waker:None}));
        let thread_shared_state = share_state.clone();
        thread::spawn(move || {
            thread::sleep(duration);
            let mut share_state = thread_shared_state.lock().unwrap();
            share_state.completed = true;
            if let Some(waker) = share_state.waker.take() {
                println!("detect future is ready, wakeup the future task to executor.");
                waker.wake()    // wakeup the future task to executor.
            }
        });

        TimerFuture {share_state}
    }
}

執行結果如下:

future not ready, tell the future task how to wakeup to executor
detect future is ready, wakeup the future task to executor.
future ready. execute poll to return.

可以看到,剛開始的時候,定時10s事件還未完成,處在Pending狀態,這時要告訴這個任務後面就緒后怎麼喚醒去調度執行。等10s后,定時事件完成了,通過前面的設置的Waker,喚醒這個Future任務去調度執行。這裏,我們看一下ContextWaker是怎麼定義的:

/// The `Context` of an asynchronous task.
///
/// Currently, `Context` only serves to provide access to a `&Waker`
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Context<'a> {
    waker: &'a Waker,
    // Ensure we future-proof against variance changes by forcing
    // the lifetime to be invariant (argument-position lifetimes
    // are contravariant while return-position lifetimes are
    // covariant).
    _marker: PhantomData<fn(&'a ()) -> &'a ()>,
}

// A Waker is a handle for waking up a task by notifying its executor that it is ready to be run.
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
    waker: RawWaker,
}

現在你應該對Future有新的理解了,上面的代碼,我們並沒有實現調度器,而是使用的futures庫中提供的一個調度器去執行,下面自己實現一個調度器,看一下它的原理。而在Rust中,真正要用的話,還是要學習tokio庫,這裏我們只是為了講述一下實現原理,以便於理解異步是怎麼一回事。完整代碼見:future_study, 關鍵代碼如下:

use std::{future::Future, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll, Waker}, thread, time::Duration};
use std::sync::mpsc::{sync_channel, SyncSender, Receiver};
use futures::{future::{FutureExt, BoxFuture}, task::{ArcWake, waker_ref}};

use super::timefuture::*;

pub fn run_executor() {
    let (executor, spawner) = new_executor_and_spawner();
    // 將Future封裝成一個任務,分發到調度器去執行
    spawner.spawn( async {
        let v = TimerFuture::new(Duration::new(10, 0)).await;
        println!("return value: {}", v);
        v
    });

    drop(spawner);
    executor.run();
}

fn new_executor_and_spawner() -> (Executor, Spawner) {
    const MAX_QUEUE_TASKS: usize = 10_000;
    let (task_sender, ready_queue) = sync_channel(MAX_QUEUE_TASKS);
    (Executor{ready_queue}, Spawner{task_sender})
}

// executor , received ready task to execute.
struct Executor {
    ready_queue: Receiver<Arc<Task>>,
}

impl Executor {
    // 實際運行具體的Future任務,不斷的接收Future task執行。
    fn run(&self) {
        let mut count = 0;
        while let Ok(task) = self.ready_queue.recv() {
            count = count + 1;
            println!("received task. {}", count);
            let mut future_slot = task.future.lock().unwrap();
            if let Some(mut future) = future_slot.take() {
                let waker = waker_ref(&task);
                let context = &mut Context::from_waker(&*waker);
                if let Poll::Pending = future.as_mut().poll(context) {
                    *future_slot = Some(future);
                    println!("executor run the future task, but is not ready, create a future again.");
                } else {
                    println!("executor run the future task, is ready. the future task is done.");
                }
            }
        }
    }
}

// 負責將一個Future封裝成一個Task,分發到調度器去執行。
#[derive(Clone)]
struct Spawner {
    task_sender: SyncSender<Arc<Task>>,
}

impl Spawner {
    // encapsul a future object to task , wakeup to executor.
    fn spawn(&self, future: impl Future<Output = String> + 'static + Send) {
        let future = future.boxed();
        let task = Arc::new(Task {
            future: Mutex::new(Some(future)),
            task_sender: self.task_sender.clone(),
        });
        println!("first dispatch the future task to executor.");
        self.task_sender.send(task).expect("too many tasks queued.");
    }
}

// 等待調度執行的Future任務,這個任務必須要實現ArcWake,表明怎麼去喚醒任務去調度執行。
struct Task {
    future: Mutex<Option<BoxFuture<'static, String>>>,
    task_sender: SyncSender<Arc<Task>>,
}

impl ArcWake for Task {
    // A way of waking up a specific task.
    fn wake_by_ref(arc_self: &Arc<Self>) {
        let clone = arc_self.clone();
        arc_self.task_sender.send(clone).expect("too many tasks queued");
    }
}

運行結果如下:

first dispatch the future task to executor.     
received task. 1                                
future not ready, tell the future task how to wakeup to executor
executor run the future task, but is not ready, create a future again.
detect future is ready, wakeup the future task to executor.     
received task. 2
future ready. execute poll to return.
return value: timer done.
executor run the future task, is ready. the future task is done.

第一次調度的時候,因為還沒有就緒,在Pending狀態,告訴這個任務,後面就緒是怎麼喚醒該任務。然後當事件就緒的時候,因為前面告訴了如何喚醒,按方法喚醒了該任務去調度執行。其實,在實際應用場景中,難的地方還在於,你怎麼知道什麼時候事件就緒,去喚醒任務,我們很容易聯想到Linux系統的epoll,tokio等底層,也是基於epoll實現的。通過epoll,我們就能方便的知道事件什麼時候就緒了。

參考資料

主要學習資料如下:

  • Asynchronous Programming in Rust
  • Futures Explained in 200 Lines of Rust
  • 200行代碼講透RUST FUTURES

上面的文章主要是學習異步的實現原理,理解異步是怎麼實現的,而進行Rust異步編程時的具體實現,則主要依賴下面2個庫:

  • future —— 主要完成了對異步的抽象
  • tokio —— 異步Future運行時

學習這兩個庫的時候,一定要注意版本問題,這兩個庫最近變化的比較快,一定要學最新的。

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家公司費用怎麼算?

ELK的踩坑之旅

前言

起源
許多年前,一個剛結婚的名叫 Shay Banon 的失業開發者,跟着他的妻子去了倫敦,他的妻子在那裡學習廚師。 在尋找一個賺錢的工作的時候,為了給他的妻子做一個食譜搜索引擎,他開始使用 Lucene 的一個早期版本。
直接使用 Lucene 是很難的,因此 Shay 開始做一個抽象層,Java 開發者使用它可以很簡單的給他們的程序添加搜索功能。 他發布了他的第一個開源項目 Compass。
後來 Shay 獲得了一份工作,主要是高性能,分佈式環境下的內存數據網格。這個對於高性能,實時,分佈式搜索引擎的需求尤為突出, 他決定重寫 Compass,把它變為一個獨立的服務並取名 Elasticsearch。
第一個公開版本在2010年2月發布,從此以後,Elasticsearch 已經成為了 Github 上最活躍的項目之一,他擁有超過300名 contributors(目前736名 contributors )。 一家公司已經開始圍繞 Elasticsearch 提供商業服務,並開發新的特性,但是,Elasticsearch 將永遠開源並對所有人可用。
據說,Shay 的妻子還在等着她的食譜搜索引擎…​

設計思路如下

有3台機器

2台做elasticsearch的主副節點

1台做kibana和elasticsearch_head 由於機器匱乏我還在這台機器上部署了logstash和nginx服務(雖然下面的架構中都提到了redis等緩存,但是暫時沒有加該服務,後期會研究添加上的)

先說目的:將nginx的日誌通過logstash收集后發送到ela,然後kibana進行展示

環境如下
elasticsearch master 10.5.2.175:9200
elasticsearch salve 10.5.2.176:9200
logstash 172.17.211.153 啟動命令: nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/config/agent.conf -w 10 -l /usr/local/logstash/logs/logstash-plain.log &
nginx 
es-head: 172.16.211.143:9100
kibana: 172.16.211.143:5601

架構如下:

加redis/kafa的原因:

在生產環境中,我們的日誌可能會有瞬時高峰,而這個時候如果直接存入es,可能會導致es承受不住,從而影響日誌的收集和查詢。 一般情況下,我們會將日誌存直接放到kafka或者redis這種讀寫性能非常高的應用中,作為一個緩存,然後通過下游組件(例如logstash)進行消費、過濾后存入ES,然後通過可視化界面查看。

ELK的工作流程

  • logstash客戶端收集到日誌后將日誌存入到redis之類的緩存中
  • Logstash_server將數據從redis中提取出來並根據/usr/local/logstash/patterns下的文件(文件名隨意取)這裏叫grok-patterns裏面根據不同的日誌,比如apache、nginx服務規定的不同格式來進行切割,切割完畢后將日誌存入到elastaicsearch中,格式裏面的key vlaue值就是els中的字段和值
  • elastaicsearch對logstash_server發送過來的值進行集群保存,提供被調用接口以及快速的搜索服務(這裏還可以安裝分詞插件,當做搜索引擎)
  • kibana對es根據條件進行搜索並對搜索到的數據進行展示,使我們看起來更加直觀。

一、elasticsearch

Elasticsearch 是一個開源的搜索引擎,建立在一個全文搜索引擎庫 Apache Lucene™ 基礎之上。 Lucene 可以說是當下最先進、高性能、全功能的搜索引擎庫—無論是開源還是私有。
中文文檔https://www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html#intro

elasticsearch的安裝

具體安裝可以參考https://www.cnblogs.com/yanjieli/p/11187430.html這個教程,這裏直說下配置和思路,首先懂思路,安裝看教程就行。

需要有jdk環境
vim /etc/elasticsearch/jvm.options
2g
2g

1.vim /etc/elasticsearch/elasticsearch.yml
http.port: 9200
discovery.zen.ping.unicast.hosts: ["10.5.2.175","10.5.2.176"]
network.host: 10.5.2.175

2.vim /etc/systemd/system.conf
DefaultLimitNOFILE=65536
DefaultLimitNPROC=32000
DefaultLimitMEMLOCK=infinity

3.vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
* soft nproc 32000
* hard nproc 32000
* hard memlock unlimited
* soft memlock unlimited

4.vim /etc/sysconfig/elasticsearch
JAVA_HOME=/usr/java/jdk1.8.0_151

5.vim /usr/lib/systemd/system/elasticsearch.service
[Service]
LimitMEMLOCK=infinity

elasticsearch的問題

啟動elasticsearch失敗,報找不到JAVA環境,可明明系統是有的 解決方法如下:

vim /etc/sysconfig/elasticsearch
JAVA_HOME=/usr/java/jdk1.8.0_151

elasticsearch的概念

index 索引 相當於數據庫里的“數據庫” 他是我們存儲和索引關聯數據的地方

type 類數據 將一類的數據放到一起 相當於數據庫中的“表”

id 相當於數據庫表中的一行

  • Elastic 本質上是一個分佈式數據庫,允許多台服務器協同工作,每台服務器可以運行多個 Elastic 實例。單個 Elastic 實例稱為一個節點(node)。一組節點構成一個集群(cluster)。

  • Elastic 會索引所有字段,經過處理后寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。

    倒排索引(反向索引)

    原始文檔

    創建倒排索引列表

    倒排索引創建索引的流程:

    1) 首先把所有的原始數據進行編號,形成文檔列表

    2) 把文檔數據進行分詞,得到很多的詞條,以詞條為索引。保存包含這些詞條的文檔的編號信息。

    搜索的過程:

    當用戶輸入任意的詞條時,首先對用戶輸入的數據進行分詞,得到用戶要搜索的所有詞條,然後拿着這些詞條去倒排索引列表中進行匹配。找到這些詞條就能找到包含這些詞條的所有文檔的編號。

    然後根據這些編號去文檔列表中找到文檔

  • 所以,Elastic 數據管理的頂層單位就叫做 Index(索引)。它是單個數據庫的同義詞。每個 Index (即數據庫)的名字必須是小寫。

下面的命令可以查看當前節點的所有 Index。

$ curl -X GET 'http://localhost:9200/_cat/indices?v

index 索引 相當於數據庫里的“數據庫” 他是我們存儲和索引關聯數據的地方

type 類數據 將一類的數據放到一起 相當於數據庫中的“表”

id 相當於數據庫表中的一行

pertty 在網頁中格式化輸出響應內容

elasticsearch的操作方法

官方教程在這裏,我覺得這個更加實用官方教程 https://www.cnblogs.com/chuyuan/p/11380744.html

# 增加
http://10.5.103.176:9200/database1/table1 

{
  "name": "doudou",
  "age": 4.5,
  "weight": 20,
}

# 查詢

# 以上方法是正確的
但是再增加一個table2的是否發生如下報錯
http://10.5.103.176:9200/database1/table2
{
  "name": "dianche1",
   "weight": 1000
}

原因是elastic search在6.x版本調整了, 一個index只能存儲一種type。

GET /atguigu/_mapping
1. 檢索文檔
Mysql : select * from user where id = 1
ES : GET /atguigu/doc/1
響應結果
{
  "_index" :   "megacorp",
  "_type" :    "employee",
  "_id" :      "1",
  "_version" : 1,
  "found" :    true,
  "_source" :  {
      "first_name" :  "John",
      "last_name" :   "Smith",
      "age" :         25,
      "about" :       "I love to go rock climbing",
      "interests":  [ "sports", "music" ]
  }
}

2.簡單檢索
Mysql : select * from user
ES : GET /megacorp/employee/_search

3.全文檢索
ES : GET /megacorp/employee/_search?q=haha
查詢出所有文檔字段值為haha的文檔

4.搜索(模糊查詢)
ES : GET /megacorp/employee/_search?q=hello
查詢出所有文檔字段值分詞后包含hello的文檔

5.聚合
PUT atguigu/_mapping/doc
{ 
  "properties": { 
    "interests": { 
      "type": "text", 
      "fielddata": true 
      } 
  }
}

elasticsearch-head的安裝

ealsticsearch只是後端提供各種api,那麼怎麼直觀的使用它呢?elasticsearch-head將是一款專門針對於elasticsearch的客戶端工具,是es的集群管理工具、數據可視化、增刪改查工具。相關詳細的教程在這裏
1 https://www.sojson.com/blog/85.html
2 https://www.cnblogs.com/xuwenjin/p/8792919.html
3 https://blog.csdn.net/huwei2003/article/details/40581143

一、下載head插件
https://github.com/mobz/elasticsearch-head

二、解壓到任意目錄
注意:為避免找不到,一定要和elasticsearch的安裝目錄區分開

三、安裝Node.js
因為head是一個Node.js項目。所以,如果沒有安裝nodejs需要先安裝Node.js
32位安裝包下載地址: https://nodejs.org/dist/v4.4.3/node-v4.4.3-x86.tar.gz
64位安裝包下載地址: https://nodejs.org/dist/v4.4.3/node-v4.4.3-x64.tar.gz
檢測PATH環境變量是否配置了Node.js,打開命令行輸入命令"which npm",輸出如下結果:
/usr/bin/npm
wget https://nodejs.org/dist/latest-v8.x/node-v8.16.0.tar.gz
tar xf node-v8.16.0.tar.gz
cd node-v8.16.0
./configure --prefix=/usr/local/node-v8.16
make -j 8 && make install
添加環境變量
vim /etc/profile
################nodejs###############
export NODE_HOME=/usr/local/node-v8.16
export PATH=$PATH:$NODE_HOME/bin
source /etc/profile
node -v
v8.16.0
npm -v
6.4.1

四、安裝npm 
yum install npm -y

五、es-head安裝:
解壓源碼包:elasticsearch-head.tar.gz
啟動:cd /usr/local/src/elasticsearch-head
npm run start &
訪問地址是http://{你的ip地址}:9200/_plugin/head/
在瀏覽器中輸入:這台機器的ip+端口
http://10.5.2.220:9100/

問題解決:

在elasticsearch中沒有當天的索引

頭一天使用過的bj日誌第二天無法收集到,原因是昨天logstash已經收集過一遍,就被打過了標籤,今天再使用的話,如果這個日誌是不再增加的就不會被收集,因為日誌中沒有新的內容進來,解決方法如下:

在logstash的config文件下的agent.conf加入以下配置
start_position =>"beginning"#檢查時間戳

二、kibana

語言設置

vim config/kibana.yml
i18n.locale: "en" 或者zh-CN中文
systemctl restart kibana重啟即可

安裝配置

重新加載systemctl配置,這個是針對centos7以上使用systemctl kibana restart命令的

systemctl daemon-reload

這裏由於是二進制的安裝方法,所以要設置一個systemctl start kibana.service的啟動方法

1. vim /usr/lib/systemd/system/kibana.service
添加以下內容
[Unit]
Description=Kibana
After=network.target

[Service]
ExecStart=/usr/local/kibana/bin/kibana
Type=simple
PIDFile=/usr/local/kibana/kibana.pid
Restart=always
#User=es 這裏我直接使用root用戶進行啟動
#Group=es
[Install]
WantedBy=default.target

2. 重新加載一下配置文件
systemctl daemon-reload

3. 啟動
systemctl start kibana.service

4. 訪問測試
http://10.5.2.220:5601

查詢語法

參考地址1 參考地址2 參考地址3https://blog.csdn.net/u013958257/article/details/88567581

kibana查詢語法基於Lucene

Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。Lucene的目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程式接口,能夠做全文索引和搜尋。在Java開發環境里Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java信息檢索程序庫。人們經常提到信息檢索程序庫,雖然與搜索引擎有關,但不應該將信息檢索程序庫與搜索引擎相混淆。
Lucene最初是由Doug Cutting開發的,在SourceForge的網站上提供下載。在2001年9月作為高質量的開源Java產品加入到Apache軟件基金會的 Jakarta家族中

kibana在ELK陣營中用來查詢展示數據
elasticsearch構建在Lucene之上,過濾器語法和Lucene相同

1. 根據某個字段查詢
精確匹配: agent:"Mozilla/5.0"
如果不帶雙引號,只要包含指定值就可以搜索到 agent:Mozilla/5.0
如果是數值類型沒有以上區別

2. 數組範圍查詢
[7758794 TO 7758794] 表示等於,原意思是一個區間範圍
指定區間: response:[100 TO 200]
大於等於指定數值的: response:[201 TO *]
小於等於指定數值的: response:[* TO 200]

3. 從指定時間到現在/或者查詢指定時間前數據
2015-05-20T09:20:41.943Z之後的數據: @timestamp:{2015-05-20T09:20:41.943Z TO *}
2015-05-20T09:20:41.943Z之前的數據: @timestamp:{* TO 2015-05-20T09:20:41.943Z }
指定時間範圍: @timestamp:{2015-05-20T09:20:41.943Z TO 015-05-22T09:20:41.943Z}
備註:09:20:41事實上是17:20:41,存在8個小時差

4. 正則匹配
包含指定值: request:/uploads*/
不包含指定值: !request:/uploads*/

5. 邏輯查詢
AND(與關係數據庫一樣) request:/uploads*/ AND response:404
OR(與關係數據庫一樣) request:/uploads*/ OR response:200
組合查詢: (uid OR token) AND version

6. 存在/不存在
存在host字段但不存在url字段: _exists_:host AND _missing_:url
特殊轉義字符
+ – && || ! () {} [] ^” ~ * ? : \

kibana創建索引模式(手動)

https://blog.csdn.net/weixin_34727238/article/details/81540692

當在els中有了當天的索引,就可以到kibana中取創建索引模式了,只是這裏提供了一手動創建的方式,無法自動進行,需要本地定義腳本的方式進行自動索引的創建。

等所有索引都創建完畢后,在下面就能看到了

然後在下面這個裡面就能看到我們的索引裏面的數據情況了,前提是你的logstash成功將切割后的日誌發送到了els中

否則就是以下這種的

kibana創建索引模式(自動)

由於logstash客戶端運行的問題,只要有當天日誌產生,就會將該日誌發送給elasticsearch,然後會在elasticsearch裏面產生一個新的索引

方法如下:

在kibana節點上寫一個腳本,然後設置定時任務執行kibana中索引與elasticsearch的關聯
vim /usr/local/scripts/kibana_create_index.sh
#!/bin/bash
today=`date +%Y-%m-%d`
index_name="nginx-log-${today}.log"
curl -X POST -H "kbn-xsrf:reporting" -H "Content-Type: application/json"  -d  '{"attributes":{"title":"'$log_name'"}}'  'http://172.16.211.143:5601/api/saved_objects/index-pattern'

這裏遇到一個問題,json中調用變量的問題,一直調用不到,後來各種查詢原來是格式不對

json數據里變量要用''括起來
<font color=gray size=72>color=gray</font>

json數據里變量要用”括起來https://www.cnblogs.com/landhu/p/7048255.html

ELK 索引生命周期管理

問題解決

Kibana server is not ready yet出現的原因

第一點:KB、ES版本不一致(網上大部分都是這麼說的)

解決方法:把KB和ES版本調整為統一版本

第二點:kibana.yml中配置有問題(通過查看日誌,發現了Error: No Living connections的問題)

解決方法:將配置文件kibana.yml中的elasticsearch.url改為正確的鏈接,默認為: http://elasticsearch:9200

改為http://自己的IP地址:9200

第三點:瀏覽器沒有緩過來

解決方法:刷新幾次瀏覽器。

終極解決方法:在elasticsearch中刪除kibana的相關索引,只是再打開kibana看不到其他了之前創建的圖形什麼的了

kibana可以做哪些分析

分析的必要性:頂級

  • 用戶分佈
  • PV、UV
  • 狀態碼
  • 訪問時間

更多圖形看這裏https://www.cnblogs.com/hanyifeng/p/5860731.html

比較牛逼一點的教程看這裏https://www.bilibili.com/video/BV1TE411A77i?p=6

三、logstash

logstash和filebeat的對比

Filebeat是收集日誌的另外一種方式,二者區別在於以下

Filebeat用於日誌收集和傳輸,相比Logstash更加輕量級和易部署,對系統資源開銷更小,日誌流架構的話,Filebeat適合部署在收集的最前端,Logstash相比Filebeat功能更強,可以在Filebeat收集之後,由Logstash進一步做日誌的解析,至於kafka也可以考慮添加,然後收集的數據都存放在elasticsearch中。

  1. logstash和filebeat都是可以作為日誌採集的工具,目前日誌採集的工具有很多種,如fluentd, flume, logstash,betas等等。甚至最後我決定用filebeat作為日誌採集端工具的時候,還有人問我為什麼不用flume,logstash等採集工具。
  2. logstash出現時間要比filebeat早許多,隨着時間發展,logstash不僅僅是一個日誌採集工具,它也是可以作為一個日誌搜集工具,有豐富的input|filter|output插件可以使用。常用的ELK日誌採集方案中,大部分的做法就是將所有節點的日誌內容上送到kafka消息隊列,然後使用logstash集群讀取消息隊列內容,根據配置文件進行過濾。上送到elasticsearch。logstash詳細信息可前往https://www.elastic.co/
  3. logstash是使用Java編寫,插件是使用jruby編寫,對機器的資源要求會比較高,網上有一篇關於其性能測試的報告。之前自己也做過和filebeat的測試對比。在採集日誌方面,對CPU,內存上都要比前者高很多。LogStash::Inputs::Syslog 性能測試與優化
  4. filebeat也是elastic.公司開發的,其官方的說法是為了替代logstash-forward。採用go語言開發。代碼開源。elastic/beats filebeat是beats的一個文件採集工具,目前其官方基於libbeats平台開發的還有Packetbeat, Metricbeat, Winlogbeat。filebeat性能非常好,部署簡單。是一個非常理想的文件採集工具。我自己採集工具也是基於beats源碼進行的二次開發。

https://blog.csdn.net/m0_38120325/article/details/79072921

自動創建elasticsearch的索引

在logstash客戶端的配置文件中會有這麼一個配置文件

就是會將日誌發送到當天日期的索引匯總,沒有的話自動創建索引,我們只需要做的就是每日刪除舊的索引。

电子書教程推薦:http://doc.yonyoucloud.com/doc/logstash-best-practice-cn/get_start/introduction.html

啟動方法 基於最基礎的 nohup 方式
nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/conf/agent.conf &> /dev/null

也可以用daemontools來進行管理
安裝
yum -y install supervisord --enablerepo=epel
在 /etc/supervisord.conf 配置文件里添加內容,定義你要啟動的程序:
[program:elkpro_1]
environment=LS_HEAP_SIZE=5000m
directory=/opt/logstash
command=/opt/logstash/bin/logstash -f /etc/logstash/pro1.conf --pluginpath /opt/logstash/plugins/ -w 10 -l /var/log/logstash/pro1.log
[program:elkpro_2]
environment=LS_HEAP_SIZE=5000m
directory=/opt/logstash
command=/opt/logstash/bin/logstash -f /etc/logstash/pro2.conf --pluginpath /opt/logstash/plugins/ -w 10 -l /var/log/logstash/pro2.log

然後啟動 service supervisord start 即可。
logstash 會以 supervisord 子進程的身份運行,你還可以使用 supervisorctl 命令,單獨控制一系列 logstash 子進程中某一個進程的啟停操作:

supervisorctl stop elkpro_2

關於grok語法

官方給定的語法

https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

https://github.com/elastic/logstash/tree/v1.4.2/patterns

如果你使用的正則語言可以將nginx日誌進行匹配,就可以成功對日誌進行切割,效果看下圖:

調試的過程中可以使用這個網站來進行正則語法的測試:http://grokdebug.herokuapp.com/

1. 線上配置的信息格式192.168.70.94 跟權威指南中的一樣
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:

以下這個是Logstash默認自帶了Apache標準日誌的grok正則表達式:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest
})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)

COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}

2. 我的nginx日誌切割格式
NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:tiem_local}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_referer}\" \"%{DATA:http_user_agent}\"

MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}
COMBINEDAPACHELOG 合併的apache日誌  logstash客戶端用的是這種方式
COMMONAPACHELOG 普通的apache日誌
當grok匹配失敗的時候,插件會為這個事件打個tag,默認是_grokparsefailure。LogStash允許你把這些處理失敗的事件路由到其他地方做後續的處理
input { # ... }
filter {
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{IPV4:ip};%{WORD:environment}\] %{LOGLEVEL:log_level} %{GREEDYDATA:message}" }
  }
}
output {
  if "_grokparsefailure" in [tags] {
    # write events that didn't match to a file
    file { "path" => "/tmp/grok_failures.txt" }
  } else {
     elasticsearch { }
  }
}

看下面紅色的地方,表示grok匹配失敗,才會將tags的標籤定義成_grokparsefailure這個默認的

解決說是要設置錨點 目前不懂什麼意思 先放到這裏

https://www.jianshu.com/p/86133dd66ca4

另外一種說法,暫時不會用,先放着
1.
if "_grokparsefailure" in [tags] { drop { } }
2.match語句跟第一個一樣的  沒啥要點,看着官網例子搞就行了

3.盡量用grok吧 ,grep功能以後要去掉的。

當時想的另外一種解決方法就是改nginx的日誌格式成json形式的,但是我不想用這種方法。

log_format json '{"@timestamp":"$time_iso8601",'
                 '"host":"$server_addr",'
                 '"clientip":"$remote_addr",'
                 '"request":"$request",'
                 '"status":"$status",'
                 '"request_method": "$request_method",'
                 '"size":"$body_bytes_sent",'
                 '"request_time":"$request_time",'
                 '"upstreamtime":"$upstream_response_time",'
                 '"upstreamhost":"$upstream_addr",'
                 '"http_host":"$host",'
                 '"url":"$uri",'
                 '"http_forward":"$http_x_forwarded_for",'
                 '"referer":"$http_referer",'
                 '"agent":"$http_user_agent"}';

access_log  /var/log/nginx/access.log json ;

問題解決

Nginx日誌沒有被成功切割的終極原因

    以下是兩種日誌方式:
    log_format  main  '$remote_addr - $remote_user [$time_iso8601] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$host" "$request_time"';

    log_format format2  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$host" "$request_time"';
 
 在logstash中進行切割的時候調用的時間變量是不同的,靈感來自如下:
 grok {
        match => { "message" => "%{TIMESTAMP_ISO8601:time}" }
    }
date{
        match => ["time", "yyyy-MM-dd HH:mm:ss", "ISO8601"]
        target => "@timestamp"
    }
mutate{
        remove_field => ["time"]
    }
定義:
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
#NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:time_iso8601}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_referer}\" \"%
{DATA:http_user_agent}\"

{DATA:http_user_agent}\"
NGINX_ACCESS %{IPORHOST:remote_addr} - %{USERNAME:remote_user} \[%{TIMESTAMP_ISO8601:time_iso8601}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_refere
r}\" \"%{DATA:http_user_agent}\"

SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest
})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}

Nginx中時間格式1:$time_local   對應logstash中\[%{HTTPDATE:timestamp}\]
Nginx中時間格式2:$time_iso8601 對應logstash中\[%{TIMESTAMP_ISO8601:timestamp}\]

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價

區分http請求狀態碼來理解緩存(協商緩存和強制緩存)

什麼是http緩存呢,當我們使用chrome瀏覽器,按F12打開控制台,在網絡請求中有時候看到狀態碼是200,有時候狀態碼是304,當我們去看這種請求的時候,我們會發現狀態碼為304的狀態結果是:Status Code: 304 Not Modified,而狀態碼為200的時候一般會有四種情況,一種是直接返回200,沒有任何其他的標誌,另一種是Status Code: 200 OK (from memory cache),還有一種是Status Code: 200 (from disk cache)。最後一種不是太常見,Status Code: 200 (from Service Worker).後面這三種狀態碼看到的效果是灰色的,其實從給出的信息也能看出來是從緩存中獲取上數據。下面我們來詳細介紹一下他們都分別是什麼時候出現的。

其實我們可以按狀態碼來區分其為兩大類,分別是協商緩存–304和強制緩存–200

協商緩存(304)

這種方式使用到了headers請求頭裡的兩個字段,Last-Modified & If-Modified-Since 。服務器通過響應頭Last-Modified告知瀏覽器,資源最後被修改的時間:

Last-Modified: Thu, 20 Jun 2019 15:58:05 GMT 

當再次請求該資源時,瀏覽器需要再次向服務器確認,資源是否過期,其中的憑證就是請求頭If-Modified-Since字段,值為上次請求中響應頭Last-Modified字段的值:

If-Modified-Since: Thu, 20 Jun 2019 15:58:05 GMT 

瀏覽器在發送請求的時候服務器會檢查請求頭request header裏面的If-modified-Since,如果最後修改時間相同則返回304,否則給返回頭(response header)添加last-Modified並且返回數據(response body)。

另外,瀏覽器在發送請求的時候服務器會檢查請求頭(request header)裏面的if-none-match的值與當前文件的內容通過hash算法(例如 nodejs: cryto.createHash(‘sha1’))生成的內容摘要字符對比,相同則直接返回304,否則給返回頭(response header)添加etag屬性為當前的內容摘要字符,並且返回內容。

綜上總結為:

  • 請求頭last-modified的日期與響應頭的last-modified一致
  • 請求頭if-none-match的hash與響應頭的etag一致
    這兩種情況會返回Status Code: 304

強制緩存(200(from …))

這裏我們使用到了Cache-Control和Expires這兩個字段來進行控制,Cache-Control裏面可以有多個屬性,可以組合設置,其屬性有如下幾種:

  • max-age=xxx,最大的有效時間 單位秒,是一個相對時間
  • must-revalidate,如果超過了max-age的時間,必須向服務器發送請求,驗證資源的有效性
  • no-cache,基本等價於max-age=0,由協商緩存來決定是否緩存資源
  • no-store,真正意義上的不緩存
  • public,代表 http 請求返回的內容所經過的任何路徑當中(包括中間一些http代理服務器以及發出請求的客戶端瀏覽器),都可以對返回內容進行緩存操作
  • private,代表只有發起請求的瀏覽器才可以進行緩存。默認值

比如我們設置

Catch-Control:public,max-age=360000 

我們在之前說了強制緩存有三種情況,上面說返回200有四種,第一種其實是不緩存,正常服務器返迴響應。

Service Worker

這個東西其實本質上時服務器和客戶端之間的代理服務器,一般我們在使用react開發的時候,會發現在根目錄出現了一個server-worker.js文件,這個東西就是和service Worker緩存相關的,他會根據網絡的狀態做出不同的緩存策略,有時候斷網了,之前訪問過的接口有可能依然會返回數據,其數據來源就是從其緩存中讀取。

memory cache

這個是將資源緩存在了內存中。事實上,所有的網絡請求都會被瀏覽器緩存到內存中,當然,內存容量有限,緩存不能無限存放在內存中,因此,註定是個短期緩存。而其控制權在於瀏覽器。

disk cache

與內存緩存相對的,這個是將資源緩存在硬盤中。雖然相比於內存,硬盤的讀取速度要慢很多,但總比沒有強。硬盤緩存的控制權在後端,通過什麼控制呢?通過HTTP響應頭控制,也就是我們在上面說到的catche-control和expires

Expires設置的過期時間是一個絕對的GMT時間,例如:Expires:Thu,20 Jun 2019 20:00:00 GMT; 他告訴瀏覽器緩存有效性持續到2019年6月20日為止,一直都使用緩存來處理。

Expires有一個非常大的缺陷,它使用一個固定的時間,要求服務器與客戶端的時鐘保持嚴格的同步,並且這一天到來后,服務器還得重新設定新的時間。

HTTP1.1引入了Cathe-Control,它使用max-age指定組件被緩存多久,從請求開始在max-age時間內瀏覽器使用緩存,之外的使用請求,這樣就可以消除Expires的限制,

如果對瀏覽器兼容性要求很高的話,可以兩個都使用。

其實在上面說到的Last-Modified對比最後修改時間與Expires一樣是有缺陷的,如果,資源的變化的時間間隔小於秒級,比如說是毫秒級的,或者說資源直接是動態生成的,那根據Last-Modified判斷,資源就是每時每刻都最新的,即被修改過!

所以,Etag & If-Node-Match 就是來解決這個問題的。
Etag字段的值為文件的特殊標識,一般都是hash生成的,服務器存儲着資源的Etag值。接下來的流程都與Lst-Modified & If-Modified-Since一致,只不過,比較的值從最後修改時間變成了Etag值。

Etag的優點在於,對於動態資源或者現在流行的Restful API返回的JSON數據,這些是沒有修改時間這一說法的,但是Http標準並沒有規定Etag值如何生成,因此我們通過代碼自己生成Etag值。當然,計算Etag值會消耗服務器性能。

Cache-Control+Last-Modified+ETag 的優先級會如何?

因為http1.1>http1.0,所以Cache-Control>Expires,ETag>Last-Modified。依照就近原則,先找本地緩存,沒有再向服務器發請求,所以Expires>Last-Modified,Cache-Control>ETag,

如果瀏覽器只支持http1.0,那麼瀏覽器只會攜帶Last-Modified發送給後台,
如果服務器只支持http1.0,那麼服務器會以Last-Modified為標準。
如果瀏覽器支持http1.1,那麼瀏覽器會攜帶Cache-Control+Last-Modified+ETag發送給後台,
如果服務器支持http1.1,那麼服務器會以Cache-Control+ETag為標準。

200狀態碼和304狀態碼何時出現

在沒有設置Cache-Contral的情況下,設置Last-Modified和ETag緩存,會出現200(from cache)和304 交替出現的情況。

設置Cache-Contral的情況下,過期刷新會出現304(如果有更新內容,則是200),之後再過期之前刷新都是200(from cache)。如果要確保要向服務端確認,可以將Cache-Contral的max-age設置為0。

通過下圖我們可以清晰的明白200和304

https://www.oecom.cn/http-header-control/

 

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

【其他文章推薦】

※回頭車貨運收費標準

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

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

※推薦評價好的iphone維修中心

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

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

氦元素 – CUBA 應用程序新樣式主題

    CUBA 框架一直以來定位的目標是業務系統的開發。業務系統的界面通常是給後台員工使用的,看重的是功能實現。多年來,界面外觀和樣式並不是後台管理系統的主要關注點,界面中的控件也更緊湊,唯一的原因就是:在單一屏幕中擺放盡可能多的控件,以提供足夠多的功能。

    但是在最近十年裡,人們使用了越來越多的小尺寸觸控屏設備,遊戲規則因此而改變。要有易於觸控點擊的控件,它們之間需要有足夠的間距,防止被誤點擊。應用程序的配色也變得偏於使用雜色和對比色。所以,近些年的現代應用程序在設計上更注重樣式,其中非功能性需求都佔了很大的一部分。

    順應趨勢,我們很高興推出新可視化主題 – 氦元素(Helium)!與以前的樣式主題相比,氦元素主題更簡潔、明亮,視覺噪音也更少。另外很重要的一點:能夠以最少的工作量為最終用戶和 CUBA 開發人員提供樣式定製。

功能

    首先要提到的是,新主題是動態的,意味着您可以隨時在線更改應用程序樣式!以前,CUBA 使用 SCSS 變量定義顏色,這樣每次修改過後都需要重新編譯。而新主題依賴 CSS 定製屬性 ,即使沒有頁面刷新或重新登錄,這些屬性也可以在運行時立即起效。

預設配色

    開箱即用支持兩種預設的配色方案:淺色(light)和深色(dark)。

    終端用戶可選擇的主題需要通過下列屬性配置(主題安裝流程請參考後續章節):

cuba.theme.modes = light|dark
cuba.theme.defaultMode = light

    另外,也可以通過在線主題編輯器創建自定義的配色方案(點擊下方的在線示例和編輯器章節名稱了解更多細節)。

預設大小

    主題自帶三種內置的控件大小配置:小(small),中(medium)和大(large)。

    跟配色方案類似,也可以通過主題屬性修改:

cuba.theme.sizes = small|medium|large
cuba.theme.defaultSize = medium

設置界面

    設置界面可以通過主菜單的 Help -> Theme Settings 打開。這裏可以讓最終用戶自定義他們喜歡的配色和控件大小。該界面帶有幾乎所有的主要控件,所以用戶可以預覽他調整之後的界面大概什麼樣。

在線示例和編輯器

    關於新主題的另一個重要部分就是其在線交互式編輯器。這裏可以試試調整樣式變量,馬上就能看到調整結果 – 一旦樣式滿足您的需求,只需要點擊下載按鈕並按照提供的說明將其安裝到您的 CUBA 應用程序中即可。

    其實,在線編輯器最好的一點是:不只是開發人員可以使用。將這個鏈接發送給您的追求極致的客戶,這樣他們可以根據自己的偏好自定義配色,然後下載併發送結果給開發人員,只需要幾分鐘便可以應用新的樣式。同時,編輯器本身也允許導入顏色變量,這樣可以基於已有的配色做修改。

    如需使用自定義配色,需要基於氦元素創建主題擴展。

安裝

    該主題是通過 擴展插件 的形式發布。該擴展兼容 7.1.5 以上的 CUBA 應用程序(注意,我們推薦您跟蹤 CUBA 框架的 bugfix 版本並更新您的應用程序至最新版)。可以參考 Studio 的 相關章節 了解如何安裝擴展插件。

    擴展安裝完成后,可以通過下面的方式啟用新的主題:
    啟動應用程序,打開主菜單下的設置界面:Help -> Settings。在可視化主題選項中選擇 Helium 即可。

    如需將氦元素主題設為默認主題,可以在 web-app.properties 中添加:

cuba.web.theme = helium

    如果之前自定義設置過 cuba.themeConfig 屬性,別忘了也需要添加氦元素屬性:

cuba.themeConfig = +/com/haulmont/addon/helium/web/helium-theme.properties

    如需自定義主題屬性,可以在 web 模塊的主包路徑創建 helium-theme.properties,內容如下:

@include=com/haulmont/addon/helium/web/helium-theme.properties

cuba.theme.modes = light|dark
cuba.theme.defaultMode = light

cuba.theme.sizes = small|medium|large
cuba.theme.defaultSize = medium\

    然後在 cuba.themeConfig 屬性中註冊一下該文件:

cuba.themeConfig = +/com/example/project/helium-theme.properties

    如需深度定製該主題,包括應用自定義配色,則需要創建主題擴展。按照該說明操作。

路線圖

    我們計劃繼續開發氦元素主題並添加新功能,包括:

  • 深色模式改進
  • 在主題編輯器中提供更有用的模板
  • 在淺色和深色模式之間自動切換
  • 提供可自定義的 border radius 變量,同樣也基於 CSS 變量。
  • 提供 Figma 的 CUBA 套件。Figma 是 UI/UХ 設計師最流行的工具之一,他們可以用來創建界面模型。

結論

    我們很樂意看到新主題和在線編輯器能用在您的項目中,希望新主題能讓您的應用煥然一新。如果您有任何問題,可以在我們的論壇創建主題討論。項目源碼可以在 Github 找到: 主題 / 編輯器。期待您的反饋!

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

※推薦台中搬家公司優質服務,可到府估價