Go语言学习笔记
发表于 · 归类于
技术 · 阅读完需 19 分钟 ·
阅读量 报告错误
(1)Go备份MySQL数据库至阿里云OSS
package main
import (
"fmt"
"os"
"os/exec"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
const (
ossBucket = "da**xn"
ossPoint = "http://oss-cn-chengdu.aliyuncs.com"
ossAccessKeyId = "LT*********oz"
ossAccessKeySecret = "MI*********OT"
originPath = "/data/database/"
)
func main() {
path := originPath
file := "linzening-db-" + time.Now().Format("20060102150405") + ".sql.gz"
cmd := exec.Command("/bin/sh", "-c", "/usr/bin/mysqldump --host 127.0.0.1 --port 3306 -uroot -pword dbname | gzip > "+path+file)
err1 := cmd.Run()
if err1 != nil {
fmt.Println("error")
os.Exit(-1)
}
fmt.Println("databasefile:" + path + file)
// 创建OSSClient实例。
client, err := oss.New(ossPoint, ossAccessKeyId, ossAccessKeySecret)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 获取存储空间。
bucket, err := client.Bucket(ossBucket)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 上传本地文件。按月份文件夹保存到OSS
osspath := "database-"+time.Now().Format("2006")+"/"+time.Now().Format("01")+"/"
err = bucket.PutObjectFromFile(osspath+file, path+file)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("Upload Success.")
}
源代码
https://github.com/linzening/code/blob/main/go/oss-backup.go
(2)Go处理Nginx日志
打印日志状态码统计
package main
import (
"fmt"
"os"
"io/ioutil"
"strings"
"strconv"
)
func main() {
path := "i6.log"
if len(os.Args) >=2 {
path = os.Args[1]
}
fmt.Println("日志路径:",path)
f, err := os.Open(path)
if err != nil {
fmt.Println("文件不存在")
os.Exit(-1)
}
str,err := ioutil.ReadAll(f)
if err != nil {
fmt.Println("日志读取失败")
os.Exit(-1)
}
strs := string(str)
var countryCapitalMap map[int]int
countryCapitalMap = make(map[int]int)
lists := strings.Split(strs,"\n")
for i := 0; i < len(lists);i++ {
line := lists[i]
row := strings.Split(line," ")
if len(row) > 8 {
b,_ := strconv.Atoi(row[8])
if b >= 100 && b < 600 {
countryCapitalMap[b] += 1
}
}
}
for country := range countryCapitalMap {
fmt.Println(country, "状态码", countryCapitalMap[country])
}
}
运行效果
[root@ecs go]# go run log.go /home/wwwlogs/access.log
日志路径: /home/wwwlogs/access.log
200 状态码 1532
404 状态码 1057
150 状态码 113
403 状态码 127
146 状态码 6
400 状态码 331
405 状态码 103
304 状态码 350
302 状态码 1
301 状态码 2
把日志统计输出到接口中
package main
import (
"fmt"
"os"
"io/ioutil"
"strings"
"strconv"
"net/http"
)
func getinfo() string {
path := "i6.log"
if len(os.Args) >=2 {
path = os.Args[1]
}
fmt.Println("日志路径:",path)
f, err := os.Open(path)
if err != nil {
fmt.Println("文件不存在")
os.Exit(-1)
}
str,err := ioutil.ReadAll(f)
if err != nil {
fmt.Println("日志读取失败")
os.Exit(-1)
}
strs := string(str)
var countryCapitalMap map[int]int
countryCapitalMap = make(map[int]int)
var countryCapitalUrl map[string]int
countryCapitalUrl = make(map[string]int)
lists := strings.Split(strs,"\n")
for i := 0; i < len(lists);i++ {
line := lists[i]
row := strings.Split(line," ")
if len(row) > 8 {
b,_ := strconv.Atoi(row[8])
if b >= 100 && b < 600 {
countryCapitalMap[b] += 1
}
if b != 200 && b != 304 && b != 206 && b != 302 {
key := row[6]
countryCapitalUrl[row[0]+","+strconv.Itoa(b)+","+key] += 1
}
}
}
strlog := "[{"
for country := range countryCapitalMap {
// fmt.Println(country, "状态码", countryCapitalMap[country])
strlog += "\"" + strconv.Itoa(country) + "\":\""+ strconv.Itoa(countryCapitalMap[country])+"\","
}
// 去掉最后一个字符
strlog = strlog[0:len(strlog)-1]
strlog += "},{"
for country := range countryCapitalUrl {
// fmt.Println(countryCapitalUrl[country],country)
country = strings.Replace(country,"\"","0",-1)
country = strings.Replace(country,"\\","00",-1)
strlog += "\""+country +"\":\""+ strconv.Itoa(countryCapitalUrl[country])+"\","
}
strlog = strlog[0:len(strlog)-1]
return strlog+"}]"
}
type helloHandler struct{}
func (h *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
b := getinfo()
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Write([]byte(b))
}
func main() {
to := "web"
if to == "web" {
fmt.Println("服务器已启动:8000")
http.Handle("/", &helloHandler{})
http.ListenAndServe(":8000", nil)
}else{
fmt.Println("配置错误")
}
}
生成二进制程序
go build flog.go
执行命令
nohup ./flog /home/wwwlogs/ayouleyangs.log &
(3)Go协程程序
package main
import (
"fmt"
"time"
)
//生产者
func Producer(queue chan<- int) {
for i := 0; i < 10; i++ {
queue <- i //写入
fmt.Println(time.Now().Format("2006-01-02 15:04:05"),"create :", i)
time.Sleep(1 * time.Second)
}
}
//消费者
func Consumer(queue <-chan int) {
for i := 0; i < 10; i++ {
v := <-queue // 读出
fmt.Println(time.Now().Format("2006-01-02 15:04:05"),"receive:", v)
}
}
func main() {
queue := make(chan int, 88)
go Producer(queue)
go Consumer(queue)
time.Sleep(12 * time.Second)
}
无限循环语句
//消费者
func Consumer(queue <-chan int) {
for {
v := <-queue
fmt.Println(time.Now().Format("2006-01-02 15:04:05"),"receive:", v)
}
}
(4)使用Go做一个HTTP服务器
2022年8月23日
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"path"
"strconv"
)
var dir string
var port int
var indexs []string
// 初始化参数
func init() {
dir = path.Dir(os.Args[0])
fmt.Println("本地地址:",dir)
flag.IntVar(&port, "port", 80, "服务器端口")
flag.Parse()
indexs = []string{"index.html", "index.htm"}
}
func main() {
http.HandleFunc("/", StaticServer)
err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
// 静态文件处理
func StaticServer(w http.ResponseWriter, req *http.Request) {
file := dir + req.URL.Path
fi, err := os.Stat(file)
if os.IsNotExist(err) {
http.NotFound(w, req)
return
}
if err != nil {
http.Error(w, err.Error(), 500)
return
}
if fi.IsDir() {
if req.URL.Path[len(req.URL.Path)-1] != '/' {
http.Redirect(w, req, req.URL.Path+"/", 301)
return
}
for _, index := range indexs {
fi, err = os.Stat(file + index)
if err != nil {
continue
}
http.ServeFile(w, req, file+index)
return
}
http.NotFound(w, req)
return
}
http.ServeFile(w, req, file)
}
配置dir为本地目录,访问 http://127.0.0.1/ 即可