思源:秒級體驗百億級數據量監控鑽取

編者薦語:

當業務量快速增長的時候,業務保障平台就要應運而生,預判問題發出告警,越快越好,從宏觀到微觀一路下鑽響應越快越好,尤其是交易量暴漲的高峰時段。怎麼做到?看思源的現身說法:

以下文章來源於雲縱達摩院 ,作者劉勤紅

 

——業務保障平台性能提升走過的那些路
禧雲信息/研發中心/劉勤紅(思源) 2019年11月
 
業務保障平台需從多維度去監控業務的可靠性,快速定位問題並自動解決或推薦出解決方案,所以時效性顯得非常重要。接下來我將從以下三個維度展開如何將百億級數據量監控鑽取從十幾秒提升到秒級體驗:
· 工具升級:OpenTSDB–>Druid
· 調用鏈收集的優化
· 聚合查詢的優化
 

一、背景回顧

· 禧雲的團餐業務發展非常迅速,短短几個月的時間,日交易量就從數百萬拉高到千萬級,隨着調用鏈追蹤得愈發細緻,業務數據量也從億級上升到百億級別。
· 團餐的高峰交易量比外賣更集中,外賣可以提前預訂,而團餐的早中晚就餐非常集中,全國的學生幾乎都是一個點兒下課,從下單到吃完也就集中在20-30分鐘內,下圖0為交易量的曲線圖,坡度幾乎是直線上升,真是爭分奪秒!

圖0 團餐高峰期爭分奪秒不容有失
在這種高強度業務場景下,業務保障平台應運而生,它主要是多場景多維度實時監控大盤,從設備終端到服務端全鏈路監控,讓技術團隊從事後追查和整改,轉變為事前預警和快速判定根因。它主要涉及交易、業務調用鏈路、網絡監控、設備運行指標、業務日誌等維度數據。架構如下圖1所示。
圖1 基於OpenTSDB版的大致架構
· 千萬級日交易數據:從各業務系統或支付網關迴流的交易數據—>交易迴流服務—>多維度聚合入庫OpenTSDB和ElasticSearch集群;
· 十億級業務調用鏈數據:基於Jaeger Trace植入–>Nginx多路分發–>經Jaeger-collector收集到Kafka–>被多組消費者處理(Flink實時寫入OpenTSDB,批量寫入ES);
· 百億級網絡和設備指標數據:主要是智能設備上報的各種監控指標:基於HTTP/HTTPS層監視–>Nginx–>太空橋(我司IoT平台)設備監控–>批量入庫ES。
技術棧為:
· 鏈路採集:Uber開源的Jaeger
· 基礎數據存儲:ES
· 指標數據存儲:OpenTSDB
· 削峰填谷的消息隊列:Kafka
· 實時計算:Flink  

二、工具升級:OpenTSDB升級到Druid

在禧雲業務保障平台上,OpenTSDB確實沒有太好的性能表現,查詢數據量在百萬級的時候,速度還是可以的,在暑假交易額低谷期並未暴露出OpenTSDB的性能問題。但是進入9月開學季之後,數據延時和查詢緩慢的問題立馬就暴露出來了,中途也寄希望於升級OpenTSDB版本,但依然效果不佳。
 

A. OpenTSDB性能表現不佳的原因

第一個原因,Rowkey設計過長的問題。Rowkey第一大設計原則是保證唯一性,否則原先的數據會被覆蓋掉,第二大設計原則是長度原則,Rowkey是一個二進制,它的長度建議設計在10~100個字節,越短越好。Rowkey如果過長,對性能有以下影響:
1)HBase的持久化文件HFile是按照KeyValue存儲的,如果Rowkey過長,比如500個字節,1000萬列數據,光Rowkey就要佔用500*1000萬=50億個字節,將近1G數據,這會極大影響HFile的存儲效率。
2)MemStore緩存部分數據到內存,如果Rowkey字段過長,內存的有效利用率會降低,系統無法緩存更多的數據,這會降低檢索效率。
需要指出的是不僅Rowkey的長度越短越好,列族名、列名等也盡量使用短名字,因為這些名字都是會寫入HFile中的,過長的Rowkey、列族名、列名都會導致整體的存儲量成倍增加。
 
第二個原因,業務監控業務場景非常多,涉及到不同業務線的多個維度,比如多機房、多支付渠道、商戶/門店/設備/碼等多維度聚合,很難設計出一個滿足全場景的Rowkey方案。在任意維度的組合查詢下,OpenTSDB 查詢效率會明顯降低。
比如對於組合條件查詢使用的就是scan方式,在使用時有以下幾點值得注意:
1)通過setCaching、setBatch方法提高速度,以空間換時間;
2)通過setStartRow與setEndRow來限定範圍,範圍越小,性能越高;
3)通過setFilter方法添加過濾器,這也是分頁、多條件查詢的基礎,比如使用SingleColumnValueFilter。
以上優化當遇到真正海量數據時,會消耗很大的資源,每次都需要花較長的時間處理。
 

B. 升級為Druid

我司其他技術團隊已經試用了Druid, 其核心是通過數據預先聚合提高查詢性能,針對預先定義好的Schema,因此適合實時分析的場景,結果返回時間在亞秒級。
我們切換到Druid之後,響應速度上確實有一個數量級的提升,查詢千萬級的數據範圍基本秒級響應。
 

三、調用鏈收集的優化

調用鏈收集的數據流為:jaeger-collector–>Kafka–>jaeger-ingester 消費–>入庫ES。下面講一下如何優化。
A. 第一階段:Kafka消息堆積高峰期由千萬級降到百萬級
強調一點,合理的分區設置很重要。
剛開始我們嘗試調整每次拉取的消息條數,將ingester.parallelism由1000調整為6000,消息堆積似乎好了一點,但效果不明顯。
考慮到可能是因為併發數不夠,所以通過擴充Kafka的分區數去提高併發。先將分區數由5個擴到8個,消息堆積由千萬級降到百萬級。但繼續將分區擴到10個,就幾乎沒有什麼效果了。  
B. 第二階段:Kafka的版本選擇不可忽視
莫名其妙的是jaeger-ingester消費非常不穩定,頻繁與kafka斷開重連,嘗試去消費其他分區消息,導致消費速率上不去。
後來發現,當Kafka版本為v2.3時,多個jaeger-ingester節點會反覆觸發kafka的消費再平衡機制,結果導致jaeger-ingester只能單點消費。
所以我們又將Kafka版本回退到了v2.2,調整jaeger-ingester實例個數和Kafka分區數為1:1,可橫向擴容支持高併發。
 
C. 第三階段:消息堆積高峰期由百萬降到萬級,延時秒級已可接受
我們觀察到ES的負載已經很高了,單節點高峰期CPU負載達到16。之前為了方便定位問題,給網絡請求實時加上了traceId標記,調用的是jaeger原生的trace鏈路計算。現在分析發現查詢QPS太高,所以嘗試優化查詢邏輯,一方面改為自定義的邏輯直接查詢ES,一方面調整好批量閾值查詢(指的是1次查多少,目前是按時間10ms和數據條數100條一個批次去查ES)。
優化完成后,消息堆積又下降一個數量級。目前高峰期堆積非常少,秒級消費已可接受。
 

四、聚合查詢的優化

A. 散點圖 vs 柱狀圖

對於調用鏈宏觀展示來說,慣常使用散點圖,它可以表達出一段時間內請求的耗時分佈情況,如下圖2所示。

圖2 調用鏈散點圖
但是存在一個問題,當時間區間選得比較大的時候,服務端查詢的數據過多而響應變慢,客戶端要渲染的點太多也會非常卡。所以點要抽樣。抽樣方式能想得到的有:
a.過濾出耗時長的數據;
b.取最近一段時間的數據;
c.只取指定數量的數據;
d.對相同耗時進行聚合展示等等。
這些調整可謂犧牲了監控者的真實需求,因為有些數據監控者看不了,或者很難看全。
我們對比了阿里雲日誌服務的設計,他山之石可以攻玉,借鑒了以下兩點:
第一點,人們看問題的方式總是從宏觀一路下鑽到微觀,所以我們加了柱狀圖做為時間段聚合,方便從宏觀上看到請求量的規模分佈。下圖3是某區域的訂單趨勢柱狀圖。

圖3 訂單趨勢柱狀圖
第二點,如果數據量非常大,可繼續點擊柱圖,展開當前時間條件下的子柱狀圖。系統根據數據量規模,自動展示出散點圖,方便用戶瀏覽耗時分佈。這樣一層層穿刺下鑽,既滿足了人的操作習慣,又提高了處理速度,做到了秒級響應。

圖4柱狀圖下鑽
 

B. 從宏觀到微觀,化繁為簡

就宏觀到微觀的監控下鑽,下面講三個案例。
案例一,單一維度下鑽
其實多數時候人們只想關注某一維度的分佈情況,比如按應用、按工程、按服務IP、按請求URL、按商戶、按門店、按設備看分佈。對於ES來說,單一條件聚合速度很快,秒級響應。
案例二,網絡質量監察
我司在全國大江南北分佈着大量餐飲中心(即食堂),如何快速定位出哪些食堂網絡環境糟糕呢?不能等客戶告訴我們。
我們從請求量級篩選(系統推薦和自定義)、dns/http/ssl/tcp/mqtt耗時情況、趨勢發展等諸多因子中分析出餐飲中心網絡情況,哪怕是學校食堂的一次網絡抖動,都可以被我們偵查到。不僅能分析出網絡問題,而且還能下鑽到請求鏈路上的任何階段,比如是DNS、TCP、SSL、首包等,並分析出受影響的終端設備。依然是秒級響應,如下圖5所示。

圖5 設備耗時下鑽
 
案例三,找出掉單
當用戶已支付而商戶未收款時,如何從千萬級訂單中快速找到丟失的那一筆訂單呢?內部稱sos訂單:

  • 秒級偵查出來;
  • 快速定位在哪個環節出了問題;
  • 系統自我修復能力

具體做法為:
第一步,將內部可能發生的業務場景圈出來,通過Flink實時計算形成閉環,當其中一個鏈條斷了,就會立馬把待排查的sos訂單壓入隊列任務,然後不斷主動查詢第三方支付渠道確認支付狀態。
第二步,對於一些疑難問題如短時間內系統無法解決時,比如第三方支付渠道出現了故障,就會發出告警消息給客服,客服預先跟進,減少用戶投訴處理時間。
 
