屋頂不夠用沒關係 日開發新太陽能建材 突破瓶頸

文:宋瑞文(加州能源特約撰述)

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

比亞迪將在太原打造中西部首個純電動客車、專用車基地

3月25日,“太原比亞迪新能源汽車基地奠基儀式”在太原經濟技術開發區舉行。比亞迪將在太原打造中西部地區首個以純電動客車、專用車、工礦作業車為重點領域的新能源汽車製造與研發基地。

根據規劃,太原比亞迪新能源汽車基地位於太原市經濟技術開發區太太路(西攢村),專案分兩期建設,計畫總投資40億元人民幣,占地1100畝,規劃年產5000輛純電動客車、5000輛純電動專用車和2000輛工礦作業車生產能力。兩期工程全部建成投產後,可實現年產值超過150億元。此外,比亞迪還將進駐山西省科創城,成立純電動工礦作業車研發中心,全面深化新能源汽車“7+4”全市場戰略佈局。

未來,太原比亞迪基地將立足山西,在輻射中西部的同時,面向中、西、南亞,構建山西省新能源汽車產業核心競爭力,積極融入國家“一帶一路”經濟圈。

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

【Spring】Spring的定時任務註解@Scheduled原來如此簡單

1 簡介

定時任務的實現非常多,JDK的Timer、Spring提供的輕量級的Scheduled TaskQuartZLinux Cron等,還有一些分佈式的任務調度框架。本文主要介紹Scheduled Task的使用。

2 方便的4種方式

註解@Scheduled只能用於滿足下面兩個條件的方法上:

(1)沒有返回類型,或者說返回類型為void

(2)沒有參數;

開啟Spring的Scheduler非常簡單,一個註解@EnableScheduling即可:

@Configuration
@EnableScheduling
public class SchedulingConfig {
}

如果是Springboot應用,則直接在啟動類上面加上@EnableScheduling就可以使用了。

2.1 固定延遲fixedDelay

代表下一個任務的開始與上一個任務的結束間隔總是固定的時長,而且總是會等上一個任務完成了,才會開啟下一個任務。如果需求是有這樣依賴要求的,使用這種模式是非常合適的。代碼如下:

@Scheduled(fixedDelay = 1000)
public void fixedDelay() {
  log.info("fixedDelay");
}

參數為1000,代表固定延遲為1000毫秒,即1秒鐘,所以輸出為:

2019-11-19 21:02:43,977 scheduling-1:fixedDelay 
2019-11-19 21:02:44,981 scheduling-1:fixedDelay 
2019-11-19 21:02:45,983 scheduling-1:fixedDelay 
2019-11-19 21:02:46,984 scheduling-1:fixedDelay 

2.2 固定頻率fixedRate

2.2.1 正常情況

定頻任務的特性是任務的執行的時間間隔總是一樣的。比如每1小時執行一次,就是任務執行開始的時間點的時間間隔為1小時。代碼如下:

@Scheduled(fixedRate = 2000)
public void fixedRate() {
  log.info("fixedRate");
}

參數為2000,則每2秒執行一次,輸出為:

2019-11-19 21:38:45,073 scheduling-1:fixedRate 
2019-11-19 21:38:47,076 scheduling-1:fixedRate 
2019-11-19 21:38:49,073 scheduling-1:fixedRate 
2019-11-19 21:38:51,075 scheduling-1:fixedRate 

2.2.2 默認單線程

需要注意的是它默認是單線程的,不會并行執行。即使是固定頻率,但下一次的任務也必須等到上一次任務執行完畢才會開始。下面這個例子能很好說明:

@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
  log.info("fixedRateLongTimeTask");
  Thread.sleep(3000);
}

由於任務需要執行3秒才能完成,即使fixedRate設置為1秒,並不能每一秒執行一次,輸出如下:

2019-11-19 21:46:00,108 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:03,113 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:06,113 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:09,117 scheduling-1:fixedRateLongTimeTask 

每3次輸出一次。

2.2.3 註解@Async來幫你

上述問題有辦法解決嗎?答案是肯定的,而且非常簡單。只需要加一個註解@Async就可以使任務能異步多線程地執行了,代碼如下:

@Async
@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
  log.info("fixedRateLongTimeTask");
  Thread.sleep(3000);
}

通過日誌可以看出是每秒執行一次的,即使前面的任務還沒有完成。而且線程名不一樣,通過多線程來執行,輸出結果為:

2019-11-19 21:54:22,261 task-5:fixedRateLongTimeTask 
2019-11-19 21:54:23,257 task-6:fixedRateLongTimeTask 
2019-11-19 21:54:24,257 task-4:fixedRateLongTimeTask 
2019-11-19 21:54:25,257 task-8:fixedRateLongTimeTask 
2019-11-19 21:54:26,259 task-1:fixedRateLongTimeTask 
2019-11-19 21:54:27,262 task-2:fixedRateLongTimeTask 
2019-11-19 21:54:28,260 task-3:fixedRateLongTimeTask 

