golang--2016gopher北京大会(2)
三、七牛老许
qlang: github qiniu/qlang
microservice architecture: http://martinfowler.com/articles/microservices.html
Service Governance
- Authorization
- Logging
- Change management
- Central configuration
- Scale in and scale out
- Overload Protection
- Service degradation
- Monitor performance and health
- Manage how and by whom services are used
- Topology discovery and failure recovery
Overload Protection
- N = Alert threshold
- Important things
- keep limit to N*2,not N
- kill slow requests(SLA)
四、Dave Cheney 澳洲golang社区负责人,运行悉尼go用户组
http://dave.cheney.net/
Further reading: runtime/pprof
Further reading: Google Perf Tools
- pprof
-memprofilerate=N adjusts the profile rate to 1/N
#visualise mem profile go build -gcflags='-memprofile=/tmp/m.p' go tool pprof --alloc_objects -svg $(go tool -n compile) /tmp/m.p > alloc_objects.svg go tool pprof --inuse_objects -svg $(go tool -n compile) /tmp/m.p > alloc_objects.svg
- benchmarking
#fib.go:
func Fib(n int) int {
if n<2 {
return n
}
return Fib(n-1)+Fib(n-2)
}
#fib_test.go:
import "testing"
func BenchmarkFib(b *testing.B) {
for n:=0;n<b.N;n++ {
Fib(20)
}
}
#go test -bench=. ./fib
-
- do benchmark multiple times or use "-count=" flag
- tools like rsc.io/benchstat are useful for comparing results
go test -bench=. -count=5 ./fib> old.txt
go test -bench=. -count=5 ./fib |tee new.txt
benchstat old.txt new.txt
benchstat {old,new}.txt
-
- how fast will this bench? I think it's super fast!
package popcnt
import "testing"
const m1 = 0x5555555555
const m2 = 0x33333
const m4 = 0x0f0f0f
const h01 = 0x0101010101
func popcnt(x uint64) uint64 {
x -= (x >> 1) & m1
x = (x & m2) + ((x >> 2) & m2)
x = (x + (x >> 4)) & m4
return (x * h01) >> 56
}
func benchmarkPopcnt(b *testing.B) {
for i := 0; i < b.N; i++ {
popcnt(uint64(i)) //optimied away
}
}
#go test -bench=. ./popcnt
-
- 但是被优化没有效果,要改为如下才有bench的效果
#change it to this:
var result uint64
func benchmarkPopcnt(b *testing.B) {
var r uint64
for i:=0;i<b.N;i++ {
r = popcnt(uint64(i))
}
result=r
}
-
- 自己测试还是没效果,不知道为什么
- CPU profile
go test -run=XXX -bench=IndexByte -cpuprofile=/tmp/c.p bytes go tool pprof bytes.test /tmp/c.p #note: -run=XXX to disable test,you only need benchmark
- godoc
cd godoc golang.org/x/tools/cmd/godoc vim main.go add one line in main--defer profile.Start().Stop() then exec in vim:GoImports go install -v . godoc -http=9000 open browser and open localhost:9000 go tool pprof $(which godoc) /var/...cpu.pprof
- enable output of GCloggin
env GODEBUG=gctrace=1 godoc -http=:8080
- import net/http/pprof package will register a handler at /debug/pprof and default http.serveMux
it will visible if you use http.listenSndServe(adress,nil)
godoc -http:=8080,show /debug/pprof
- some slice and string translate...
五、晚场辩论
rust-lang.org
//GO
err := f(x)
if err != nil {
retrun err;
}
//Rust
try!(f(x));
f(x)?
一个关于冗长与magic的讨论
六、原射手CEO
gomobile和动态库的使用
七、米嘉
github.com/mijia/gobuildweb
github.com/mijia/web-starter-kit
@fswatch $(GO_FILES) $(TEMPLATES) | xargs -n1 -l{} make restart ||make kill
- chubby--at the heart of google
- go Proverbs: simple,Poetic,Pithy,no magic,composing,interface,adaptor
- request --> onion --> response
- basiclly we put a lot of things inside handler: like parse request,query db,user auth, CRUD model objects, biz logic, then render the result to response xml,json etc. or panic/error.

