Giter Site home page Giter Site logo

hackstoic.github.io's People

Contributors

coinstoic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

ziranjuanchow

hackstoic.github.io's Issues

Golang学习笔记之数据结构

##数据结构
###变量和常量
####变量
Go 是静态类型语⾔,不能在运⾏期改变变量类型。
也就是说必须在使用时声明, 且使用过程赋值不对的话会报错。 比如给一个int类型的变量赋值一个字符串,就会报错。
var x int // 只定义不赋值, 默认系统赋值为0
var f float32 = 1.6 // 声明类型,并具体赋值
var s = "abc" // 不声明类型, 系统会自动判断
z := 5 // 用于定义新的局部变量或修改全局变量的值,不能修改局部变量的值!
var (
m int
n string
) // 定义多个变量, 注意这里时括号,不是花括号
var m, n, p int // 如果多个变量都是同种类型,可以使用这种方式简化定义
s, p = 0, "test" // 给多个变量赋值, 赋值时请先检查有没有定义,否则会报错
特殊变量: _ 用于忽略值,该变量 只写不可读
编译器会将未使⽤的局部变量当做错误。
var s string // 全局变量没问题。
func main() {
i := 0 // Error: i declared and not used。(可使⽤ "_ = i" 规避)
}
注意重新赋值与定义新同名变量的区别。
s := "abc"
println(&s)
s, y := "hello", 20 // 重新赋值: 与前 s 在同⼀层次的代码块中,且有新的变量被定义。
println(&s, y) // 通常函数多返回值 err 会被重复使⽤。
{
s, z := 1000, 30 // 定义新同名变量: 不在同⼀层次代码块。
println(&s, z)
}
输出:
0x2210230f30
0x2210230f30 20
0x2210230f18 30

在函数中, := 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。

函数外的每个语句都必须以关键字开始( var 、 func 、等等),** := 结构不能使用在函数外**。
####常量
const
常量值必须是编译期可确定的数字、字符串、布尔值

const x, y int = 1, 2 // 多常量初始化
const s = "Hello, World!" // 类型推断
const ( // 常量组
 a, b = 10, 100
 c bool = false
)
func main() {
 const x = "xxx" // 未使⽤局部常量不会引发编译错误。这个和变量有所不同
}

不⽀持 1UL、2LL 这样的类型后缀。
在常量组中,如不提供类型和初始化值,那么视作与上⼀常量相同
const (
s = "abc"
x // x = "abc"
)
常量值还可以是 len、cap、unsafe.Sizeof 等编译期可确定结果的函数返回值。
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(b)
)
如果常量类型⾜以存储初始化值,那么不会引发溢出错误
枚举
关键字 iota 定义常量组中从 0 开始按⾏计数的⾃增枚举值。
const (
Sunday = iota // 0
Monday // 1,通常省略后续⾏表达式。
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)

const (
_ = iota // iota = 0
KB int64 = 1 << (10 * iota) // iota = 1
MB // 与 KB 表达式相同,但 iota = 2
GB
TB
)
在同⼀常量组中,可以提供多个 iota,它们各⾃增⻓。
const (
A, B = iota, iota << 10 // 0, 0 << 10
C, D // 1, 1 << 10
)
如果 iota ⾃增被打断,须显式恢复。
const (
A = iota // 0
B // 1
C = "c" // c
D // c,与上⼀⾏相同。
E = iota // 4,显式恢复。注意计数包含了 C、D 两⾏。
F // 5
)
可通过⾃定义类型来实现枚举类型限制。

type Color int
const (
 Black Color = iota
 Red
 Blue
)
func test(c Color) {}
func main() {
 c := Black
 test(c)
 x := 1
 test(x) // Error: cannot use x (type int) as type Color in function argument
 test(1) // 常量会被编译器⾃动转换。
}

Tips:

  1. 常量如果没有定义,默认和上一个定义同种类型
  2. iota是golang中独有的关键字,是一种自增枚举类型

###基本数据类型
更明确的数字类型命名,⽀持 Unicode,⽀持常⽤数据结构。

类型 |⻓度| 默认值 |说明
bool |1| false
byte |1| 0| uint8
rune |4 |0 |Unicode Code Point, int32
int, uint| 4 或 8| 0 |32 或 64 位
int8, uint8 |1 |0| -128 ~ 127, 0 ~ 255
int16, uint16| 2| 0 |-32768 ~ 32767, 0 ~ 65535
int32, uint32 |4| 0| -21亿 ~ 21 亿, 0 ~ 42 亿
int64, uint64| 8| 0
float32| 4 |0.0
float64| 8| 0.0
complex64| 8
complex128| 16
uintptr| 4 或 8| |⾜以存储指针的 uint32 或 uint64 整数
array|| |值类型
struct|| |值类型
string ||""| UTF-8 字符串
slice ||nil |引⽤类型
map|| nil |引⽤类型
channel ||nil |引⽤类型
interface ||nil |接⼝
function ||nil| 函数

⽀持⼋进制、⼗六进制,以及科学记数法。标准库 math 定义了各数字类型取值范围。
a, b, c, d := 071, 0x1F, 1e9, math.MinInt16
空指针值 nil,⽽⾮ C/C++ NULL。

Go 的在不同类型之间的项目赋值时需要显式转换, 比如

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

