2024年3月

先前的版本在处理休眠时有点问题,这个版本修正了
因为正好需要24的机器,所以晚上抢了一把,很成功。注意截图时间。 :)

grabali.jpg

/*
https://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair 获得主帐号的AccessKey ID AccessKey Secret
确保有不少于24块的余额
*/

package main

import (
        "fmt"
        "os"
        "time"

        openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
        swas_open20200601 "github.com/alibabacloud-go/swas-open-20200601/client"
        "github.com/alibabacloud-go/tea/tea"
)

func CreateClient(Key, Secret string) (_result *swas_open20200601.Client, _err error) {
        config := &openapi.Config{
                AccessKeyId:     tea.String(Key),
                AccessKeySecret: tea.String(Secret),
        }
        config.Endpoint = tea.String("swas.cn-hongkong.aliyuncs.com")
        _result = &swas_open20200601.Client{}
        _result, _err = swas_open20200601.NewClient(config)
        return _result, _err
}

func SDKCreate(Key, Secret string) error {
        client, err := CreateClient(Key, Secret)
        if err != nil {
                return err
        }
        request := &swas_open20200601.CreateInstancesRequest{
                RegionId: tea.String("cn-hongkong"),                      //香港
                ImageId:  tea.String("8b798eb927684a08b26bb95da94f5812"), //debian11
                PlanId:   tea.String("swas.s2.c2m1s40b30t1.un"),          //轻量24
                Period:   tea.Int32(1),
        }
        _, err = client.CreateInstances(request)
        if err != nil {
                return err
        }
        return nil
}

func main() {
        location, err := time.LoadLocation("Asia/Shanghai")
        if err != nil {
                fmt.Println("Error loading location:", err)
                return
        }
        time.Local=location
        args := os.Args
        if len(args) < 3 {
                fmt.Printf("Usage: %s <AccessKeyId> <AccessKeySecret>\n", args[0])
                return
        }

        now := time.Now()
        tomorrowMidnight := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, time.Local)

        if now.Hour() != 0 {
                fmt.Println("Waiting for 00:00:00 to start...")
                sleepDuration := tomorrowMidnight.Sub(now)
                time.Sleep(sleepDuration)
        }

        //因为阿里可能不整点放货,所以,这里不再连续抢了,因为SDK的限制是10次/分钟
        //现在改为每分钟抢10次左右,一直抢5分钟。 也就是6秒左右抢一次。按照中位数,3秒,应该还是希望很大。
        for i := 1; i <= 50; i++ {
                err := SDKCreate(args[1], args[2])
                if err != nil {
                        fmt.Printf("%d - Error: %s\n", i, err)
                } else {
                        fmt.Printf("%d - Success! Please check it in your aliyun console.\n", i)
                        break
                }
                time.Sleep(6 * time.Second)
        }

        fmt.Println("Done")
}

突然想到,这不就自己看看的嘛,然后偶尔有几个访客。
既然这样,我还中国优化线路干嘛? 我还想着防C防D干嘛? 思维定势太可怕了。
狂笑,立马CF+Netcup,搞定!

昨晚一台低频使用的测试服务器进行了一次向内部服务器发起的api请求,结果被雷池拦截了。这个操作是一个不允许出错、正常也不会出错的操作,程序对出错的机制是一直重试直到成功。这就死循环了,一直到早上发现后手工处理。
这个锅雷池不背,是我们把测试服务器忘记设在白名单中。然而,这次事故暴露出雷池的一个大问题,有点象反射放大攻击,测试服务器向雷池发一个几十字节的HTTP请求包,雷池就返回一个大得多的拦截出错页,几十上百倍的放大,准确数据我懒得看了。而且这个出错页是不可修改的。
我这是腾讯云的按量计费,0.8元/G啊!真有人攻击,那不分分钟第二天起来房子不见了? 还好我有先见之明,我是把API服务器的闲时最大带宽设置成的3M,攻击就攻击,跑满就跑满吧,否则,今早就该提桶跑路了。
成事不足,败事有余。把雷池撤了算了。

