golang打造基于mail的提醒服务
初识golang
逻辑如下:
程序开启http服务器接收请求,且每隔20秒查询一次表auto_backup中flag为0的值,如果有查到且计划执行时间小于当前时间,则将表to_do的数据抓出来,通过邮件发送,完成后将数据表flag update 为1
表结构:
MySQL []> desc auto_backup; +----------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+---------------+------+-----+---------+----------------+ ) | NO | PRI | NULL | auto_increment | ) | NO | | NULL | | ) | NO | | NULL | | ) | NO | MUL | NULL | | +----------+---------------+------+-----+---------+----------------+ rows in set (0.04 sec)
表数据:
MySQL []> SELECT -> `id`, -> FROM_UNIXTIME(`auto_backup`.`datetime`) AS `datetimes`, -> `auto_backup`.`to_do` AS `to_do`, -> `auto_backup`.`flag` AS `flag` -> FROM -> `auto_backup` -> order by datetimes desc ; +----+---------------------+-----------------+------+ | id | datetimes | to_do | flag | +----+---------------------+-----------------+------+ :: | +----+---------------------+-----------------+------+ row in set (0.04 sec)
效果如下:
添加记录
发送记录
服务器log:
代码如下:
package main // 导入相关包 import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "gopkg.in/gomail.v2" "log" "net/http" "strconv" "time" ) // http 服务器 func Httpd_beiwang(w http.ResponseWriter, r *http.Request) { r.ParseForm() // 赛选掉访问的url路径为 /favicon.ico if "/favicon.ico" != r.URL.Path { log.Println(r.Form) // 获取url参数 time_value, timeOK := r.Form["time"] beiwang_value, beiwangOK := r.Form["beiwang"] // 如果两个参数正确,则判断参数正确,需要将定时任务写到数据库中去 if timeOK && beiwangOK { log.Println("参数判断ok,参数值为:") log.Println(time_value[]) log.Println(beiwang_value[]) // 定义初始时间 const base_format = "\"2006-01-02 15:04\"" // 转化为unix时间 loc, _ := time.LoadLocation("Local") parse_time, err := time.ParseInLocation(base_format, time_value[], loc) unix_parse_time := parse_time.Unix() log.Println("Unix 时间为: ", unix_parse_time) if err != nil { fmt.Println(err) } // 需要Insert的sql insert_sql := fmt.Sprintf(]) log.Println("执行的sql: ", insert_sql) // 执行sql results, err := db.Exec(insert_sql) if err != nil { log.Println("sql执行错误,错误内容为:") log.Println(err) } else { log.Println("执行成功,", results) fmt.Fprintf(w, "request ok") } } else { fmt.Fprintf(w, "request error") } } } // 发送邮件 func SendMail(body string) error { mailConn := map[string]string{ "user": "from_user", "pass": "password", "host": "smtp", "port": "port", } port, _ := strconv.Atoi(mailConn["port"]) m := gomail.NewMessage() //m.SetHeader("From" , "XD Game" + "<" mailConn["user"] + ">") m.SetHeader("From", "XD Game"+"<"+mailConn["user"]+">") m.SetHeader("To", "to_user") m.SetHeader("Subject", "执行计划") m.SetBody("text/html", body) d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"]) err := d.DialAndSend(m) return err } // 返回需要执行定时任务的id,返回值为Int数组 func Deal_Exec_id(db *sql.DB) []int { var send_id []int // 获取当前时间戳 now_t := time.Now() // 执行查询sql select_datetime := fmt.Sprintf("select id from auto_backup where flag = 0 and datetime <= %d", now_t.Unix()) // 执行sql select_rows, err := db.Query(select_datetime) log.Println(select_datetime) if err != nil { log.Println(err) } for select_rows.Next() { var id int if err := select_rows.Scan(&id); err != nil { log.Println(err) } //fmt.Println(id) // 将查询的结果追加到send_id中 send_id = append(send_id, id) } log.Println("查询结果返回ID", send_id) // 将send_id数组返回 return send_id } func Deal_SendMail(db *sql.DB, send_id []int) { var to_do string for id := range (send_id) { fmt.Println(send_id[id]) // 根据send_id查询 messages select_sql := fmt.Sprintf("SELECT to_do FROM auto_backup WHERE id = '%d';", send_id[id]) log.Println(select_sql) err := db.QueryRow(select_sql).Scan(&to_do) if err != nil { log.Println(err) } log.Println("发送的内容", to_do) SendMail(to_do) // 执行 update sql update_sql := fmt.Sprintf("UPDATE auto_backup SET flag = 1 WHERE id = '%d'", send_id[id]) log.Println(update_sql) results, err := db.Exec(update_sql) if err != nil { log.Println(err) } else { log.Println(results) } } } func start_jobs() { for { log.Println("Auto Time jobs Start") send_id := Deal_Exec_id(db) == len(send_id) { log.Println("未找到相关jobs") } else { Deal_SendMail(db, send_id) } // 每隔20秒刷新一次数据库,查看是否存在新数据 time.Sleep(time.Second * ) } } // 定义*sql.DB 变量 var db *sql.DB func main() { // 连接mysql var err error c := make(chan ) db, err = sql.Open("mysql", "username:password@tcp(host)/database_name") // 在main退出时关闭链接 defer db.Close() if err != nil { log.Println("Connect DB failed") log.Println(err) } // 开启http服务器 http.HandleFunc("/", Httpd_beiwang) // 开启协程 go func() { err = http.ListenAndServe("0.0.0.0:9090", nil) if err != nil { log.Fatal(err) } }() go start_jobs() <- c }
golang打造基于mail的提醒服务的更多相关文章
- 翻译-使用Ratpack和Spring Boot打造高性能的JVM微服务应用
这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices with Ratpack & Spring Boot,InfoQ上的中 ...
- 基于 REST 的 Web 服务:基础
代表性状态传输(Representational State Transfer,REST)在 Web 领域已经得到了广泛的接受,是基于 SOAP 和 Web 服务描述语言(Web Services D ...
- 新项目架构从零开始(三)------基于简单ESB的服务架构
这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ...
- 使用Ratpack和Spring Boot打造高性能的JVM微服务应用
使用Ratpack和Spring Boot打造高性能的JVM微服务应用 这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices wit ...
- Golang 在电商即时通讯服务建设中的实践
马蜂窝技术原创文章,更多干货请搜索公众号:mfwtech 即时通讯(IM)功能对于电商平台来说非常重要,特别是旅游电商. 从商品复杂性来看,一个旅游商品可能会包括用户在未来一段时间的衣.食.住.行等 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统
本来想在Dpar 1.0GA时发布这篇文章,由于其他事情耽搁了放到现在.时下微服务和云原生技术如何如荼,微软也不甘示弱的和阿里一起适时推出了Dapr(https://dapr.io/),园子里关于da ...
- 基于thrift的微服务框架
前一阵开源过一个基于spring-boot的rest微服务框架,今天再来一篇基于thrift的微服务加框,thrift是啥就不多了,大家自行百度或参考我之前介绍thrift的文章, thrift不仅支 ...
- Jquery打造的类似新浪微博@提醒功能
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 基于TCPCopy的Dubbo服务引流工具-DubboCopy
TCPCopy顾名思义,就是一个可以将tcp流量复制的工具(其实也可以复制UDP).有了这样一个工具,我们就可以真实的复制线上流量,然后将这些流量复制到我们的测试服务器上.这样就可以很容易模拟线上真实 ...
随机推荐
- 史上最全最详细的环境搭建教程,行百里者手把手教你在windows下搭建Anaconda+pycharm+库文件(TensorFlow,numpy)环境搭建
我是在搭建TensorFlow开发环境的道路上走了很多弯路 掉了很多头发,为了让广大同学们不在受苦受累 下面我将手把手教你学习如特快速搭建python环境 快速导入numpy,PIL,pillow,等 ...
- C# 多线程传递参数或多个参数
using System;using System.IO;using System.Text;using System.Threading; namespace ConsoleApp7{ class ...
- SpringCloud-day08-Hystrix断路器
8.Hystrix断路器 8.1.Hystrix简介 在分布式环境中,许多服务依赖项中的一些必然会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互. Hys ...
- Game Engine Architecture 2
[Game Engine Architecture 2] 1.endian swap 函数 floating-point endian-swapping:将浮点指针reinterpert_cast 成 ...
- Linux Apache虚拟主机配置方法
apache 虚拟主机配置 注意: 虚拟主机可以开很多个 虚拟主机配置之后,原来的默认/etc/httpd/httpd.conf中的默认网站就不会生效了 练习: 主机server0 ip:172.25 ...
- 方位话机X2主、备用服务器问题
1.当主.备用服务器有关联时采用开启分组,SIP1.SIP2的方式 2.当主.备用服务器无关联时采用,SIP1主.备用服务器的方式
- Retrofit 2.0 上传文件
1.用MultipartBody.Part的方式上传文件(单文件上传)(表单方式) @Multipart @POST("xxx/xxx") Call<ResponseBody ...
- axios POST提交数据的三种请求方式写法
1.Content-Type: application/json import axios from 'axios' let data = {"code":"1234&q ...
- https与http的区别
HTTPS协议 由于http协议中,服务器和客户端之间传输的报文是明文,很容易被攻击截取,为了保证一些敏感信息的安全,https协议在http的基础上加了一层SSL协议,依靠证书来保证服务器和客户端之 ...
- Mysql数据库性能优化(一)
参考 http://www.jb51.net/article/82254.htm 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要 ...