刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • go-kit

    • 【go-kit教程】go-kit初识
    • 【go-kit教程】go-kit启动http服务
      • 环境准备
      • 快速上手
      • 代码分层
      • 完整代码
    • 【go-kit教程】go-kit集成gin启动服务
    • 【go-kit教程】go-kit集成grpc和protobuf
    • 【go-kit教程】go-kit中间件
    • 【go-kit教程】go-kit服务注册发现与负载均衡
    • 【go-kit教程】go-kit限流和熔断
    • 【go-kit教程】go-kit链路追踪
    • 【go-kit教程】go-kit集成Prometheus
  • 微服务
  • go-kit
bigox
2023-02-23
目录

【go-kit教程】go-kit启动http服务

# 环境准备

  • gokit工具集:go get github.com/go-kit/kit;
  • http请求路由组件:go get github.com/gorilla/mux;

# 快速上手

  • 上代码

    package main
    
    import (
    	"context"
    	"encoding/json"
    	"errors"
    	"log"
    	"net/http"
    
    	"github.com/gorilla/mux"
    	httptransport "github.com/go-kit/kit/transport/http"
    	"github.com/go-kit/kit/endpoint"
    )
    
    type MyService interface {
    	Foo(context.Context, string) (string, error)
    	Bar(context.Context, int64) (bool, error)
    }
    
    type myService struct{}
    
    func (s myService) Foo(ctx context.Context, str string) (string, error) {
    	return "foo" + str, nil
    }
    
    func (s myService) Bar(ctx context.Context, n int64) (bool, error) {
    	return n%2 == 0, nil
    }
    
    type fooRequest struct {
    	Str string `json:"str"`
    }
    
    type fooResponse struct {
    	Str string `json:"str"`
    	Err string `json:"err,omitempty"`
    }
    
    type barRequest struct {
    	N int64 `json:"n"`
    }
    
    type barResponse struct {
    	Result bool   `json:"result"`
    	Err    string `json:"err,omitempty"`
    }
    
    func makeFooEndpoint(svc MyService) endpoint.Endpoint {
    	return func(ctx context.Context, request interface{}) (interface{}, error) {
    		req := request.(fooRequest)
    		res, err := svc.Foo(ctx, req.Str)
    		if err != nil {
    			return fooResponse{res, err.Error()}, nil
    		}
    		return fooResponse{res, ""}, nil
    	}
    }
    
    func makeBarEndpoint(svc MyService) endpoint.Endpoint {
    	return func(ctx context.Context, request interface{}) (interface{}, error) {
    		req := request.(barRequest)
    		res, err := svc.Bar(ctx, req.N)
    		if err != nil {
    			return barResponse{res, err.Error()}, nil
    		}
    		return barResponse{res, ""}, nil
    	}
    }
    
    func decodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
    	var req fooRequest
    	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    		return nil, err
    	}
    	return req, nil
    }
    
    func decodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
    	var req barRequest
    	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    		return nil, err
    	}
    	return req, nil
    }
    
    func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
    	return json.NewEncoder(w).Encode(response)
    }
    
    func main() {
    	// Create a new service
    	svc := myService{}
    
    	// Create the endpoints
    	fooEndpoint := makeFooEndpoint(svc)
    	barEndpoint := makeBarEndpoint(svc)
    
    	// Create the router and register the endpoints
    	r := mux.NewRouter()
    	r.Methods("POST").Path("/foo").Handler(httptransport.NewServer(
    		fooEndpoint,
    		decodeFooRequest,
    		encodeResponse,
    	))
    	r.Methods("POST").Path("/bar").Handler(httptransport.NewServer(
    		barEndpoint,
    		decodeBarRequest,
    		encodeResponse,
    	))
    
    	// Start the server
    	log.Fatal(http.ListenAndServe(":8080", r))
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
  • 执行命令 curl http://127.0.0.1:8080/foo -d '{"data":"111"}' -XPOST 响应{"str":"foo"}

# 代码分层

  • 目录结构

    .
    ├── endpoints
    │   └── my_endpoint.go
    ├── go.mod
    ├── go.sum
    ├── main.go
    ├── services
    │   └── my_service.go
    └── transports
        └── my_transport.go
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  • services/my_service.go

    /**
     * @date: 2023/2/18
     * @desc: 服务层 业务具体实现
     */
    
    package endpoints
    
    import "context"
    
    type MyServicer interface {
    	Foo(context.Context, string) (string, error)
    	Bar(context.Context, int64) (bool, error)
    }
    
    type MyService struct{}
    
    func (s *MyService) Foo(ctx context.Context, str string) (string, error) {
    	return "foo" + str, nil
    }
    
    func (s *MyService) Bar(ctx context.Context, n int64) (bool, error) {
    	return n%2 == 0, nil
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
  • endpoints/endpoint.go

    /**
     * @date: 2023/2/18
     * @desc: endpoints 层
     */
    
    package endpoints
    
    import (
    	"context"
    	"github.com/go-kit/kit/endpoint"
    	services "kit-demo/services"
    )
    
    type FooRequest struct {
    	Str string `json:"str"`
    }
    
    type FooResponse struct {
    	Str string `json:"str"`
    	Err string `json:"err,omitempty"`
    }
    
    type BarRequest struct {
    	N int64 `json:"n"`
    }
    
    type BarResponse struct {
    	Result bool   `json:"result"`
    	Err    string `json:"err,omitempty"`
    }
    
    func MakeFooEndpoint(svc services.MyServicer) endpoint.Endpoint {
    	return func(ctx context.Context, request interface{}) (interface{}, error) {
    		req := request.(FooRequest)
    		res, err := svc.Foo(ctx, req.Str)
    		if err != nil {
    			return FooResponse{res, err.Error()}, nil
    		}
    		return FooResponse{res, ""}, nil
    	}
    }
    
    func MakeBarEndpoint(svc services.MyServicer) endpoint.Endpoint {
    	return func(ctx context.Context, request interface{}) (interface{}, error) {
    		req := request.(BarRequest)
    		res, err := svc.Bar(ctx, req.N)
    		if err != nil {
    			return BarResponse{res, err.Error()}, nil
    		}
    		return BarResponse{res, ""}, nil
    	}
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
  • transports/my_transport.go

    /**
     * @date: 2023/2/18
     * @desc: 传输层 http/rpc...
     */
    
    package endpoints
    
    import (
    	"context"
    	"encoding/json"
    	"github.com/go-kit/kit/endpoint"
    	httptransport "github.com/go-kit/kit/transport/http"
    	"github.com/gorilla/mux"
    	"kit-demo/endpoints"
    	"net/http"
    )
    
    func decodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
    	var req endpoints.FooRequest
    	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    		return nil, err
    	}
    	return req, nil
    }
    
    func decodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
    	var req endpoints.BarRequest
    	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    		return nil, err
    	}
    	return req, nil
    }
    
    func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
    	return json.NewEncoder(w).Encode(response)
    }
    
    // MakeHttpHandler make http handler use mux
    func MakeHttpHandler(ctx context.Context, fooEndpoint, barEndpoint endpoint.Endpoint) http.Handler {
    	r := mux.NewRouter()
    
    	options := []httptransport.ServerOption{
    		httptransport.ServerErrorEncoder(httptransport.DefaultErrorEncoder),
    	}
    
    	r.Methods("POST").Path("/foo").Handler(httptransport.NewServer(
    		fooEndpoint,
    		decodeFooRequest,
    		encodeResponse,
    		options...,
    	))
    
    	r.Methods("POST").Path("/bar").Handler(httptransport.NewServer(
    		barEndpoint,
    		decodeBarRequest,
    		encodeResponse,
    		options...,
    	))
    
    	return r
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
  • main.go

    package main
    
    import (
    	"context"
    	"fmt"
    	"kit-demo/endpoints"
    	services "kit-demo/services"
    	transports "kit-demo/transports"
    	"net/http"
    	"os"
    	"os/signal"
    	"syscall"
    )
    
    func main() {
    	errChan := make(chan error)
    
    	// Create a new service
    	svc := services.MyService{}
    	ctx := context.Background()
    
    	// Create the endpoints
    	fooEndpoint := endpoints.MakeFooEndpoint(&svc)
    	barEndpoint := endpoints.MakeBarEndpoint(&svc)
    
    	r := transports.MakeHttpHandler(ctx, fooEndpoint, barEndpoint)
    
    	go func() {
    		fmt.Println("Http Server start at port:8080")
    		handler := r
    		errChan <- http.ListenAndServe(":8080", handler)
    	}()
    
    	go func() {
    		c := make(chan os.Signal, 1)
    		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
    		errChan <- fmt.Errorf("%s", <-c)
    	}()
    
    	fmt.Println(<-errChan)
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42

# 完整代码

  • https://github.com/hellolib/go-kit-demo/tree/main/kit-demo
#Go
上次更新: 2023/04/16, 18:35:33
【go-kit教程】go-kit初识
【go-kit教程】go-kit集成gin启动服务

← 【go-kit教程】go-kit初识 【go-kit教程】go-kit集成gin启动服务→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式