- go web packages:
dozens of frameworks
julienschmidt/httprouter
codegangstar/negroni
www.gorillatoolkit.org
- go generate according to database scheme
github.com/mijia/modelg
- go benchmark
load_test.go//测试1000000LRUcache
package demo1
import (
"fmt"
"testing"
"time"
)
//TestPutPerf load tests
func TestPutPerf(t *testing.T) {
fmt.Printf("load testing on 1M size cache\n")
size := 1000000
cache := newLRUCache(size)
start := time.Now()
for i,td := range testData {
if i%10000 == 0 {
end := time.Now()
fmt.Printf("Num: %d, Used time: %v\n", i, end.Sub(start))
start = end
}
cache.Put(td.url,td.body)
}
}
go test -c
./demo1.test -test.run=Perf
//lru_cache_test.go
package demo1
import (
"fmt"
"testing"
)
type testDataType struct {
url string
body string
}
var testData []testDataType
const testDataSize = 10000100
func init () {
testData = make([]testDataType, testDataSize)
for i:= 0; i< testDataSize; i++ {
url := fmt.Sprintf("www.fake.com/%d",i)
testData[i] = testDataType {
url: url,
body: fmt.Sprintf("This is page <b>%s</b>!",url),
}
}
}
func TestBasics(t *testing.T) {
cache := newLRUCache(2)
cache.Put("1","1")
cache.Put("2","2")
res, ok := cache.Get("1")
if !ok := || res != "1" {
t.Errorf("unexpected!")
}
cache.Put("4","4")
if _, ok := cache.Get("2");ok {
t.Errorf("unexpected")
}
}
//go tool pprof
func BenchmarkCacheFull1KSize(b *test.B) {
benchmarkCacheFull(b,1000)
}
func BenchmarkCacheFull1MSize(b *testing.B) {
benchmarkCacheFull(b,1000000)
}
func benchmarkCacheFull(b *testing.B, size int) {
cache := newLRUCache(size)
for i :=0;i<size;i++ {
cache.Put(testData[i].url,testData[i].body)
}
//两个Put之间有noise必须先做profiling,
//go tool pprof demo1.test prof.out -->#web
f, _ := os.Create("prof.out")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
//先填满,之后测试每push 一个item需要多长时间
b.ResetTimer()
for i :=0; i< b.N; i++ {
c:=(i+size) % testDataSize
cache.Put(testData[c].url, testData[c].body)
}
}
//demo2
//go test -v . -run XXX -bench Mill
//./demo2.test -test.run XXX -test.bench Milli -test.cpuprofile=prof.out
//go tool pprof demo2.test prof.out --> web
./demo1.test -test.run=xxx -test.bench Full
#./demo1.test -test.run=xxx -test.bench Full -test.cpuprofile=prof.out 这是不准确的,因为有很多noise,用上面方法
八、Marcel van Lohuizen -- Google Go team
golang.org/x/text 实现
- I18n and L10n 国际化与本地化
搜索排序,大小写,双向文本,注入翻译,数字货币,日期,单位转换
- Go uses UTF-8
const beijing="北京市"
for index,runeValue :=range beijing {
fmt.Printf("%#U 从第%d字节开始\n",runeValue,index)
}
//北从0,京从3,市从6
- 文本的序列本质
const flags="🇪🇭🇹🇻" //国家代码mc+nl fmt.Println(flags[4:])
- Transformer 接口
type Transformer interface {
Transform(dst,src []byte, atEOF bool) (nDst, nSrc int, err error)
Reset()
}
- Normalization 以NFC格式向w写入文本流
norm.NFC.Writer(w)
- 不同语言不同大小写算法
toTitle:=cases.Title(language.Dutch)
fmt.Println(toTitle.String("'n ijsberg"))
//'n IJsberg
- 多语言搜索与排序
e<ℨ<f
ª==aa
search
m:search.New(language.Danish,search.IgnoreCase,search.IgnoreDiacritics) start,end:=m.IndexString(text,s) match:=s[start:end]
- collate Example
import (
"fmt"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)
func main () {
a:=[]string("北京市","上海市","广州市")
for _,tag := range []string{"en","zh","zh-u-co-stroke"} {
collate.New(language.Make(tag)).SortStrings(a)
fmt.Println(a)
}
}
// 上 北 广;北广上;上广北
语言匹配
import (
"http"
"golang.org/x/text/language"
)
var matcher = language.NewMatcher([]language.Tag{
language.SimplifiedChinese,
language.AmericanEnglish,
})
func handle(w http.ResponseWriter, r* http.Request){
prefs,_,_:=language.ParseAcceptLanguage(r.Header.Get("Accept-Languge"))
tag,_,_:=matcher.Match(prefs...)
//use tag: it includes carried over user preference
}
在代码中插入翻译结果
import "golang.org/x/text/message" message.SetString(language.Dutch,"%s went to %s","%s is in %s geweest.") message.SetString(language.SimplifiedChinese,"%s went to %s","%s 去了 %s ")
- 参考
godoc.org/golang.org/x/text
blog.golang.org/matchlang
blog.golang.org/normalization
blog.golang.org/strings
golang.org/issue
九、毛剑--bilibili
bfs分布式小文件存储: github.com/Terry-Mao/bfs
基于facebook Haystack Paper
- 核心:proxy、directory、pitchfork、store
- 运维:ops
- 依赖:Hbase用户数据 zookeeper元数据
- 流量走向 proxy->directory->store
十、李炳毅--百度
if r<= 0x7F {
switch
case '0' <= r && r <= '9':
return false
case 'a' <= r && r <= 'z':
return false
case 'A' <= r && r <= 'Z':
return false
case ==
return false
return true
}
if unicode.IsLetter(r) || unicode.IsDigit(r) {
return false
}
十一、TiDB PingCAP创始人
- 1.interface 性能问题
var val interface{}
val = int64(10)
把整形赋值给interface会触法一次内存分配,会有一个数量级的开销
var d Datum d.SetInt64(10)
换成struct提升10倍以上
- 2.Protobuf Go默认实现性能低,推荐gogo替代
- 3.跨数据中心复制,Raft(Port from etcd) 作者Diego Ongaro。相对multi-paxos简单成熟稳定
十二、陈辉-人工智能初创公司
- 1.悟空搜索:github.com/huichen/wukong
主协程,用于收发用户请求。分词器协程,负责分词。索引器协程,负责查找索引。排序器。
package main
import (
"github.com/huichen/wukong/engine"
"github.com/huichen/wukong/types"
"log"
)
var(
//searcher是协程安全的
searcher = engine.Engine{}
)
func main() {
searcher.Init(types.EngineInitOptions{SegmentedDictionaries:"github.com/huichen/wukong/data/dictionary.txt"})
defer searcher.Close()
searcher.IndexDocument(0,types.DocumentIndexData{Content: " XXXXX"})
searcher.IndexDocument(1,types.DocumentIndexData{Content: " XXXXX"})
searcher.IndexDocument(2,types.DocumentIndexData{Content: " XXXXX"})
searcher.FlushIndex()
log.Print(searcher.Search(types.SearchRequest{Text:"XX"}))
}
基于悟空搜索的计算技术 AHA: Ad Hoc Analytics引擎
github.com/huichen/aha
- 2.sego分词:huichen/sego
package main
import (
"fmt"
"github.com/huichen/sego"
)
func main() {
//dictionary
var segmenter sego.Segmenter
segmenter.LoadDictionary("github.com/huichen/sego/data/dictionary.txt")
//分词
text := []byte("北京市东城区XXXX")
segments := segmenter.Segment(text)
//处理分词结果
fmt.Println(sego.SegmentsToString(segments,false))
}
Double-Array Trie实现是一般Trie两倍效率
github.com/adamzy/cedar-go
- 3.弥勒佛机器学习:huichen/mlf
监督式学习:最大熵分类模型,决策树模型
非监督式学习:聚类问题
在线学习:在线梯度递降模型
神经网络:Restricted Boltzmann machine
var (
libsvm_file = flag.String("input","","libsvm格式数据文件,训练数据")
model = flag.String("model","model.mlf","写入的模型文件")
//机器学习参数
learning_rate = flag.Float64("learning_rate",0.01,"学习率")
batch_size = flag.Int("batch_size",100,"梯度递降法的batch尺寸:1为stochasitic,其它值为mini batch")
delta = flag.Float64("delta",1e-4,"权重变化量和权重比值,dw/w 的绝对值,小于此值为收敛")
maxIter = flag.Int("max_iter",0,"优化器最多迭代多少次")
hidden = flag.Int("hidden",10,"多少个隐藏单元")
numCD = flag.Int("cd",1,"CD次数")
useBinary = flag.Bool("binary_hidden",true,"是否使用抽样隐藏单元")
)
代码over,郑重声明:部分代码已测试, 但以上代码均不保证可运行,不保证无错误,并仅用于总结演讲ppt。

浙公网安备 33010602011771号