图片_20240319154731.png

图片_20240319154743.png

这个是很多人的痛,如果遇到D哥C哥一晚上起来房子就不见了。
这个代码会检测套餐流量包使用情况,如果低于限定值就停机,扔进crontab定时执行一下就好了。安心睡觉吧。

package main

import (
    "fmt"

    openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
    swas_open20200601 "github.com/alibabacloud-go/swas-open-20200601/client"
    "github.com/alibabacloud-go/tea/tea"
)

const (
    ReservedGB = 10                                 // 预留流量GB,低于此值将自动关机
    RegionId   = "cn-hongkong"                      //区域ID
    Key        = "XXXX"         //AccessKey
    Secret     = "XXXX"   //AccessSecret
    InstanceID = "XXXX" //实例ID
)

func CreateClient(Key, Secret string) (_result *swas_open20200601.Client, _err error) {
    config := &openapi.Config{
        AccessKeyId:     tea.String(Key),
        AccessKeySecret: tea.String(Secret),
    }
    config.Endpoint = tea.String("swas." + RegionId + ".aliyuncs.com")
    _result = &swas_open20200601.Client{}
    _result, _err = swas_open20200601.NewClient(config)
    return _result, _err
}

// 返回套餐已用流量,总流量,错误信息
func GetTrafficQuota(Key, Secret, InstanceID string) (int, int, error) {
    client, err := CreateClient(Key, Secret)
    if err != nil {
        return 0, 0, err
    }

    request := &swas_open20200601.ListInstancesTrafficPackagesRequest{
        InstanceIds: tea.String("[\"" + InstanceID + "\"]"),
        RegionId:    tea.String(RegionId),
    }

    response, err := client.ListInstancesTrafficPackages(request)
    if err != nil {
        return 0, 0, err
    }

    return int(*response.Body.InstanceTrafficPackageUsages[0].TrafficUsed), int(*response.Body.InstanceTrafficPackageUsages[0].TrafficPackageTotal), nil
}

func HaltServer(Key, Secret, InstanceID string) error {
    client, err := CreateClient(Key, Secret)
    if err != nil {
        return err
    }

    request := &swas_open20200601.StopInstanceRequest{
        InstanceId: tea.String(InstanceID),
        RegionId:   tea.String(RegionId),
    }

    _, err = client.StopInstance(request)
    if err != nil {
        return err
    }
    return nil
}

func main() {
    Used, Total, err := GetTrafficQuota(Key, Secret, InstanceID)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("Used: %d GB, Total: %d GB\n", BytesToGB(Used), BytesToGB(Total))
    if BytesToGB(Total-Used) < ReservedGB {
        fmt.Printf("Warning: The remaining traffic is less than %dGB,server halt!\n", ReservedGB)
        HaltServer(Key, Secret, InstanceID)
    } else {
        fmt.Println("The remaining traffic is enough!")
    }
}

func BytesToGB(b int) int {
    return b / 1024 / 1024 / 1024
}

这个blog是用typecho弄的,够简单,搭起来很快,不过真要用问题不少。
先前弄在netcup上,性能足够强大,不过国内网络访问一言难尽。
然后弄在香港阿里,为了这个我特地把机器从24升到了34,就是2C1G到了2C2G。不过nginx+php+mariadb+长亭一跑,没多少空闲内存了。其实对于1IP也可以接受,虚拟内存开上应付一下可能偶尔出现的OOM就好,不过我处女座,你懂。
最后决定,手里有个免费的甲骨文的ARM机,已经吃灰了好几年了,4C24G,用起来吧。香港反代到甲骨文,两地连接40ms,用户感觉不出来啥,但24G内存彻底就没了内存焦虑了。
至于甲骨文可能会不稳被删号的问题,小意思,一是我这老号基本不可能删,二是,我跑了一个脚本,每天把它备份到香港就好。甲骨文口子够大,流量不要钱,对阿里,备份是进流量,口子也大也不要钱,完美。