Go 开发环境配置

以下方式已不建议使用,使用 Go Module 配置的方式

一、安装 govendor 工具

go get -u github.com/kardianos/govendor

二、创建工程

cd $GOPATH/src
mkdir demo
cd demo
govendor init

三、安装依赖

govendor fetch github.com/go-sql-driver/mysql@=v1.4.1
govendor fetch github.com/gin-gonic/gin@=v1.3.0
govendor fetch github.com/gomodule/redigo/redis@=v1.7.0

四、开发

package main

import (
	"database/sql"
	"log"

	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
)

var Database *sql.DB

func main() {
	DatabaseInit()
	defer Database.Close()
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.GET("/", IndexAction)
	r.GET("/user/:name", UserAction)
	r.Run()
}

func DatabaseInit() {
	var err error
	Database, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/wordpress")
	if err != nil {
		log.Fatalln(err)
	}
	Database.SetMaxIdleConns(500)
	Database.SetMaxOpenConns(500)
	err = Database.Ping()
	if err != nil {
		log.Fatalln(err)
	}
}

func IndexAction(c *gin.Context) {
	c.JSON(200, gin.H{"message": "index"})
}

func UserAction(c *gin.Context) {
	var ID int
	err := Database.QueryRow("SELECT ID FROM wp_users WHERE user_login = ?", c.Param("name")).Scan(&ID)
	if err == nil {
		c.String(200, "Hello %d", ID)
	} else {
		c.String(200, "Hello nobody")
	}
}

五、gin-app

gin-app-0.1

发布于
归类为Golang

golang发送阿里云短信

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "1111"
const TemplateCode = "SMS_2222"
const SignName = "发送测试"

func UrlEncode(in string) string {
	r := strings.NewReplacer("+", "%20", "*", "%2A", "%7E", "~")
	return r.Replace(url.QueryEscape(in))
}

