说明
因为这个项目是公司要求私有的,不允许写在公开仓库上,这里也不说其他的了,只说设计的技术栈和经验
这只是整个服务的一个小细分,功能也很重要。
项目技术栈
技术细分
我负责的部分 :
项目当前进度 :
讲讲遇到的坑
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和任务列表之类的,这些就不讲了。
写了这个项目对自己的收获很大。