注意:需要指出的是,需要像@EnableScheduling一樣,需要添加配置註解@EnableAsync來打開這個功能開關。另外,如果任務執行時間很長,例如1分鐘,情況又不一樣。以後再詳細介紹@Async的使用吧。

2.3 初始延遲initialDelay

初始延遲是用initialDelay來指定的,它可以延遲第一次任務執行的時間。如下例子的參數為30秒,則在啟動30秒后,才開始執行第一次。可以減輕項目啟動的負擔,也可以為任務執行前準備數據。

@Scheduled(fixedDelay = 1000, initialDelay = 30*1000)
public void fixedDelayWithIntialDelay() {
  log.info("fixedDelayWithIntialDelay");
}

輸出如下:

2019-11-19 22:10:02,092 main:Tomcat started on port(s): 443 (http) with context path '' 
2019-11-19 22:10:02,095 main:Started DemoApplication in 1.272 seconds (JVM running for 1.767) 
2019-11-19 22:10:32,063 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:33,067 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:34,069 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:35,069 scheduling-1:fixedDelayWithIntialDelay

可以看出,在項目啟動后30秒左右,才開始執行任務。

2.4 Cron表達式

上述提供的功能並不能滿足定時任務調度的所有需求,比如需要每個月1號發送短信,每周六做數據分析等。這裏Cron表達式就派上用場了。

下面的例子表示每當秒數為06的時候就執行。代碼如下:

@Scheduled(cron = "6 * * ? * *")
public void cron() {
  log.info("cron");
}

結果如下:

2019-11-19 22:20:06,003 scheduling-1:cron 
2019-11-19 22:21:06,004 scheduling-1:cron 
2019-11-19 22:22:06,002 scheduling-1:cron 

Cron表達式功能非常強大,網上資料很豐富,這裏不展開講了。

3 參數配置化

之前的例子都將參數寫死在代碼上了,如果需要更靈活,其實可以用參數來配置。這樣需要修改參數的時候,不用修改代碼、編譯打包再部署了,直接修改配置文件即可。

代碼如下:

@Scheduled(cron = "${pkslow.cron}")
public void cronWithConfig() {
  log.info("cronWithConfig");
}

在application.properties配置如下:

pkslow.cron=* * * ? * *

代碼1秒執行一次。

4 如果她突然消失了

由於Spring的Scheduler默認是單線程的,這樣會存在一個問題,如果某個任務執行卡住了,那就無法繼續往下執行了。在日誌上表現就是突然消失了。這種情況出現的概率還是不小的,如操作數據庫死鎖了,http請求timeout為無限等待,還有其它原因的死鎖等。

當遇到這種情況,應通過命令jstack pid > pid.ThreadDump.txt獲取當前線程情況,然後分析是否真的是卡住了,卡在了哪個環節,然後再分析具體代碼。通過設置超時或重試等方法來解決。

5 結論

本文主要介紹了Spring的定時任務註解@Scheduled的使用,講述了多種方式的使用和配置。它非常方便簡潔,對於簡單的定時任務足以應對了。

歡迎關注公眾號<南瓜慢說>,將持續為你更新…

多讀書,多分享;多寫作,多整理。

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

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

社交距離引爆孤獨感 美國認養寵物暴增

摘錄自2020年03月22日中央通訊社美國報導

為避免武漢肺炎疫情擴散,包括美國在內,全球許多國家呼籲民眾不要外出留在家。但待在家裡無法與人接觸引發的孤獨感,以及可以空出時間照料,都讓寵物認養數目大幅攀升。

華盛頓郵報(Washington Post)報導,過去一段時間寵物認養倍增,馬里蘭州蓋瑟斯堡(Gaithersburg)動物救援所過去週日平均約15隻貓狗能找到認養家庭,最近排隊認養的人數從10人增加到40人,3小時就有30隻動物被認養。

美國愛護動物協會(American Society for the Prevention of Cruelty to Animals)總裁兼執行長薄夏德克爾(Matt Bershadker)透過郵件表示,動物能夠提供舒適感與陪伴感,特別是在危機時刻,他們鼓勵民眾繼續認養或暫時認養動物。

動物福利
流浪動物
國際新聞
美國
寵物
COVID-19

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

神州專車與阿裡巴巴將在“互聯網+汽車”領域進行全方位戰略合作

4月11日,神州專車的運營主體神州優車股份有限公司正式宣佈,已與阿裡巴巴(中國)網路技術有限公司簽署戰略合作協定,結成戰略合作夥伴關係。

