you are better than you think

备忘

last update:

golang邮件抄送

最近接触的一个api模块中使用了smtp.SendMail发送邮件。因为要实现cc功能,看了下源码,简单记录下。

smtp中关于SendMail的声明

SendMail(addr string, a Auth, from string, to []string, msg []byte) error

参数依次是,

    addr: smtp server地址,格式为hostname:port 或者 ip:port;
    a: smtp PlainAuth信息, 包含identity, username, password, host, 即身份id、用户名、密码、smtp服务器host. identify 一般为空,表明identity与username一致;
    from: 发件邮箱
    to: 收件人地址列表,包含to,cc,bcc的所有收件地址
    msg: 邮件内容,包含邮件header和body

来一个栗子

有一个内网服务的模块,升级过程大体是在一个目录A中git pull->go build, 然后B目录中备份->stop->替换->start。这个模块有个control.sh负责起停模块,有个build.sh负责编译,备份是靠cp module module.bak。这样就可能会有备份版办覆盖的问题,比较好的方式是使用模块的版本号作为备份文件后缀。

总的需求就是自动化,可以编译/备份/升级/回滚。备份时候希望按照版本号进行,回滚的时候可以按照指定版本号进行回滚。这种升级方式不可取,作为一个过渡的临时方案.

改造第一步,利用golang 的ldflags 在模块编译的时候给模块指定版本号。版本号就用 short commit id + date的格式。

流量入口迁移到云的负载均衡。第二天收到合作方的反馈,提示连接被重置,我们将流量重新切回老入口。简单排查后发现,使用java的合作方出现 connection reset,而其他(如python)的调用方并没有此类报错。安卓客户端也是部分机型报错。

1.初步排查

跟调用方要了一个demo,在我本地机器上跑了一下,发现并没有被重置。抓包对比发现:jdk1.7默认使用TLSv1.0请求https服务,被reset;jdk1.8默认使用TLSv1.2请求https服务,不会被reset。Java HttpClient可以通过SSLContext指定TSL版本避免这个问题, 但是推动调用方去改,显然不妥。

jdk1.8使用TSLv1.2握手,访问新的入口 034.png