###字符串类型
字符串是不可变值类型,内部⽤指针指向 UTF-8 字节数组。
• 默认值是空字符串 ""。
• ⽤索引号访问某字节,如 s[i]。
• 不能⽤序号获取字节元素指针,&s[i] ⾮法。
• 不可变类型,⽆法修改字节数组。
• 字节数组尾部不包含 NULL。
runtime.h
struct String
{
byte* str;
intgo len;
};
使⽤索引号访问字符 (byte)。
s := "abc"
println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63)
输出:
true true true
使⽤ "" 定义不做转义处理的原始字符串,⽀持跨⾏。 s := a
b\r\n\x00
c`
println(s)
输出:
a
b\r\n\x00
c

⽀持⽤两个索引号返回⼦串。⼦串依然指向原字节数组,仅修改了指针和⻓度属性。
s := "Hello, World!"
s1 := s[:5] // Hello
s2 := s[7:] // World!
s3 := s[1:5] // ello

单引号字符常量表⽰ Unicode Code Point,⽀持 \uFFFF、\U7FFFFFFF、\xFF 格式。
对应 rune 类型,UCS-4。
func main() {
fmt.Printf("%T\n", 'a')
var c1, c2 rune = '\u6211', '们'
println(c1 == '我', string(c2) == "\xe4\xbb\xac")
}
输出:
int32 // rune 是 int32 的别名
true true

要修改字符串,可先将其转换成 []rune 或 []byte,完成后再转换为 string。⽆论哪种转
换,都会重新分配内存,并复制字节数组。
func main() {
s := "abcd"
bs := []byte(s)
bs[1] = 'B'
println(string(bs))
u := "电脑"
us := []rune(u)
us[1] = '话'
println(string(us))
}
输出:
aBcd
电话
⽤ for 循环遍历字符串时,也有 byte 和 rune 两种⽅式。
func main() {
s := "abc汉字"
for i := 0; i < len(s); i++ { // byte
fmt.Printf("%c,", s[i])
}
fmt.Println()
for _, r := range s { // rune
fmt.Printf("%c,", r)
}
}
输出:
a,b,c,æ,±,,å,­,,
a,b,c,汉,字,
###结构体
###时间日期类型
###复杂数据类型
####Array
和以往认知的数组有很⼤不同。
• 数组是值类型,赋值和传参会复制整个数组,⽽不是指针。
• 数组⻓度必须是常量,且是类型的组成部分。[2]int 和 [3]int 是不同类型。
• ⽀持 "=="、"!=" 操作符,因为内存总是被初始化过的。
• 指针数组 [n]*T,数组指针 *[n]T。
可⽤复合语句初始化

a := [3]int{1, 2} // 未初始化元素值为 0。
b := [...]int{1, 2, 3, 4} // 通过初始化值确定数组⻓度。
c := [5]int{2: 100, 4:200} // 使⽤索引号初始化元素。
d := [...]struct {
 name string
 age uint8
}{
 {"user1", 10}, // 可省略元素类型。
 {"user2", 20}, // 别忘了最后⼀⾏的逗号。
}

⽀持多维数组。

a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能⽤ "..."。

值拷⻉⾏为会造成性能问题,通常会建议使⽤ slice,或数组指针。

func test(x [2]int) {
 fmt.Printf("x: %p\n", &x)
 x[1] = 1000
}
func main() {
 a := [2]int{}
 fmt.Printf("a: %p\n", &a)
 test(a)
 fmt.Println(a)
}
// 输出:
a: 0x2101f9150
x: 0x2101f9170
[0 0]

内置函数 len 和 cap 都返回数组⻓度 (元素数量)。

a := [2]int{}
println(len(a), cap(a)) // 2, 2

####Slice
需要说明,slice 并不是数组或数组指针。它通过内部指针和相关属性引⽤数组⽚段,以
实现变⻓⽅案。
runtime.h

struct Slice
{ // must not move anything
 byte* array; // actual data
 uintgo len; // number of elements
 uintgo cap; // allocated number of elements
};

引⽤类型。但⾃⾝是结构体,值拷⻉传递。
• 属性 len 表⽰可⽤元素数量,读写操作不能超过该限制。
• 属性 cap 表⽰最⼤扩张容量,不能超出数组限制。
• 如果 slice == nil,那么 len、cap 结果都等于 0。

data := [...]int{0, 1, 2, 3, 4, 5, 6}
slice := data[1:4:5] // [low : high : max]

创建表达式使⽤的是元素索引号,⽽⾮数量

data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

|expression |slice | len| cap |comment|
data[:6:8] |[0 1 2 3 4 5]| 6|8 |省略 low.
data[5:] |[5 6 7 8 9]| 5 |5| 省略 high、max。
data[:3] |[0 1 2] |3 |10| 省略 low、max。
data[:] |[0 1 2 3 4 5 6 7 8 9] |10 |10| 全部省略。

读写操作实际⺫标是底层数组,只需注意索引号的差别。

data := [...]int{0, 1, 2, 3, 4, 5}
s := data[2:4]
s[0] += 100
s[1] += 200
fmt.Println(s)
fmt.Println(data)
//输出:
[102 203]
[0 1 102 203 4 5]

可直接创建 slice 对象,⾃动分配底层数组。

s1 := []int{0, 1, 2, 3, 8: 100} // 通过初始化表达式构造,可使⽤索引号。
fmt.Println(s1, len(s1), cap(s1))
s2 := make([]int, 6, 8) // 使⽤ make 创建,指定 len 和 cap 值。
fmt.Println(s2, len(s2), cap(s2))
s3 := make([]int, 6) // 省略 cap,相当于 cap = len。
fmt.Println(s3, len(s3), cap(s3))

//输出:
[0 1 2 3 0 0 0 0 100] 9 9
[0 0 0 0 0 0] 6 8
[0 0 0 0 0 0] 6 6

使⽤ make 动态创建 slice,避免了数组必须⽤常量做⻓度的⿇烦。还可⽤指针直接访问底层数组,退化成普通数组操作。

s := []int{0, 1, 2, 3}
p := &s[2] // *int, 获取底层数组元素指针。
*p += 100
fmt.Println(s)
//输出:
[0 1 102 3]

⾄于 [][]T,是指元素类型为 []T

data := [][]int{
 []int{1, 2, 3},
 []int{100, 200},
 []int{11, 22, 33, 44},
}

可直接修改 struct array/slice 成员。

d := [5]struct {
 x int
}{}
s := d[:]
d[1].x = 10
s[2].x = 20
fmt.Println(d)
fmt.Printf("%p, %p\n", &d, &d[0])
//输出:
[{0} {10} {20} {0} {0}]
0x20819c180, 0x20819c180

所谓 reslice,是基于已有 slice 创建新 slice 对象,以便在 cap 允许范围内调整属性。

s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := s[2:5] // [2 3 4]
s2 := s1[2:6:7] // [4 5 6 7]
s3 := s2[3:6] // Error

data | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---+---+---+---+---+---+---+---+---+---+
0 2 5
+---+---+---+---+---+---+---+---+
s1 | 2 | 3 | 4 | | | | | | len = 3, cap = 8
+---+---+---+---+---+---+---+---+
0 2 6 7
+---+---+---+---+---+
s2 | 4 | 5 | 6 | 7 | | len = 4, cap = 5
+---+---+---+---+---+
0 3 4 5
+---+---+---+
s3 | 7 | 8 | X | error: slice bounds out of range

新对象依旧指向原底层数组。

s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := s[2:5] // [2 3 4]
s1[2] = 100
s2 := s1[2:6] // [100 5 6 7]
s2[3] = 200
fmt.Println(s)
//输出:
[0 1 2 3 100 5 6 200 8 9]

向 slice 尾部添加数据,返回新的 slice 对象。

s := make([]int, 0, 5)
fmt.Printf("%p\n", &s)
s2 := append(s, 1)
fmt.Printf("%p\n", &s2)
fmt.Println(s, s2)
//输出:
0x210230000
0x210230040
[] [1]

⼀旦超出原 slice.cap 限制,就会重新分配底层数组,即便原数组并未填满。

data := [...]int{0, 1, 2, 3, 4, 10: 0}
s := data[:2:3]
s = append(s, 100, 200) // ⼀次 append 两个值,超出 s.cap 限制。
fmt.Println(s, data) // 重新分配底层数组,与原数组⽆关。
fmt.Println(&s[0], &data[0]) // ⽐对底层数组起始指针。
//输出:
[0 1 100 200] [0 1 2 3 4 0 0 0 0 0 0]
0x20819c180 0x20817c0c0 

从输出结果可以看出,append 后的 s 重新分配了底层数组,并复制数据。如果只追加⼀个值,则不会超过 s.cap 限制,也就不会重新分配。
通常以 2 倍容量重新分配底层数组。在⼤批量添加数据时,建议⼀次性分配⾜够⼤的空间,以减少内存分配和数据复制开销。或初始化⾜够⻓的 len 属性,改⽤索引号进⾏操作。及时释放不再使⽤的 slice 对象,避免持有过期数组,造成 GC ⽆法回收。

s := make([]int, 0, 1)
c := cap(s)
for i := 0; i < 50; i++ {
 s = append(s, i)
 if n := cap(s); n > c {
 fmt.Printf("cap: %d -> %d\n", c, n)
 c = n
 }
}
输出:
cap: 1 -> 2
cap: 2 -> 4
cap: 4 -> 8
cap: 8 -> 16
cap: 16 -> 32
cap: 32 -> 64

函数 copy 在两个 slice 间复制数据,复制⻓度以 len ⼩的为准。两个 slice 可指向同⼀底层数组,允许元素区间重叠。

data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := data[8:]
s2 := data[:5]
copy(s2, s) // dst:s2, src:s
fmt.Println(s2)
fmt.Println(data)
//输出:
[8 9 2 3 4]
[8 9 2 3 4 5 6 7 8 9]

应及时将所需数据 copy 到较⼩的 slice,以便释放超⼤号底层数组内存。

####Map

引⽤类型,哈希表。键必须是⽀持相等运算符 (==、!=) 类型,⽐如 number、string、
pointer、array、struct,以及对应的 interface。值可以是任意类型,没有限制。

m := map[int]struct {
 name string
 age int
}{
 1: {"user1", 10}, // 可省略元素类型。
 2: {"user2", 20},
}
println(m[1].name)

预先给 make 函数⼀个合理元素数量参数,有助于提升性能。因为事先申请⼀⼤块内存,
可避免后续操作时频繁扩张。

m := make(map[string]int, 1000)

常⻅操作:

m := map[string]int{
 "a": 1,
}
if v, ok := m["a"]; ok { // 判断 key 是否存在。
 println(v)
}
println(m["c"]) // 对于不存在的 key,直接返回 \0,不会出错。
m["b"] = 2 // 新增或修改。
delete(m, "c") // 删除。如果 key 不存在,不会出错。
println(len(m)) // 获取键值对数量。cap ⽆效。
for k, v := range m { // 迭代,可仅返回 key。随机顺序返回,每次都不相同。
 println(k, v)
}

不能保证迭代返回次序,通常是随机结果,具体和版本实现有关。
从 map 中取回的是⼀个 value 临时复制品,对其成员的修改是没有任何意义的。

type user struct{ name string }
m := map[int]user{ // 当 map 因扩张⽽重新哈希时,各键值项存储位置都会发⽣改变。 因此,map
 1: {"user1"}, // 被设计成 not addressable。 类似 m[1].name 这种期望透过原 value
} // 指针修改成员的⾏为⾃然会被禁⽌。
m[1].name = "Tom" // Error: cannot assign to m[1].name

正确做法是完整替换 value 或使⽤指针。

u := m[1]
u.name = "Tom"
m[1] = u // 替换 value。
m2 := map[int]*user{
 1: &user{"user1"},
}
m2[1].name = "Jack" // 返回的是指针复制品。透过指针修改原对象是允许的。

可以在迭代时安全删除键值。但如果期间有新增操作,那么就不知道会有什么意外了。

for i := 0; i < 5; i++ {
 m := map[int]string{
 0: "a", 1: "a", 2: "a", 3: "a", 4: "a",
 5: "a", 6: "a", 7: "a", 8: "a", 9: "a",
 }
 for k := range m {
 m[k+k] = "x"
 delete(m, k)
 }
 fmt.Println(m)
}
//输出:
map[12:x 16:x 2:x 6:x 10:x 14:x 18:x]
map[12:x 16:x 20:x 28:x 36:x]
map[12:x 16:x 2:x 6:x 10:x 14:x 18:x]
map[12:x 16:x 2:x 6:x 10:x 14:x 18:x]
map[12:x 16:x 20:x 28:x 36:x]

####Struct
值类型,赋值和传参会复制全部内容。可⽤ "_" 定义补位字段,⽀持指向⾃⾝类型的指针
成员。

type Node struct {
 _ int
 id int
 data *byte
 next *Node
}
func main() {
 n1 := Node{
 id: 1, 
 data: nil,
 }
 n2 := Node{
 id: 2,
 data: nil,
 next: &n1,
 }
}

顺序初始化必须包含全部字段,否则会出错。

type User struct {
 name string
 age int
}
u1 := User{"Tom", 20}
u2 := User{"Tom"} // Error: too few values in struct initializer

⽀持匿名结构,可⽤作结构成员或定义变量

type File struct {
 name string
 size int
 attr struct {
 perm int
 owner int
 }
}
f := File{
 name: "test.txt",
 size: 1025,
 // attr: {0755, 1}, // Error: missing type in composite literal
}
f.attr.owner = 1
f.attr.perm = 0755
var attr = struct {
 perm int
 owner int
}{2, 0755}
f.attr = attr

⽀持 "=="、"!=" 相等操作符,可⽤作 map 键类型。

type User struct {
 id int
 name string
}
m := map[User]int{
 User{1, "Tom"}: 100,
}

注: 在go语言中只要支持 ==, !=操作符的数据结构, 就可以用做map的key, 这个比python语言更加灵活

可定义字段标签,⽤反射读取。标签是类型的组成部分。

var u1 struct { name string "username" }
var u2 struct { name string }
u2 = u1 // Error: cannot use u1 (type struct { name string "username" }) as
 // type struct { name string } in assignment

空结构 "节省" 内存,⽐如⽤来实现 set 数据结构,或者实现没有 "状态" 只有⽅法的 "静
态类"。

var null struct{}
set := make(map[string]struct{})
set["a"] = null

匿名字段不过是⼀种语法糖,从根本上说,就是⼀个与成员类型同名 (不含包名) 的字段。
被匿名嵌⼊的可以是任何类型,当然也包括指针。

type User struct {
 name string
}
type Manager struct {
 User
 title string
}
m := Manager{
 User: User{"Tom"}, // 匿名字段的显式字段名,和类型名相同。
 title: "Administrator",
}

可以像普通字段那样访问匿名字段成员,编译器从外向内逐级查找所有层次的匿名字段,
直到发现目标或出错。

type Resource struct {
 id int
}
type User struct {
 Resource
 name string
}
type Manager struct {
 User
 title string
}
var m Manager
m.id = 1
m.name = "Jack"
m.title = "Administrator"

外层同名字段会遮蔽嵌⼊字段成员,相同层次的同名字段也会让编译器⽆所适从。解决⽅
法是使⽤显式字段名。

type Resource struct {
 id int
 name string
}
type Classify struct {
 id int
}
type User struct {
 Resource // Resource.id 与 Classify.id 处于同⼀层次。
 Classify
 name string // 遮蔽 Resource.name。
}
u := User{ 
Resource{1, "people"},
 Classify{100},
 "Jack",
}
println(u.name) // User.name: Jack
println(u.Resource.name) // people
// println(u.id) // Error: ambiguous selector u.id
println(u.Classify.id) // 100

不能同时嵌⼊某⼀类型和其指针类型,因为它们名字相同。

type Resource struct {
 id int
}
type User struct {
 *Resource
 // Resource // Error: duplicate field Resource
 name string
}
u := User{
 &Resource{1},
 "Administrator",
}
println(u.id)
println(u.Resource.id)

⾯向对象三⼤特征⾥,Go 仅⽀持封装,尽管匿名字段的内存布局和⾏为类似继承。没有
class 关键字,没有继承、多态等等。

type User struct {
 id int
 name string
}
type Manager struct {
 User
 title string
 }
m := Manager{User{1, "Tom"}, "Administrator"}
// var u User = m // Error: cannot use m (type Manager) as type User in assignment
 // 没有继承,⾃然也不会有多态。
var u User = m.User // 同类型拷⻉。

内存布局和 C struct 相同,没有任何附加的 object 信息。


可⽤ unsafe 包相关函数输出内存地址信息。
m : 0x2102271b0, size: 40, align: 8
m.id : 0x2102271b0, offset: 0
m.name : 0x2102271b8, offset: 8
m.title: 0x2102271c8, offset: 24
###不可变数据

AWS Lambda服务初体验


title: AWS Lambda服务初体验

前段时间看到serverless架构,FaaS这些概念,觉的很新奇。 说不定又是什么未来新趋势。 很想去一探究竟。 苦于前段时间工作很忙,没时间弄。 这周刚好空下来, 赶紧试用了一把。 并记录之。

入门

aws的功能强大, 但是配置也繁琐。 好在它的文档很全,上手还比较顺畅。

申请一个aws账号

先到aws.amazon.com上注册一个aws账号。 绑定下信用卡。 获得750小时1年免费使用权。
但是有这个账号还不够, aws建议使用IAM创建一个新的管理员账号, 例如命名为adminuser, 而不是使用你的aws默认的网站账号来登陆。
创建账号的过程大致分成3步:
创建组并赋予权限 ——> 创建用户并绑定组 --> 为用户创建密码并登陆验证。

更加详细的操作可以参考:创建IAM user

安装aws cli 命令行工具

仅介绍 pip安装的方式, 主要是pip装完之后,后面做对应的aws 相关的开发, 安装python模块, 可能也会用到

安装步骤

  1. curl -O https://bootstrap.pypa.io/get-pip.py
  2. sudo python get-pip.py
  3. pip install awscli

详情请参考pip安装awscli
其它安装方式请参考awscli安装说明

添加配置文件

执行命令aws config
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: adminuser
执行完命令后 ,会在对应home目录的.aws 隐藏目录下生成两个文件
config 和 credentials, 当然你也可以手动创建这两个文件

[profile adminuser]
aws_access_key_id = adminuser access key ID
aws_secret_access_key = adminuser secret access key
region = aws-region

注:
aws_access_key_id 和 aws_secret_access_key 可以在IAM界面下找到对应用户的信息https://console.aws.amazon.com/iam/home?region=ap-northeast-1#users
region只要你登陆aws的ec2, 就可以在url链接里看到了region=ap-northeast-1之类的信息
如何配置命令行工具详情可以参考awscli命令行工具配置

hello-world

登陆到aws管理控制台, 进入lambda服务界面,点击get started now ,接下来执行下列步骤

  1. 选择blueprint , 这里选择hello-world-python
  2. 配置trigger, 这里直接跳过
  3. 配置function, 填下第一行的function name即可, 这个function name可以先随便填一个
  4. 点击next, 再点击创建create function,即可

blueprint是一些写好的代码示例,你也可以参考这些示例,自己创建新的函数
配置function的时候,需要创建IAM用户, 不过你不选择的话, Lambda服务默认会为你创建

触发lambda函数
创建好函数后,会自动转向触发函数的测试页面
点击test,选择触发方式,这里选择sample event temlate,然后点击save and test, 过一会儿就能看到执行结果了。 执行结果可以在当前页面的trigger选项卡里查看。

原理

event sources : 事件源,即trigger
handler: 处理事件的函数,会传入两个参数, 一个是event,即事件描述数据,一个是context, 即lamdba函数本身的设定,可用内存大小, 执行超时时间等

整个触发流程:
event sources触发一个事件, 通知到lambda服务, lambda传参给handler, handler开始执行相关的代码逻辑,执行一些操作, 操作aws上的资源或者其它。如果操作的是在aws上的资源,如ec2实例, s3 等,会使用授权的IAM用户的去操作。 执行完毕后, 返回结果。 另外,handler产生所有的日志会定向到cloudwatch。

实验

ec2定时开关机


使用aws lambda, 将event source设置为CloudWatch Events - Schedule , 再把启动或者关闭服务的函数放到handler里, 这样的话就可以定时触发instance的启动和关闭了,另外在cloudwatch可以看到详细日志流和调用成功率和延时的dashboard,方便调试排障和了解概况。
这个方法的优点是:
操作简单, 稳定性好(由lambda服务自身保证高可用), 无需启用新的实例,或者占用额外资源,且几乎是免费的方案,因为目前lambda服务前100万次的运算是免费的。

参考使用可以设定时间计划的lambda服务
开关机的代码参见github 代码

一周IT博文精选TOP10(第9期)

  1. SRE系列教程 | 孙宇聪:来自Google的DevOps理念及实践(上)http://www.dockone.io/article/1820

本文为上篇,讲述了SRE的基本概念和核心原理. 文章内容有: 什么是SRE?; 传统运维模式的弱点 ;Google SRE的起源与特点;SRE的工作职责; 应急响应;日常运维; 工程研发; SRE模型成功的关键要素(职业化, 专业化, 打通与产品团队的反馈回路);

  1. SRE系列教程 | 孙宇聪:来自Google的DevOps理念及实践(下)http://www.dockone.io/article/1823

本文为下篇, 介绍google的平台化建设, 容量规划和管理,实战演习,oncall制度, 事后总结, slo预估等

  1. Ansible 超详细使用指南 http://www.jianshu.com/p/f0cf027225df

详细介绍了ansible playbook配置和相关的概念

  1. Apprenda发布Kubernetes自动化运维工具KET www.infoq.com/cn/news/2016/11/apprenda-kubernetes-ket

KET试图对“在生产环境运行可信任Kubernetes平台的最佳实践”进行标准化。本文介绍了它的相关特性。

  1. 如何打造一个高逼格的云运维平台? http://www.greatops.net/?id=47

金融体系的运维平台建设实践, 内容涉及痛点和愿景, 云运维产品介绍, 场景规划, 技术方案,成果展示等

  1. 分布式锁总结 https://my.oschina.net/pingpangkuangmo/blog/784879

介绍分布式锁的几个问题, 如单点问题,超时问题。

  1. 日志文件系统是怎样工作的 http://linuxperf.com/?p=153

深入浅出的介绍了日志文件系统的原理

  1. Docker 学习资源整理 https://zhuanlan.zhihu.com/p/23508637

docker的中文资源,作者整理的很全

  1. 运维改革探索(一):用多层级监控实现可视化运维 http://www.yunweipai.com/archives/10065.html

介绍**移动监控系统的建设

  1. 运维改革探索(二):构建可视化分布式运维手段 http://www.yunweipai.com/archives/10176.html

介绍**移动自动化巡检, 自动化运维操作, 自动化部署, 自动化数据管理 , 大数据实时分析的实践

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

Golang学习笔记之quickstart

##Quick Start
###开发环境搭建
golang官网下载安装包, 按照提示安装即可。
截止2017年6月24日,最新的安装包为1.8.3版本。


如果golang的官网访问不了(ps:有时候会被墙),可以从国内的golang中文论坛下载。
下载地址: https://dl.gocn.io/
###构建工具
###依赖管理工具
godep
glide
dep

以上三种依赖管理的比较可以参考文章https://github.com/kubernetes/client-go/blob/master/INSTALL.md
###常用IDE
gogland
JetBrains团队开发,提供远程调试功能,自动补全,函数跳转, 语法检查等功能

liteIDE

国人开发

vim

编辑器之神, 自行DIY IDE

vscode

据说不错

IntelliJ idea

没用过

sublime text 3

没用过, 有插件支持

Atom

没用过

###Hello World

package main
import "fmt"
func main() {
	fmt.Printf("hello, world\n")
}

一周IT博文精选TOP10(第4期)

  1. 微服务场景下的自动化测试 http://icodeit.org/2016/10/testing-in-microservice-context/
  2. 2016 Web开发资源工具大搜罗 https://zhuanlan.zhihu.com/p/22730771
  3. PyCon China 深圳站精彩回顾(附PPT及视频)https://segmentfault.com/a/1190000007061423
  4. 学习分布式系统需要怎样的知识?http://www.zhihu.com/question/23645117/answer/124708083
  5. 传统企业应用容器化的痛点、坑和解决之道 http://dockone.io/article/1725
  6. 一行 Python 能实现什么丧心病狂的功能? https://www.zhihu.com/question/37046157
  7. 《Kubernetes与云原生应用》系列之容器设计模式 http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-app-container-design-pattern
  8. 大数据下的技术运营(一)——监控系统概览篇 http://www.infoq.com/cn/articles/technical-operation-under-big-data-part01
  9. 大数据下的技术运营(二)——数据采集系统设计与实现 http://www.infoq.com/cn/articles/TalkingDataOps2-Monitor-DataColllection
  10. 大话程序猿眼里的高并发架构 http://blog.jobbole.com/105938/

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

一周IT博文精选TOP10(第7期)

  1. JVM 架构解读 http://www.codeceo.com/article/jvm-architecture-explained.html
  2. 如何做一个小型公司的技术总监 http://mp.weixin.qq.com/s?__biz=MzA5ODExMTkwMA==&mid=401610150&idx=1&sn=76634db462956a532a46c5096a741258
  3. 技术行业的宏观趋势 http://insights.thoughtworkers.org/macro-trends-technology-industry/
  4. 张小龙最新内部演讲:警惕 KPI 和流程 http://www.leiphone.com/news/201610/KoA7nWnVJPls5p5g.html
  5. 深度剖析分布式监控CAT http://tech.meituan.com/cat_develop.html
  6. 青云QingCloud沈鸥:企业应用如何往云端迁移? http://www.tmtpost.com/2513580.html
  7. 微服务架构下,如何打造别具一格的服务治理体验?(上) http://dbaplus.cn/news-21-767-1.html
  8. 「企业上云」之云灾备的起源、发展和实践 http://www.infoq.com/cn/articles/origin-development-and-practice-of-cloud-disaster-recovery
  9. 大数据杂谈微课堂|Elasticsearch 5.0新版本的特性与改进 http://www.infoq.com/cn/news/2016/08/Elasticsearch-5-0-Elastic
  10. 从建设到治理,从系统到团队,谈高可用架构之道 http://www.infoq.com/cn/news/2016/10/High-availability-arch

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

[译文]谷歌云服务出现大面积故障的原因公布


title: [译文]谷歌云服务出现大面积故障的原因公布

原文链接: https://status.cloud.google.com/incident/appengine/16008#5673385510043648
原文镜像: #5
本文仅供学习参考。 水平有限,如有翻译谬误,还望指出。欢迎转载,转载请附上本文地址和作者hackstoic。

App Engine 服务中断故障

故障发生在 2016-08-11 13:13, 并于 2016-08-11 15:00 恢复正常(上述时间均为 US/Pacific时间).

Aug 23, 2016 09:54

SUMMARY(概述)

On Thursday 11 August 2016, 21% of Google App Engine applications hosted in the US-CENTRAL region experienced error rates in excess of 10% and elevated latency between 13:13 and 15:00 PDT. An additional 16% of applications hosted on the same GAE instance observed lower rates of errors and latency during the same period.
2016年8月11号星期四, 托管在Google App Engine(译者注: google的PaaS云服务)的US-CENTRAL区域 的21%的应用在太平洋时间的白天13:13 - 15:00之间经历了超过10%的出错率和不断升高的访问延时。

We apologize for this incident. We know that you choose to run your applications on Google App Engine to obtain flexible, reliable, high-performance service, and in this incident we have not delivered the level of reliability for which we strive. Our engineers have been working hard to analyze what went wrong and ensure incidents of this type will not recur.

我们为这次事故深感歉意。 我们深知您选择在我们的云平台运行应用是为了能够获得灵活可靠,高质量的服务。 在这次事故中, 我们并没有提供好我们所追求的高可靠服务。我们的工程师日夜兼程的分析事故的原因,以保证此类事故不会再发生。

DETAILED DESCRIPTION OF IMPACT(细节和影响)

On Thursday 11 August 2016 from 13:13 to 15:00 PDT, 18% of applications hosted in the US-CENTRAL region experienced error rates between 10% and 50%, and 3% of applications experienced error rates in excess of 50%. Additionally, 14% experienced error rates between 1% and 10%, and 2% experienced error rate below 1% but above baseline levels. In addition, the 37% of applications which experienced elevated error rates also observed a median latency increase of just under 0.8 seconds per request.

太平洋时间2016年8月11日 13:13 - 15:00之间, 托管在在US-CENTRAL 区域的应用,有18%的应用出错概率在 10% 到 50% 之间, 其中 3% 的应用出错概率超过 50%,14% 的应用出错概率在 1% 到 10% 之间,有 2% 的应用出错率在 1% 以下但依然高于正常水平。这37%的应用遭受了不断攀升的出错率, 且其每次请求的平均延时在0.8s以下。 剩余 63% 的应用访问正常,没有受到影响。

The remaining 63% of applications hosted on the same GAE instance, and applications hosted on other GAE instances, did not observe elevated error rates or increased latency.

Both App Engine Standard and Flexible Environment applications in US-CENTRAL were affected by this incident. In addition, some Flexible Environment applications were unable to deploy new versions during this incident.
App Engine applications in US-EAST1 and EUROPE-WEST were not impacted by this incident.

托管在US-CENTRAL区域的App Engine的标准环境和仿真环境的应用均受到此次事故的影响。 一些仿真环境的应用无法在事故发生期间部署新的版本。 所有在US-EAST1 和 EUROPE-WEST的应用没有受到影响。

App Engine applications in US-EAST1 and EUROPE-WEST were not impacted by this incident.

ROOT CAUSE(事故原因分析)

The incident was triggered by a periodic maintenance procedure in which Google engineers move App Engine applications between datacenters in US-CENTRAL in order to balance traffic more evenly.

这次事故是由一次例行的维护工作导致的。 谷歌的工程师为使负载流量更加均衡, 在US-CENTRAL区域内做app迁移。

As part of this procedure, we first move a proportion of apps to a new datacenter in which capacity has already been provisioned. We then gracefully drain traffic from an equivalent proportion of servers in the downsized datacenter in order to reclaim resources. The applications running on the drained servers are automatically rescheduled onto different servers.

我们配置了新的数据中心, 我们先挪走了一定比例的app到新的数据中心,然后逐渐把相当比例的服务器的流量从旧的数据中心导向新的数据中心,以重新分配资源。 运行在被引走流量的服务器上的应用会自动在不同的服务器上重新计划启动。

During this procedure, a software update on the traffic routers was also in progress, and this update triggered a rolling restart of the traffic routers. This temporarily diminished the available router capacity.
不巧的是, 在这个迁移过程中, 在负载均衡路由器上同时运行着软件升级。 软件升级触发了负载均衡路由器的不断重启。 这减少路由器上可用的负载容量。

The server drain resulted in rescheduling of multiple instances of manually-scaled applications. App Engine creates new instances of manually-scaled applications by sending a startup request via the traffic routers to the server hosting the new instance.
服务器流量引流导致不少手动扩容的应用进行流量重定向。 App Engine 通过负载均衡路由器向托管新应用的服务器发送启动的请求,为这些手动扩容的应用创建新的实例。

Some manually-scaled instances started up slowly, resulting in the App Engine system retrying the start requests multiple times which caused a spike in CPU load on the traffic routers. The overloaded traffic routers dropped some incoming requests.
一些手动扩容的实例启动的比较慢, 导致了App Engine系统不断向这些应用发送重启的请求, 负载均衡路由器出现了cpu负载峰值, 负载均衡路由器由于过载,从而丢掉了一些入流量。

Although there was sufficient capacity in the system to handle the load, the traffic routers did not immediately recover due to retry behavior which amplified the volume of requests.
尽管处理这些负载的系统的容量是足够的, 但是由于不断的重试请求,进一步加重了路由器负载, 从而使负载均衡路由器不能立即恢复过来。

REMEDIATION AND PREVENTION(补救和避免措施)

Google engineers were monitoring the system during the datacenter changes and immediately noticed the problem. Although we rolled back the change that drained the servers within 11 minutes, this did not sufficiently mitigate the issue because retry requests had generated enough additional traffic to keep the system’s total load at a substantially higher-than-normal level.
谷歌的工程师通过监控数据中心的变化, 立即发现了这次问题。 尽管我们紧急在11分钟内紧急做了回滚, 但是并没有有效的减轻这次事故, 因为不断的重试请求已经让系统的总体负载一直处于高于平常的水平。

As designed, App Engine automatically redirected requests to other datacenters away from the overload - which reduced the error rate. Additionally, our engineers manually redirected all traffic at 13:56 to other datacenters which further mitigated the issue.
根据之前的设计, App Engine自动从过载的数据中心重定向请求到其它数据中心,以减少出错概率。 此外, 我们的工程师在13:56时, 手动重定向了所有的流量到其它数据中心, 重新减轻了这次事故的影响。

Finally, we then identified a configuration error that caused an imbalance of traffic in the new datacenters. Fixing this at 15:00 finally fully resolved the incident.
最后我们定位了一个配置错误。 这个配置错误导致了在新数据中心间的流量不均问题。 我们在15:00时修复了这个错误, 最后完全解决了这个事故。

In order to prevent a recurrence of this type of incident, we have added more traffic routing capacity in order to create more capacity buffer when draining servers in this region.

为了避免此类事故的再次发生, 我们增加了更多流量路由的容量, 来保证在该区域进行服务器引流的时候有更多的缓冲空间。

We will also change how applications are rescheduled so that the traffic routers are not called and also modify that the system's retry behavior so that it cannot trigger this type of failure.

我们也改变了应用漂移的策略,因此流量路由器不会被调用,同时修改了系统的重试策略, 从而使它不会再触发这类问题。

We know that you rely on our infrastructure to run your important workloads and that this incident does not meet our bar for reliability. For that we apologize. Your trust is important to us and we will continue to all we can to earn and keep that trust.
我们深知你们对运行你们的重要负载的基础设施是很依赖的。 这次事故并没有达到我们对可靠性的要求。 对此, 我们深表歉意。 您的信任对于我们是十分重要的, 我们将继续竭尽全力来承载您的信任。

Aug 11, 2016 15:45

The issue with App Engine APIs is now resolved for most of the affected projects as of 14:12 US/Pacific. We will follow up directly with the few remaining affected applications. We will also conduct a thorough internal investigation of this issue and make appropriate improvements to our systems to prevent or minimize any future recurrence. Finally, we will publish a more detailed analysis of this incident once we have completed an internal investigation.
大部分受影响的项目的App Engine API的问题在14:12的时候被解决。 我们继续跟进剩余的少量受影响的应用。 我们将彻底的调用这次时间, 并制定一个合理的改善措施来完善我们的系统, 避免或者最小限度的减少此类事故的再次发生。 最后, 一旦我们完成了内部调查,我们将会发布一份详细的事故分析报告。

Aug 11, 2016 15:15

We are still investigating the issue with App Engine apis being unavailable.
我们仍旧接着调查 App Engine api不可用的问题。
Current data indicates that some projects are affected by this issue. We will provide another status update by 15:45 US/Pacific with current details.
当前数据表明一些项目受到此次事件的影响。 我们在 15:45提供了一份状态更新报告。

Aug 11, 2016 14:44

The issue with App Engine apis being unavailable should have been resolved for the majority of projects and we expect a full resolution in the near future.
大部分项目的App Engine api 不可用的问题本该被解决, 我们希望在不久的将来有一个完整的决议。
We will provide another status update by 15:15 US/Pacific with current details.
我们在15:15提供了另外一份当前细节的状态更新报告。

Aug 11, 2016 14:16

We are experiencing an issue with App Engine apis being unavailable beginning at Thursday, 2016-08-11 13:45 US/Pacific.
Current data indicates that Applications in us-central are affected by this issue.
我们发现App Engine 的api在13:45分就开始不可用。 当前的数据表明us-central 的应用受到此次事件的影响。

Aug 11, 2016 14:01

We are investigating reports of an issue with App Engine. We will provide more information by 02:15 US/Pacific.
我们调查了 App Engine的这次事故, 并在太平洋时间02:15提供了更多细节的信息。

一周IT博文精选TOP10(第1期)

  1. 如何投资自己(可行方法论:附赠工具表格) https://zhuanlan.zhihu.com/p/22442310
  2. 一分钟了解负载均衡的一切 http://www.tuicool.com/articles/vi2Qrqz
  3. 云计算那点事儿 https://zhuanlan.zhihu.com/p/22445510
  4. 不懂构建知识体系,你迟早被信息洪水淹死 http://www.digitaling.com/articles/30443.html
  5. 关注行业、深入研究和总结反思,这5个点能帮助你更好成长 http://www.woshipm.com/pmd/411765.html
  6. 什么是刷微信朋友圈的正确姿势? https://www.huxiu.com/article/163672.html
  7. 一分钟让你的程序支持队列和并发 https://zhuanlan.zhihu.com/p/22386793
  8. HTTPS 工作原理和 TCP 握手机制 http://blog.jobbole.com/105633/
  9. 2016 Github开源报告 https://octoverse.github.com/
  10. 什么是工程师文化? http://coolshell.cn/articles/17497.html

开源web堡垒机GateOne初探(1)


title: 开源web堡垒机GateOne初探(1)

Gateone是一个基于tornado和html5技术的开源web ssh项目,功能很强大, 支持多个账户多个终端窗口连接远程机器, 支持多种认证登陆方式, 支持嵌入到各种web应用,支持多种插件等等。

【背景】

最近公司项目要求做一个web ssh工具,能够在网页上登陆交换机,即web ssh功能。第一时间到网上查找有没有对应的开源方案可以借鉴, 大致调研了一下,有如下的方案可以参考:

  1. shellinabox

  2. 浏览器插件secure shell 或者 firessh

  3. java applet 技术 mindterm

  4. 在浏览器中使用securecrt

上面各个方案局限性较大,这里不做赘述。

本文主要介绍一种更加完美和强大的web ssh方案: GateOne

【GateOne简介】

Gate One是一款基于html5实现的ssh客户端,有如下特点:

不需要任何浏览器插件

支持多用户和多终端,同时支持上百个用户和终端

终端支持高级特性,例如256色彩,高级文本样式支持

支持终端截图,保存为图片和pdf文件

多语言支持

支持复制和粘贴,快捷键支持

终端会话持久化,关闭浏览器不会影响终端的运行

支持服务器记录用户会话到syslog

支持嵌入到其他系统。

支持多种用户验证方式。匿名,Kerberos,SSO,PAM,Google Auth...

轻松定制化。支持插件形式的扩展,插件支持多语言,python,js,css

用户连接时,可以关闭和启动服务器(用户的ssh会话保留)

ssh插件支持复制会话,支持使用密钥登录

系统支持Python 2.6,Python 3,pypy

更多的介绍可以参考gateone的官网介绍(列举了gateone的19条特性)

http://liftoffsoftware.com/Products/GateOne

官网有demo,可以先去体验一下: http://gateone1.ln.liftoffsoftware.com/

【部署方法和过程】

下面主要讲部署的过程和方法。

系统运行环境: ubuntukylin 14.04 python 2.7.8 GateOne 1.1.0 (截止2015.5.9的最新软件版本)

主要参考资源:

gateone github : https://github.com/liftoff/GateOne

gateone document : liftoff.github.io/GateOne/index.html

网络上的安装方法针对的是以前的版本, 不少方法都已经过时。针对新版本的安装方法叙述如下。

有三种方式 按照简单排序就是docker镜像安装法, 源码安装法,deb或rpm包安装法

docker 镜像安装法

可以从docker官方仓库下载liftoff/gateone

sudo docker pull liftoff/gateone

或者下载dockerfile自己build一个

sudo docker build -t liftoff/gateone .

镜像生成后,运行容器的命令也很简单

sudo docker run -d --name=gateone -p 443:8000 liftoff/gateone

<<<<<扩展阅读>>>>

镜像创建教程参见:http://dockerpool.com/static/books/docker_practice/image/create.html
镜像下载教程参见 http://dockerpool.com/static/books/docker_practice/image/pull.html

容器运行教程参见 http://dockerpool.com/static/books/docker_practice/container/run.html

gateone docker用法参见: https://github.com/liftoff/GateOne/tree/master/docker

gateone dockerfile说明: https://registry.hub.docker.com/u/liftoff/gateone/dockerfile/

源码安装法*

从github下载源码后,进入代码目录

运行 sudo python setup.py install

会自动安装各种依赖包,直至gateone安装完成。

deb或rpm包安装法

先用源码打包成deb包或者rpm包,再进行安装,具体方法见

http://liftoff.github.io/GateOne/About/index.html#installation

安装完后运行程序

python run_gateone.py

然后用火狐浏览器打开 https://127.0.0.1:10443 (后面的10443端口,根据具体情况而定,要看程序运行时侦听了哪个端口),就可以看到web ssh界面了。

备注:我部署后,用谷歌浏览器打开页面时会有问题,无法弹出ssh登陆界面,但是看官方的demo是没有这个问题的。原因暂时没有找到。

<<<<<扩展阅读>>>>>

如果你的系统环境和本人不一致,如centos,或者使用了老的gateone版本进行安装,按照上面的安装出现问题,请参见官方文档的说明,或者以下几篇博文。或许对你有帮助。

http://blog.csdn.net/rexkang/article/details/40819537

http://itnihao.blog.51cto.com/1741976/1311506

http://www.shencan.net/index.php/2013/10/19/gate-one-web%E7%89%88%E7%9A%84ssh%E7%BB%88%E7%AB%AF/

--------------------------------------------------------未完待续

Read more

微信扫一扫
关注该公众号

一周IT博文精选TOP10(第2期)

  1. 程序员的成长离不开哪些软技能? http://dev.qq.com/topic/57ce8068d4d44a246f72baf2
  2. 搭建一个私有区块链环境 http://blog.lixf.cn/essay/2016/09/02/ethereum-1/
  3. 带你入门Spark(资源整理) https://zhuanlan.zhihu.com/p/22427880?refer=shiyanlou
  4. 构建微服务体系结构的最佳实践 http://www.infoq.com/cn/articles/best-practice-of-constructing-micro-service-system
  5. 中小公司员工统一用户认证方案 https://zhuanlan.zhihu.com/p/21364666
  6. 浅谈Go语言 http://www.jianshu.com/p/91e40c3e3acb
  7. 基于Event Sourcing和DSL的积分规则引擎设计实现案例 http://www.infoq.com/cn/articles/design-and-implementation-of-the-integral-rule-engine
  8. 多机房数万台服务器管理实践 http://www.tuicool.com/articles/iQZ3mq7
  9. 谈谈创业公司的技术选型 http://www.tuicool.com/articles/IvUbqum
  10. 全球首个微信应用号开发教程!通宵吐血赶稿,每日更新! https://my.oschina.net/wwnick/blog/750055?from=timeline&isappinstalled=0

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

一周IT博文精选TOP10(第8期)

  1. 怎样构建一个可持续发展的程序员能力成长模型? http://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==&mid=2650994549&idx=1&sn=860b85a9dcc04cd4aa9ea8941f676aa8&chksm=bdbf0f268ac886309e5d0db15d4ac3f7f1d4004eea9637a859b92a4aa595fd1e6199f1d5a5b2&mpshare=1&scene=1&srcid=1030gg79OAw9WBtum2Vnbckd#rd
  2. 「云端的DevOps」系列之大话DevOps解决方案变迁 http://www.infoq.com/cn/articles/devops-solution-change
  3. 类似Google Dapper,微服务需要这样的分布式跟踪工具 http://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=2659597444&idx=1&sn=391fc6e108488f78e45a8421ea311fdd&scene=21#wechat_redirect
  4. 微服务架构下,如何实现分布式跟踪? http://www.infoq.com/cn/articles/how-to-realize-distributed-tracking
  5. LVS实践系列(1)-LVS是什么鬼 http://xialingsc.github.io/home//linux/what-is-the-Linux-Virtual-Server/
  6. SystemTap新手指南中文翻译 https://spacewander.gitbooks.io/systemtapbeginnersguide_zh/content/
  7. 系统数据一致性的6种方案 http://www.uml.org.cn/sjjm/2016110405.asp
  8. 《Kubernetes与云原生应用》系列之实践案例“单节点多容器模式” http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-applications-part03
  9. 容器和Kubernetes应用与开发 http://www.uml.org.cn/yunjisuan/201611014.asp
  10. 老专家详解 DevOps “八荣八耻” http://www.greatops.net/?id=38

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

一周IT博文精选TOP10(第10期)

  1. Kubernetes从部署到运维详解 http://geek.csdn.net/news/detail/115128

介绍k8s架构, 部署过程, 部署相关的组件介绍, 运维管理, 包括主机, 命名空间, 配置等

  1. 在Google使用Borg进行大规模集群的管理[全文pdf] http://www.dockone.io/article/763

谷歌集群管理经典论文的译文。 内容包括: 1. 简介 2.用户视角 3. Borg架构 4. 可用性 5. 使用效率 6. 隔离性 7. 相关工作 8. 经验教训和未来工作

  1. CaaS最佳实践——平安金融云 http://mp.weixin.qq.com/s?__biz=MzIyMDUxMTY2MQ==&mid=2247483930&idx=1&sn=7fc1ad051dd10a2da83238ee9e9e33ea&chksm=97cbaed8a0bc27ce461208d07a509b0753e58996eb750d266178aa68f309fc65135127afe7f5&mpshare=1&scene=1&srcid=1121c8svSIa6UF8e8NlDS0f9#rd

介绍caas平台建设的资源模型, 应用场景和架构设计等内容和最佳实践。

  1. 智慧监视:一种持续性能监视方法 http://www.ibm.com/developerworks/cn/devops/d-smarter-monitoring-trs/index.html

使用关联 ID 来跟踪传入系统的单一请求, 辅助分析错误条件和性能问题。

  1. Apache Mesos 1.1.0 正式发布 http://www.dockone.io/article/1840

介绍了版本发布主要包含新功能和改进, 包括网络故障感知, mesos-cni-port-mapper, 支持Linux Capabilities, 支持“POD”等特性

  1. 世界级的开源项目:TiDB如何重新定义下一代关系型数据库 http://zhuanlan.51cto.com/art/201611/521468.htm

介绍TiDB的整体架构, 编程语言的选择, 事务模型, 与nosql的对比, 传统数据库的痛点, TiDB的应用场景, TiDB的未来等

  1. 微服务化改造系列之一:总览 http://emacoo.cn/blog/microservice-overview

微服务简介, 康威定律, 微服务总览

  1. 微服务化改造系列之二:服务注册中心 http://emacoo.cn/blog/microservice-registry-center

服务注册中心概述, 注册中心方案选型, 分析Eureka,SmartStack,Consul的利弊,Consul + Consul Template的解决方案的落地

  1. 一张路线图帮你《逐层分析云原生架构的各子系统》 http://mp.weixin.qq.com/s?__biz=MjM5MzM3NjM4MA==&mid=2654679599&idx=2&sn=a7c62692504e577db09b2e8788f6052d&chksm=bd58633c8a2fea2af5e817a0842cd088cff22b439f2bc09b1f83bda1d022a1f5847cb368a8c2&mpshare=1&scene=1&srcid=1123slH6gePwAp4TqWUu9RIf#rd

介绍了云原生系统架构和云原生生态厂商的概况。

  1. 容器,你还只用Docker吗?(上) http://www.dockerinfo.net/3824.html

介绍了容器撕逼大战, runC标准化, 可以了解到整个容器生态的进展和现状

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

Google_App_Engine_Incident_16008


title: Google_App_Engine_Incident_16008

App Engine Outage

Incident began at 2016-08-11 13:13 and ended at 2016-08-11 15:00 (all times are US/Pacific).

Aug 23, 2016 09:54
SUMMARY:

On Thursday 11 August 2016, 21% of Google App Engine applications hosted in the US-CENTRAL region experienced error rates in excess of 10% and elevated latency between 13:13 and 15:00 PDT. An additional 16% of applications hosted on the same GAE instance observed lower rates of errors and latency during the same period.

We apologize for this incident. We know that you choose to run your applications on Google App Engine to obtain flexible, reliable, high-performance service, and in this incident we have not delivered the level of reliability for which we strive. Our engineers have been working hard to analyze what went wrong and ensure incidents of this type will not recur.

DETAILED DESCRIPTION OF IMPACT:

On Thursday 11 August 2016 from 13:13 to 15:00 PDT, 18% of applications hosted in the US-CENTRAL region experienced error rates between 10% and 50%, and 3% of applications experienced error rates in excess of 50%. Additionally, 14% experienced error rates between 1% and 10%, and 2% experienced error rate below 1% but above baseline levels. In addition, the 37% of applications which experienced elevated error rates also observed a median latency increase of just under 0.8 seconds per request.

The remaining 63% of applications hosted on the same GAE instance, and applications hosted on other GAE instances, did not observe elevated error rates or increased latency.

Both App Engine Standard and Flexible Environment applications in US-CENTRAL were affected by this incident. In addition, some Flexible Environment applications were unable to deploy new versions during this incident.

App Engine applications in US-EAST1 and EUROPE-WEST were not impacted by this incident.

ROOT CAUSE:

The incident was triggered by a periodic maintenance procedure in which Google engineers move App Engine applications between datacenters in US-CENTRAL in order to balance traffic more evenly.

As part of this procedure, we first move a proportion of apps to a new datacenter in which capacity has already been provisioned. We then gracefully drain traffic from an equivalent proportion of servers in the downsized datacenter in order to reclaim resources. The applications running on the drained servers are automatically rescheduled onto different servers.

During this procedure, a software update on the traffic routers was also in progress, and this update triggered a rolling restart of the traffic routers. This temporarily diminished the available router capacity.

The server drain resulted in rescheduling of multiple instances of manually-scaled applications. App Engine creates new instances of manually-scaled applications by sending a startup request via the traffic routers to the server hosting the new instance.

Some manually-scaled instances started up slowly, resulting in the App Engine system retrying the start requests multiple times which caused a spike in CPU load on the traffic routers. The overloaded traffic routers dropped some incoming requests.

Although there was sufficient capacity in the system to handle the load, the traffic routers did not immediately recover due to retry behavior which amplified the volume of requests.

REMEDIATION AND PREVENTION:

Google engineers were monitoring the system during the datacenter changes and immediately noticed the problem. Although we rolled back the change that drained the servers within 11 minutes, this did not sufficiently mitigate the issue because retry requests had generated enough additional traffic to keep the system’s total load at a substantially higher-than-normal level.

As designed, App Engine automatically redirected requests to other datacenters away from the overload - which reduced the error rate. Additionally, our engineers manually redirected all traffic at 13:56 to other datacenters which further mitigated the issue.

Finally, we then identified a configuration error that caused an imbalance of traffic in the new datacenters. Fixing this at 15:00 finally fully resolved the incident.

In order to prevent a recurrence of this type of incident, we have added more traffic routing capacity in order to create more capacity buffer when draining servers in this region.

We will also change how applications are rescheduled so that the traffic routers are not called and also modify that the system's retry behavior so that it cannot trigger this type of failure.

We know that you rely on our infrastructure to run your important workloads and that this incident does not meet our bar for reliability. For that we apologize. Your trust is important to us and we will continue to all we can to earn and keep that trust.
Aug 11, 2016 15:45
The issue with App Engine APIs is now resolved for most of the affected projects as of 14:12 US/Pacific. We will follow up directly with the few remaining affected applications. We will also conduct a thorough internal investigation of this issue and make appropriate improvements to our systems to prevent or minimize any future recurrence. Finally, we will publish a more detailed analysis of this incident once we have completed an internal investigation.
Aug 11, 2016 15:15
We are still investigating the issue with App Engine apis being unavailable.

Current data indicates that some projects are affected by this issue. We will provide another status update by 15:45 US/Pacific with current details.
Aug 11, 2016 14:44
The issue with App Engine apis being unavailable should have been resolved for the majority of projects and we expect a full resolution in the near future.

We will provide another status update by 15:15 US/Pacific with current details.
Aug 11, 2016 14:16
We are experiencing an issue with App Engine apis being unavailable beginning at Thursday, 2016-08-11 13:45 US/Pacific.

Current data indicates that Applications in us-central are affected by this issue.
Aug 11, 2016 14:01
We are investigating reports of an issue with App Engine. We will provide more information by 02:15 US/Pacific.

读“技术的执念”有感


title: 读“技术的执念”有感

”技术的执念“ 全文链接http://blog.jobbole.com/106135/

我比较认可作者的以下观点:

  1. 知识更新换代太快,我们永远无法跟上技术演化的步伐,需要有选择性的学习
  2. 技术人员有一个误区:以为自己可以掌握所有软件开发相关的知识(或者说太过于纵容自己的好奇心和兴趣),实际上大部分处于自己兴趣学习的知识,在实际应用时,又要重新学习一遍
  3. 身处这样的信息过载环境,我们很难不为自己对信息的缺乏而感到不安,我们的焦虑反过来又会让我们无暇思考什么才是重要的
  4. 碎片化的阅读方式易于消费,只需要很少的思考就可以读懂,但是危害严重,它们并不会帮助你提升理解力
  5. 面对浩瀚的知识海洋, 我们需要有节制的来聚焦在某些技术上,而视其他技术如无物,这需要很大的勇气和魄力,不过唯有如此,技术人员才可能有真正的长进和成就
  6. 以前端开发领域为例, 首先要了解软件开发全生命周期中的所有节点,然后再有所侧重的去找自己的兴趣点来发展,即:先建立广度,再建立深度
  7. 如果有一天你很冲动,想学习某种新技术,建议先泡杯咖啡,等这种冲动自己过去
  8. 对于过载的信息, 你需要做减法,建立自己的知识框架,然后有针对性的学习, 主动且深度的阅读经典, 为那些有趣但非自己关注方向的知识赋予较低的优先级
  9. 尝试将微信、微博关闭一段时间,或者至少可以不去点那些朋友圈里的《老X聊微服务》或者《12个你不知道的Sublime技巧》文章,保持专注,保持简单

学习而不行动, 等于浪费时间。 因此看完文章, 我做了四件事情。

  1. 关闭掉我关注的所有微信公众号的消息推送,每周日看一次
  2. 关闭朋友圈, 每周日看一次
  3. sdk.cn, 码农周刊, 推酷每周日看一次
  4. 绘制自己的知识框架图

[公告]个人博客将陆续迁移到github issue


title: 个人博客将陆续迁移到github issue

Why Github Issue?

博客网站该有的核心功能它都有,而且浑然一体,无需配置,真正做到开箱即用:

  • 搜索, 可关键词搜索,可以根据标签过滤。
  • 评论, 还可以@互动,用户还可以给你的文章点赞, 评论能及时通知
  • 标签功能, 标签还支持颜色标记
  • 编辑器, 支持markdown,支持预览,支持上传文件,支持使用#做文章的链接
  • 网页自适应, 在电脑和移动端上看,网页会自动编排

此外, 它还有一些额外的亮点,比如

  • 结合github的wiki可以做知识的串联
  • 结合github api实现自动化发布,统计等等
  • 整个写作是open的, 所有人都可以加入
  • 它是免费的, 且没有广告
  • 更多功能有待发掘!

这样的博客神器居然被我忽视了这么久! 果断转到issue!

我也是受到另一位仁兄的启发, 他也是用github issue当博客网站:
https://github.com/abbshr/abbshr.github.io/issues

个人博客工具演进史

早期是在qq空间,人人网发文章, 信息流太杂
虚拟主机空间比较火的时代,用的wordpress,折腾配置,配皮肤,没写几篇文章
然后是在csdn上写博客,但是csdn上的图片插入功能无力吐槽,现在也在写,主要csdn流量会比较高
再往后是折腾jekyll,jekyll的功能比较弱,需要各种折腾才能搞得比较像样,最后中途放弃
再往后是购买了vps,自己建站,用python + django + bootstrap 写了一个个人网站,页面比较丑,网页自适应做得比较差,移动端阅读的话体验不好
再往后是搭建hexo, hexo其实也还不错,我用mac本地的markdown编辑器写好文章后,需要执行命令编译上传。 但是折腾下来也花了不少时间,构建编译环境需要安装一堆插件,还要翻墙, 另外还有不少优化的空间,比如搜索,比如加载速度,比如标签等等
最后我在github上看到有人用github issue写博客, 豁然开朗, 众里寻她千百度,那人却在灯火阑珊处。 github issues不就是一个不错的博客工具吗? 为何舍近求远呢?时间都花在折腾环境上了, 感觉有点舍本逐末。 因此我决定把博客陆续迁移到github issues上。

定时关闭和启动ec2实例的7种方法


title: 定时关闭和启动ec2实例的7种方法

方法一: 使用aws lambda + cloudwatch服务

使用aws lambda, 将trigger/event source设置为CloudWatch Events - Schedule , 再把启动或者关闭服务的函数放到handler里, 这样的话就可以定时触发instance的启动和关闭了,另外在cloudwatch可以看到详细日志流和调用成功率和延时的dashboard,方便调试排障和了解概况。
这个方法的优点是:
操作简单, 稳定性好(由lambda服务自身保证高可用), 无需启用新的实例,或者占用额外资源,且几乎是免费的方案,因为目前lambda服务前100万次的运算是免费的。

参考使用可以设定时间计划的lambda服务

方法二: 使用aws data pipeline

大致实现是使用data pipeline运行aws cli命令。 需要单独起一台ec2实例来运行data pipeline

参考How do I stop and start Amazon EC2 Instances at scheduled intervals with AWS Data Pipeline?

方法三: 使用aws OpsWorks服务

定制chef的cookbook,或者使用aws提供的gui界面来实现,不需要用到命令行

参考aws opsworks 介绍

方法四: 使用auto scaling服务

大致实现是定时增减实例数。
有网友反应使用这种方法可能会使原有的EBS不能挂载到主机上,且autoscaling貌似使直接删除实例的,不能保持原有的instance 的状态。 暂未验证。

参考Running EC2 Instances on a Recurring Schedule with Auto Scaling

方法五: 使用第三方网站提供的服务

第三方的网站有
Elastic Cloud Gate
Skeddly
Ylastic
优点: 操作简单, 且能实现更多的功能定制。
缺点: 需要额外注册第三方网站的账号, 有的网站需要收费, 另外需要暴露secret key给第三方

方法六: 将定时关机程序部署在其它机器或者实例

大致的过程是起一台单独的instance跑脚本,
然后给其它要定时开关的机器打上tag, 脚本会去读取tag, 按照tag上定义的时间定时关闭和启动机器。 这种做法需要另起一台ec2实例, 另外需要脚本需要定时扫描,适合机器量适中,且不同instance的起停时间不一致的场景 。 且需要保证跑脚本的那台ec2实例的可用性。
优点: 可以灵活地为每个实例设定不同时间。
缺点: 需要定时扫描, 起停的时间不能精确设定

参考Auto Start and Stop Your EC2 Instances

方法七: 自己开发app,定时调用aws api

介绍略。

Golang学习笔记之流程控制和异常处理

##流程控制和异常处理
###流程控制
####IF
很特别的写法:
• 可省略条件表达式括号。
• ⽀持初始化语句,可定义代码块局部变量。
• 代码块左⼤括号必须在条件表达式尾部

x := 0
// if x > 10 // Error: missing condition in if statement
// {
// }
if n := "abc"; x > 0 { // 初始化语句未必就是定义变量,⽐如 println("init") 也是可以的。
 println(n[2])
} else if x < 0 { // 注意 else if 和 else 左⼤括号位置。
 println(n[1])
} else {
 println(n[0])
}

不⽀持三元操作符 "a > b ? a : b"。
####FOR
⽀持三种循环⽅式,包括类 while 语法。

s := "abc"
for i, n := 0, len(s); i < n; i++ { // 常⻅的 for 循环,⽀持初始化语句。
 println(s[i])
}
n := len(s)
for n > 0 { // 替代 while (n > 0) {}
 println(s[n]) // 替代 for (; n > 0;) {}
 n--
}
for { // 替代 while (true) {}
 println(s) // 替代 for (;;) {}
}

不要期望编译器能理解你的想法,在初始化语句中计算出全部结果是个好主意。

func length(s string) int {
 println("call length.")
 return len(s)
}
func main() {
 s := "abcd"
 for i, n := 0, length(s); i < n; i++ { // 避免多次调⽤ length 函数。
 println(i, s[i])
 }
}

输出:
call length.
0 97
1 98
2 99
3 100
####RANGE
类似迭代器操作,返回 (索引, 值) 或 (键, 值)。

| x|1st value |2nd value

 string |index |s[index] |unicode, rune
 array/slice| index| s[index]
 map| key |m[key]
 channel| element

可忽略不想要的返回值,或⽤ "_" 这个特殊变量。

s := "abc"
for i := range s { // 忽略 2nd value,⽀持 string/array/slice/map。
 println(s[i])
}
for _, c := range s { // 忽略 index。
 println(c)
}
for range s { // 忽略全部返回值,仅迭代。
 ...
}
m := map[string]int{"a": 1, "b": 2}
for k, v := range m { // 返回 (key, value)。
 println(k, v)
}

注意,range 会复制对象。

a := [3]int{0, 1, 2}
for i, v := range a { // index、value 都是从复制品中取出。
 if i == 0 { // 在修改前,我们先修改原数组。
 a[1], a[2] = 999, 999
 fmt.Println(a) // 确认修改有效,输出 [0, 999, 999]。
 }
 a[i] = v + 100 // 使⽤复制品中取出的 value 修改原数组。
}
fmt.Println(a) // 输出 [100, 101, 102]。

建议改⽤引⽤类型,其底层数据不会被复制。

s := []int{1, 2, 3, 4, 5}
for i, v := range s { // 复制 struct slice { pointer, len, cap }。
 if i == 0 {
 s = s[:3] // 对 slice 的修改,不会影响 range。
 s[2] = 100 // 对底层数据的修改。
 }
 println(i, v)
}
//输出:
0 1
1 2
2 100
3 4
4 5

另外两种引⽤类型 map、channel 是指针包装,⽽不像 slice 是 struct。
####SWITCH
分⽀表达式可以是任意类型,不限于常量。可省略 break,默认⾃动终⽌。

x := []int{1, 2, 3}
i := 2
switch i {
 case x[1]:
 println("a")
 case 1, 3:
 println("b")
 default:
 println("c")
}
// 输出:
a

如需要继续下⼀分⽀,可使⽤ fallthrough,但不再判断条件。

x := 10
switch x {
case 10:
 println("a")
 fallthrough
case 0:
 println("b")
}

//输出:
a
b

省略条件表达式,可当 if...else if...else 使⽤。

switch {
 case x[1] > 0:
 println("a")
 case x[1] < 0:
 println("b")
 default:
 println("c")
}
switch i := x[2]; { // 带初始化语句
 case i > 0:
 println("a")
 case i < 0:
 println("b")
 default:
 println("c")
}

####GOTO, BREAK, CONTINUE
⽀持在函数内 goto 跳转。标签名区分⼤⼩写,未使⽤标签引发错误。

func main() {
 var i int
 for {
 println(i)
 i++
 if i > 2 { goto BREAK }
 }
 BREAK:
 println("break")
EXIT: // Error: label EXIT defined and not used
}

配合标签,break 和 continue 可在多级嵌套循环中跳出。

func main() {
L1:
 for x := 0; x < 3; x++ {
L2:
 for y := 0; y < 5; y++ {
 if y > 2 { continue L2 }
 if x > 1 { break L1 }
 print(x, ":", y, " ")
 }
 println()
 }
}

//输出:
0:0 0:1 0:2
1:0 1:1 1:2

附:break 可⽤于 for、switch、select,⽽ continue 仅能⽤于 for 循环。

x := 100
switch {
case x >= 0:
 if x == 0 { break }
 println(x)
}

###异常处理
没有结构化异常,使⽤ panic 抛出错误,recover 捕获错误。

func test() {
Go 学习笔记,  4 
35
 defer func() {
 if err := recover(); err != nil {
 println(err.(string)) // 将 interface{} 转型为具体类型。
 }
 }()
 panic("panic error!")
}

由于 panic、recover 参数类型为 interface{},因此可抛出任何类型对象。

func panic(v interface{})
func recover() interface{}

延迟调⽤中引发的错误,可被后续延迟调⽤捕获,但仅最后⼀个错误可被捕获。

func test() {
 defer func() {
 fmt.Println(recover())
 }()
 defer func() {
 panic("defer panic")
 }()
 panic("test panic")
}
func main() {
 test()
}
//输出:
defer panic

捕获函数 recover 只有在延迟调⽤内直接调⽤才会终⽌错误,否则总是返回 nil。任何未
捕获的错误都会沿调⽤堆栈向外传递。

func test() {
 defer recover() // ⽆效!
 defer fmt.Println(recover()) // ⽆效!
 defer func() {
 func() {
 println("defer inner")
 recover() // ⽆效!
 }()
 }()
 panic("test panic")
}
func main() {
    test()
}
//输出:
defer inner
<nil>
panic: test panic

使⽤延迟匿名函数或下⾯这样都是有效的。

func except() {
 recover()
}
func test() {
 defer except()
 panic("test panic")
}

如果需要保护代码⽚段,可将代码块重构成匿名函数,如此可确保后续代码被执⾏。

func test(x, y int) {
 var z int
 func() {
 defer func() {
 if recover() != nil { z = 0 }
 }()
 z = x / y
 return
 }()
 println("x / y =", z)
}

除⽤ panic 引发中断性错误外,还可返回 error 类型错误对象来表⽰函数调⽤状态。

type error interface {
 Error() string
}

标准库 errors.New 和 fmt.Errorf 函数⽤于创建实现 error 接⼝的错误对象。通过判断
错误对象实例来确定具体错误类型。

var ErrDivByZero = errors.New("division by zero")
func div(x, y int) (int, error) {
 if y == 0 { return 0, ErrDivByZero }
 return x / y, nil
}
func main() {
 switch z, err := div(10, 0); err {
 case nil:
 println(z)
 case ErrDivByZero:
 panic(err)
 }
}

如何区别使⽤ panic 和 error 两种⽅式?惯例是:导致关键流程出现不可修复性错误的
使⽤ panic,其他使⽤ error。

Golang学习笔记之入门概述

##入门概述

Golang的优点

  1. golang的goroutine有比线程更快的启动速度,另外通过channel支持goroutine之间的安全通信
  2. golang的goroutine比线程更节省内存, 启动一个goroutine只需要2kb内存,但是java启动线程需要1M
  3. 更优雅的书写并发代码, 其它语言在使用并发时可能会有线程锁, 竞争条件,死锁的问题,使得编写并发程序变得困难, Goroutines允许您避免在共享数据结构时使用互斥锁
  4. golang有接近C/C++等低级语言的性能, 同时支持垃圾回收来分配和释放内存,而不需要自动分配和释放内存(不需要使用malloc和free), 所有的内存分配是在语言运行时自行分配的。
  5. 代码更容易维护, golang故意去掉了很多现代OOP语言的特点,比如它没有类, 不支持继承, 没有构造函数, 无注解,没有泛型, 没有异常
  6. google公司的技术能力的背书

总体来说, go融合了多个编程语言的优点, 它具有c/c++的高性能, 有像java那样好用的并发处理, 有像python和perl那样简洁的代码。

###Tutorial & Docs

###Practice&Tips

  • Go性能优化技巧
  • 阅读falcon源码, 写源码解析博客
  • 编写falcon集群管理工具
  • 在项目中使用etcd
  • 阅读fabric源码
  • 使用beego重构个人网站
  • 修改falcon alarm模块使其支持电话告警 *
  • 修改falcon alarm模块使其支持微信告警 *

###Forum&Lessons

由著名的开源作者谢孟军创建,提高国内的go技术交流, 招聘, 文章分享等

###Blog&News
###Book&Resources

go语言包管理,无需git和hg等版本管理工具,就可以下载指定版本的go语言包

gopher meetup 深圳站2016-08-28


title: gopher meetup 深圳站2016-08-28

主要的讲师和安排如下:

  • 谢孟军 逼格 Go基金会介绍
  • 陈晓黎 两点一线 人工智能在资产管理方面的应用
  • 陈非 腾讯 如何用Go打造一个mysql中间件
  • 杨文 小恩爱 小恩爱Go 语言之路
  • 艾义 ASTRI Go语言学习及项目实战经验分享
  • 李亚川 众联网游 Go语言爬虫Pholcus的开发经验分享

Go基金会介绍

促进golang在**的发展
社区 + 企业 + 高校
正在落实中

人工智能在资产管理方面的应用

讲目前很火的机器人投顾领域的golang应用
golang的机器学习库整体还是不如python

如何用Go打造一个mysql中间件

干货较多的一个分享

现有的mysql proxy 方案

atlas: 扩展性不高, 基本不维护
cobar: 基本不再维护
mycat: 功能复杂, 商业化

新方案

kingshard
优点:

  1. 读写分离
  2. 支持数据分片
  3. 开发专注业务逻辑
  4. db的上下线无感知

SQL Parser的设计

词法分析器: sql的切片
语法分析器: 目的是读写分离, 数据分片
数据分片: hash, range, time
二级映射: ??

连接池设计

一个db实例对应一个连接池
复用连接, 减少后端db压力
无空闲连接则阻塞, 提升用户体验

安全和审计

客户端ip限制
sql黑名单,正则匹配,基于语法树进行判断更佳
慢查询sql记录

高可用

db的高可用: 自动踢掉down掉的节点
怎么保证kingshard自身的高可用?lvs + keepalived

kingshard 不支持自增id,但是可以通过外部的id生成器来实现, 不支持判断node主从同步是否完全达到数据同步

小恩爱Go 语言之路

golang的企业应用, 高并发系统的构建实践

70-80%的后端程序使用go开发
6个虚拟机4c*4g, 抗住1亿pv并发
因为ruby使用的一些坑, 使用go重构了后端代码

依赖包管理 : godep
所有的依赖都放在一个repo

Go语言学习及项目实战经验分享

时间最长的一次分享, 前面介绍了很多通信方面的背景知识,时间一久,注意力容易泛散, 有点跟不上讲师的思路

严谨的程序员,使用开源库, 先研究开源库代码
golang在ICT领域的应用
tcp server 的设计
code generator 减少代码量,代码自动生成

Go语言爬虫Pholcus的开发经验分享

如果对爬虫没有一些了解, 直接听源码分析一头雾水。 讲师如果能介绍一些背景,还有介绍下为什么要做这个开源项目, 这个开源项目跟现有的爬虫开源项目比,有什么优点这些,他的一些设计理念等等, 我想这也是我们感兴趣的。

介绍了pholcus的架构设计等
源码分析
6个golang技巧(总结得不错, 值得一看)

一周IT博文精选TOP10(第5期)

  1. 像调度程序那样安排任务,是什么样的体验? http://blog.jobbole.com/105853/
  2. 怎么保证服务可靠性、数据一致性、以及一旦宕机数据恢复 http://www.tuicool.com/articles/AfiY7f7
  3. 当服务 QPS 增高时,我们做什么 http://blog.jobbole.com/106140/
  4. 技术的执念 http://blog.jobbole.com/106135/
  5. 年过30?告诉你程序员保值的5个秘密 http://www.techug.com/programmer-keep-your-value-when-over-30-years-old?utm_source=tuicool&utm_medium=referral
  6. 坚持完成这套学习手册,你就可以去 Google 面试了 (上) http://www.jianshu.com/p/be2e3e6e944b
  7. 如何设计稳定性横跨全球的Cron服务 https://segmentfault.com/a/1190000007146045
  8. 了解 Nginx 的基本概念 http://huang-jerryc.com/2016/10/14/了解 Nginx 的基本概念/
  9. 通过微服务进行分布式应用开发 https://www.oschina.net/translate/distributed-application-development
  10. 接下来,我们想聊聊 OKR https://zhuanlan.zhihu.com/p/22814515

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

请戳: http://weixin.sogou.com/weixin?type=1&query=hackstoic

一周IT博文精选TOP10(第3期)

  1. 从搭建一个微信小程序开始 https://www.qcloud.com/act/event/yingyonghao.html?from=timeline&isappinstalled=0
  2. 论运维自动化(下):先克服难点完成自动化,再连通业务实现技术运营 http://www.infoq.com/cn/news/2016/09/DevOps-automation-operation-1?utm_source=tuicool&utm_medium=referral
  3. 软件定义网络在携程的运维实践 http://www.yunweipai.com/archives/9750.html
  4. 用Harbor实现容器镜像仓库的管理和运维 http://dockone.io/article/1640
  5. Kubernetes 1.4发布:让Kubernetes能在任何地方更简单地运行 http://www.dockone.io/article/1717
  6. 重塑世界的区块链技术剖析及应用简析 http://www.gongxiangcj.com/show-22-2186-1.html
  7. 谷歌神经网络翻译系统发布后,我们和Google Brain的工程师聊了聊 http://www.jiqizhixin.com/article/1578
  8. 日消息量突破 50 亿,谈小米的高可用推送系统设计 http://www.tuicool.com/articles/ANzIj2z
  9. Github 安全军火库(三) https://zhuanlan.zhihu.com/p/22684414
  10. 一篇好TM长的关于配置中心的文章 http://jm.taobao.org/2016/09/28/an-article-about-config-center/

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

开源web堡垒机GateOne初探(2)


title: 开源web堡垒机GateOne初探(2)

本文主要介绍基于GateOne搭建web 版的putty,并集成到你的应用里。 网上的教程大多过时, 官网文档的介绍是英文的,而且知识点比较零散。 本篇教程是基于自己的开发实战写的。 希望能减少大家自己摸索的时间。

基于GateOne搭建web 版的putty,并集成到你的应用里。

安装方法,请参考我之前写的一篇文章: . 开源web堡垒机GateOne初探(1)

输入关键词gateone进行查看

这里需要对前一篇文章做下补充说明:
经过几个星期的测试, 发现GateOne在github的master分支,有较多bug。 建议下载最新的分支代码(截至日期2015.6.17)。

附下载链接:https://github.com/liftoff/GateOne/archive/GateOne-a34f7e0a9215ca4868f1bbdfe29cea217d444863.zip

如果连接github有问题, 也可以从我的百度网盘下载: http://pan.baidu.com/s/1gd6dqBh

下面介绍下如何配置GateOne,并集成到你的应用里。

【 解压并进入代码目录】

cd GateOne-a34f7e0a9215ca4868f1bbdfe29cea217d444863/

运行一遍run_gateone.py脚本, 这时会生成一个conf.d目录, gateone的配置文件放在这个目录下

sudo python run_gateone.py --new_api_key

【 进入conf.d 修改对应的配置文件】

$ ls conf.d

10server.conf 20authentication.conf 30api_keys.conf 50terminal.conf
$ vim 10server.conf

把"origins": ["localhost:10443", "127.0.0.1:10443", "VMS02911:10443"],
----> 修改成 "origins": ["localhost:10443", "127.0.0.1:10443", "VMS02911:10443", ],
^ 在这里添加允许跨域访问gateone server的ip和端口, 即你的应用所在的服务器和端口

比如,我部署了web应用在192.168.1.1 上面,通过8080端口, 我的gateone部署在192.168.1.2 上面, 这时候你就需要添加"192.168.1.1:8080",否则你的应用访问gateone server的时候会有403错误, 无法嵌入web ssh页面

$ vim 20authentication.conf

把 "auth": "none",
-----> 修改成"auth": "api ",

使用api进行验证应用,开启该项后, 没有通过验证的应用无法嵌入web ssh页面

$ cat 30api_keys.conf

查看api ,左边的MDAzODhiYTY0ZmNjNDgzOGI2MmZjZWU1YTRhN2U1ZGYwR为secret , 右边的ZDdmMWQxNzMzYzA0NGI0Y2JmOWVlMmJlOWIzNmE4ZDljL 为api key

这两个是做验证用的, 下面会讲到怎么用
// This file contains the key and secret pairs used by Gate One's API authentication method.
{
"*": {
"gateone": {
"api_keys": {
"MDAzODhiYTY0ZmNjNDgzOGI2MmZjZWU1YTRhN2U1ZGYwR": "ZDdmMWQxNzMzYzA0NGI0Y2JmOWVlMmJlOWIzNmE4ZDljL"
}
}
}
}

【编写一个提供验证的接口】

(这里提供python的代码示例, 其它编程语言的示例请移步官方文档http://liftoff.github.io/GateOne/Developer/embedding.html#example-api-authentication-code )
def generate_gate_one_auth_obj():
import time, hmac, hashlib, json
secret = "MDAzODhiYTY0ZmNjNDgzOGI2MmZjZWU1YTRhN2U1ZGYwR"
authobj = {
'api_key': "ZDdmMWQxNzMzYzA0NGI0Y2JmOWVlMmJlOWIzNmE4ZDljL",
'upn': "ctools",
'timestamp': str(int(time.time() * 1000)),
'signature_method': 'HMAC-SHA1',
'api_version': '1.0'
}
my_hash = hmac.new(secret, digestmod=hashlib.sha1)
my_hash.update(authobj['api_key'] + authobj['upn'] + authobj['timestamp'])
authobj['signature'] = my_hash.hexdigest()
valid_json_auth_object = json.dumps(authobj)
return valid_json_auth_object

这个函数可以生成认证所需要的认证信息(json格式),如下示例(伪造的示例,仅做格式参考)

{"upn": "ctools", "signature_method": "HMAC-SHA1", "timestamp": "1434545252254", "signature": "7777e365f2a6b2212149e066fde1d4596ade5af", "api_key": "ZDdmMWQxNzMzYzA0NGI0Y2JmOWVlMmJlOWIzNmE4ZDljL", "api_version": "1.0"}

【嵌入你的web应用】

上面的工作做完之后, 就可以开始在你的web应用嵌入gateone的web ssh页面了

<script type="text/javascript" src="/static/js/gateone/gateone.js"></script> <script type="text/javascript"> $(document).ready(function(){ var request = $.ajax({ url:'/get_auth_obj', // 这里填写提供接口验证的访问地址 type:"GET", dataType:"json", }); request.done(function(auth_data){ GateOne.init({ auth:auth_data, url: "https://192.168.1.2/", // 这里是搭建gateone的ip或对应网址 }); }); }); // end of document ready </script>

这时候打开并访问对应的页面就可以愉快的使用你的专属定制版web ssh了。

如果有机会, 我会在后面讲解更多的配置,和更高级的应用。 敬请期待。

微信扫一扫
关注该公众号

一周IT博文精选TOP10(第6期)

  1. 扛住618过亿订单量,京东弹性云15万容器规模这样炼成!(附PPT) http://dbaplus.cn/news-21-664-1.html
  2. 工程师成长之路:工作1-3年工程师如何突破瓶颈期? https://www.sdk.cn/news/5502
  3. 谷歌的开源成绩单 https://linux.cn/article-7876-1.html
  4. 老司机“四招”带你玩转运维 http://www.10tiao.com/html/488/201610/2247483921/1.html
  5. 传统企业应用容器化的痛点、坑和解决之道 http://dockone.io/article/1725
  6. 当你喜刷刷时,你可知为何朋友圈能这么流畅? http://36kr.com/p/5055005.html
  7. 实现Cloud-Native可运维性 http://www.tuicool.com/articles/3ERVJjb
  8. 从建设到治理,从系统到团队,谈高可用架构之道 http://www.infoq.com/cn/news/2016/10/High-availability-arch
  9. Spring Cloud和Docker微服务 http://www.uml.org.cn/yunjisuan/201610171.asp
  10. 大数据下的技术运营(三)——报警系统设计与实现 http://www.infoq.com/cn/articles/technical-operation-under-big-data-part03

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

ELK不权威指南


title: ELK不权威指南

ELK的简单科普文章,加入了自己的一些理解。 内容包括ELK的基本介绍, 应用场景, 架构设计, 监控及自监控, 业界进展及推荐资料等。

用户故事

场景一

作为一个运维工程师, 某天虚拟机出现故障, 想看看虚拟机是否有异常日志,物理机上是否有异常日志, 管理物理机的云平台/系统是否有发生异常日志, 一个个主机 系统登陆过去, 输入账号密码费时费力,有时还会出现记不住密码干着急的情况,大大影响了排障的效率。 有没有一个系统,能够集中查看和搜索日志,不需要繁琐的登陆, 方便的获取排障所需的重要信息, 有异常还能够订阅?

场景二

作为一个开发人员, 开发的系统经常需要调用外部的api, 每次出现问题需要去查看日志,看是哪个环节出现问题, 是调用第三方api出错,还是连接数据库出错,只能一个一个查。 另外还会遇到的问题是, 有时候无意中grep了一个大的文件,导致iowait冲高,引发不必要的系统异常告警。 有没有一个工具能够提供各种仪表盘,每次打开一个页面就能一目了然的看到调用各个api的情况,调用了多少次, 失败了多少次?

场景三

开发人员上线新版本,上线过程中可能会出现各种问题。 有时不能及时发现会引起哪些异常,对其它系统有哪些影响。有没有一个工具 可以看到和分析上线新版本前后的变化?这样 就能有助于分析相应的故障是否是和上线新版本有关了。

场景四

作为一个团队领导, 团队开发产品已经上线一段时间了, 希望看到产品有多少人访问, 哪个功能访问了多少次,模块的出错率如何,每次都到机器上去跑分析脚本,费时费力,还不直观, 如果产品部署在分布式集群统计起来更是麻烦, 有没有一个系统能以更加简便的方式可以查看到这些情况?

上述的问题,ELK统统可以解决。

ELK是什么鬼?

简而言之, 如果说日志是埋在土里的宝藏,那么ELK是开采宝藏的蓝翔挖掘机。

概述

ELK是一套解决方案而不是一款软件, 三个字母分别是三个软件产品的缩写。 E代表Elasticsearch,负责日志的存储和检索; L代表Logstash, 负责日志的收集,过滤和格式化;K代表Kibana,负责日志的展示统计和数据可视化。

其中Elasticsearch是整个ELK的核心, L和K都有相应的替代方案。 这里重点介绍下ElasticSearch(下面简称es)的一些知识。

相关架构概念


2016-08-30 21-36-02

  • 上面是一个1个node, 2个replica, 3个shard的结构
  • cluster(集群)由多个node(节点)组成
  • 数据会被索引,并保存在index里(类比RDBMS里的DB)
  • 一个index可以切成多个shard(分片),每个shard可以有多个replica(副本)
  • node分为三种类型, 分别是master node,data node ,state node。 每个cluster会有一个node被选举成master,负责维护cluster state data。
  • shard均匀分布在所有可用的data node

ES 和 关系型数据库的概念比较

ES本身可以理解为自带搜索引擎的数据库。 有些概念可以和关系型数据库(比如说MySQL) 进行对比。 概念的对比如下表所示:


2016-08-30 21-46-34

ELK vs Linux Grep

ELK Grep
多台机器的日志可以集中查询 只能查看一台机器的日志
UI界面显示查询结果 无数据可视化功能
支持多维度复杂查询 较难实现
查询效率高, 亿条数据秒级查询 需要登陆系统,进到相关目录, 编写规则, 查询大文件效率低,且对磁盘io也是有影响
实时性好, 自动索引展示, 配合第三方工具,可以做实时告警 实时性差, 只能出问题,再到系统去查看
提供了api接口供第三方工具集成 没有api接口
可以查看历史趋势 不能

ELK能做什么?

应用场景

  • 安全领域
    通过分析系统日志, 发现攻击或者非法访问行为,可以追踪定位相关安全问题。 比如结合FreeIPA(一款集成的安全信息管理解决方案), 可以做一些暴力破解行为可视化分析等。

  • 网络领域
    日志分析和监控可以作为网络设备监控的一种补充, 其它监控系统,如zabbix大多是通过snmp的方式来获取网络设备的性能数据, 这种方式有其局限性,如无法监控端口的flapping, 无法监测到设备引擎挂掉等情况。 此外由于snmp监控的方案通用型不好, 各个厂商有自己的私有OID, 意味着需要对这些不同的厂商适配不同的监控模板。 另外, snmp获取数据的实时性相对会比syslog日志慢一些。

  • 应用领域
    分析和展示移动端业务的实时情况,如设备类型分析, 业务访问量, 业务访问高峰情况等;
    分析nginx日志得到网站的访问情况,如网站点击数, api请求总数、平均每秒请求数、峰值请求数,可以大体了解系统压力,作为系统扩容、性能及压力测试时的直接参考。

  • 另类应用
    用于社会工程学的用户画像;
    函数堆栈调用分析;
    网络流量分析

ELK落地方案

架构选型

下面是一种常见的ELK架构


2016-09-05 16-53-12

这个架构的优点是简单,维护起来也方便。 但是也有一些问题。

  • shipper耗主机资源。 直接用logstash当作日志采集的agent, 会比较重,会占用不少主机资源, 因此官方现在已经不推荐用logstash当shipper了, 推荐使用beat。
  • 权限控制的问题。 kibana自身对页面访问权限控制这块是比较弱。 如果希望对页面的访问权限做控制, 可以考虑使用es search guard + ldap + nginx的方案来实现。
  • 跨网络分区的问题 。如果有多个数据中心,且日志的流量比较大, 让日志跨网络分区进行传输,无疑会占用不少宝贵的专线带宽资源,会增加运营的成本,且有可能影响到其它应用的正常运行。 有一个解决此类问题的方案, 在各个网络分区各搭建一套ELK集群,日志不跨网络分区进行传输, 然后单独使用某些es节点作为tribe角色, 对搜索请求进行合并和路由。

为解决上面提到的问题, 设计了以下架构:

2016-08-30 23-23-42

当然, 上面的架构也不是一层不变。如果日志量更大,可以考虑使用hangout来代替logstash, 用kafka来替代redis, 从而获得更大的日志吞吐量。

监控告警

日志的告警

可以采用elastalert。 当然也可以自己开发应用从es或者kafka取数据来做分析。

自身的监控

  • 使用zabbix 监控。 网上可以找到对应的模版。
  • 使用官方提供的marvel方案, 不过是收费的。
  • 使用open falcon监控。 我们内部有一套open falcon系统, 所以我们尝试用open falcon来监控es集群。

挑战和思路

SaaS化

就是把ELK提供为SaaS服务,目前新浪云, 青云, aws等云平台上面已经有相应的服务了。 把日志分析系统SaaS化, 可以免去用户搭建和维护elk集群的麻烦,减少用户的使用成本,同时也可以给云平台自身带来更多的附加值。

大数据分析

用ELK堆栈来存储和索引海量的日志数据, 后面再结合大数据分析和机器学习工具,可以做智能运维分析, 减少运维人员之苦。

推荐资料

  • 《Elasticsearch 权威指南》
  • 《ELK中文指南》
  • 《Mastering ElasticSearch》
  • 《Manning Elasticsearch in Action》

如果需要一些ELK相关技术分享ppt, 电子书等,可以关注我们的公众号,在公众号里回复您的姓名,邮箱,注明elk, 进行获取。 我们将在三个工作日内将资料发送到您的邮箱。

数据分析遐想


title: 数据分析遐想

前言

马云说未来是DT(Data Technology)时代。 随着互联网和移动互联网的大量普及和飞速发展, 互联网越来越融入人们生活的方方面面, 社交,购物, 商务等等。人们使用互联网的频率越来越高, 在上面花费的时间越来越多, 我们在互联网上买衣服,买手机, 买电器, 买零食,订外卖, 看新闻,听广播, 听音乐, 发表心情, 和朋友甚至陌生人互动交流, 我们在互联网上做生意,开淘宝店,开微店, 架设自媒体, 如自己的公众号, 自己的电台, 自己的歌曲专辑等等。 互联网让信息发布变得越来越便利, 沟通和交流的成本也大大降低。 这也意味着互联网上面每天都在生产着巨量的数据。 对于懂得数据分析的商业公司而言,互联网上的数据就是一座取之不尽的金矿。 借助数据的提取,分析, 整合,从看似杂乱而庞大的数据中挖掘数据的价值, 了解互联网用户群体的消费习惯, 喜爱偏好等,然后实施精准营销, 为公司创造价值。 对于懂得数据分析的个人而言, 他可以把那些无价值的数据转化成有价值的知识。随着数据分析在商业应用中的地位越来越重要, 我们看到很多公司设置了商业智能部门, 数据分析的岗位 , 对于数据分析人才的需求也越来越旺盛。 数据分析这项技能也必定会越来越吃香。 学习和掌握数据分析工具, 学会有效分析数据的理论知识和方法, 在一定程度上可以给我们的职业发展增加更有价值的筹码。
好了。 扯远了。 实战才是提升技能的最有效方式。
我给自己设想了一个任务, 通过抓取某大学bbs交友版块上的帖子信息, 了解大部分女性或者男性的交友需求。
这个任务,大致需要四个过程:

  1. 抓取帖子信息
  2. 存储信息
  3. 分析统计
  4. 展示分析结果
    每个过程需要用的工具或者方法,以及需要参考的资料:

抓取帖子信息

需要用到爬虫的知识,需要了解web相关的知识, 不排除使用一些hack的方法

参考资料:
《web前端黑客技术揭秘》
Scapy爬虫框架介绍 http://docs.pythontab.com/scrapy/scrapy0.24/
另外还可以参考我之前收集的一些关于爬虫的一些专题知识

存储信息

考虑使用NoSQL数据库来存储, 比如MongoDB。

参考资料:
mongodb入门 http://www.imooc.com/view/295

数据分析

可能会用到中文分词, 概率论与统计方法, 一些算法, 已经Python数据分析工具

参考资料:
《统计思维》
《算法导论》
计算机科学与编程导论 http://open.163.com/special/opencourse/bianchengdaolun.html
计算机科学与python编程导论 https://www.edx.org/course/introduction-computer-science-mitx-6-00-1x-0#.U_HC-_mSxSU (5星推荐)
中文分词,使用python的中文分词库结巴分词http://www.oschina.net/p/jieba

#展示结果
web上展示结果会用到可视化库, 考虑使用D3.js ,

参考资料:
D3.js 参见https://github.com/mbostock/d3

以上只是初步的想法, 未来会根据自己的实战,内容会进行动态更新。

微信命令行


title: 微信命令行

看到360爆出微信的一个远程执行漏洞, 然后360团队教大家一个自检有没有存在漏洞的方式, 是在微信的任意聊天窗口,输入//gettbs, 然后会显示一些信息, 查看信息即可知悉。 觉得很好奇,原来微信下也有命令行, 赶紧google了一下, 发现了很多微信命令。

以下命令在android, 微信6.3.16版本测试通过,注意, 在ios下输这些命令没有反应

//opentrace 打开跟踪
//getfpkey 得到手机基本信息
//fullexit 完全退出微信
//traceroute 打开诊断网络
//netstatus 显示当前网络情况
//gettbs gettbs 显示tbs信息
//channelId 显示频道编号
//qzone 3527181931 直接打开某用户的qq空间
//checkcount 统计聊天记录的数量
//bankcard 扫描拍照识别银行卡
//voipfacedebug 开启或关闭voip调试功能

参考资料

  1. 漏洞预警:微信曝任意代码执行漏洞(附自检方案)
  2. wechat cmd

运维世界大会干货总结

演讲主题


2016-12-04-05-38-50

2016-12-04-05-39-17

我自己听了以下几场:

  • 云时代下的运维
  • 秒级时代下的全栈溯源
  • google运维解密
  • 海量日志搜索分析技术及行业应用案例
  • 基于日志数据的运维和运营之道
  • devops在又拍云的实践
  • 魅族基础系统运维之道
  • 基于devops的paas运维实践

针对我听的这几场演讲谈几点心得体会:

  • 现场人很多, 大家对devops的热情很高啊,可能是这几年互联网+的热炒, 很多传统厂商也转型做互联网了吧
  • 对于演讲内容, 首先承认是有干货的。 但是干货不够干。 有些演讲变成了产品推销会。
  • 新的干货不多, 有不少演讲之前就在公众号文章就看过了
  • 我听的这几场演讲,主题基本可以划分为5类: 监控, SRE, devops, paas, 云实践。 我画了思维导图, 分享出来让大家参考。 (url链接在文末)

干货总结


2016-12-04-06-01-59

下面简要谈一下这5个主题相关的一些主要观点, 详细的内容见文末的参考资料:
云实践

  1. 应用上云是一种大趋势,不可抗拒
  2. 在云上也是有坑的, 比如说很多系统参数不透明,造成排障时间长的问题
  3. 在云上, 瓶颈还在,只是被隐藏了
  4. 混合云是一种趋势
  5. 云时代,运维人员的价值体现在混合云管理, 云平台的调优, 排障等等
  6. 个人观点 : 演讲的嘉宾是网易的工程师, 对于网易这种大型的互联网企业而言,他们的机器规模大, 场景复杂, 有深度调优的需求, 因此踩了很多上公有云的坑。 对于中小的互联网企业和创业公司,未必会遇到类似的问题。 总体而言, 上云的利大于弊。

监控

  1. 全栈溯源和日志分析都是为了快速定位和解决故障而生的
  2. 机器学习和人工智能将会是日志分析技术的下一代引擎
  3. 日志分析,检索,监控应该打造成一个ops品牌服务提供出来
  4. 个人观点: 对互联网企业而言, 日志就是隐藏的宝藏, 而日志分析技术就是打开宝藏之门的钥匙。 在日志分析上,已经有比较成熟的技术方案, 开源的有: elkstack, 商业方案有splunk, 日志易, 阿里云LogSearch等。

SRE

  1. SRE的两个职责: 应急响应和日常运维
  2. 每个SRE要有50%的工程时间, 用于开发, 用于有价值的系统运维
  3. 每个事故要6个小时去处理, 这里其实强调的是, 事故后的深度分析追踪, 从故障中学习
  4. 要有计划的安排灾难演习, 这样能使系统更加健壮, 更能防范于未然
  5. 应用系统的设计应该充分考虑人可能会犯的错误
  6. 不需要处理的告警, 就不要告警
  7. 要开发能够自愈的系统
  8. 个人观点: 即使我们不是SRE,但是也要有SRE的心, 坚持以google的SRE的标准来要求自己。 时常检视自己是否一直在做重复无意义的运维工作, 是否可以自动化。做运维是管理和驾驭机器和系统, 而不是反过来被其奴役。

DevOps

  1. 运维的八荣八耻
  2. 云原生应用的12要素原则
  3. 个人观点: 话题基本是围绕着12要素原则来讲的, 运维的八荣八耻可以理解为12要素原则的中文翻译。 总结起来就是设计一个可配置, 高可用, 自动化, 标准化, 可视化的运维系统。

PaaS

  1. 提出将运维能力平台化的观点
  2. 实现NoOps的目标, 即自助式运维
  3. 构建运维自动化平台需要考虑八个方面: 标准化, xaas化 ,持续交付, 高可用架构, 弹性扩展, noops, 收益和风险, 平台运营。
  4. 个人观点: 运维能力PaaS化是一种站在更高层面的ops视角。初级的自动化是构建一些自动化脚本和工具,但是这些工具还是需要运维工程师来执行, 当用户的需求量上去了, 运维工程师依然会占用大量的时间来处理这些需求。 如果能变成可控的自助式服务,将会大大简化运维工程师的运维工作, 同时提供更快的交付速度。 我自己总结了一个运维形式的演进过程是这样的: 人肉 -> 脚本 -> web工具应用 -> 供运维工程师使用的运维系统 -> 用户自助式的运维平台。

扩展阅读

  1. 基于 DevOps 理念的私有 PaaS 平台实践 http://www.tuicool.com/wx/bMriYbi
  2. 详解DevOps八荣八耻 http://jiasuhui.com/archives/106524
  3. 来自 Google 的 DevOps 理念及实践 http://www.tuicool.com/articles/7NFjumb
  4. 12要素原则 https://12factor.net/zh_cn/
  5. ops world 演讲思维导图 http://naotu.baidu.com/file/4641e828c679dc46f1b1ecaa917e33d8?token=45d171bd832baf43

[欢迎关注我的微信公众号hackstoic, 在移动端获得最新的文章推送]

个人网站建设之路


title: 个人网站建设之路

2015-03-08
网站搭建,在个人网站写下第一篇博客

本博客出于个人的业余兴趣爱好,使用Python+Django框架搭建,1.0版本花了大概4个小时的时间搭建而成,目前比较粗糙,但是最基本的写博客的需求已经满足,后期会继续完善。
博客的大致情况如下:
整合了django-suit(django admin的美化工具),django-ueditor(百度的富文本编辑器) ,目前能够满足基本的编写博客要求。
目前只有两个页面,博客详情页,和个人介绍
搭建过程中有参考网络上的一些教程,自己再根据自己的开发经验进行功能的改进,和细节的完善。
感谢http://www.dannysite.com/提供的教程。
后期会完成如下工作:

  1. 展示所有的文章分类,按标签,按时间,按内容分类
  2. 提供内容的全文检索功能
  3. 提供文章的评论功能
  4. 提供文章的订阅功能
  5. 提供文章的分享功能
    我会把搭建博客网站的过程细节,陆续写成文章发表在我的网站上,源码也会在后期发布到github上面。

2015-04-26
网站源码开源, 放到github上。 原来建站的时候, 我也是开源社区的受益者, 现在也要成为贡献者。

做这个网站纯粹是出于个人的业余兴趣。 本人的水平有限,也是在学习前人的经验的基础上, 边做边摸索。 遇到问题就google 。 工作上事情比较多,就利用下班的时间和双休日,陆陆续续把一些功能完善了。当然目前网站还做得比较简单,我会继续努力去打磨它,把它做得更好。本着开源的精神,已经把网站的源码放到Github上面了。如果您有什么批评建议,麻烦您不要吝惜在github上给我留言。
源码地址: https://github.com/hackstoic/codelife
开发语言: python
web框架: django
目前已完成的两个功能:
博客系统
微信公众平台自动回复
接下来除了继续完善上述的功能,还会新增功能:
程序员网站导航页面
电子书推荐页面
python在线手册页面
多媒体展示页面
其实以上这些都已经有人做过,我并不介意再重复造个轮子。因为我相信那句话: 不自己造轮子,怎么知道轮子有多难造呢?
题外话:
使用的VPS是在DigitalOcean购买的。1CPU,512M的RAM, 20G的SSD硬盘空间,新加坡机房,5美元1个月, 访问速度还可以,基本能够满足我的需求。顺便说说我使用VPS的一些心得体会:
DO(DigitalOcean)的镜像备份功能用起来比较方便,建议在系统做了重要改动的时候备份一下,以后删除了系统,还可以根据备份快速构建起来
DO是按小时计费的, 可以体验了之后觉得不满意就把镜像删掉,这样就不会被扣费了。我觉得这种按小时收费的方式比那些按月付费的云平台实在的多。
DO支持使用Google authention 做二次验证, 感觉还是比较安全的
DNS解析可以选择DNSPod
域名的话建议在Goddy购买,goddy支持支付宝付款
DigitalOcean购买链接: https://www.digitalocean.com/?refcode=3c2eb74293ef (这个链接是推荐链接, 可以为你节省10美元, 同时digitalocean也会给我一定的回报)

2015-2016
断断续续发表了30篇文章

2015-12-19
主机从digitocean迁移到aws, 原因是digitocean访问缓慢, 另外一个原因是aws提供一年的免费使用, 而且功能丰富

2016-07-17
开始使用github的静态网页托管服务来替代自己搭建的博客网站。 原因是:

  1. 静态网页免费,简洁
  2. 和github结合方便版本管理
  3. 静态网页维护起来更加方便
  4. 用hexo+markdown写文章和发布文章更加方便

2016-08-27
将原来个人网站博客上的主要文章都迁移到github page上

2016-11-16
使用github issues当博客工具, 在github issue发表第一篇博客

搭建NGINX+UWSGI+DJANGO+MYSQL环境


title: 搭建NGINX+UWSGI+DJANGO+MYSQL环境

系统环境: ubuntu12.04; python2.7( ubuntu12.04 默认安装了python2.7版本)

安装pip工具和python开发环境

$ sudo apt-get install python-pip python-dev build-essential 
$ sudo pip install --upgrade pip 
$ sudo pip install --upgrade virtualenv 
$ sudo apt-get install libmysqld-dev

安装django

sudo pip install django (下载最新的django)
也可以指定django版本进行安装,例如
sudo pip install django==1.7.3
或者也可以采用源码安装的方式
各种系统和各种安装方式的详细说明可以查看这个链接:
https://docs.djangoproject.com/en/1.8/intro/install/
如果你需要移除老的django版本,再进行安装,可以查看:
https://docs.djangoproject.com/en/1.8/topics/install/

安装mysql

$ sudo apt-get install mysql-server

安装mysql-python

$ sudo pip install mysql-python
或者使用sudo apt-get install python-mysqldb

安装uwsgi

sudo pip install uwsgi
或者使用源码安装
建议不使用apt-get的方式安装uwsgi,
用apt-get install安装的uwsgi ,结果nginx无论怎么配置,都会出现502 bad gateway
具体原因不明。

安装nginx

sudo apt-get install nginx

测试uwsgi

新建test文件

# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')]) 
   return"Hello World"

然后执行:
uwsgi --http :8001 --wsgi-file test.py
在浏览器访问 http://youip:8001 即可看到结果

建立django项目工程

假设在/opt/django/目录下建立工程
django-admin.py startproject django_test #创建一个Django项目

配置uwsgi

(vim /opt/django/django_test/uwsgi_setting.ini, 粘贴以下内容)

[uwsgi]
chdir=/opt/django/django_test/
module=django_test.wsgi
master=True
pidfile=/tmp/net.pid
vacuum=True
max-requests=5000
daemonize=/var/log/uwsgi.log
processes=10
socket=127.0.0.1: 8001

启动uwsgi --> uwsgi --ini /opt/django/django_test/uwsgi_setting.ini

配置nginx

(在/etc/nginx/sites-available下建文件django_test.conf,内容如下,并且在 /etc/nginx/sites-enabled下建该文件的软链接ln -s ../sites-available/django_test.conf django_test.conf)

server {   
# 侦听的端口
listen       80; 
# 绑定的ip地址或者域名 
server_name  127.0.0.1;
access_log  /var/log/django_test_nginx.log;
location / { 
send_timeout 120; 
# 这里的端口要和uswgi配置的一致 
uwsgi_pass 127.0.0.1: 8001;
include /etc/nginx/uwsgi_params;
}
location /static/admin/{ 
#  django模块路径可能会有差异,请根据实际情况调整 
alias /usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/contrib/admin/static/admin/;
access_log off;
}

location /static{
    alias /opt/django/django_test/static/;
    access_log off;
} 

location /file/{
alias /var/www/file/;
access_log off;
}

location /webalizer/ {
alias /var/www/webalizer/;
access_log off;
}
}

启动nginx --> nginx -c /etc/nginx/nginx.conf
配置重载(修改配置后要进行此操作) --> nginx -s reload

就此django + mysql + uwsgi + nginx的配置就完成了。你可以打开127.0.0.1访问你的网站了。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.