根據協定,雙方將在“互聯網+汽車”領域進行全方位的戰略合作,致力於重塑相關產業鏈及生態體系。 在雙方戰略合作的總體框架下,雙方將首先在汽車電商、大資料行銷、雲計算應用、高精地圖及出行大資料、智慧汽車等各方面推進合作。

對此,阿裡方面表示,阿裡巴巴與神州優車確已達成戰略合作協定,但阿裡巴巴目前在神州優車沒有股權。

值得注意的是,神州專車、神州租車與阿裡旅行在業務層面合作早已展開,並已經在阿裡旅行平臺上開設官方旗艦店。神州專車曾對媒體表示,未來神州專車、神州租車還將把用車服務與阿裡旅行出行項目進行諸如“酒店+車”“高爾夫+車”“旅遊路線+車”等形式增值打包。

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

Zabbix-(四)郵件、釘釘告警通知

Zabbix-(四)郵件、釘釘告警通知

一.前言

在之前的文章里,通過Zabbix對主機的磁盤、CPU以及內存進行了監控,並在首頁Dashboard里創建了監控圖形,但是只有當我們登錄到Zabbix后才能看到監控到的問題(Problem),因此在本篇文章里,將利用觸發器(Trigger),以及媒介(Media)等配置項,實現當觸發器觸發時,通過不同媒介,如:郵件、釘釘,發送動作(Action),實現實時通知告警功能。

準備

  • Zabbix Server (Zabbix 4.4)
  • 在Zabbix中已配置一些監控項和觸發器(這些配置可以參考我的)

二.安裝相關環境

由於使用到腳本告警媒介,本文中通過調用Python腳本觸發告警,因此需要在Zabbix Server主機上安裝pip以及相關模塊。(這裏Python使用Centos7自帶的Python2.7.5)

  1. 安裝pip

    # yum install -y epel-release
    
    # yum install -y python-pip
  2. 安裝requests模塊

    # pip install requests

三.配置告警媒介類型

Zabbix默認自帶了2種報警媒介類型(Media Type)电子郵件以及短信,我們將修改电子郵件類型配置,並新建腳本類型和Webhook類型。希望通過腳本、Webhook告警媒介發送釘釘消息。

注:Webhook告警媒介是Zabbix 4.4的新特性

  1. 修改电子郵件告警媒介

    點擊【管理】-【報警媒介類型】-【Email】

    修改Email配置,我這裏用的是Outlook郵箱,具體SMTP服務器可以參考。使用其他郵箱也可以去對應官網查詢SMTP配置。

    測試發送郵箱,點擊【測試】

    輸入收件人郵箱

    收到郵件

  2. 新增腳本告警媒介

    新建Python腳本告警媒介,用戶釘釘告警

    點擊【創建媒體類型】

    進行配置

    配置項
    * 名稱 Python腳本
    類型 腳本
    * 腳本名稱 pythonScript.py
    腳本參數(參數1) {ALERT.MESSAGE}
    腳本參數(參數2) {ALERT.SENDTO}
    腳本參數(參數3) {ALERT.SUBJECT}

    接下來新建Python腳本,Zabbix Server配置文件中可以配置告警腳本路徑,默認為 /usr/lib/zabbix/alertscripts

    # 查看告警腳本路徑
    # cat zabbix_server.conf | grep AlertScriptsPath

    編寫告警腳本

    # cd /usr/lib/zabbix/alertscripts
    # vim pythonScript.py

    腳本內容

    #!/usr/bin/env python
    #coding:utf-8
    
    import requests,json,sys,os,datetime
    
    # 釘釘機器人地址
    webhook="https://oapi.dingtalk.com/robot/send?access_token=your_dingding_robot_access_token"
    
    # 對應{ALERT.SENDTO}, Zabbix告警媒介配置界面第2個參數
    user=sys.argv[2]
    
    # 對應{ALERT.MESSAGE}, Zabbix告警媒介配置界面第1個參數
    text=sys.argv[1]
    data={
        "msgtype": "text",
        "text": {
            "content": text
        },
        "at": {
            "atMobiles": [
                user
            ],
            "isAtAll": False
        }
    }
    headers = {'Content-Type': 'application/json'}
    x=requests.post(url=webhook,data=json.dumps(data),headers=headers)

    給腳本可執行權限

    # chmod uo+x /usr/lib/zabbix/alertscripts/pythonScript.py

    測試腳本

    釘釘收到消息

  3. 新增Webhook告警媒介

    配置項
    * 名稱 Webhook
    類型 Webhook
    參數: (名稱)
    user {ALERT.SENDTO}
    subject {ALERT.SUBJECT}
    message {ALERT.MESSAGE}

    腳本:

    try {
        Zabbix.Log(4, 'params= '+value);
    
        params = JSON.parse(value);
        req = new CurlHttpRequest();
        data = {};
        result = {};
    
        req.AddHeader('Content-Type: application/json');
    
        data.msgtype = "text";
        //   對應 message參數
        data.text = {"content" : params.message};
        //   對應 user參數
        data.at = {"atMobiles": [params.user], "isAtAll": "false"};
    
        //   釘釘機器人
        resp = req.Post('https://oapi.dingtalk.com/robot/send?access_token=your_access_token',
            JSON.stringify(data)
        );
    } catch (error) {
        result = {};
    }
    
    return JSON.stringify(result);

    測試Webhook