總結一下:
OpenTSDB切換為Druid,明顯提升了從宏觀下鑽到微觀的響應時間,基本能做到百億級數據量秒級響應。高峰時段Kafka消息堆積也大幅降低。下鑽方式做了優化,更符合工程師探查習慣。
 
-完-

歡迎關注公眾號:老兵筆記

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

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

武漢肺炎疫情影響奈良鹿? 愛鹿協會:野生植物才是主食 鹿沒人餵不會餓死

文:宋瑞文

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

路上跑的全是電動車!印度設下 2030 年達標,擬推電動車免頭期款政策

被視為未來趨勢的電動車,目前在車市中的市占仍然相當低,而若談到推動電動車發展,印度絕對是當前最野心勃勃的國家。近日,印度電力部長提出新政策,要讓電動車購車族免付頭期款,以提高民眾購買的意願,最終目標是要在 2030 年前,讓印度境內上路的車輛 100% 為電動車。

印度為目前全球空氣污染最嚴重的國家之一,國內有 13 個城市名列全球前 20 大最受污染城市。為了從根本改善印度的空氣品質,降低對化石燃料的依賴勢在必行,而印度電力部懷抱著強大的信心,表示不造成人民經濟上的壓力,就能全力推動國內電動車發展。   印度電力部長 Piyush Goyal 日前信誓旦旦的表示,「印度將成為全球首個在如此國土規模大小之下,100% 全電動車上路的國家」,且 Goyal 透露,將努力嘗試讓這項計畫由電力部的資金供應運作,「我們不需要用到政府與印度人民的任何一毛錢」。   有了電動車購車零頭期款的政策,Goyal 相信,這可提高購車意願,使人們更輕鬆的將省下大筆油錢轉往購買電動車。Goyal 透露,目前正與其他政府官員合作,由印度道路運輸與公路部部長 Nitin Gadkari、石油部長 Dharmendra Pradhan 及環境部長 Prakash Javadekar 帶領成立的工作小組,商討與評估這個政策提議是否可行,以及「確保電動車車主能享有便宜的充電價格」。   雖然利用電動車取代排放溫室氣體的傳統汽車,能夠為空氣品質本就相當糟糕的印度,減少交通運輸這部分所造成的碳排放,但也有人質疑,推動電動車的結果將造成電力需求上升,最終可能會導致供給發電的能源產業製造更多碳排放量也說不定,畢竟,印度目前約 60% 的能源產出來自燃煤發電,而燃煤發電廠在印度已經是一大污染來源之一,且其溫室氣體排放量在這幾年依然持續成長中。   此外,印度曾對外公開其再生能源目標,要使再生能源裝置量從 2016 年的不到 12 GW,增加到 2022 年的 175 GW,根據先前的報導曾指出,印度要達到 175 GW 的目標,所需花費的資金相當「可觀」,若又加上推動電動車發展所提出的免付頭期款政策,可能會讓印度走向再生能源主導之路,更顯困難重重了。

(首圖來源: CC BY 2.0)

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

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

4. 彤哥說netty系列之Java NIO實現群聊(自己跟自己聊上癮了)

你好,我是彤哥,本篇是netty系列的第四篇。

歡迎來我的公從號彤哥讀源碼系統地學習源碼&架構的知識。

簡介

上一章我們一起學習了Java中的BIO/NIO/AIO的故事,本章將帶着大家一起使用純純的NIO實現一個越聊越上癮的“群聊系統”。

業務邏輯分析

首先,我們先來分析一下群聊的功能點:

(1)加入群聊,並通知其他人;

(2)發言,並通知其他人;

(3)退出群聊,並通知其他人;

一個簡單的群聊系統差不多這三個功能足夠了,為了方便記錄用戶信息,當用戶加入群聊的時候自動給他分配一個用戶ID。

業務實現

上代碼:

// 這是一個內部類
private static class ChatHolder {
    // 我們只用了一個線程,用普通的HashMap也可以
    static final Map<SocketChannel, String> USER_MAP = new ConcurrentHashMap<>();

    /**
     * 加入群聊
     * @param socketChannel
     */
    static void join(SocketChannel socketChannel) {
        // 有人加入就給他分配一個id,本文來源於公從號“彤哥讀源碼”
        String userId = "用戶"+ ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
        send(socketChannel, "您的id為:" + userId + "\n\r");

        for (SocketChannel channel : USER_MAP.keySet()) {
            send(channel, userId + " 加入了群聊" + "\n\r");
        }

        // 將當前用戶加入到map中
        USER_MAP.put(socketChannel, userId);
    }

    /**
     * 退出群聊
     * @param socketChannel
     */
    static void quit(SocketChannel socketChannel) {
        String userId = USER_MAP.get(socketChannel);
        send(socketChannel, "您退出了群聊" + "\n\r");
        USER_MAP.remove(socketChannel);

        for (SocketChannel channel : USER_MAP.keySet()) {
            if (channel != socketChannel) {
                send(channel, userId + " 退出了群聊" + "\n\r");
            }
        }
    }

    /**
     * 擴散說話的內容
     * @param socketChannel
     * @param content
     */
    public static void propagate(SocketChannel socketChannel, String content) {
        String userId = USER_MAP.get(socketChannel);
        for (SocketChannel channel : USER_MAP.keySet()) {
            if (channel != socketChannel) {
                send(channel, userId + ": " + content + "\n\r");
            }
        }
    }