func Sign(stringToSign string) string {
	h := hmac.New(sha1.New, []byte(fmt.Sprintf("%s&", AccessKeySecret)))
	h.Write([]byte(stringToSign))
	return UrlEncode(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func Keys(data map[string]string) []string {
	var keys []string
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return keys
}

func SortedString(data map[string]string) string {
	var sortQueryString string
	for _, v := range Keys(data) {
		sortQueryString = fmt.Sprintf("%s&%s=%s", sortQueryString, v, UrlEncode(data[v]))
	}
	return sortQueryString
}

func AliyunSendSMS(PhoneNumber string, code string) string {

	rand.Seed(time.Now().UnixNano())

	data := map[string]string{
		"SignatureMethod":  "HMAC-SHA1",
		"SignatureNonce":   strconv.FormatFloat(rand.Float64(), 'f', 6, 64),
		"AccessKeyId":      AccessKeyID,
		"SignatureVersion": "1.0",
		"Timestamp":        time.Now().UTC().Format("2006-01-02T15:04:05Z"),
		"Format":           "JSON",

		"RegionId":      "cn-hangzhou",
		"Action":        "SendSms",
		"Version":       "2017-05-25",
		"PhoneNumbers":  PhoneNumber,
		"SignName":      SignName,
		"TemplateCode":  TemplateCode,
		"TemplateParam": `{"code":"` + code + `"}`,
	}

	sortQueryString := SortedString(data)
	stringToSign := "GET&%2F&" + UrlEncode(sortQueryString[1:])
	url := fmt.Sprintf("https://dysmsapi.aliyuncs.com/?Signature=%s%s", Sign(stringToSign), sortQueryString)

	r, err := http.Get(url)
	if err != nil {
		return ""
	}
	defer r.Body.Close()

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return ""
	}

	return string(b)
}

func main() {
	html := AliyunSendSMS("18611112222", "123456")
	fmt.Println(html)
}
发布于
归类为Golang

golang发送阿里云邮件

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "1111"
const AccountName = "admin@sendmail.aliyun.com"

func UrlEncode(in string) string {
	r := strings.NewReplacer("+", "%20", "*", "%2A", "%7E", "~")
	return r.Replace(url.QueryEscape(in))
}

func Sign(stringToSign string) string {
	h := hmac.New(sha1.New, []byte(fmt.Sprintf("%s&", AccessKeySecret)))
	h.Write([]byte(stringToSign))
	return UrlEncode(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func Keys(data map[string]string) []string {
	var keys []string
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return keys
}

func SortedString(data map[string]string) string {
	var sortQueryString string
	for _, v := range Keys(data) {
		sortQueryString = fmt.Sprintf("%s&%s=%s", sortQueryString, v, UrlEncode(data[v]))
	}
	return sortQueryString
}

func AliyunSendMail(email string, subject string, body string) string {

	rand.Seed(time.Now().UnixNano())

	data := map[string]string{
		"SignatureMethod":  "HMAC-SHA1",
		"SignatureNonce":   fmt.Sprintf("%s", rand.Int63()),
		"AccessKeyId":      AccessKeyID,
		"SignatureVersion": "1.0",
		"Timestamp":        time.Now().UTC().Format("2006-01-02T15:04:05Z"),
		"Format":           "JSON",

		"Action":         "SingleSendMail",
		"Version":        "2015-11-23",
		"AccountName":    AccountName,
		"ReplyToAddress": "true",
		"AddressType":    "1",
		"ToAddress":      email,
		"Subject":        subject,
		"TextBody":       body,
	}

	sortQueryString := SortedString(data)
	stringToSign := fmt.Sprintf("GET&%s&%s", UrlEncode("/"), UrlEncode(sortQueryString[1:]))
	url := fmt.Sprintf("http://dm.aliyuncs.com/?Signature=%s%s", Sign(stringToSign), sortQueryString)

	r, err := http.Get(url)
	if err != nil {
		return ""
	}
	defer r.Body.Close()

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return ""
	}

	return string(b)
}

func main() {
	html := AliyunSendMail("123456@qq.com", "Database Backup Email", "Database Backup Completed")
	fmt.Println(html)
}
发布于
归类为Golang

golang上传文件到OSS

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

const AccessKeyID = "0000"
const AccessKeySecret = "0000"

const Bucket = "bbbb"
const BucketUrl = "https://bbbb.oss-cn-beijing.aliyuncs.com"

var datetime string = time.Now().UTC().Format(http.TimeFormat)

func Sign(dest string) string {
	h := hmac.New(sha1.New, []byte(AccessKeySecret))
	h.Write([]byte("PUT\n\napplication/octet-stream\n" + datetime + "\n/" + Bucket + dest))
	return "OSS " + AccessKeyID + ":" + base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func Upload(file string, dest string) error {

	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	request, err := http.NewRequest("PUT", BucketUrl+dest, f)
	if err != nil {
		return err
	}

	request.Header.Add("Date", datetime)
	request.Header.Add("Authorization", Sign(dest))
	request.Header.Add("Content-Type", "application/octet-stream")

	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}

	if response.StatusCode == 200 {
		return nil
	} else {
		return errors.New(string(body))
	}

}

func main() {
	up := Upload("02.zip", "/08.zip")
	fmt.Println(up)
}
发布于
归类为Golang

golang使用协程和管道的例子

1. 协程和管道

package main

import (
	"fmt"
	"time"
)

func write(ch chan int) {
	for i := 0; i < 10; i++ {
		ch <- i
		fmt.Println("write data: ", i)
	}
}

func read(ch chan int) {
	for {
		var b int
		b = <-ch
		fmt.Println("read data: ", b)
		time.Sleep(time.Second)
	}
}

func main() {
	intChan := make(chan int, 5)
	go write(intChan)
	go read(intChan)

	time.Sleep(10 * time.Second)
}

2. 使用 WaitGroup 控制协程

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func write(ch chan int) {
	for i := 0; i < 10; i++ {
		ch <- i
		fmt.Println("write data: ", i)
	}
}

func read(ch chan int) {
	for {
		fmt.Println("read data: ", <-ch)
		wg.Done()
	}
}

func main() {
	ch := make(chan int, 5)
	wg.Add(10)

	go write(ch)
	go read(ch)

	wg.Wait()
}
发布于
归类为Golang

Golang使用zip压缩文件


package main

import (
	"archive/zip"
	"io"
	"os"
)

func main() {
	compress("01.png", "01.zip")
}

func compress(file string, dest string) error {
        f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()

	d, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer d.Close()

	wr := zip.NewWriter(d)
	defer wr.Close()

	w, err := wr.Create(file)
	if err != nil {
		return err
	}

	_, err = io.Copy(w, f)
	if err != nil {
		return err
	}

	return nil
}
发布于
归类为Golang

Golang使用tar压缩文件


package main

import (
	"archive/tar"
	"compress/gzip"
	"io"
	"os"
)

func main() {
	Compress("01.png", "02.tar.gz")
}

func Compress(file string, dest string) error {
	f, err := os.Open(file)
	if err != nil {
		return err
	}
	defer f.Close()
	d, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer d.Close()
	gw := gzip.NewWriter(d)
	defer gw.Close()
	tw := tar.NewWriter(gw)
	defer tw.Close()
	info, err := f.Stat()
	if err != nil {
		return err
	}
	header, err := tar.FileInfoHeader(info, "")
	if err != nil {
		return err
	}
	err = tw.WriteHeader(header)
	if err != nil {
		return err
	}
	_, err = io.Copy(tw, f)
	if err != nil {
		return err
	}
	return nil
}
发布于
归类为Golang

golang模拟浏览器请求


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

func httpRequest(url string) []byte {
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return []byte{}
	}

	request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
	request.Header.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
	request.Header.Add("Connection", "keep-alive")
	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36")

	client := http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return []byte{}
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return []byte{}
	}

	return body
}
发布于
归类为Golang

Golang实现端口转发

package main

import (
	"io"
	"net"
)

func main() {
	server, err := net.Listen("tcp", ":8080")
	if err != nil {
		return
	}
	for {
		client, err := server.Accept()
		if err == nil {
			go handleClientRequest(client)
		}
	}
}

func handleClientRequest(client net.Conn) {
	defer client.Close()

	remote, err := net.Dial("tcp", "127.0.0.1:80")
	if err != nil {
		return
	}
	defer remote.Close()

	go io.Copy(remote, client)
	io.Copy(client, remote)
}
发布于
归类为Golang

Golang二进制包下载地址

# linux
https://dl.google.com/go/go1.10.1.linux-amd64.tar.gz

# Win
https://dl.google.com/go/go1.10.1.windows-amd64.msi
发布于
归类为Golang