分类目录归档:Go语言

通过http代理安装go包

大家知道,在国内访问国外网站有时候比较困难,安装go的包也很麻烦,所以需要用到http代理了。如果你有一个代理,在windows环境下,执行下面的命令即可使用http代理了。

set https_proxy=127.0.0.1:1080
set http_proxy=127.0.0.1:1080

 

go实现一个简单的http代理

当请求http://localhost:8080/html/home.html 自动转发请求到 http://192.168.0.1/html/home.html,带cookie请求,不过cookie要每次都手工抓取

package main

import (
	"io/ioutil"
	"log"
	"net/http"
	//	"strings"
)

func statistic(w http.ResponseWriter, r *http.Request) {
	//r.URL.RequestURI()
	client := &http.Client{}
	req, err := http.NewRequest("GET", "http://192.168.0.1"+r.URL.Path, nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Cookie", `SessionID=y151QXjszzoP5D2Lvfun0S/JPnFfquDtASLyWz+ZiSg6ngSt1gpakE2DChVN+hnfFOS6rFJ6gwUL+y0pAG+RpYYSogAFcZsuN919FXZle45UGP+ka6fZmceI9ew7Mj4Z;path=/;HttpOnly;`)
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
	w.Write(body)
}
func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", statistic)
	err := http.ListenAndServe(":8080", mux)

	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

 

go访问sqlite3删除数据

来个增删改查完整版了

删除数据代码如下

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "./foo.db")
	checkErr(err)

	stmt, err := db.Prepare("delete from userinfo  where uid=?")
	checkErr(err)
	res, err := stmt.Exec(3)
	checkErr(err)
	affect, err := res.RowsAffected()
	checkErr(err)
	fmt.Println(affect)
}
func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

 

go访问sqlite3更新数据

前面两个文章说了插入,和读取,这个例子演示如何更新数据

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "./foo.db")
	checkErr(err)

	stmt, err := db.Prepare("update userinfo set username=? where uid=?")
	checkErr(err)
	res, err := stmt.Exec("kkkkk", 2)
	checkErr(err)
	affect, err := res.RowsAffected()
	checkErr(err)
	fmt.Println(affect)
}
func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

 

go访问sqlite3读取数据

前一文说了如何插入数据,现在可以把数据记录读成一个二维数组,真的太方便了。

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/mattn/go-sqlite3"
)

type userinfo struct {
	id                            int
	username, departname, created string
}

func main() {
	db, err := sql.Open("sqlite3", "./foo.db")
	checkErr(err)
	rows, err := db.Query("select * from userinfo")
	checkErr(err)
	var userlist []userinfo
	var u userinfo
	for rows.Next() {
		rows.Scan(&u.id, &u.username, &u.departname, &u.created)
		userlist = append(userlist, u)
	}
	fmt.Printf("%#v\n", userlist)
	fmt.Printf("len %d\n", len(userlist))
}
func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

输出记录如下

E:\golang\pj2>sqlite4.exe
[]main.userinfo{main.userinfo{id:2, username:"fy", departname:"mydep", created:"2017-01-14T00:00:00Z"}, main.userinfo{id:3, username:"fy", departname:"mydep", created:"2017-01-14T00:00:00Z"}, main.userinfo{id:4, username:"fy", departname:"mydep", created:"2017-01-14T00:00:00Z"}}
len 3

 

go访问sqlite3插入数据

用go访问sqlite真的非常简单,先用sqlite工具创建库,执行sql创建表

   CREATE TABLE `userinfo` (
        `uid` INTEGER PRIMARY KEY AUTOINCREMENT,
        `username` VARCHAR(64) NULL,
        `departname` VARCHAR(64) NULL,
        `created` DATE NULL
    );

    CREATE TABLE `userdeatail` (
        `uid` INT(10) NULL,
        `intro` TEXT NULL,
        `profile` TEXT NULL,
        PRIMARY KEY (`uid`)
    );

go代码如下

package main

import (
	"database/sql"
	"fmt"
	"flag"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "./foo.db")
	checkErr(err)
	sth, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)")
	checkErr(err)
	res, err := sth.Exec("fy", "www.yiyou.org", "2017-01-14")
	checkErr(err)
	id, _ := res.LastInsertId()

	fmt.Println(id)
	db.Close()
}
func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

 

 

zabbix检查硬盘S.M.A.R.T状态[go语言实现]

因为服务器比较多,以前都是喜欢用perl写程序,后来发现部署的时候还要安装perl环境,实在太麻烦了,所以改用go编程,把go编译发后,复制到服务器就可以运行,还真的挻方便的。

之前已经用go写了一个mysql 主从同步,检查从服务器是否出错的程序,如果同步出错就可以在zabbix里警告了,把mysql密码写到程序里,再编译,这样比脚本语言要安全很多,而且不用添加一个用户。

原因是这样的,有很多服务器,有很大一部分是普通硬盘,普通硬盘就很容易出问题,因为服务器上面没有办法做badblock 检查(太耗IO资源了),但是检查S.M.A.R.T状态可以提前预知硬盘故障,还是有点用,好过没有,对吧。