    /**
     * 發送消息
     * @param socketChannel
     * @param msg
     */
    static void send(SocketChannel socketChannel, String msg) {
        try {
            ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
            writeBuffer.put(msg.getBytes());
            writeBuffer.flip();
            socketChannel.write(writeBuffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服務端代碼

服務端代碼直接使用上一章NIO的實現,只不過這裏要把上面實現的業務邏輯適時地插入到相應的事件中。

(1)accept事件,即連接建立的時候,說明加入了群聊;

(2)read事件,即讀取數據的時候,說明有人說話了;

(3)連接斷開的時候,說明退出了群聊;

OK,直接上代碼,為了與上一章的代碼作區分,彤哥特意加入了一些標記:

public class ChatServer {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);
        // 將accept事件綁定到selector上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 阻塞在select上
            selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            // 遍歷selectKeys
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                // 如果是accept事件
                if (selectionKey.isAcceptable()) {
                    ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel socketChannel = ssc.accept();
                    System.out.println("accept new conn: " + socketChannel.getRemoteAddress());
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                    // 加入群聊,本文來源於公從號“彤哥讀源碼”
                    ChatHolder.join(socketChannel);
                } else if (selectionKey.isReadable()) {
                    // 如果是讀取事件
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    // 將數據讀入到buffer中
                    int length = socketChannel.read(buffer);
                    if (length > 0) {
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        // 將數據讀入到byte數組中
                        buffer.get(bytes);

                        // 換行符會跟着消息一起傳過來
                        String content = new String(bytes, "UTF-8").replace("\r\n", "");
                        if (content.equalsIgnoreCase("quit")) {
                            // 退出群聊,本文來源於公從號“彤哥讀源碼”
                            ChatHolder.quit(socketChannel);
                            selectionKey.cancel();
                            socketChannel.close();
                        } else {
                            // 擴散,本文來源於公從號“彤哥讀源碼”
                            ChatHolder.propagate(socketChannel, content);
                        }
                    }
                }
                iterator.remove();
            }
        }
    }
}

測試

打開四個XSHELL客戶端,分別連接telnet 127.0.0.1 8080,然後就可以開始群聊了。

彤哥發現,自己跟自己聊天也是會上癮的,完全停不下來,不行了,我再去自聊一會兒^^

總結

本文彤哥跟着大家一起實現了“群聊系統”,去掉註釋也就100行左右的代碼,是不是非常簡單?這就是NIO網絡編程的魅力,我發現寫網絡編程也上癮了^^

問題

這兩章我們都沒有用NIO實現客戶端,你知道怎麼實現嗎?

提示:服務端需要監聽accept事件,所以需要有一個ServerSocketChannel,而客戶端是直接去連服務器了,所以直接用SocketChannel就可以了,一個SocketChannel就相當於一個Connection。

最後,也歡迎來我的公從號彤哥讀源碼系統地學習源碼&架構的知識。

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

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

生魚片注意!海獸胃線蟲暴增283倍

摘錄自2020年3月23日Yahoo!新聞報導

華盛頓大學研究團隊於近日指出,寄生在魚類的線蟲「海獸胃線蟲」 (Anisakis),自1978年至2015年的這段時間暴增283倍。

對此,威斯康辛大學水海洋學教授伍德(Chelsea Wood)表示,儘管對人類健康風險低,但對於海豚、鯨魚、海報等海洋哺乳動物,可能產生有害影響,內容提到若人類吃到活生生的海獸胃線蟲,蟲子會入侵腸壁,進而引發類似食物中毒的症狀,例如噁心嘔吐腹瀉等等,但蟲子幾乎會在幾天後就死亡,症狀隨即消失,因此大多數人都認為只是單純的食物中毒而很難被查覺到。

雖然海獸胃線蟲不能在人類體內存活太久,不過卻可以在海洋哺乳動物中生活並繁殖,伍德表示,他們仍不確定線蟲大量爆增的原因,氣候變遷、肥料、洋流等等所產生的養分,以及同其海洋哺乳動物的數量增加,都可能是潛在原因。

食品安全
糧食
生活環境
永續發展
國際新聞
生魚片
線蟲

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

上汽集團150億定增用於投資新能源汽車、車聯網等

上汽集團4月20日晚間公告稱,中國證監會發行審核委員會於4月20日對公司非公開發行A股股票的申請進行了審核。根據會議審核結果,公司本次非公開發行A股股票的申請獲得審核通過。

根據調整後的定增預案,上汽集團擬以不低於15.56元/股非公開發行不超過9.64億股,募集資金不超過150億元用於投資新能源汽車、智慧化大規模定制、前瞻技術與車聯網、汽車服務與汽車金融領域內多個項目,其中公司控股股東上汽總公司擬認購不超過30億元,公司員工持股計畫擬認購不超過11.6745億元。

定增募集資金主要投向新興領域:其中新能源相關專案72億、智慧定制化專案20億、前瞻技術(燃料電池/智慧汽車)及車聯網19億、汽車服務與金融專案39億。

戰略定位由汽車製造轉為綜合服務:研發製造業環節,資源更多的向新能源汽車、智慧汽車傾斜;同時更加注重汽車服務領域的潛力挖掘,包括汽車金融、維修服務等。

公司為業務轉型已做大量的準備和調整:1、組織架構調整,新成立服務貿易事業部、金融事業部,用於整合內部相關業務;2、廣泛儲備技術,公司先後投入60億用於新能源產品開發,是國內少有的推出插電式車型的車企;3、積極跨界合作,公司已與阿裡巴巴、中國石油等企業在車聯網、汽車後市場方面建立戰略合作;4、激勵機制調整,本次增發實現更大額度的持股,同時在部分新業務上還實現了更大幅度的員工持股。

公司新業務發展目標:1、新能源汽車領域,完善供應鏈體系,有效降低成本,加快推出產品,2016、2020年分別實現2.6、20萬銷量;2、智慧汽車領域,2016年下半年推出與阿裡巴巴合作開發的首款互聯網汽車;3、服務貿易領域,以車享網/車享家為服務平臺,建立涵蓋(自建1500家)1萬家店的服務體系,至2020年,實現收入3000億(含物流/維修/金融)。

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

SpringBoot基本配置詳解

SpringBoot項目有一些基本的配置,比如啟動圖案(banner),比如默認配置文件application.properties,以及相關的默認配置項。

示例項目代碼在:

一、啟動圖案banner

編寫banner.txt放入resources文件夾下,然後啟動項目即可修改默認圖案。

關於banner的生成,可以去一些專門的網站。

比如:https://www.bootschool.net/ascii

二、配置文件application

2.1 application.properties/yml

resources下通常會默認生成一個application.properties文件,這個文件包含了SpringBoot項目的全局配置文件。裏面的配置項通常是這樣的:

server.port=8080

在這個文件里我們可以添加框架支持的配置項,比如項目端口號、JDBC連接的數據源、日誌級別等等。

現在比較流行的是將properties文件改為yml文件。yml文件的格式yaml是這樣的:

server:
    port: 8080

yml和properties的作用是一樣的。而yml的好處是顯而易見的——更易寫易讀。

屬性之間互相調用使用${name}:

eknown:
    email: eknown@163.com
    uri: http://www.eknown.cn
    title: 'hello, link to ${eknown.uri} or email to ${eknown.email}'

鏈接:

2.2 多環境配置文件

通常開發一個應用會有多個環境,常見如dev/prod,也會有test,甚至其他一些自定義的環境,SpringBoot支持配置文件的靈活切換。

定義新配置文件需要遵循以下格式:application-{profile}.properties 或者application-{profile}.yml

比如現在有dev和prod兩個環境,我需要在application.yml文件之外新建兩個文件:

  1. application-dev.yml

    server:
       port: 8080
  2. application-prod.yml

    server:
      port: 8081

然後在application.yml中通過application.profiles.active={profile}指明啟用那個配置:

application:
    profiles:
      active: dev

除了在application.yml中指定配置文件外,還可以通過啟動命令指定:java -jar xxx.jar --spring.profiles.active=dev

2.2 自定義配置項並獲取它

主要介紹兩種方式,獲取單個配置項和獲取多個配置項。

舉例:

eknown:
    email: eknown@163.com
    uri: http://www.eknown.cn

2.2.1 使用@Value註解獲取單個配置項

@Value("${eknown.email}")
private String email;

@Value("${eknown.uri}")
private String url;

注意:使用@Value註解的時候,所在類必須被Spring容器管理,也就是被@Component、@Controller、@Service等註解定義的類。

2.2.2 獲取多個配置項

第一種,定義一個bean類,通過@Value獲取多個配置項:

@Component
public class MyConfigBean {
  
}

然後我們通過get方法來獲取這些值:

@RestController
public class BasicAction {
  
  @Autowired
  private MyConfigBean myConfigBean;

}

第二種,使用註解@ConfigurationProperties:

@Component
@ConfigurationProperties(perfix="eknown")
public class MyConfigBean {

  private String email;
  private String uri;
}

這裏只需要通過prefix指定前綴即可,後面的值自動匹配。

這裏我們還使用了@Component註解來讓spring容器管理這個MyConfigBean。

此外,我們可以不需要引入@Component,轉而在Application啟動類上加上@EnableConfigurationProperties({MyConfigBean.class})來啟動這個配置。

注意:我們這裡是從主配置文件,也就是SpringBoot默認的application-profile文件中獲取配置數據的。

而從自定義的配置文件,比如test.yml這種形式中獲取配置項時,情況是有點不大一樣的。

三、自定義配置文件

上面介紹的配置文件都是springboot默認的application開頭的文件。如果要自定義一個配置文件呢,比如test.yml或test.properties,怎麼獲取其中的配置項呢?

使用@PageResource註解即可。

首先我們來看一下讀取自定義的properties文件里的內容:

test.properties

hello.time=2019.11.19
hello.name=eknown

定義Configuration類:

@Configuration
@PropertySource("classpath:test.properties")
//@PropertySource("classpath:test.yml") // 注意,yml文件不能直接這樣寫,會讀不出數據
@ConfigurationProperties(prefix = "hello")
public class TestConfiguration {
    private String name;
    private String time;

    // hide get and set methods
}

測試一下:

@RestController
@RequestMapping(value = "test")
public class TestAction {

    @Autowired
    private TestConfiguration testConfiguration;

    @GetMapping(value = "config")
    public String test() {
        return testConfiguration.getName() + "<br/>" + testConfiguration.getTime();
    }
}

如果將properties文件換成yml文件呢?

我們嘗試一下,發現:

