Skip to content
/ myrpc Public
forked from andeya/tp-micro

Myrpc is a high availability / high concurrent RPC micro service framework.

Notifications You must be signed in to change notification settings

aoleah/myrpc

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

myrpc GoDoc

MMyrpc is a high availability / high concurrent RPC micro service framework.

It's added router Group, Plugin, Selector and customized ServiceMethod.

myrpc_server

Demo

package main

import (
    "errors"
    "net/rpc"
    "strconv"
    "time"

    "github.com/henrylee2cn/myrpc/client"
    "github.com/henrylee2cn/myrpc/client/selector"
    "github.com/henrylee2cn/myrpc/log"
    "github.com/henrylee2cn/myrpc/plugin/auth"
    "github.com/henrylee2cn/myrpc/plugin/ip_whitelist"
    "github.com/henrylee2cn/myrpc/server"
)

type Worker struct{}

func (*Worker) Todo1(arg string, reply *string) error {
    log.Info("[server] Worker.Todo1: do job:", arg)
    *reply = "OK: " + arg
    return nil
}

func (*Worker) Todo2(arg string, reply *string) error {
    log.Info("[server] Worker.Todo2: do job:", arg)
    *reply = "OK: " + arg
    return nil
}

type serverRedirectPlugin struct{}

func (t *serverRedirectPlugin) Name() string {
    return "server_plugin"
}

func (t *serverRedirectPlugin) PostReadRequestHeader(ctx *server.Context) error {
    if ctx.Path() == "/test/1.0.work/todo1" {
        ctx.SetPath("/test/1.0.work/todo2")
        log.Info("Redirect to todo2")
    }
    return nil
}

type clientPlugin struct{}

func (t *clientPlugin) Name() string {
    return "client_plugin"
}

func (t *clientPlugin) PostReadResponseHeader(resp *rpc.Response) error {
    log.Infof("clientPlugin.PostReadResponseHeader -> resp: %v", resp)
    return nil
}

const (
    __token__ = "1234567890"
    __tag__   = "basic"
)

func checkAuthorization(serviceMethod, tag, token string) error {
    if serviceMethod != "/test/1.0.work/todo1" {
        return nil
    }
    if __token__ == token && __tag__ == tag {
        return nil
    }
    return errors.New("Illegal request!")
}

// myrpc
func main() {
    // server
    srv := server.NewServer(server.Server{})

    // ip filter
    ipwl := ip_whitelist.NewIPWhitelistPlugin()
    ipwl.Allow("127.0.0.1")
    srv.PluginContainer.Add(ipwl)

    // redirect
    srv.PluginContainer.Add(new(serverRedirectPlugin))

    // authorization
    group := srv.Group(
        "test",
        auth.NewServerAuthorizationPlugin(checkAuthorization),
    )

    group.NamedRegister("1.0.work", new(Worker))

    go srv.Serve("tcp", "0.0.0.0:8080")
    time.Sleep(2e9)

    // client
    c := client.NewClient(
        client.Client{
            FailMode: client.Failtry,
        },
        &selector.DirectSelector{
            Network: "tcp",
            Address: "127.0.0.1:8080",
        },
    )

    c.PluginContainer.Add(
        auth.NewClientAuthorizationPlugin(new(server.URLFormat), __tag__, __token__),
        new(clientPlugin),
    )

    N := 1
    bad := 0
    good := 0
    mapChan := make(chan int, N)
    t1 := time.Now()
    for i := 0; i < N; i++ {
        go func(i int) {
            var reply = new(string)
            e := c.Call("/test/1.0.work/todo1?key=henrylee2cn", strconv.Itoa(i), reply)
            log.Info(i, *reply, e)
            if e != nil {
                mapChan <- 0
            } else {
                mapChan <- 1
            }
        }(i)
    }
    for i := 0; i < N; i++ {
        if r := <-mapChan; r == 0 {
            bad++
        } else {
            good++
        }
    }
    c.Close()
    srv.Close()
    log.Info("cost time:", time.Now().Sub(t1))
    log.Info("success rate:", float64(good)/float64(good+bad)*100, "%")
}

About

Myrpc is a high availability / high concurrent RPC micro service framework.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 99.9%
  • Protocol Buffer 0.1%