程序是基于linux的,window 改改也能用,主要是先检查/dev/sda…b…c…d  循环检查系统有多少个硬盘,再检查状态,如果程序返回1 则正常,程序返回0 表示有硬盘出问题了。

package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}
func smartctl(dev string, debug int) int {
	path, err := exec.LookPath("smartctl")
	if err != nil {
		log.Fatal(err)
	}

	cmd := exec.Command(path, "-H", dev)
	var out bytes.Buffer
	cmd.Stdout = &out
	err = cmd.Run()
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("%s\n", out.String())
	if strings.Contains(out.String(), "OK") || strings.Contains(out.String(), "PASSED") {
		if debug == 1 {
			fmt.Printf("%s test ok\n", dev)
		}

		return 1
	}

	return 0
}
func main() {
	debug := flag.Int("debug", 0, "to debug -debug 1 ")
	flag.Parse()

	for _, drive := range "abcd" {
		//dev:=fmt.Sprintf("/dev/sd%s",drive)
		dev := "/dev/sd" + string(drive)
		//fmt.Println(dev)
		if ok, _ := PathExists(dev); ok {
			mystat := smartctl(dev, *debug)
			if mystat ==0 {
				fmt.Print(0)
				os.Exit(-1)
			}
		}

	}
	fmt.Print(1)
}

 

go处理命令行参数

GO实在太方便了,处理命令行参数已经有现成的包,看看下面的例子,用 command -h 还会自动生成使用方法。

package main
 
import (
    "flag"
    "fmt"
)
 
func main() {
    ok := flag.Bool("ok", false, "is ok")
    id := flag.Int("id", 0, "id")
    port := flag.String("port", ":8080", "http listen port")
    var name string
    flag.StringVar(&name, "name", "123", "name")
 
    flag.Parse()
 
    fmt.Println("ok:", *ok)
    fmt.Println("id:", *id)
    fmt.Println("port:", *port)
    fmt.Println("name:", name)
}

 

golang获取硬盘分区剩余空间大小

需求是这样的,想远程执行这个命令,返回各个硬盘分区的剩余空间的大小,当然,剩余空间太小可能就要处理了。

package main

import (
	"fmt"
	"syscall"
//	"strings"
	gofstab "github.com/deniswernert/go-fstab"
)

type DiskStatus struct {
	All  uint64 `json:"all"`
	Used uint64 `json:"used"`
	Free uint64 `json:"free"`
}
const (
	B  = 1
	KB = 1024 * B
	MB = 1024 * KB
	GB = 1024 * MB
)
// disk usage of path/disk
func DiskUsage(path string) (disk DiskStatus) {
	fs := syscall.Statfs_t{}
	err := syscall.Statfs(path, &fs)
	if err != nil {
		return
	}
	disk.All = fs.Blocks * uint64(fs.Bsize)
	disk.Free = fs.Bfree * uint64(fs.Bsize)
	disk.Used = disk.All - disk.Free
	return
}
func main(){
	mounts ,_ :=gofstab.ParseSystem()
	
	for _,val := range mounts{
		//fmt.Printf("%v\n",val.File)
		if val.File == "swap"||val.File == "/dev/shm"||val.File == "/dev/pts"||val.File == "/proc"||val.File =="/sys"{
			continue
		}
		disk := DiskUsage(val.File)
		//fmt.Printf("All: %.2f GB\n", float64(disk.All)/float64(GB))
		//fmt.Printf("Used: %.2f GB\n", float64(disk.Used)/float64(GB))
		//fmt.Printf("Free: %.2f GB\n", float64(disk.Free)/float64(GB))
		diskall:=float64(disk.All)/float64(GB)
		diskfree:= float64(disk.Free)/float64(GB)
		
		dfpercent:=float64(diskfree/diskall)
		fmt.Printf("%s %.2f%%\n",val.File, dfpercent*100)
	}
}

 

golang获取linux硬盘分区空间大小

获得当前分区空间大小

package main

import (
	"fmt"
	"syscall"
)

type DiskStatus struct {
	All  uint64 `json:"all"`
	Used uint64 `json:"used"`
	Free uint64 `json:"free"`
}

// disk usage of path/disk
func DiskUsage(path string) (disk DiskStatus) {
	fs := syscall.Statfs_t{}
	err := syscall.Statfs(path, &fs)
	if err != nil {
		return
	}
	disk.All = fs.Blocks * uint64(fs.Bsize)
	disk.Free = fs.Bfree * uint64(fs.Bsize)
	disk.Used = disk.All - disk.Free
	return
}

const (
	B  = 1
	KB = 1024 * B
	MB = 1024 * KB
	GB = 1024 * MB
)

func main() {
	disk := DiskUsage("/")
	fmt.Printf("All: %.2f GB\n", float64(disk.All)/float64(GB))
	fmt.Printf("Used: %.2f GB\n", float64(disk.Used)/float64(GB))
	fmt.Printf("Free: %.2f GB\n", float64(disk.Free)/float64(GB))
}