讀不出數據?

分析一下@PropertySource註解,發現其使用的PropertySourceFactory是DefaultPropertySourceFactory.

這個類的源碼如下:

public class DefaultPropertySourceFactory implements PropertySourceFactory {
    public DefaultPropertySourceFactory() {
    }

    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource);
    }
}

這個類只能處理properties文件,無法處理yml文件。所以我們需要自定義一個YmlSourceFactory。

public class YamlSourceFactory extends DefaultPropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        return new YamlPropertySourceLoader().load(resource.getResource().getFilename()
                , resource.getResource()).get(0);
    }
}

然後定義test.yml文件的config類:

@Configuration
@PropertySource(value = "classpath:test.yml", encoding = "utf-8", factory = YamlSourceFactory.class)
@ConfigurationProperties(prefix = "yml.hello")
public class TestYamlConfiguration {
    private String name;
    private String time;

    // hide get and set methods
}

注:為了區分test.properties和test.yml,這裏的test.yml中的屬性以yml.hello開頭。

編寫一下測試:

    @Autowired
    private TestYamlConfiguration ymlConfiguration;

    @GetMapping(value = "yml")
    public String testYml() {
        return "yml config: <br/>" + ymlConfiguration.getName() + "<br/>" + ymlConfiguration.getTime();
    }

訪問:

四、補充@ConfigurationProperties

網上一些資料中,為配合使用@ConfigurationProperties,還使用了@EnableConfigurationProperties註解。

經過測試發現:

  1. 從SpringBoot默認配置文件讀取配置信息,使用@ConfigurationProperties + @Component/@Configuration,或者@ConfigurationProperties + 在啟動類添加@EnableConfigurationProperties({class})。這兩種方式都能解決問題

  2. 從非默認配置文件讀取配置信息,需要利用@PropertySource註解。同樣兩種方式:

    2.1 @PropertySource + @ConfigurationProperties + @Component/@Configuration

    2.2 @PropertySource + @ConfigurationProperties + @Component/@Configuration + @EnableConfigurationProperties,第二種方式存在一個問題,即還是必須要使用@Component註解,如果不使用,則會導致讀取配置信息為null,但程序不會報錯;而如果採用了,則會導致bean類的set方法被執行兩次(也就是生成了兩個同樣類型的bean類)。這種方式不建議!

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

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

Model X 高價轉賣,買家是 Ford

據彭博社報導,Tesla 首批發售的 SUV Tesla  Model X 其中一輛的買家是汽車廠商 Ford,後者以高出定價 5.5 萬美元的價格買下了這輛電動車,Ford 是透過一家經銷商購買原車主轉賣的全新 Model X,通常購買競爭對手的新車主要是為了進行測試或者拆解。

Ford 購買 Model X 是 Founders 系列,起售價是 14.4 萬美元,由於首批發售的數量有限,每輛車都有一個編號,Ford 購買的這一輛是 Tesla 加州工廠生產第 64 輛 Model X。原車主是 Tesla 的老客戶、來自加州的 Wayne Skiles,他擁有一輛 Model S,並參加了向親友推薦購車的活動,由於他的推薦 Tesla 售出了 10 輛車,在 Model X 發售時他能夠有機會買到 Founders 系列的 Model X,當然他並沒有打算把這輛車留給自己,選擇在芝加哥交車,隨後就開到汽車店將 Model X 轉賣掉了,還賺了一筆錢。   這輛加州生產的 Model X 最終在底特律被發現,掛著密西根州的車牌,它的車主就是汽車廠商 Ford 公司,購買這輛 Model S,加上稅費和手續費,Ford 一共支付了 21.2 萬美元。為了能夠更早地買到這台車,支付比定價更高的費用是正常的,相信這筆錢對於 Ford 公司來說也不是什麼大數目,那 Ford 為什麼要買競爭對手的新車呢?   汽車廠商購買競爭對手的產品,主要是用於測試或是拆解,以了解對手的設計和技術,Tesla 在電動車的設計製造方面可謂是相當成功,Ford 購買新車來偷師也不足為奇。Ford 公司在聲明中稱,購買汽車廠商的新車進行測試正汽車產業非常常見,為了更早拿到產品,高於定價購買也很正常。   Ford 公司計劃在 2020 年投資 45 億美元研發電動車,至少推出 13 款電動車新品。

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

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

一文看懂 K8s 日誌系統設計和實踐

作者 | 元乙  阿里雲存儲服務技術專家

導讀:上一篇文章中我們介紹了為什麼需要一個日誌系統、為什麼雲原生下的日誌系統如此重要以及雲原生背景下日誌系統的建設難點,相信 DevOps、SRE、運維等同學看了之後深有體會。本篇文章單刀直入,會直接跟大家分享一下如何在雲原生的場景下搭建一個靈活、功能強大、可靠、可擴容的日誌系統。

需求驅動架構設計

技術架構,是將產品需求轉變為技術實現的過程。對於所有的架構師而言,能夠將產品需求分析透徹是非常基本也是非常重要的一點。很多系統剛建成沒多久就要被推翻,最根本的原因還是沒有解決好產品真正的需求。

我所在的日誌服務團隊在日誌這塊有近10年的經驗,幾乎服務阿里內部所有的團隊,涉及電商、支付、物流、雲計算、遊戲、即時通訊、IoT等領域,多年來的產品功能的優化和迭代都是基於各個團隊的日誌需求變化。

有幸我們最近幾年在阿里雲上實現了產品化,服務了數以萬計的企業用戶,包括國內各大直播類、短視頻、新聞媒體、遊戲等行業Top1互聯網客戶。產品功能從服務一個公司到服務上萬家公司會有質的差別,上雲促使我們更加深入的去思考:究竟哪些功能是日誌這個平台需要去為用戶去解決的,日誌最核心的訴求是什麼,如何去滿足各行各業、各種不同業務角色的需求…

需求分解與功能設計

上一節中我們分析了公司內各個不同角色對於日誌的相關需求,總結起來有以下幾點:

  1. 支持各種日誌格式、數據源的採集,包括非K8s
  2. 能夠快速的查找/定位問題日誌
  3. 能夠將各種格式的半結構化/非結構化日誌格式化,並支持快速的統計分析、可視化
  4. 支持通過日誌進行實時計算並獲得一些業務指標,並支持基於業務指標實時的告警(其實本質就是APM)
  5. 支持對於超大規模的日誌進行各種維度的關聯分析,可接受一定時間的延遲
  6. 能夠便捷的對接各種外部系統或支持自定義的獲取數據,例如對接第三方審計系統
  7. 能夠基於日誌以及相關的時序信息,實現智能的告警、預測、根因分析等,並能夠支持自定義的離線訓練方式以獲得更好的效果

為滿足上述這些功能需求,日誌平台上必須具備的功能功能模塊有:

  1. 全方位日誌採集,支持DaemonSet、Sidecar各種採集方式以應對不同的採集需求,同時支持Web、移動端、IoT、物理機/虛擬機各種數據源的採集;
  2. 日誌實時通道,這個是為了對接上下游所必備的功能,保證日誌能夠被多種系統所便捷的使用;
  3. 數據清洗(ETL: Extract,Transform,Load),對各種格式的日誌進行清洗,支持過濾、富化、轉換、補漏、分裂、聚合等;
  4. 日誌展現與搜索,這是所有日誌平台必須具備的功能,能夠根據關鍵詞快速的定位到日誌並查看日誌上下文,看似簡單的功能卻最難做好;
  5. 實時分析,搜索只能完成一些定位到問題,而分析統計功能可以幫助快速分析問題的根因,同時可以用於快速的計算一些業務指標;
  6. 流計算,通常我們都會使用流計算框架(Flink、Storm、Spark Stream等)來計算一些實時的指標或對數據進行一些自定義的清洗等;
  7. 離線分析,運營、安全相關的需求都需要對大量的歷史日誌進行各種維度的關聯計算,目前只有T+1的離線分析引擎能夠完成;
  8. 機器學習框架,能夠便捷、快速的將歷史的日誌對接到機器學習框架進行離線訓練,並將訓練后的結果加載到線上實時的算法庫中。

開源方案設計

藉助於強大的開源社區,我們可以很容易基於開源軟件的組合來實現這樣一套日誌平台,上圖是一個非常典型的以ELK為核心的日誌平台方案:

  • 利用FileBeats、Fluentd等採集Agent實現容器上的數據統一收集。
  • 為了提供更加豐富的上下游以及緩衝能力,可以使用kafka作為數據採集的接收端。
  • 採集到的原始數據還需要進一步的清洗,可以使用Logstash或者Flink訂閱Kafka中的數據,清洗完畢后再寫入kafka中。
  • 清洗后的數據可以對接ElasticSearch來做實時的查詢檢索、對接Flink來計算實時的指標和告警、對接Hadoop來做離線的數據分析、對接TensorFlow來做離線模型訓練。
  • 數據的可視化可以使用grafana、kibana等常用的可視化組件。

為什麼我們選擇自研

採用開源軟件的組合是非常高效的方案,得益於強大的開源社區以及龐大用戶群體的經驗積累,我們可以很快搭建出這樣一套系統,並且可以滿足我們絕大部分的需求。

當我們把這套系統部署好,能夠把日誌從容器上採集上來、elasticsearch上能夠查到、Hadoop上能夠成功執行SQL、Grafana上能看到圖、告警短信能收到……完成上述流程打通后,加加班可能只需要花費幾天的時間,當系統終於跑通的時候,這時候終於可以長舒一口氣,躺在辦公椅上放鬆放鬆。

