树莓派网站容灾:利用DNSPod,Google App Engine和Github

背景介绍

把网站托管在树莓派上后如果家里停电或是宽带故障,会造成网站中断。本文提供一个免费的解决方案(前提是你需要有自己的一个域名,并由DNSPod解析)

DNSPod

首先需要在DNSPod里设置好需要failover的域名CNAME:比如hugozhu.myalert.info

其中默认指向pi.myalert.info, 这是一个域名的A Record,会由运行在树莓派上的脚本来更新动态IP,国外则指向github。当停电时我们需要自动把`默认`这条纪录修改成github。

使用下面命令获得相应CNAME的domain_id:

curl -k https://dnsapi.cn/Domain.List -d "login_email=xxx&login_password=xxx" 

使用下面命令获得相应CNAME的record_id:

curl -k https://dnsapi.cn/Record.List -d "login_email=xxx&login_password=xxx&domain_id=xxx"

Google App Engine

切换DNS脚本

package dnspod

import (
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

const (
	login_email    = "<your_login_email>"
	login_password = "<your_login_password>"
	format         = "json"
	domain_id      = "<domain_id>"
	record_id      = "<record_id>"
	sub_domain     = "<your_subdomain>"
	record_type    = "CNAME"
	record_line    = "默认"
	ttl            = "600"
)

func Update(client *http.Client, cname string) string {
	body := url.Values{
		"login_email":    {login_email},
		"login_password": {login_password},
		"format":         {format},
		"domain_id":      {domain_id},
		"record_id":      {record_id},
		"sub_domain":     {sub_domain},
		"record_type":    {record_type},
		"record_line":    {record_line},
		"value":          {cname},
		"ttl":            {ttl},
	}
	req, err := http.NewRequest("POST", "https://dnsapi.cn/Record.Modify", strings.NewReader(body.Encode()))
	req.Header.Set("Accept", "text/json")
	req.Header.Set("Content-type", "application/x-www-form-urlencoded")
	resp, err := client.Do(req)
	if err != nil {
		return err.Error()
	}
	defer resp.Body.Close()
	bytes, _ := ioutil.ReadAll(resp.Body)
	return string(bytes)
}

检测接口

部署一个web应用到Google App Engine上,该应用接受树莓派上的一个URL(注意这里不应该用需failver的域名),并请求该域名以检查网站是否正常。这里也可以使用监控宝来监控,但只有付费专业版才支持出错后回调URL。

[Read More]