initial import

This commit is contained in:
kevin
2020-07-26 17:09:05 +08:00
commit 7e3a369a8f
647 changed files with 54754 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"sync"
"time"
"zero/core/lang"
"zero/core/threading"
"gopkg.in/cheggaaa/pb.v1"
)
var (
freq = flag.Int("freq", 100, "frequence")
duration = flag.String("duration", "10s", "duration")
)
type (
counting struct {
ok int
fail int
reject int
errs int
unknown int
}
metric struct {
counting
lock sync.Mutex
}
)
func (m *metric) addOk() {
m.lock.Lock()
m.ok++
m.lock.Unlock()
}
func (m *metric) addFail() {
m.lock.Lock()
m.ok++
m.lock.Unlock()
}
func (m *metric) addReject() {
m.lock.Lock()
m.ok++
m.lock.Unlock()
}
func (m *metric) addErrs() {
m.lock.Lock()
m.errs++
m.lock.Unlock()
}
func (m *metric) addUnknown() {
m.lock.Lock()
m.unknown++
m.lock.Unlock()
}
func (m *metric) reset() counting {
m.lock.Lock()
result := counting{
ok: m.ok,
fail: m.fail,
reject: m.reject,
errs: m.errs,
unknown: m.unknown,
}
m.ok = 0
m.fail = 0
m.reject = 0
m.errs = 0
m.unknown = 0
m.lock.Unlock()
return result
}
func runRequests(url string, frequence int, metrics *metric, done <-chan lang.PlaceholderType) {
ticker := time.NewTicker(time.Second / time.Duration(frequence))
defer ticker.Stop()
for {
select {
case <-ticker.C:
go func() {
resp, err := http.Get(url)
if err != nil {
metrics.addErrs()
return
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
metrics.addOk()
case http.StatusInternalServerError:
metrics.addFail()
case http.StatusServiceUnavailable:
metrics.addReject()
default:
metrics.addUnknown()
}
}()
case <-done:
return
}
}
}
func main() {
flag.Parse()
fp, err := os.Create("result.csv")
lang.Must(err)
defer fp.Close()
fmt.Fprintln(fp, "seconds,goodOk,goodFail,goodReject,goodErrs,goodUnknowns,goodDropRatio,"+
"heavyOk,heavyFail,heavyReject,heavyErrs,heavyUnknowns,heavyDropRatio")
var gm, hm metric
dur, err := time.ParseDuration(*duration)
lang.Must(err)
done := make(chan lang.PlaceholderType)
group := threading.NewRoutineGroup()
group.RunSafe(func() {
runRequests("http://localhost:8080/heavy", *freq, &hm, done)
})
group.RunSafe(func() {
runRequests("http://localhost:8080/good", *freq, &gm, done)
})
go func() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
var seconds int
for range ticker.C {
seconds++
g := gm.reset()
h := hm.reset()
fmt.Fprintf(fp, "%d,%d,%d,%d,%d,%d,%.1f,%d,%d,%d,%d,%d,%.1f\n",
seconds, g.ok, g.fail, g.reject, g.errs, g.unknown,
float32(g.reject)/float32(g.ok+g.fail+g.reject+g.unknown),
h.ok, h.fail, h.reject, h.errs, h.unknown,
float32(h.reject)/float32(h.ok+h.fail+h.reject+h.unknown))
}
}()
go func() {
bar := pb.New(int(dur / time.Second)).Start()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
bar.Increment()
}
bar.Finish()
}()
<-time.After(dur)
close(done)
group.Wait()
time.Sleep(time.Millisecond * 900)
}

View File

@@ -0,0 +1,3 @@
#!/bin/bash
hey -z 60s http://localhost:8080/good

View File

@@ -0,0 +1,3 @@
#!/bin/bash
hey -z 60s http://localhost:8080/heavy

View File

