go-kit创建服务
创建三层结构
service, endpoint, transport
service 代码
package service
type IUserService interface {
GetName(userid int) string
}
type UserService struct {
}
func (u UserService) GetName(userid int) string {
if userid == 101 {
return "admin"
}
return "guest"
}
endpoint
package endpoint
import (
"context"
"github.com/go-kit/kit/endpoint"
"mygin/go_study/go-kit/server/service"
)
type UserRequest struct {
Uid int `json:"uid"`
}
type UserResponse struct {
Result string `json:"result"`
}
func GetUserEndpoint(s service.IUserService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(UserRequest)
result := s.GetName(req.Uid)
return UserResponse{Result: result}, nil
}
}
transport
package transport
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/gorilla/mux"
"github.com/spf13/cast"
"mygin/go_study/go-kit/server/endpoint"
"net/http"
)
func DecodeUserRequest(_ context.Context, r *http.Request) (interface{}, error) {
vars := mux.Vars(r)
fmt.Println(vars)
uidStr := vars["uid"]
if uidStr != "" {
return endpoint.UserRequest{Uid: cast.ToInt(uidStr)}, nil
}
return nil, errors.New("uid is empty")
}
func EncodeUserResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
w.Header().Set("Content-Type", "application/json;charset=utf-8")
return json.NewEncoder(w).Encode(response)
}
main
package main
import (
"flag"
"fmt"
transporthttp "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
"log"
"mygin/go_study/go-kit/server/consul"
"mygin/go_study/go-kit/server/endpoint"
"mygin/go_study/go-kit/server/service"
"mygin/go_study/go-kit/server/transport"
"net/http"
"os"
"os/signal"
"syscall"
)
var port = flag.Int("port", 8080, "The server port")
var instance = flag.String("instance", "user", "The server instancId")
func main() {
flag.Parse()
user := service.UserService{}
ept := endpoint.GetUserEndpoint(user)
handler := transporthttp.NewServer(ept, transport.DecodeUserRequest, transport.EncodeUserResponse)
r := mux.NewRouter()
r.Handle("/user/{uid}", handler)
r.Methods("GET").Path("/health").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=utf-8")
w.Write([]byte(`{"status":"ok"}`))
})
errChan := make(chan error)
go func() {
err := consul.Register(*port, "user", []string{"user"}, *instance)
if err != nil {
log.Printf("Register err %s", err)
return
}
err = http.ListenAndServe(fmt.Sprintf(":%d", *port), r)
if err != nil {
errChan <- fmt.Errorf("%s", err)
}
}()
go func() {
sigChan := make(chan os.Signal)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
errChan <- fmt.Errorf("%s", <-sigChan)
}()
getErr := <-errChan
err := consul.Deregister("user")
if err != nil {
return
}
log.Println(getErr)
}
consul
package consul
import (
"github.com/hashicorp/consul/api"
"github.com/spf13/cast"
)
func Register(port int, name string, tags []string, id string) error {
cfg := api.DefaultConfig()
cfg.Address = "http://192.168.1.8:8500"
client, err := api.NewClient(cfg)
if err != nil {
return err
}
check := &api.AgentServiceCheck{
Interval: "5s",
HTTP: "http://192.168.1.8:" + cast.ToString(port) + "/health",
}
reg := &api.AgentServiceRegistration{
ID: id,
Name: name,
Tags: tags,
Port: port,
Address: "192.168.1.8",
Check: check,
}
return client.Agent().ServiceRegister(reg)
}
func Deregister(id string) error {
cfg := api.DefaultConfig()
cfg.Address = "http://192.168.1.8:8500"
client, err := api.NewClient(cfg)
if err != nil {
return err
}
return client.Agent().ServiceDeregister(id)
}
func GetService(name string) ([]*api.ServiceEntry, error) {
cfg := api.DefaultConfig()
cfg.Address = "http://192.168.1.8:8500"
client, err := api.NewClient(cfg)
if err != nil {
return nil, err
}
services, _, err := client.Health().Service(name, "", true, nil)
if err != nil {
return nil, err
}
return services, nil
}
测试
curl -X GET "http://192.168.1.8:8080/user/101"
zhaohongfeng@zhaohongfengdeMacBook-Pro ~ % curl http://localhost:8081/user/101
{"result":"admin"}