四.為用戶添加告警媒介

需要將新增的告警媒介添加給用戶

點擊【用戶】-【告警媒介】

將上述步驟添加的告警媒介(Python腳本、Webhoob、Email),進行添加(收件人根據告警媒介類型填寫郵箱手機號),嚴重性也根據需要勾選。

五.配置動作

完成上述配置完成后,需要創建動作(Action),將觸發器(Trigger)告警媒介(Media Type)進行關聯,一旦觸發器觸發,那麼Zabbix會執行動作,再去執行告警媒介。

  1. 添加動作

    點擊【配置】-【動作】-【創建動作】

  2. 配置【動作】相關信息

    配置項
    * 名稱 告警動作
    新的觸發條件 【觸發器】【等於】【Template Disk Free Size: 磁盤剩餘空間觸發器】

    操作步驟如下圖:

    群組選擇 ->Linux servers

    主機選擇 -> Template Disk Free Size 模板()

    勾選觸發器 -> 磁盤剩餘空間觸發器 ()

    勾選後點擊【選擇】

  3. 配置【操作】相關信息

    點擊【操作】

    先配置以下信息

    配置項
    * 默認操作步驟持續時間 1h(保持默認)
    默認標題 告警: {EVENT.NAME}
    消息內容 【磁盤空間不足告警】
    告警事件: {EVENT.DATE} {EVENT.TIME}
    告警問題: {EVENT.NAME}
    告警主機: {HOST.IP} {HOST.NAME}
    告警級別: {EVENT.SEVERITY}
    磁盤剩餘:{ITEM.VALUE}

    上述配置表格【默認標題】和【消息內容】值中形如{EVENT.NAME}的內容是Zabbix中的宏(Marco),宏是一個變量,例如 {HOST.IP} 表示告警主機的IP地址,Zabbix自帶的宏可以參考

    繼續配置操作

    點擊【新的】

    【操作類型】選擇發送消息,【發送到用戶】添加Admin

    【僅送到】根據需要選擇之前配置的,本文選擇Email和Python腳本(這裏只能單選或全選,所以需要先選擇一個,因此需要多次)

    添加完成後點擊【添加】

六.測試

向被監控主機拷貝或下載大文件,使其磁盤剩餘空間低於觸發器監控閾值,等待觸發器觸發問題,查看儀錶盤、郵件等。

儀錶盤

釘釘

郵件

七.參考文檔

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

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

一文帶你深入了解 Redis 的持久化方式及其原理

Redis 提供了兩種持久化方式,一種是基於快照形式的 RDB,另一種是基於日誌形式的 AOF,每種方式都有自己的優缺點,本文將介紹 Redis 這兩種持久化方式,希望閱讀本文後你對 Redis 的這兩種方式有更加全面、清晰的認識。

RDB 快照方式持久化

先從 RDB 快照方式聊起,RDB 是 Redis 默認開啟的持久化方式,並不需要我們單獨開啟,先來看看跟 RDB 相關的配置信息:

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#   save ""
# 自動生成快照的觸發機制 中間的是時間,單位秒,後面的是變更數據 60 秒變更 10000 條數據則自動生成快照
save 900 1
save 300 10
save 60 10000

# 生成快照失敗時,主線程是否停止寫入
stop-writes-on-bgsave-error yes

# 是否採用壓縮算法存儲
rdbcompression yes

# 數據恢復時是否檢測 RDB文件有效性
rdbchecksum yes

# The filename where to dump the DB
# RDB 快照生成的文件名稱
dbfilename dump.rdb

# 快照生成的路徑 AOF 也是存放在這個路徑下面
dir .

關於 RDB 相關配置信息不多,需要我們調整的就更少了,我們只需要根據自己的業務量修改生成快照的機制和文件存放路徑即可。

RDB 有兩種持久化方式:手動觸發自動觸發手動觸發使用以下兩個命令:

  • save:會阻塞當前 Redis 服務器響應其他命令,直到 RDB 快照生成完成為止,對於內存 比較大的實例會造成長時間阻塞,所以線上環境不建議使用

  • bgsave:Redis 主進程會 fork 一個子進程,RDB 快照生成有子進程來負責,完成之後,子進程自動結束,bgsave 只會在 fork 子進程的時候短暫的阻塞,這個過程是非常短的,所以推薦使用該命令來手動觸發

