Skip to content

Instantly share code, notes, and snippets.

@majest
Created March 14, 2016 14:45
Show Gist options
  • Save majest/797b6ead83b4cd41c594 to your computer and use it in GitHub Desktop.
Save majest/797b6ead83b4cd41c594 to your computer and use it in GitHub Desktop.
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