golang使用AWS ElasticSearch

用到了AWS ElasticSearch,研究了一下,整理了一下研究过程

AWS本身自带ElasticSearch服务,且可以方便的在本地布置Kibana,这个不需要多说,只需要去搜索文档执行即可。

AWS的ES首先是新建域,这个原来已经有服务,所以在这个基础要上新建index

研究了N久怎么建index,最后发现在kibana的Dev Tools用put命令即可

建好后,去找golang的Elastic包,最终决定使用github.com/olivere/elastic

然后推送数据,推送过程中发现并不需要先建index,在推送数据的时候如果index不存在会自动创建

推送成功后发现在Discover里找不到新建的index,研究良久,最后在kibana的Management里对index pattern有了怀疑,于是试着创建一个新的index pattern并指向新的index这个indices,创建后终于成功在Discover看到数据,搞定!

在Linux安装s3cmd

s3cmd是用于创建和管理数据到Amazon S3存储命令行的实用程序。本文将帮助你如何在CentOS上安装s3cmd

s3cmd 是用于创建S3桶,上传,检索和管理数据到Amazon S3存储命令行实用程序。 本文将帮助你如何在CentOS,RHEL,OpenSUSE系统,Ubuntu,Debian和LinuxMint系统上安装s3cmd,并通过简单的步骤命令行管理S3桶。 要在阅读文章Windows服务器安装s3cmd 在Windows中安装s3cmd。 我们还可以使用S3FS与FUSE在我们的系统本地驱动器安装S3存储桶。要配置阅读下一篇文章在Linux上安装S3存储 。 女将-S3-中心标志
安装s3cmd包
s3cmd是默认的RPM库针对CentOS,RHEL和Ubuntu系统上可用,您可以简单的在系统上执行以下命令进行安装。
在CentOS / RHEL:

# yum install s3cmd

在Ubuntu / Debian:

$ sudo apt-get install s3cmd

在SUSE Linux Enterprise Server 11:

# zypper addrepo http://s3tools.org/repo/SLE_11/s3tools.repo
# zypper install s3cmd

使用Source安装最新s3cmd
如果使用上述软件包管理器s3cmd,你没有得到最新的版本,可以使用源代码,在系统上安装最新的s3cmd版本。访问此网址或者使用下面的命令来下载最新版本的s3cmd。

$ wget http://ufpr.dl.sourceforge.net/project/s3tools/s3cmd/1.6.1/s3cmd-1.6.1.tar.gz
$ tar xzf s3cmd-1.6.1.tar.gz 

现在,使用下面的命令与源文件进行安装。

$ cd s3cmd-1.6.1
$ sudo python setup.py install

配置s3cmd环境
为了配置s3cmd我们将要求有您S3 Amazon帐户访问key和钥匙。获取安全密钥AWS securityCredentials 。将提示登录到您的Amazon帐户。 获取密钥文件后,请使用以下命令来配置s3cmd。

# s3cmd --configure
Enter new values or accept defaults in brackets with Enter.
Refer to user manual for detailed description of all options.

Access key and Secret key are your identifiers for Amazon S3
Access Key: xxxxxxxxxxxxxxxxxxxxxx
Secret Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Encryption password is used to protect your files from reading
by unauthorized persons while in transfer to S3
Encryption password: xxxxxxxxxx
Path to GPG program [/usr/bin/gpg]:

When using secure HTTPS protocol all communication with Amazon S3
servers is protected from 3rd party eavesdropping. This method is
slower than plain HTTP and can't be used if you're behind a proxy
Use HTTPS protocol [No]: Yes

New settings:
  Access Key: xxxxxxxxxxxxxxxxxxxxxx
  Secret Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Encryption password: xxxxxxxxxx
  Path to GPG program: /usr/bin/gpg
  Use HTTPS protocol: True
  HTTP Proxy server name:
  HTTP Proxy server port: 0

Test access with supplied credentials? [Y/n] Y
Please wait, attempting to list all buckets...
Success. Your access key and secret key worked fine :-)

Now verifying that encryption works...
Success. Encryption and decryption worked fine :-)

Save settings? [y/N] y
Configuration saved to '/root/.s3cfg'

s3cmd命令行的使用
一旦配置成功完成。现在找到下面的命令细节,如何使用命令管理S3桶。
1.列出全部S3桶
使用以下命令列出在您的AWS账户中的所有S3桶。

# s3cmd ls

2.创建新桶
要在下面的命令Amazon S3上使用的新桶。这将创建S3帐户名为howtoing桶。

# s3cmd mb s3://howtoing
Bucket 's3://howtoing/' created
  1. 上传文件到S3桶
    以下命令将使用s3cmd命令上传文件file.txt的到S3桶。
    # s3cmd put file.txt s3://howtoing/
    file.txt -> s3://howtoing/file.txt  [1 of 1]
    190216 of 190216   100% in    0s  1668.35 kB/s  done
    

4.上传文件夹到s3桶
如果我们需要上传整个目录使用-r递归上传,像下面这样。

# s3cmd put -r backup s3://howtoing/

backup/file1.txt -> s3://howtoing/backup/file1.txt  [1 of 2]
 9984 of 9984   100% in    0s    18.78 kB/s  done
backup/file2.txt -> s3://howtoing/backup/file2.txt  [2 of 2]
 0 of 0     0% in    0s     0.00 B/s  done 

请确保您上传目录的结尾没有斜杠 / (如:backup/),否则将只上传备份目录中的内容。

# s3cmd put -r backup/ s3://howtoing/

backup/file1.txt -> s3://howtoing/file1.txt  [1 of 2]
 9984 of 9984   100% in    0s    21.78 kB/s  done
backup/file2.txt -> s3://howtoing/file2.txt  [2 of 2]
 0 of 0     0% in    0s     0.00 B/s  done

5.列出S3存储数据
使用 ls 与 s3cmd 切换目录S3桶的对象。

# s3cmd ls s3://howtoing/

                       DIR   s3://howtoing/backup/
2013-09-03 10:58    190216   s3://howtoing/file.txt

6.从s3下载文件
有些时候,如果我们需要从S3下载文件,使用下面的命令来下载。

# s3cmd get s3://howtoing/file.txt

s3://howtoing/file.txt -> ./file.txt  [1 of 1]
 4 of 4   100% in    0s    10.84 B/s  done

7.删除S3桶的数据
要删除的文件夹都是从S3桶使用下面的命令。

 Removing file from s3 bucket 
# s3cmd del s3://howtoing/file.txt

File s3://howtoing/file.txt deleted

 Removing directory from s3 bucket 
# s3cmd del s3://howtoing/backup

File s3://howtoing/backup deleted

8.卸下S3桶
如果我们不需要S3存储,我们可以用下面的命令直接删除它。取出桶之前,请确保它是空的。

# s3cmd rb s3://howtoing

ERROR: S3 error: 409 (BucketNotEmpty): The bucket you tried to delete is not empty

上面的命令失败,因为S3桶不为空 要删除s3 桶先删除里面所有对象,然后再次使用命令。

# s3cmd rb s3://howtoing

Bucket 's3://howtoing/' removed

解决 golang获取 golang.org/x 包失败的方法

git 获取golang.org/x包失败

go get
package golang.org/x/net/websocket: unrecognized import path 
"golang.org/x/net/websocket" (https fetch: Get https://golang.org/x/net/websocket?go-get=1: 
dial tcp 216.239.37.1:443: i/o timeout)

加上代理,还是不行
解决方法
golang 在 github 上建立了一个镜像库,如 https://github.com/golang/net 即是 https://golang.org/x/net 的镜像库
手动的去这个库拉就到指定目录就行了,没有目录就创建

解决微信小游戏request fail unexpected end of ZLI

微信小游戏ios没问题,android版始终不能使用
console发现报错 request fail unexpected end of ZLI,

查这个错误是Java io流错误的返回,抓包看了接口,思索良久突然发现header里的gzip压缩,感觉应该是gzip压缩后android版小程序里面不能识别对应的压缩算法,返回里把gzip压缩去掉
正常

golang Http ioutil.ReadAll 惊现 Unexpected EOF解决办法

今天用Golang 读取Get请求接口在走到 ioutil.ReadAll 碰到 Unexpected EOF,原代码如下

    url := ""

    client := &http.Client{}

    req, err := http.NewRequest("GET", url, nil)
    req.Close = true

    resp, err := client.Do(req)
    if err != nil {
        fmt.Println(`aaaaaa`)
        return nil, (err)
    }

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(`bbbbbb`)
        return ms, err
    }

当然,还是Google,最后发现返回是gzip压缩过的,而直接获取是获取不到的,所以要加设置要求接口明码返回

req.Header.Add("Accept-Encoding", "identity")

注:资料来源https://stackoverflow.com/questions/21147562/unexpected-eof-using-go-http-client

It looks like the that server (Apache 1.3, wow!) is serving up a truncated gzip response. If you explicitly request the identity encoding (preventing the Go transport from adding gzip itself), you won’t get the ErrUnexpectedEOF:

这句话是这么理解的吧?

macOS 终端通过代理访问网络的方法(包括ssh)

终端是默认不会走代理的(一直以为是会),今天网络问题始终连不上AWS的服务器,没办法找解决办法。
在终端试一下当前出口:

curl cip.cc

返回

IP    : ********
地址    : 中国  上海
运营商    : 联通

数据二    : 上海市 | 联通

数据三    : 中国上海上海市 | 联通

URL    : http://www.cip.cc/**********

说明确实不走代理, 因为shadowsocks是全局模式,web看到的出口是香港
解决方法:(比较喜欢在当前终端解决问题,不修改全局,有问题关掉这个终端窗口就没事了)

vim .bash_profile

加入

# proxy list
alias proxy='export all_proxy=socks5://127.0.0.1:1086' #1086不是写死的端口,是根据每个人本地socks5真是端口
alias unproxy='unset all_proxy'

OK,让配置生效

source ~/.bash_profile

这个终端proxy别名就生效了,于是开始设置代理生效

proxy

再次查看出口

curl cip.cc

IP    : **********
地址    : 中国  香港 

数据二    : 香港 | 特别行政区

数据三    : 中国香港香港

URL    : http://www.cip.cc/***************

生效。

本来以为这样就可以解决ssh连不上AWS的问题,结果当然不行,原因嘛,应该如下:
socks,http代理等使用的是TCP或UDP协议, 而ping命令则是ICMP协议, 所以proxychains4对ping命令无效
想当然这样以为吧,大致是这个方向的原因。

总得解决,因为让终端走代理的最终目的是为了ssh到AWS啊
还是G找
终于发现一个最简易的问题
命令

ssh myserver -o "ProxyCommand=nc -X 5 -x 127.0.0.1:1086 %h %p"

终于就走了代理,服气

当然还有个没试过的复杂方法,也记录一下

vim ~/.ssh/config
# 添加以下内容
Host 52.* # 这里可以通配也可以指定IP
    ProxyCommand nc -X 5 -x 127.0.0.1:1079 %h %p
    # "5" 是 SOCKS 5, "1079" 是本地socks端口

Ubuntu 安装 mysql

wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.25-linux-glibc2.12-x86_64.tar.gz
tar xvf mysql-5.7.25-linux-glibc2.12-x86_64.tar.gz
mv mysql/ /usr/local/
useradd mysql
mkdir mydata
mkdir mydata/data
chown -R mysql mysql/
vim /etc/my.cnf

[client]
port = 3306
socket = /tmp/mysql.sock

[mysqld]
character_set_server=utf8
init_connect='SET NAMES utf8'
basedir=/usr/local/mysql
datadir=/usr/local/mysql/mydata/data
socket=/tmp/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/mysqld.pid
lower_case_table_names = 1
user=mysql

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
max_connections=1000

这里的内容尽量不要有改变,要不然会有不可预测问题

touch /var/log/mysqld.log
chmod 777 /var/log/mysqld.log
touch /var/run/mysqld/mysqld.pid
chmod 777 /var/run/mysqld

安装 libaio
apt-get install libaio-dev

/usr/local/mysql/bin/mysqld –initialize –user=mysql –basedir=/usr/local/mysql –datadir=/usr/local/mysql/mydata/data –lc_messages_dir=/usr/local/mysql/share –lc_messages=en_US

touch mysqld.pid
chmod 777 mysqld.pid
chown mysql.mysql mysqld.pid
support-files/mysql.server start

加入系统服务
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
Ubuntu
update-rc.d mysqld defaults
centOs
chkconfig –add mysqld
chkconfig –level 2345 mysqld on

golang csv文件操作

一、写csv文件

函数:

func NewWriter(w io.Writer) *Writer

func (w *Writer) Flush()

func (w *Writer) Write(record []string) (err os.Error)

func (w *Writer) WriteAll(records [][]string) (err os.Error)

demo

package main

import (
    "bytes"
    "encoding/csv"
    "fmt"
    "os"
)

func main() {
    fileName := "2.csv"
    buf := new(bytes.Buffer)
    r2 := csv.NewWriter(buf)
    for i := 0; i < 10; i++ {
        s := make([]string, 3)
        s[0] = "user id"
        s[1] = "name"
        s[2] = "depart"
        r2.Write(s)
        r2.Flush()
    }
    fmt.Println(buf)
    fout, err := os.Create(fileName)
    defer fout.Close()
    if err != nil {
        fmt.Println(fileName, err)
        return
    }
    fout.WriteString(buf.String())
}

二、读csv文件

函数:

func NewReader(r io.Reader) *Reader

func (r *Reader) Read() (record []string, err os.Error)

func (r *Reader) ReadAll() (records [][]string, err os.Error)

demo

package main

import (
    "encoding/csv"
    "fmt"
    "io/ioutil"
    "strings"
)

func main() {
    //fileName := "1.csv"
    fmt.Printf("Input file name : ")
    var fileName string
    fmt.Scanf("%s", &fileName)
    cntb, err := ioutil.ReadFile(fileName)
    if err != nil {
        panic(err)
    }
    r2 := csv.NewReader(strings.NewReader(string(cntb)))
    ss, _ := r2.ReadAll()
    //fmt.Println(ss)
    sz := len(ss)
    for i := 0; i < sz; i++ {
        fmt.Println(ss[i])
    }
}

golang map的排序

老是掉进golang数据结构map的坑里,PHP习惯了只有数组一种结构,老是会把map想成PHP不是默认key的数组,其实最大的不同就是map是随机排序的,以后用map的时候要提醒自己是不是有排序需求

golang map按key排序

//golang的map不保证有序性,所以按key排序需要取出key,对key排序,再遍历输出value
package main

import (
    "fmt"
    "sort"
)

func main() {
    // To create a map as input
    m := make(map[int]string)
    m[1] = "a"
    m[2] = "c"
    m[0] = "b"

    // To store the keys in slice in sorted order
    var keys []int
    for k := range m {
        keys = append(keys, k)
    }
    sort.Ints(keys)

    // To perform the opertion you want
    for _, k := range keys {
        fmt.Println("Key:", k, "Value:", m[k])
    }
}

golang map按value排序

//要对golang map按照value进行排序,思路是直接不用map,用struct存放key和value,实现sort接口,就可以调用sort.Sort进行排序了。
// A data structure to hold a key/value pair.
type Pair struct {
    Key   string
    Value int
}

// A slice of Pairs that implements sort.Interface to sort by Value.
type PairList []Pair

func (p PairList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p PairList) Len() int           { return len(p) }
func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }

// A function to turn a map into a PairList, then sort and return it.
func sortMapByValue(m map[string]int) PairList {
    p := make(PairList, len(m))
    i := 0
    for k, v := range m {
        p[i] = Pair{k, v}
        i ++
    }
    sort.Sort(p)
    return p
}

golang map递增排序

//sort.Sort是递增排序,如果要实现递减排序,用sort.Reverse
package main

import (
    "fmt"
    "sort"
)

func main() {
    a := []int{4,3,2,1,5,9,8,7,6}
    sort.Sort(sort.Reverse(sort.IntSlice(a)))
    fmt.Println("After reversed: ", a)
}

golang map 排序的稳定性

//sort不保证排序的稳定性(两个相同的值,排序之后相对位置不变),排序的稳定性由sort.Stable来保证。
package main

import (
    "fmt"
    "sort"
)

type person struct {
  Name string
  Age int
}

type personSlice []person

func (s personSlice) Len() int { return len(s) }
func (s personSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s personSlice) Less(i, j int) bool { return s[i].Age < s[j].Age }

func main() {
    a := personSlice {
      {
        Name: "AAA",
        Age: 55,
      },
      {
        Name: "BBB",
        Age: 22,
      },
      {
        Name: "CCC",
        Age: 0,
      },
      {
        Name: "DDD",
        Age: 22,
      },
      {
        Name: "EEE",
        Age: 11,
      },  
    }
    sort.Stable(a)
    fmt.Println(a)
}

golang 操作符:= 造成的err is shadowed during return

今天在编译代码时发生了一个错误

221:4: err is shadowed during return

错误范围代码

for _, v := range scontent {
        tmp := strings.Split(v, `;`)
        labels = append(labels, tmp[0])
        g, err := strconv.Atoi(tmp[3])
        if len(tmp[0]) == 0 || len(tmp[1]) == 0 || len(tmp[2]) == 0 || err != nil || g <= 2010 {
            err = err_student_data
            return
        }
    }

从错误本身理解是返回值err 被遮盖重新定义了,不再是方法的返回值了。
根据错误提示肯定是

g, err := strconv.Atoi(tmp[3])

发生了错误, 提示既是err被重新定义了, 那就是操作符 := 的问题了
Golang的:=操作符理解为

是声明并赋值,并且系统自动推断类型,不需要var关键字

另外Golang的for是独立的作用域,所以for里面用了 := , err本来是希望继承外面变量的作用域的, 但是在这里被重新定义为了一个新的变量造成了错误, 看来Golang还不够智能。