除了執行命令手動觸發之外,Redis 內部還存在自動觸發 RDB 的持久化機制,在以下幾種情況下 Redis 會自動觸發 RDB 持久化

  • 在配置中配置了 save 相關配置信息,如我們上面配置文件中的 save 60 10000 ,也可以把它歸類為“save m n”格式的配置,表示 m 秒內數據集存在 n 次修改時,會自動觸發 bgsave。

  • 在主從情況下,如果從節點執行全量複製操作,主節點自動執行 bgsave 生成 RDB 文件併發送給從節點

  • 執行 debug reload 命令重新加載 Redis 時,也會自動觸發 save 操作

  • 默認情況下執行 shutdown 命令時,如果沒有開啟 AOF 持久化功能則自動執行 bgsave

上面就是 RDB 持久化的方式,可以看出 save 命令使用的比較少,大多數情況下使用的都是 bgsave 命令,所以這個 bgsave 命令還是有一些東西,那接下來我們就一起看看 bgsave 背後的原理,先從流程圖開始入手:

bgsave 命令大概有以下幾個步驟:

  • 1、執行 bgsave 命令,Redis 主進程判斷當前是否存在正在執行的 RDB/AOF 子進程,如果存在, bgsave 命令直接返回不在往下執行。
  • 2、父進程執行 fork 操作創建子進程,fork 操作過程中父進程會阻塞,fork 完成後父進程將不在阻塞可以接受其他命令。
  • 3、子進程創建新的 RDB 文件,基於父進程當前內存數據生成臨時快照文件,完成後用新的 RDB 文件替換原有的 RDB 文件,並且給父進程發送 RDB 快照生成完畢通知

上面就是 bgsave 命令背後的一些內容,RDB 的內容就差不多了,我們一起來總結 RDB 持久化的優缺點,RDB 方式的優點

  • RDB 快照是某一時刻 Redis 節點內存數據,非常適合做備份,上傳到遠程服務器或者文件系統中,用於容災備份
  • 數據恢復時 RDB 要遠遠快於 AOF

有優點同樣存在缺點,RDB 的缺點有

  • RDB 持久化方式數據沒辦法做到實時持久化/秒級持久化。我們已經知道了 bgsave 命令每次運行都要執行 fork 操作創建子進程,屬於重量級操作,頻繁執行成本過高。
  • RDB 文件使用特定二進制格式保存,Redis 版本演進過程中有多個格式 的 RDB 版本,存在老版本 Redis 服務無法兼容新版 RDB 格式的問題

如果我們對數據要求比較高,每一秒的數據都不能丟,RDB 持久化方式肯定是不能夠滿足要求的,那 Redis 有沒有辦法滿足呢,答案是有的,那就是接下來的 AOF 持久化方式

AOF 持久化方式

Redis 默認並沒有開啟 AOF 持久化方式,需要我們自行開啟,在 redis.conf 配置文件中將 appendonly no 調整為 appendonly yes,這樣就開啟了 AOF 持久化,與 RDB 不同的是 AOF 是以記錄操作命令的形式來持久化數據的,我們可以查看以下 AOF 的持久化文件 appendonly.aof

*2
$6
SELECT
$1
0
*3
$3
set
$6
mykey1
$6
你好
*3
$3
set
$4
key2
$5
hello
*1
$8

大概就是長這樣的,具體的你可以查看你 Redis 服務器上的 appendonly.aof 配置文件,這也意味着我們可以在 appendonly.aof 文件中國修改值,等 Redis 重啟時將會加載修改之後的值。看似一些簡單的操作命令,其實從命令到 appendonly.aof 這個過程中非常有學問的,下面時 AOF 持久化流程圖:

在 AOF 持久化過程中有兩個非常重要的操作:一個是將操作命令追加到 AOF_BUF 緩存區,另一個是 AOF_buf 緩存區數據同步到 AOF 文件,接下來我們詳細聊一聊這兩個操作:

1、為什麼要將命令寫入到 aof_buf 緩存區而不是直接寫入到 aof 文件?

我們知道 Redis 是單線程響應,如果每次寫入 AOF 命令都直接追加到磁盤上的 AOF 文件中,這樣頻繁的 IO 開銷,Redis 的性能就完成取決於你的機器硬件了,為了提升 Redis 的響應效率就添加了一層 aof_buf 緩存層, 利用的是操作系統的 cache 技術,這樣就提升了 Redis 的性能,雖然這樣性能是解決了,但是同時也引入了一個問題,aof_buf 緩存區數據如何同步到 AOF 文件呢?由誰同步呢?這就是我們接下來要聊的一個操作:fsync 操作