@@ -0,0 +1,59 @@
package main
import (
"net/http"
"runtime"
"time"
"zero/core/logx"
"zero/core/service"
"zero/core/stat"
"zero/core/syncx"
"zero/ngin"
)
func main() {
logx.Disable()
stat.SetReporter(nil)
server := ngin.MustNewEngine(ngin.NgConf{
ServiceConf: service.ServiceConf{
Name: "breaker",
Log: logx.LogConf{
Mode: "console",
},
},
Host: "0.0.0.0",
Port: 8080,
MaxConns: 1000,
Timeout: 3000,
})
latch := syncx.NewLimit(10)
server.AddRoute(ngin.Route{
Method: http.MethodGet,
Path: "/heavy",
Handler: func(w http.ResponseWriter, r *http.Request) {
if latch.TryBorrow() {
defer latch.Return()
runtime.LockOSThread()
defer runtime.UnlockOSThread()
begin := time.Now()
for {
if time.Now().Sub(begin) > time.Millisecond*50 {
break
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
}
},
})
server.AddRoute(ngin.Route{
Method: http.MethodGet,
Path: "/good",
Handler: func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
},
})
defer server.Stop()
server.Start()
}

View File

@@ -0,0 +1,5 @@
#!/bin/bash
GOOS=linux go build -ldflags="-s -w" server.go
docker run --rm -it --cpus=1 -p 8080:8080 -v `pwd`:/app -w /app alpine /app/server
rm -f server

View File

@@ -0,0 +1,56 @@
package main
import (
"fmt"
"log"
"zero/core/codec"
)
const (
pubKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD7bq4FLG0ctccbEFEsUBuRxkjE
eJ5U+0CAEjJk20V9/u2Fu76i1oKoShCs7GXtAFbDb5A/ImIXkPY62nAaxTGK4KVH
miYbRgh5Fy6336KepLCtCmV/r0PKZeCyJH9uYLs7EuE1z9Hgm5UUjmpHDhJtkAwR
my47YlhspwszKdRP+wIDAQAB
-----END PUBLIC KEY-----`
body = "hello"
)
var key = []byte("q4t7w!z%C*F-JaNdRgUjXn2r5u8x/A?D")
func main() {
encrypter, err := codec.NewRsaEncrypter([]byte(pubKey))
if err != nil {
log.Fatal(err)
}
decrypter, err := codec.NewRsaDecrypter("private.pem")
if err != nil {
log.Fatal(err)
}
output, err := encrypter.Encrypt([]byte(body))
if err != nil {
log.Fatal(err)
}
actual, err := decrypter.Decrypt(output)
if err != nil {
log.Fatal(err)
}
fmt.Println(actual)
out, err := codec.EcbEncrypt(key, []byte(body))
if err != nil {
log.Fatal(err)
}
ret, err := codec.EcbDecrypt(key, out)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(ret))
}

70
example/http/demo/main.go Normal file
View File

@@ -0,0 +1,70 @@
package main
import (
"flag"
"net/http"
"zero/core/httpx"
"zero/core/logx"
"zero/core/service"
"zero/ngin"
)
var (
port = flag.Int("port", 3333, "the port to listen")
timeout = flag.Int64("timeout", 0, "timeout of milliseconds")
)
type Request struct {
User string `form:"user,options=a|b"`
}
func first(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Middleware", "first")
next(w, r)
}
}
func second(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Middleware", "second")
next(w, r)
}
}
func handle(w http.ResponseWriter, r *http.Request) {
var req Request
err := httpx.Parse(r, &req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
httpx.OkJson(w, "helllo, "+req.User)
}
func main() {
flag.Parse()
engine := ngin.MustNewEngine(ngin.NgConf{
ServiceConf: service.ServiceConf{
Log: logx.LogConf{
Mode: "console",
},
},
Port: *port,
Timeout: *timeout,
MaxConns: 500,
})
defer engine.Stop()
engine.Use(first)
engine.Use(second)
engine.AddRoute(ngin.Route{
Method: http.MethodGet,
Path: "/",
Handler: handle,
})
engine.Start()
}

65
example/http/post/main.go Normal file
View File

@@ -0,0 +1,65 @@
package main
import (
"flag"
"fmt"
"net/http"
"zero/core/httpx"
"zero/core/logx"
"zero/core/service"
"zero/ngin"
)
var (
port = flag.Int("port", 3333, "the port to listen")
timeout = flag.Int64("timeout", 0, "timeout of milliseconds")
)
type Request struct {
User string `json:"user"`
}
func handleGet(w http.ResponseWriter, r *http.Request) {
}
func handlePost(w http.ResponseWriter, r *http.Request) {
var req Request
err := httpx.Parse(r, &req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
httpx.OkJson(w, fmt.Sprintf("Content-Length: %d, UserLen: %d", r.ContentLength, len(req.User)))
}
func main() {
flag.Parse()
engine := ngin.MustNewEngine(ngin.NgConf{
ServiceConf: service.ServiceConf{
Log: logx.LogConf{
Mode: "console",
},
},
Port: *port,
Timeout: *timeout,
MaxConns: 500,
MaxBytes: 50,
CpuThreshold: 500,
})
defer engine.Stop()
engine.AddRoute(ngin.Route{
Method: http.MethodGet,
Path: "/",
Handler: handleGet,
})
engine.AddRoute(ngin.Route{
Method: http.MethodPost,
Path: "/",
Handler: handlePost,
})
engine.Start()
}

View File

@@ -0,0 +1,11 @@
FROM alpine
RUN apk update --no-cache
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache tzdata
ENV TZ Asia/Shanghai
WORKDIR /app
COPY main /app/main
CMD ["./main"]

View File

@@ -0,0 +1,63 @@
package main
import (
"flag"
"math"
"net/http"
"time"
"zero/core/httpx"
"zero/core/logx"
"zero/core/service"
"zero/ngin"
)
var (
port = flag.Int("port", 3333, "the port to listen")
timeout = flag.Int64("timeout", 1000, "timeout of milliseconds")
cpu = flag.Int64("cpu", 500, "cpu threshold")
)
type Request struct {
User string `form:"user,optional"`
}
func handle(w http.ResponseWriter, r *http.Request) {
var req Request
err := httpx.Parse(r, &req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var result float64
for i := 0; i < 30000; i++ {
result += math.Sqrt(float64(i))
}
time.Sleep(time.Millisecond * 5)
httpx.OkJson(w, result)
}
func main() {
flag.Parse()
logx.Disable()
engine := ngin.MustNewEngine(ngin.NgConf{
ServiceConf: service.ServiceConf{
Log: logx.LogConf{
Mode: "console",
},
},
Port: *port,
Timeout: *timeout,
CpuThreshold: *cpu,
})
defer engine.Stop()
engine.AddRoute(ngin.Route{
Method: http.MethodGet,
Path: "/",
Handler: handle,
})
engine.Start()
}

View File

@@ -0,0 +1,113 @@
package main
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
"time"
"zero/core/codec"
)
const pubKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD7bq4FLG0ctccbEFEsUBuRxkjE
eJ5U+0CAEjJk20V9/u2Fu76i1oKoShCs7GXtAFbDb5A/ImIXkPY62nAaxTGK4KVH
miYbRgh5Fy6336KepLCtCmV/r0PKZeCyJH9uYLs7EuE1z9Hgm5UUjmpHDhJtkAwR
my47YlhspwszKdRP+wIDAQAB
-----END PUBLIC KEY-----`
var (
crypt = flag.Bool("crypt", false, "encrypt body or not")
key = []byte("q4t7w!z%C*F-JaNdRgUjXn2r5u8x/A?D")
)
func fingerprint(key string) string {
h := md5.New()
io.WriteString(h, key)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func hs256(key []byte, body string) string {
h := hmac.New(sha256.New, key)
io.WriteString(h, body)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func main() {
flag.Parse()
var err error
body := "hello world!"
if *crypt {
bodyBytes, err := codec.EcbEncrypt(key, []byte(body))
if err != nil {
log.Fatal(err)
}
body = base64.StdEncoding.EncodeToString(bodyBytes)
}
r, err := http.NewRequest(http.MethodPost, "http://localhost:3333/a/b?c=first&d=second", strings.NewReader(body))
if err != nil {
log.Fatal(err)
}
timestamp := time.Now().Unix()
sha := sha256.New()
sha.Write([]byte(body))
bodySign := fmt.Sprintf("%x", sha.Sum(nil))
contentOfSign := strings.Join([]string{
strconv.FormatInt(timestamp, 10),
http.MethodPost,
r.URL.Path,
r.URL.RawQuery,
bodySign,
}, "\n")
sign := hs256(key, contentOfSign)
var mode string
if *crypt {
mode = "1"
} else {
mode = "0"
}
content := strings.Join([]string{
"version=v1",
"type=" + mode,
fmt.Sprintf("key=%s", base64.StdEncoding.EncodeToString(key)),
"time=" + strconv.FormatInt(timestamp, 10),
}, "; ")
encrypter, err := codec.NewRsaEncrypter([]byte(pubKey))
if err != nil {
log.Fatal(err)
}
output, err := encrypter.Encrypt([]byte(content))
if err != nil {
log.Fatal(err)
}
encryptedContent := base64.StdEncoding.EncodeToString(output)
r.Header.Set("X-Content-Security", strings.Join([]string{
fmt.Sprintf("key=%s", fingerprint(pubKey)),
"secret=" + encryptedContent,
"signature=" + sign,
}, "; "))
client := &http.Client{}
resp, err := client.Do(r)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
io.Copy(os.Stdout, resp.Body)
}

View File

@@ -0,0 +1,59 @@
package main
import (
"flag"
"io"
"net/http"
"zero/core/httpx"
"zero/core/logx"
"zero/core/service"
"zero/ngin"
)
var keyPem = flag.String("prikey", "private.pem", "the private key file")
type Request struct {
User string `form:"user,optional"`
}
func handle(w http.ResponseWriter, r *http.Request) {
var req Request
err := httpx.Parse(r, &req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
io.Copy(w, r.Body)
}
func main() {
flag.Parse()
engine := ngin.MustNewEngine(ngin.NgConf{
ServiceConf: service.ServiceConf{
Log: logx.LogConf{
Path: "logs",
},
},
Port: 3333,
Signature: ngin.SignatureConf{
Strict: true,
PrivateKeys: []ngin.PrivateKeyConf{
{
Fingerprint: "bvw8YlnSqb+PoMf3MBbLdQ==",
KeyFile: *keyPem,
},
},
},
})
defer engine.Stop()
engine.AddRoute(ngin.Route{
Method: http.MethodPost,
Path: "/a/b",
Handler: handle,
})
engine.Start()
}