说明

因为这个项目是公司要求私有的,不允许写在公开仓库上,这里也不说其他的了,只说设计的技术栈和经验

这只是整个服务的一个小细分,功能也很重要。

项目技术栈

技术细分

我负责的部分 :

80%

项目当前进度 :

100%


讲讲遇到的坑

Go读取配置文件,配置文件必须放在同一级目录,或者在同级目录里有一个叫config文件夹里面

配置文件通常放在config目录里面


Go请求和获取的数据当是json时请转化为结构体,或者直接用包格式化字符串

如像这样:

data := "{\r\n    \"Socks5\": \"%s\",\r\n    \"EdgeRouting\": \"CA0IBQ==\",\r\n    \"AuthBody\": {\r\n        \"username\": %s,\r\n        \"passive\": false,\r\n        \"user_agent\": {\r\n            \"platform\": 0,\r\n            \"app_version\": {\r\n                \"primary\": 2,\r\n                \"secondary\": 21,\r\n                \"tertiary\": 12,\r\n                \"quaternary\": 22\r\n            },\r\n            \"mcc\": \"310\",\r\n            \"mnc\": \"070\",\r\n            \"os_version\": \"7.1.2\",\r\n            \"manufacturer\": \"samsung\",\r\n            \"device\": \"fortunave32\",\r\n            \"os_build_number\": \"google-user 7.1.2 20171130.276299 release-keys\",\r\n            \"phone_id\": \"%s\",\r\n            \"locale_language_iso_639_1\": \"en\",\r\n            \"local_country_iso_3166_1_alpha_2\": \"US\",\r\n            \"Brand\": \"msm8998\"\r\n        },\r\n        \"push_name\": \"sjeyg\",\r\n        \"short_connect\": false,\r\n        \"connect_type\": 1,\r\n        \"Tag23\": 1\r\n    },\r\n    \"AuthHexData\": \"\",\r\n    \"StaticPriKey\": \"%s\",\r\n    \"StaticPubKey\": \"%s\"\r\n}"

    data = fmt.Sprintf(data, logins.Socks5, login, logins.PhoneId, logins.StaticPriKey, logins.StaticPubKey)
    resp, err := http.Post(api, "application/json", strings.NewReader(data))

这里使用%s作为字符串替换,关于字符串格式化那张可以看这篇文章

这里遇见了一个小坑,如:
特殊情况

这里可以发现他的有一个特殊的类型,interface,这个类型会让编辑器自动判断接收的类型,这里我们就不能正常的获取他的值了,单纯的json包也不行,不过这里有个包可以解决这个问题。

"github.com/mitchellh/mapstructure"

它的使用场景是把已经解析的部分json数据,其中嵌套的json结果转化,如这种情况:

{

"Code": 0,

"Data": {

    "count": 1,

    "ws": [

        {****

            "loginState": "",

            "userName": "*****"

        }

    ]

},

"Msg": null

}

在Go中获取Data.ws里面的数据就很麻烦,所以需要用到这个包,当然通过断言也可以做到,不过我这里就讲讲这个包的解决方法---

使用这个包很好解决,首先定义结构体

type InfoWS struct {
    LoginState string `mapstructure:"loginState" json:"login_state"`
    UserName   string `mapstructure:"UserName" json:"user_name"`
}

然后使用这个包的转化语句,weak是指的是弱类型,而没有就是强类型,需要注意报错
ver 是InfoWS的内容

if err := mapstructure.WeakDecode(result.Data, &ver); err != nil {
        logrus.Error("转化结构体出错--->", err)
    }

Go协程造成的并发变量抢占

这个则需要异步锁来解决这个问题

请输入图片描述


Go使用goto 语句

非常不建议使用goto语句!!!

我使用这个语句的想法是将当前这个流程判断中错误后回到起始,我不可能使用for语句,太过麻烦,而且也很不美观,于是就使用goto语句了。

我们需要在想要重新开始流程的代码前面加上标签,如这里的标签是LOOP

go func(phones []string) {
            // 开始筛选
        LOOP:
            phone := inWs.RandList()
            if phone == "" 
                goto LOOP
            }

当使用goto语句就会跳到LOOP这个标签里的代码了。

如果不是特殊情况请勿使用goto语句,臭名昭著的东西


剩下的就是简单的mysql,web框架gin的简单使用,redis和任务列表之类的,这些就不讲了。


写了这个项目对自己的收获很大。


最后修改:2021 年 10 月 22 日
如果觉得我的文章对你有用,请随意赞赏