2、aof_buf 緩存區數據如何同步到 aof 文件中?

aof_buf 緩存區數據寫入到 aof 文件是有 linux 系統去完成的,由於 Linux 系統調度機制周期比較長,如果系統故障宕機了,意味着一個周期內的數據將全部丟失,這不是我們想要的,所以 Linux 提供了一個 fsync 命令,fsync 是針對單個文件操作(比如這裏的 AOF 文件),做強制硬盤同步,fsync 將阻塞直到寫入硬盤完成后返回,保證了數據持久化,正是由於有這個命令,所以 redis 提供了配置項讓我們自行決定何時進行磁盤同步,redis 在 redis.conf 中提供了appendfsync 配置項,有如下三個選項:

# appendfsync always
appendfsync everysec
# appendfsync no
  • always:每次有寫入命令都進行緩存區與磁盤數據同步,這樣保證不會有數據丟失,但是這樣會導致 redis 的吞吐量大大下降,下降到每秒只能支持幾百的 TPS ,這違背了 redis 的設計,所以不推薦使用這種方式
  • everysec:這是 redis 默認的同步機制,雖然每秒同步一次數據,看上去時間也很快的,但是它對 redis 的吞吐量沒有任何影響,每秒同步一次的話意味着最壞的情況下我們只會丟失 1 秒的數據, 推薦使用這種同步機制,兼顧性能和數據安全
  • no:不做任何處理,緩存區與 aof 文件同步交給系統去調度,操作系統同步調度的周期不固定,最長會有 30 秒的間隔,這樣出故障了就會丟失比較多的數據。

這就是三種磁盤同步策略,但是你有沒有注意到一個問題,AOF 文件都是追加的,隨着服務器的運行 AOF 文件會越來越大,體積過大的 AOF 文件對 redis 服務器甚至是主機都會有影響,而且在 Redis 重啟時加載過大的 AOF 文件需要過多的時間,這些都是不友好的,那 Redis 是如何解決這個問題的呢?Redis 引入了重寫機制來解決 AOF 文件過大的問題。

3、Redis 是如何進行 AOF 文件重寫的?

Redis AOF 文件重寫是把 Redis 進程內的數據轉化為寫命令同步到新 AOF 文件的過程,重寫之後的 AOF 文件會比舊的 AOF 文件占更小的體積,這是由以下幾個原因導致的:

  • 進程內已經超時的數據不再寫入文件
  • 舊的 AOF 文件含有無效命令,如 del key1、hdel key2、srem keys、set a111、set a222等。重寫使用進程內數據直接生成,這樣新的AOF文件只保 留最終數據的寫入命令
  • 多條寫命令可以合併為一個,如:lpush list a、lpush list b、lpush list c可以轉化為:lpush list a b c。為了防止單條命令過大造成客戶端緩衝區溢 出,對於 list、set、hash、zset 等類型操作,以 64 個元素為界拆分為多條。

重寫之後的 AOF 文件體積更小了,不但能夠節約磁盤空間,更重要的是在 Redis 數據恢復時,更小體積的 AOF 文件加載時間更短。AOF 文件重寫跟 RDB 持久化一樣分為手動觸發自動觸發,手動觸發直接調用 bgrewriteaof 命令就好了,我們後面會詳細聊一聊這個命令,自動觸發就需要我們在 redis.conf 中修改以下幾個配置

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
  • auto-aof-rewrite-percentage:代表當前 AOF文件空間 (aof_current_size)和上一次重寫后 AOF 文件空間(aof_base_size)的比值,默認是 100%,也就是一樣大的時候
  • auto-aof-rewrite-min-size:表示運行 AOF 重寫時 AOF 文件最小體積,默認為 64MB,也就是說 AOF 文件最小為 64MB 才有可能觸發重寫

滿足了這兩個條件,Redis 就會自動觸發 AOF 文件重寫,AOF 文件重寫的細節跟 RDB 持久化生成快照有點類似,下面是 AOF 文件重寫流程圖:

AOF 文件重寫也是交給子進程來完成,跟 RDB 生成快照很像,AOF 文件重寫在重寫期間建立了一個 aof_rewrite_buf 緩存區來保存重寫期間主進程響應的命令,等新的 AOF 文件重寫完成后,將這部分文件同步到新的 AOF 文件中,最後用新的 AOF 文件替換掉舊的 AOF 文件。需要注意的是在重寫期間,舊的 AOF 文件依然會進行磁盤同步,這樣做的目的是防止重寫失敗導致數據丟失,

Redis 持久化數據恢復

