Created
March 14, 2016 14:45
-
-
Save majest/797b6ead83b4cd41c594 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"net/http" | |
"os" | |
"time" | |
"google.golang.org/grpc" | |
"golang.org/x/net/context" | |
"github.com/go-kit/kit/circuitbreaker" | |
"github.com/go-kit/kit/endpoint" | |
"github.com/go-kit/kit/loadbalancer" | |
"github.com/go-kit/kit/loadbalancer/consul" | |
"github.com/go-kit/kit/log" | |
kitratelimit "github.com/go-kit/kit/ratelimit" | |
grpctransport "github.com/go-kit/kit/transport/grpc" | |
"github.com/gorilla/mux" | |
jujuratelimit "github.com/juju/ratelimit" | |
clb "github.com/majest/go-microservice/consul" | |
"github.com/majest/go-test-service/pb" | |
"github.com/sony/gobreaker" | |
) | |
var p proxymw | |
var logger log.Logger | |
var grpcreply *pb.CountReply | |
func main() { | |
ctx := context.Background() | |
logger = log.NewLogfmtLogger(os.Stdout) | |
cconn := clb.New() | |
client := consul.NewClient(cconn.Client) | |
var ( | |
qps = 100 // max to each instance | |
publisher, err = consul.NewPublisher(client, factory(ctx, qps), logger, "com.service.string") | |
lb = loadbalancer.NewRoundRobin(publisher) | |
maxAttempts = 3 | |
maxTime = 100 * time.Millisecond | |
endpoint = loadbalancer.Retry(maxAttempts, maxTime, lb) | |
) | |
if err != nil { | |
panic("!!" + err.Error()) | |
} | |
p = proxymw{ctx, endpoint} | |
router := mux.NewRouter().StrictSlash(true) | |
router.HandleFunc("/test/{data}", GetCount) | |
logger.Log(http.ListenAndServe(":9091", router)) | |
} | |
func GetCount(w http.ResponseWriter, r *http.Request) { | |
vars := mux.Vars(r) | |
data := vars["data"] | |
res, err := p.Call(data) | |
fmt.Fprintln(w, "Data:", res) | |
logger.Log("error", err) | |
} | |
type proxymw struct { | |
context.Context | |
Endpoint endpoint.Endpoint | |
} | |
func (mw proxymw) Call(name string) (int, error) { | |
_, err := mw.Endpoint(mw.Context, &pb.CountRequest{A: name}) | |
grpcreply = &pb.CountReply{} | |
if err != nil { | |
return -1, err | |
} | |
return int(grpcreply.V), nil | |
} | |
func factory(ctx context.Context, qps int) loadbalancer.Factory { | |
return func(instance string) (endpoint.Endpoint, io.Closer, error) { | |
var e endpoint.Endpoint | |
e = makeTriggerProxy(ctx, instance) | |
e = circuitbreaker.Gobreaker(gobreaker.NewCircuitBreaker(gobreaker.Settings{}))(e) | |
e = kitratelimit.NewTokenBucketLimiter(jujuratelimit.NewBucketWithRate(float64(qps), int64(qps)))(e) | |
return e, nil, nil | |
} | |
} | |
// create client here | |
func makeTriggerProxy(ctx context.Context, instance string) endpoint.Endpoint { | |
logger.Log("instance", instance) | |
conn, err := grpc.Dial(instance, grpc.WithInsecure()) | |
if err != nil { | |
logger.Log(err.Error()) | |
} | |
//client := pb.NewStringsClient(conn) | |
q := grpctransport.NewClient( | |
conn, | |
"Strings", | |
"Count", | |
encodeRequest, | |
decodeResponse, | |
grpcreply, | |
) | |
return q.Endpoint() | |
} | |
func decodeResponse(ctx context.Context, response interface{}) (interface{}, error) { | |
r := &pb.CountReply{V: 1} | |
return r, nil | |
} | |
func encodeRequest(ctx context.Context, request interface{}) (interface{}, error) { | |
a := &pb.CountRequest{A: "123"} | |
return a, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment