vagrant 开发环境配置

1.固定私有IP

config.vm.network :private_network, ip: “11.11.11.11”

2.使用自定义用户名

config.ssh.username = “game1”

3.指定ssh端口

config.ssh.port = “2222”

4.使用private key 登录

config.ssh.private_key_path = “~/.ssh/id_rsa”

ubuntu操作

1.创建新用户(useradd会自动创建home/game1目录,并拷贝相关文件)

sudo useradd game1
sudo passwd game1

2.创建组

sudo groupadd docker

3.添加用户到组

sudo usermod -aG docker game1
//添加到sudo组,使其可使用sudo命令
sudo gpasswd -a game1 sudo

4.取消game1执行sudo命令需要输入密码, 方便vagrant系统命令

vim /etc/sudoers.d/vagrant

game1 ALL=(ALL) NOPASSWD:ALL

5.添加ssh公钥到主机

mkdir ~/.ssh
vim ~/.ssh/authorized_keys
写入公钥信息

golang-RWMutex

RWMutex 读写互斥锁

基本原则:

1.可以随便读,多个goroutine同时读
2.写的时候,啥也不能干,不能读也不能写

RWMutex四个方法:

func(*RWMutex)Lock //写锁定

func(*RWMutex)Unlock //写锁定

func(*RWMutex)RLock //读锁定

func(*RWMutex)RUnlock //读解锁

一、随便读

package main

import (
    "sync"
    "time"
)

var m *sync.RWMutex

func main() {
    m = new(sync.RWMutex)

    //多个同时读
    go read(1)
    go read(2)

    time.Sleep(2*time.Second)
}

func read(i int) {
    println(i, "read start")

    m.RLock()
    println(i, "reading")
    time.Sleep(1*time.Second)
    m.RUnlock()

    println(i,"read over")
}

result:

1 read start
1 reading
2 read start
2 reading
1 read over
2 read over

二、写的时候啥也不能干

package main

import (
    "sync"
    "time"
)

var m *sync.RWMutex

func main() {
    m = new(sync.RWMutex)

    // 写的时候啥也不能干
    go write(1)
    go read(2)
    go write(3)

    time.Sleep(2*time.Second)
}

func read(i int) {
    println(i, "read start")

    m.RLock()
    println(i, "reading")
    time.Sleep(1*time.Second)
    m.RUnlock()

    println(i, "read over")
}

func write(i int) {
    println(i, "write start")

    m.Lock()
    println(i, "writing")
    time.Sleep(1*time.Second)
    m.Unlock()

    println(i, "write over")
}

result:

1 write start
1 writing
2 read start
3 write start
1 writing over
2 reading
2 read over
3 writing
3 writing over

upstart-命令备忘

upstart script 关键字:

1. exec: 执行命令, 在script块中使用
    exec /usr/bin/zip -v

2. script: 脚本块,包括主运行脚本
       script
           exec /usr/bin/zip /root/upstart.zip /root/upstart/txt
       end script

3. pre-start: 脚本块, 在主运行脚本之前执行的脚本
    pre-start script
        exec rm /root/upstart.txt
        exec echo pre-start >> /root/upstart.txt
    end script

4. post-start: 脚本块, 在主运行脚本之后, running状态之前
    post-start script
        exec echo post-start>> /root/upstart.txt
    end script

5. pre-stop: 脚本块, 在执行stop之前
    pre-stop script
        exec echo pre-stop >> /root/upstart.txt
    end script

6. post-stop: 脚本块, 在主运行脚本被杀死之后
    post-stop script
        exex echo post-stop >> /root/upstart.txt
    end script

7. start on: 事件, 启动任务
    start on startup

8. stop on: 事件, 停止任务
    stop on shutdown

9. description: 描述, 信息提示
    desription "This is a upstart testing"

10. author: 描述, 作者信息
    author "liupeng <pengswift.github.io>"

11. version: 描述, 版本信息
    version "0.0.1 dev"

12. respawn: 命令, 设置服务异常停止后自动重启
    respawn

13. respawn limit: 命令, 设置服务异常停止后重启次数及间隔时间
    respawn limit 15 3