我們知道 Redis 是基於內存的,所有的數據都存放在內存中,由於機器宕機或者其他因素重啟了就會導致我們的數據全部丟失,這也就是要做持久化的原因,當服務器重啟時,Redis 會從持久化文件中加載數據,這樣我們的數據就恢復到了重啟前的數據,在數據恢復這一塊Redis 是如何實現的?我們先來看看數據恢復的流程圖:

Redis 的數據恢複流程比較簡單,優先恢復的是 AOF 文件,如果 AOF 文件不存在時則嘗試加載 RDB 文件,為什麼 RDB 的恢復速度比 AOF 文件快,但是還是會優先加載 AOF 文件呢?我個人認為是 AOF 文件數據更全面並且 AOF 兼容性比 RDB 強,需要注意的是當存在 RDB/AOF 時,如果數據加載不成功,Redis 服務啟動會失敗。

最後

目前互聯網上很多大佬都有 Redis 系列教程,如有雷同,請多多包涵了。原創不易,碼字不易,還希望大家多多支持。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公眾號:「平頭哥的技術博文」,和平頭哥一起學習,一起進步。

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

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

Thrift總結(四)Thrift實現雙向通信

前面介紹過 Thrift 安裝和使用,介紹了Thrift服務的發布和客戶端調用,可以查看我之前的文章:

但是,之前介紹的都是單向的客戶端發送消息,服務端接收消息。而客戶端卻得不到服務器的響應。

那如果我們要實現雙向通信(即:客戶端發送請求,服務端處理返回,服務端發送消息,客戶端處理返回)的功能,該怎麼實現呢?

 

其實在不涉及語言平台的制約,WebService或是webapi 就可以實現這種客戶端發起請求,服務端的處理的單向流程。

然而,實際場景中,可能我們的某些業務需求,更需要服務端能夠響應請求並處理數據。下面我通過一個demo案例,介紹下Thrift 是如何實現雙向通信的。

 

一、安裝Thrift

這裏不再贅述,戳這裏查看我上篇文章的介紹:

 

二、編寫Thrift IDL文件 

編寫thrift腳本,命名為student.thrift  如下:

service HelloWorldService{
    void SayHello(1:string msg);
}

生成service 的方法,之前的文章有介紹,這裏就不介紹了。

 

三、編寫服務端代碼

創建HelloThrift.Server 服務端工程,添加HelloWorldBidirectionServer類,HelloWorldBidirectionServer 實現了Iface接口用於接收客戶端消息,並有一個客戶端傳輸層對象集合用於記錄所有已連接的客戶端。

 public class HelloWorldBidirectionServer : HelloWorldBidirectionService.Iface
    {
        public void Run(int port)
        {
            try
            {
                TServerTransport transport = new TServerSocket(port);

                TTransportFactory transportFac = new TTransportFactory();

                TProtocolFactory inputProtocolFactory = new TBinaryProtocol.Factory();
                TThreadPoolServer server = new TThreadPoolServer(getProcessorFactory(), transport, transportFac, inputProtocolFactory);

                server.Serve();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static List<TTransport> TransportCollection = new List<TTransport>();

        public void SayHello(string msg)
        {
            Console.WriteLine(string.Format("{0:yyyy/MM/dd hh:mm:ss} 服務端接收到消息: {1}", DateTime.Now, msg));
        }

        public void SayToClient(string msg)
        {
            try
            {
                foreach (TTransport trans in TransportCollection)
                {
                    TBinaryProtocol protocol = new TBinaryProtocol(trans);
                    HelloWorldBidirectionService.Client client = new HelloWorldBidirectionService.Client(protocol);
                    //Thread.Sleep(1000);
                    client.SayHello(msg);
                    //Console.WriteLine("發給了客戶端喲");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public TProcessorFactory getProcessorFactory()
        {
            return new HelloWorldBidirectionProcessor();
        }
    }

    public class HelloWorldBidirectionProcessor : TProcessorFactory
    {
        public TProcessor GetProcessor(TTransport trans, TServer server = null)
        {
            if (trans.IsOpen)
            {
                HelloWorldBidirectionServer.TransportCollection.Add(trans);
                Console.WriteLine("客戶端連上。");
            }

            HelloWorldBidirectionServer srv = new HelloWorldBidirectionServer();
            return new global::HelloWorldBidirectionService.Processor(srv);
        }
    }

 

四、編寫客戶端代碼

首先創建HelloThrift.Client客戶端項目,添加接收服務端消息的類HelloWorldBidirectionClient,裏面只有一個實現Iface接口的方法:

  public class HelloWorldBidirectionClient
    {
        static HelloWorldBidirectionService.Client client = null;
        public void ConnectAndListern(int port, string ip = "127.0.0.1")
        {
            //Tsocket: TCP/IP Socket接口
            TSocket tSocket = new TSocket(ip, port);
            //消息結構協議
            TProtocol protocol = new TBinaryProtocol(tSocket);
            try
            {
                if (client == null)
                {
                    client = new global::HelloWorldBidirectionService.Client(protocol);
                    tSocket.Open();//建立連接
                    StartListern(tSocket);//啟動監聽線程
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void Say(string msg)
        {
            if (client != null)
                client.SayHello(msg);
        }

        void StartListern(TSocket tSocket)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Run));
            t.Start(tSocket);
        }

        public void Run(object tSocket)
        {
            HelloWorldBidirectionService.Processor process = new HelloWorldBidirectionService.Processor(new HelloWorldBidirectionFace());

            try
            {
                while (process.Process(new TBinaryProtocol((TSocket)tSocket), new TBinaryProtocol((TSocket)tSocket)))
                {
                    Console.WriteLine("消息接收完成,等下一波,阻塞中......");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("連接斷開..." + ex.Message);
            }
        }

    }
    class HelloWorldBidirectionFace : HelloWorldBidirectionService.Iface
    {
        public void SayHello(string msg)
        {
            Console.WriteLine(string.Format("{0:yyyy/MM/dd hh:mm:ss} 收到服務端響應消息 {1}", DateTime.Now, msg));

        }
    }

 實現客戶端,ConnectAndListern方法可以與服務端建立連接,並開啟客戶端端口監聽來自服務端的信息。Say方法可將消息發送至服務端。

 

五、測試

 測試效果如下:

 

 

 

六、最後

  1. 關於使用Thrift 構建我們自己的rpc 的方法,這裏基本講完了。其他的方法本文就不再演示了,調用起來都是一樣。  

  2. 後續會簡單討論一下Thrift 框架的通信原理。

  3. 源代碼下載,

 

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

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

蘇門答臘瀕危老虎 受困捕獸陷阱後死亡

摘錄自2018年9月26日中央社報導

印尼官員今天(26日)說,一頭被列為極度瀕危物種的蘇門答臘虎死屍在蘇門答臘島廖內省(Riau)的慕亞拉藍布村(Muara Lembu)附近山溝被發現,根據虎屍肚子上圍繞著陷阱裡的繩索研判,應是受困獵人所設陷阱後死亡。

稍早,當地村民告訴保育機構說,有人看到一頭雌蘇門答臘虎受困獵人為捕獵野豬設置的陷阱。但官員趕往現場後,已不見老虎。官員隔天回到原區域搜尋,才在附近山溝尋獲。

國際自然保育聯盟(IUCN)將蘇門答臘虎列為「極危」的瀕危動物。自然界只剩不到400頭蘇門答臘虎,環保人士說,由於蘇門答臘虎自然棲息地迅速縮減,使牠們與人類發生衝突的機率升高。

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?

百度聯手奇瑞安徽蕪湖建首個“全無人駕駛運營區域”

日前,百度與安徽省蕪湖市人民政府正式簽訂合作協定,雙方將在蕪湖共同建設“全無人駕駛汽車運營區域”。

安徽省蕪湖市市長潘朝輝稱,百度正在與奇瑞聯手打造全自動駕駛汽車。奇瑞汽車有限公司董事長尹同躍也表示,首批試運營車將由奇瑞提供。數量有20-30台,均達到全自動駕駛水準。目前車輛已經完成自動駕駛改裝,即將上路測試。

此次與蕪湖市人民政府共建的運營區域會隨著時間逐漸擴大範圍。第一階段全自動駕駛汽車會在道況簡單的有限區域進行試運營,3-5年之間擴大區域,5年之後實現全市示範。

關於車輛具體歸屬,技術分工,第一階段運營區規模、何時啟動,以及百度、蕪湖市政府、奇瑞的具體運營角色,現場稱會在未來給出更加詳細的資訊。

與其他進入自動駕駛的企業相比,百度是首家與地方政府企業合作進行城市道路試運營的企業。去年年底自動駕駛汽車事業部成立時,就對外公佈了全自動駕駛的3年商用,5年量產計畫。百度全自動駕駛汽車會以公共車輛的形式,選擇10個左右國內不同城市和示範區商用運營。此次與蕪湖市政府運營簽約,也包括了3年商用和5年量產的長遠規劃。

隨著自動駕駛汽車開始進入工程化和市場化階段,和現階段大量的封閉區域和高速公路測試相比,城市是下階段測試的理想場景。就百度而言,通過城市環境的試運營,會獲得更多道路行駛資料,説明快速反覆運算技術推向市場。除此之外,累計路測經驗也將有利於百度更加貼近未來制定的自動駕駛汽車法律法規以及行駛道路與環境標準。

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

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

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

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

小三通海運與一般國際貿易有何不同?

小三通快遞通關作業有哪些?