西维蜀黍

【Golang】Golang 使用 gRPC

定义 gRPC的.proto

syntax = "proto3";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
  ...


【Golang】Golang 连接 MySQL

安装

$ go get -u github.com/go-sql-driver/mysql

mysql数据库连接

  • 构建连接, 格式是:“用户名:密码@tcp(IP:端口)/数据库?charset=utf8”
  • 打开数据库,前者是驱动名,所以要导入: _ “github.com/go-sql-driver/mysql”
  • 设置数据库最大连接数和设置上数据库最大闲置连接数
  • 验证连接:使用Ping()函数
package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"time"
)


//数据库配置
const (
	userName = "root"
	password = "123456"
	ip = "127.0.0.1"
	port = "3306"
	dbName = "test"
)

func InitDB()  {
  path := strings.Join([]string{userName, ":", password, "@tcp(",ip, ":", port, ")/", dbName, "?charset=utf8"}, "")
	db, error := gorm.Open("mysql", path)

	// if there is an error opening the connection, handle it
	if err != nil {
		panic(err.Error())
	}

	results, err := db.Query("select * from tb")
	fmt.Println(results)
	for results.Next() {
		var promotion Promotion
		// for each row, scan the result into our tag composite object
		err = results.Scan(&promotion.id, &promotion.c1, &promotion.c2)
		if err != nil {
			panic(err.Error()) // proper error handling instead of panic in your app
		}
	}
}

type Promotion struct {
	id int
	c1 string
	c2 string

}

func main() {
	InitDB()
}
  ...


【Golang】修改代码后自动重新编译并启动

在开发 Go 的 Web 项目的过程中,让新增加或者修改的代码被自动编译并重启项目是一件可以提高工作效率的事情。

For Web Applications

Gin(https://github.com/codegangsta/gin)

$ go get github.com/codegangsta/gin

$ cd /home/project/myblog

$ gin

如果 main.go 文件不在根目录下,则通过 -d 来指定main.go 文件所在的文件夹

$ gin -d Gateway/main

这时控制台就开始编译打包执行了,注意控制台返回的信息,能知道项目的编译错误和日志,最后会有访问 url。

如果发现项目中有 go 文件新增或修改,gin 和 fresh 都会智能 reload 。

  ...


【Golang】使用 gorm(ORM 框架)

Install

$ go get -u github.com/jinzhu/gorm
  ...


【Golang】Web Framework - Gin 使用

路由

gin 框架中采用的路由库是 httprouter。

// 创建带有默认中间件的路由:
// 日志与恢复中间件
router := gin.Default()

router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)
  ...


【Golang】Print

Println 与Printf

Println 与Printf 都是fmt 包中的公共方法,在需要打印信息时,会用到这二个函数,那么这二个函数有什么区别呢?

  • Println():可以打印出字符串,和变量;
  • Printf():只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形

也就是说,当需要格式化输出信息时一般选择 Printf,其他时候用 Println 就可以了,比如:

func main() {
	a := 10
	fmt.Println(a)
	fmt.Println("abc","d")
	fmt.Printf("%d",a)
}

我们发现:

  • 在调用fmt.Println()时,可以提供多个 string,且在打印时,会自动在这些 string 之间加上空格。
  • 在调用fmt.Printf()时,需要指定 format,如 C 语言中那样。
  ...


【Format】csv

一个奇怪的 Scenario

如果你的机器上装了 Microsoft Excel 的话,.csv 文件默认是被 Excel 打开的。

需要注意的是,当你双击一个.csv 文件,Excel 打开它以后即使不做任何的修改,在关闭的时候 Excel 往往会提示是否要改成正确的文件格式,这个时候如果选择“是”,因为 Excel 认为.CSV 文件中的数字是要用科学记数法来表示的,Excel 会把 CSV 文件中所有的数字用科学计数来表示(2.54932E+5 这种形式),这样操作之后,只是在 Excel 中显示的时候会不正常,而 csv 文件由于是纯文本文件,在使用上没有影响;如果选择了“否”,那么会提示你以 xls 格式另存为 Excel 的一个副本。

所以,建议把 .csv 的默认打开方式改成任意一个文本编辑器。

  ...


【Software Testing】Postman 使用

Environment

环境变量 (Environment Variable)

  ...


【Performance】Linux 性能调优

定位性能瓶颈

查看操作系统负载

首先,当我们系统有问题的时候,我们不要急于去调查我们代码,这个毫无意义。我们首要需要看的是操作系统的报告。看看操作系统的CPU利用率,看看内存使用率,看看操作系统的IO,还有网络的IO,网络链接数,等等。Windows下的perfmon是一个很不错的工具,Linux下也有很多相关的命令和工具,比如:SystemTapLatencyTOP,vmstat, sar, iostat, top, tcpdump等等 。通过观察这些数据,我们就可以知道我们的软件的性能基本上出在哪里。比如:

  1. 先看CPU利用率,如果CPU利用率不高,但是系统的Throughput和Latency上不去了,这说明我们的程序并没有忙于计算,而是忙于别的一些事,比如IO。(另外,CPU的利用率还要看内核态的和用户态的,内核态的一上去了,整个系统的性能就下来了。而对于多核CPU来说,CPU 0 是相当关键的,如果CPU 0的负载高,那么会影响其它核的性能,因为CPU各核间是需要有调度的,这靠CPU0完成)
  ...


【Python】显示对象的所有 Attribute

dir

my_list = [1, 2, 3]
dir(my_list)
# Output: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
# '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
# '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__',
# '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__',
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
# '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',
# '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
# 'remove', 'reverse', 'sort']

inspect module

The inspect module also provides several useful functions to get information about live objects. For example you can check the members of an object by running:

import inspect
print(inspect.getmembers(str))
# Output: [('__add__', <slot wrapper '__add__' of ... ...
  ...