14. instance: 定义实例名字, 可以通过命令給任务传参数
    instance $TTY
    exec /sbin/getty -8 38300 $TTY

    #通过命令传参数
    ~ start mytest $TTY=tty1

15. kill timeout: 命令, 在达到指定时间后, 停止应用
    kill timeout 5

16. normal exit: 命令, 正常退出,不会被respawn重启
    normal exit 0 TERM

17. env: 变量, 设置任务的环境变量
    env PIDFILE=/var/run/myprocess.pid

18. umask: 变量,设置任务的文件权限掩码
    umask 0755

19. nice: 变量, 设置任务的调度优先级
    nice -5

20. limit: 变量, 设置任务的资源限制
    limit nproc 10 10

21. chroot: 变量, 设置任务的根目录
    chroot /var/lib/www/jail

22. chdir: 变量, 设置任务的工作目录
    chdir /var/tmp

upstart 命令

1. 查看版本
    ~ initctl version
    init (upstart 1.12.1)

2. 查看mytest应用状态
    ~ initctl list | grep mytest

    ~ status mytest

3. 启动mytest应用
    ~ initctl start mytest

    ~ start mytest

4. 停止mytest应用
    ~ initctl stop mytest

    ~ stop mytest

upstart封装mytest

~ vi /etc/init/mytest.conf

description "mytest"
author "bsspirit <http://blog.fens.me>"

env var=bar
export var

start on startup
stop on shutdown

respawn
respawn limit 2 5

console output

pre-start script
    logger "pre-start: before: var=$var"
    var=pre-start
    export var
    logger "pre-start: after: var=$var"
end script

post-start script
    logger "post-start: before: var=$var"
    var=post-start
    export var
    logger "post-start: after: var=$var"
end script

script
    logger "script: before: var=$var"
    var=main
    export var
    sleep 60000
    logger "script: after: var=$var"
end script

post-stop script
    logger "post-stop: before: var=$var"
    var=post-stop
    export var
    logger "post-stop: after: var=$var"
end script




测试mytest程序:

启动mytest任务
    ~ start mytest
    mytest start/running, process 3257

查看日志跟踪运行状态
    ~ tail -f /var/log/syslog

    Jun 14 20:41:13 liupeng-VirtualBox logger: pre-start: before: var=bar
    Jun 14 20:41:13 liupeng-VirtualBox logger: pre-start: after: var=pre-start
    Jun 14 20:41:13 liupeng-VirtualBox logger: script: before: var=bar
    Jun 14 20:41:13 liupeng-VirtualBox logger: post-start: before: var=bar
    Jun 14 20:41:13 liupeng-VirtualBox logger: post-start: after: var=post-start

查看mytest任务状态
    ~ status mytest
    mytest start/running, process 3257

查看系统进程,因为在程序中用sleep停止,要通过sleep查询
    ~ ps -aux|grep sleep
    root     3220  0.0  0.0   2176   276 ?        S    20:40   0:00 sleep 60000

杀掉sleep进程,mytest自动重启
    kill -9 3220

停止mytest
    stop mytest
    mytest stop/waiting

通过命令传参数,启动mytest
start mytest var=liupeng

docker-命令备忘

docker 命令

1. 创建容器
    docker run -i -t ubuntu /bin/base

2. 创建并设置容器别名
    docker run --name bob_the_container -i -t ubuntu /bin/bash

3. 启动容器
    docker start bob_the_container

    docker start aa3f365f044e


4. 重启容器
    docker restart bob_the_container

5. attach到容器
    docker attach bot_the_container

6. 创建守护式容器
    docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

7. 查看容器日志
    docker logs daemon_dave

8. 监控容器日志
    docker logs -f daemon_dave
    docker logs --tail 10 daemon_dave
    docker logs --tail 0 -f daemon_dave

9. 查看容器内进程
    docker top daemon_dave


10. 下载镜像
    docker pull ubuntu:latest

11. 查看已下载的镜像
    docker images ubuntu

12. 查找可用的镜像
    docker search puppet

13. 创建镜像
    docker commit 4aab3ce3cb76 jamtur01/apache2