然而理想很豐滿現實很骨感,當我們預發通了,測試完了上到生產,開始接入第一個應用,逐漸更多的應用接入,越來越多的人開始使用……這時候很多問題都可能暴露出來:

  • 隨着業務量的上漲,日誌量也越來越大,Kakfa和ES要不斷擴容,同時同步Kafka到ES的Connector也需要擴容,最煩的是採集Agent,每台機器上部署的DaemonSet Fluentd根本沒辦法擴容,到了單Agent瓶頸就沒辦法了,只能換Sidecar,換Sidecar工作量大不說,還會帶來一系列其他的問題,比如怎麼和CICD系統集成、資源消耗、配置規劃、stdout採集不支持等等。
  • 從剛開始上的邊緣業務,慢慢更多的核心業務接入,對於日誌的可靠性要求越來越高,經常有研發反應從ES上查不到數據、運營說統計出來的報表不準、安全說拿到的數據不是實時的……每次問題的排查都要經過採集、隊列、清洗、傳輸等等非常多的路徑,排查代價非常高。同時還要為日誌系統搭建一套監控方案,能夠即時發現問題,而且這套方案還不能基於日誌系統,不能自依賴。
  • 當越來越多的開發開始用日誌平台調查問題時,經常會出現因為某1-2個人提交一個大的查詢,導致系統整體負載上升,其他人的查詢都會被Block,甚至出現Full GC等情況。這時候一些大能力的公司會對ES進行改造,來支持多租戶隔離;或者為不同的業務部門搭建不同的ES集群,最後又要運維多個ES集群,工作量還是很大。
  • 當投入了很多人力,終於能夠把日誌平台維持日常使用,這時候公司財務找過來了,說我們用了非常多的機器,成本太大。這時候開始要優化成本,但是思來想去就是需要這麼多台機器,每天大部分的機器水位都在20%-30%,但是高峰的水位可能到70%,所以不能撤,撤了高峰頂不住,這時候只能搞搞削峰填谷,又是一堆工作量。

上述這些是一家中等規模的互聯網企業在日誌平台建設中經常會遇到的問題,在阿里這些問題會放大非常多倍:

  • 比如面對雙十一的流量,市面上所有的開源軟件都無法滿足我們那麼大流量的需求。
  • 面對阿里內部上萬個業務應用,幾千名工程師同時使用,併發和多租戶隔離我們必須要做到極致。
  • 面對非常多核心的訂單、交易等場景,整個鏈路的穩定性必須要求3個9甚至4個9的可用性。
  • 每天如此大的數據量,對於成本的優化顯得極為重要,10%的成本優化帶來的收益可能就有上億。

阿里K8s日誌方案

針對上述的一些問題,我們經過多年的時間,開發並打磨出這樣一套K8s日誌方案:

  1. 使用我們自研的日誌採集Agent Logtail實現K8s全方位的數據採集,目前Logtail在集團內有數百萬的全量部署,性能、穩定性經過多次雙十一金融級考驗。
  2. 化繁為簡,數據隊列、清洗加工、實時檢索、實時分析、AI算法等原生集成,而不是基於各種開源軟件搭積木的形式實,大大降低了數據鏈路長度,鏈路長度的降低也意味着出錯可能性的減少。
  3. 隊列、清洗加工、檢索、分析、AI引擎等全部針對日誌場景深度定製優化,滿足大吞吐、動態擴容、億級日誌秒級可查、低成本、高可用性等需求。
  4. 對於流式計算、離線分析場景這種通用需求,無論是開源還是阿里內部都有非常成熟的產品,我們通過無縫對接的方式來支持,目前日誌服務支持了數十種下游的開源、雲上產品的對接。

這套系統目前支撐了整個阿里集團、螞蟻集團、雲上上萬家企業的日誌分析,每天寫入的數據量16PB+,開發、運維這樣一套系統問題和挑戰非常多,這裏就不再展開,有興趣的同學可以參考我們團隊的技術分享:。

總結

本篇主要從架構層面去介紹如何搭建一套K8s的日誌分析平台,包括開源方案以及我們阿里自研的一套方案。然而實際這套系統落地到生產環境並有效運行還有很多工作要做:

  1. K8s上以什麼樣的姿勢來打日誌?
  2. K8s上的日誌採集方案選擇,DaemonSet or Sidecar?
  3. 日誌方案如何與CICD去集成?
  4. 微服務下各個應用的日誌存儲如何劃分?
  5. 如何基於K8s系統的日誌去做K8s監控?
  6. 如何去監控日誌平台的可靠性?
  7. 如何去對多個微服務/組件去做自動的巡檢?
  8. 如何自動的監控多個站點並實現流量異常時的快速定位?

後續文章我們會一步一步來和大家分享如何把這套系統落地,敬請期待。

“ 阿里巴巴雲原生微信公眾號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公眾號。”

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

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

NASA 確定地軸飄移三大原因,人類活動改變了地球基本運作方式

摘錄自2018年9月25日科技新報報導

NASA 科學家收集整個20世紀的數據進行研究,近期發表在《地球與行星科學快報》的新論文,確認了共有3大原因造成地軸飄移:冰期後反彈、格陵蘭島冰蓋損失以及地函對流。其中,造成格陵蘭島冰蓋流失的罪魁禍首,正是人類活動引起的全球暖化。

地球系統科學家Surendra Adhikari表示,研究團隊設計出一套地球自旋物理學電腦模型,加入20世紀大陸冰川(冰蓋)與海水平衡變化的所有數據,終於找出影響地軸飄移至關重要的第2個原因:格陵蘭島冰蓋大量融化。

目前地球上僅存的大陸冰川只剩下南極洲與格陵蘭島,南極冰蓋覆蓋範圍約1,400萬平方公里,隨著20世紀氣溫上升加劇,格陵蘭冰蓋至今已有約7,500億噸的冰融化進入海洋,這導致地球質量分佈發生變化,進而使地軸飄移。一旦南極冰蓋融化,全球海平面將上升61.1公尺;格陵蘭冰蓋則占據格陵蘭島82%陸地面積,如果格陵蘭冰蓋融化,將導致海平面上升7.2公尺。這項研究明確顯示了人類活動正在改變地球的基本性質及運作方式。

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

【其他文章推薦】

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

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

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

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

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?