14. 创建并添加提交信息 (日志, 作者, tag)
    docker commit -m="A new custom image" --author="liupeng" 4aab3ce3cb76 jamtur01/apache2:webserver

15. 查看镜像详细信息
    docker inspect jamtur01/apache2:webserver

16. 通过Dockerfile 创建镜像
    # Version: 0.0.1
    FROM ubuntu:14.04
    MAINTRAINER liupeng "pengswift.github.io"
    RUN apt-get update
    RUN ap-get install -y nginx
    RUN echo "Hi, I am in your container"
        >/usr/share/nginx/html/index.html
    EXPOSE 80

    通过本地Dockerfile
    docker build -t="jamtur01/static_web:v1" .

    通过git仓库
    docker build -t="jamtur01/static_web:v1" git@github.com:jamtur01/docker-static_web

17. 不使用缓存创建镜像
    docker build --no-cache -t="jamtur01/static_web"        
18. 查看镜像的创建历史
    docker history training/postgres

19. 启动容器,指定容器端口
    docker run -d -p 80 --name static_web jamtur01/static_web nginx -g "daemon off;"

20. 查看容器端口在宿主上的映射端口
    docker port 6752b94bb5c0 80

21. 启动容器,指定宿主和容器端口
    docker run -d -p 8080:80 --name static_web jamtur01/static_web nginx -g "daemon off;"

22. 启动容器,指定宿主和容器端口, 限制ip访问
    docker run -d -p 127.0.0.1:8080:80 --name static_web jamtur01/static_web nginx -g "daemon off;"

23. 启动容器,使用Dockerfile 默认端口
    docker run -d -P --name static_web jamtur01/static_web nginx -g "daemon off;"

golang-map遍历key随机

e.g.

package main

import (
    "fmt"
)

func main() {
    m := make(map[string]string)
    m["hello"] = "echo hello"
    m["world"] = "echo world"
    m["go"] = "echo go"
    m["is"] = "echo is"
    m["cool"] = "echo cool"

    for k, v := range m {
        fmt.Printf("k=%v, v=%v\n", k, v)
    }
}

修正版

e.g.

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := make(map[string]string)
    m["hello"] = "echo hello"
    m["world"] = "echo world"
    m["go"] = "echo go"
    m["is"] = "echo is"
    m["cool"] = "echo cool"

    sorted_keys := make([]string, 0)
    for k, _ := range m {
        sorted_keys = append(sorted_keys, k)
    }

    sort.Strings(sorted_keys)

    for _, k := range sorted_keys {
        fmt.Printf("k=%v, v=%v\n", k, m[k])
    }
}

golang-Benchmark

e.g.

package my

import(
    "sync"
    "testing"
)

var lock sync.Mutex

func test() {
    lock.Lock()
    lock.Unlock()
}

func testdefer() {
    lock.Lock()
    defer lock.Unlock()
}

func BenchmarkTest(b *testing.B) {
    for i := 0; i < b.N; i++ {
        test()
    }
}

func BenchmarkTestDefer(b *testing.B) {
    for i := 0; i < b.N; i++ {
        testdefer()
    }
}

命令:
go test defer_b_test.go -bench=”.*”

golang-返回*int指针

func test() *int {
x := 100
return &x
}

注: 此处因为返回了变量int的地址, 所以基本类型x的值不会分配到栈中,
因为栈中的数据只在作用域范围内有效。
所以此处编译器会根据需求将其分配到堆中,交给gc去处理

golang-16进制&10进制

1个字节byte(8位2进制数)
可以用来表示1个10进制数,
可以用来表示2个16进制数(每四位二进制可以表示1个16进制数),

e.g.

package main

import(
    "fmt"
    "unsafe"
)    

func main() {
    //声明1个16进制的数
    x := 0x12345678

    //将指向x的指针转变成通用指针
    p := unsafe.Pointer(&x)
    //将通用指针转变成容量是4 的字节数组的指针, 这样,由于每个字节能存储2个16进制数, 所以 4个字节的容量 可以存储 8个16进制的数
    n :=(*[4]byte)(p)

    //遍历, 每次打印一个字节, (包含2个16进制的数)
    for i := 0; i < len(n); i++ {
        fmt.Printf("%X ", n[i])
    }
}