Kratos快速入门:30分钟搭建高可用微服务应用

Kratos快速入门:30分钟搭建高可用微服务应用

【免费下载链接】kratos Your ultimate Go microservices framework for the cloud-native era. 【免费下载链接】kratos 项目地址: https://gitcode.com/gh_mirrors/krato/kratos

引言:微服务开发的痛点与解决方案

你是否还在为Go语言微服务开发中的复杂配置、服务治理和协议转换而烦恼?是否希望有一个框架能够帮你快速构建出既稳定又高效的微服务应用?本文将带你在30分钟内,使用Kratos框架从零开始搭建一个完整的微服务应用,让你轻松掌握微服务开发的核心技能。

读完本文后,你将能够:

  • 快速搭建Kratos开发环境
  • 使用Kratos工具生成微服务项目结构
  • 定义和实现Protobuf接口
  • 配置和使用HTTP/gRPC协议
  • 集成中间件实现服务治理
  • 构建和部署高可用的微服务应用

Kratos简介

Kratos是一套轻量级Go微服务框架,包含大量微服务相关功能及工具。它的名字来源于《战神》游戏中的主角奎托斯(Kratos),象征着力量与可靠。

Kratos核心特性

Kratos提供了丰富的微服务开发组件,主要包括:

组件功能描述
APIs基于Protobuf定义HTTP/gRPC协议
Errors通过Protobuf Enum定义错误码
Metadata规范化服务元信息传递
Config支持多数据源和动态配置
Logger标准日志接口,方便集成第三方日志库
Metrics统一指标接口,默认集成Prometheus
Tracing遵循OpenTelemetry规范的链路追踪
Encoding自动选择内容编码格式
Transport通用HTTP/gRPC传输层
Registry统一注册中心接口
Validation基于Protobuf的请求校验

Kratos设计原则

Kratos遵循以下设计原则,确保框架的易用性和可靠性:

  • 简单:不过度设计,代码平实简单
  • 通用:提供业务开发所需的基础功能
  • 高效:提高业务迭代效率
  • 稳定:高可测试性,高覆盖率,线上实践验证
  • 健壮:通过良好设计减少错误使用
  • 高性能:保证高性能但不引入unsafe代码
  • 扩展性:良好的接口设计,方便扩展
  • 容错性:为失败设计,提高系统鲁棒性
  • 工具链:提供丰富的辅助工具

环境准备

系统要求

  • Go 1.16+
  • Protobuf编译器
  • Git

安装Kratos CLI

首先,我们需要安装Kratos命令行工具:

go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
kratos upgrade

验证安装是否成功:

kratos -v

如果输出类似以下信息,则说明安装成功:

kratos version v2.x.x

安装Protobuf工具链

Kratos使用Protobuf定义服务接口,需要安装Protobuf编译器及相关插件:

# 安装protobuf编译器
apt-get update && apt-get -y install protobuf-compiler  # Ubuntu/Debian
# 或
brew install protobuf  # macOS

# 安装Go protobuf插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest

设置环境变量,确保插件能被找到:

export PATH="$PATH:$(go env GOPATH)/bin"

创建第一个Kratos项目

生成项目骨架

使用Kratos CLI创建一个新的微服务项目:

kratos new helloworld
cd helloworld

这个命令会生成一个完整的Kratos项目结构,如下所示:

helloworld/
├── api/                # 协议定义
│   └── helloworld/     # 业务API目录
├── cmd/                # 应用入口
│   └── server/         # 服务入口
├── internal/           # 内部代码
│   ├── biz/            # 业务逻辑
│   ├── data/           # 数据访问
│   ├── server/         # 服务实现
│   └── service/        # 服务层
├── configs/            # 配置文件
├── go.mod              # Go模块定义
└── Makefile            # 构建脚本

初始化项目依赖

go mod tidy

这个命令会下载项目所需的所有依赖包。

定义服务接口

创建Protobuf文件

使用Kratos CLI创建一个Protobuf文件:

kratos proto add api/helloworld/helloworld.proto

编辑Protobuf定义

打开api/helloworld/helloworld.proto文件,修改内容如下:

syntax = "proto3";

package helloworld.v1;

import "google/api/annotations.proto";
import "validate/validate.proto";

option go_package = "helloworld/api/helloworld/v1;v1";
option java_multiple_files = true;
option java_package = "dev.kratos.examples.helloworld.v1";
option java_outer_classname = "HelloWorldProtoV1";

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/helloworld/{name}"
    };
  }
  
  // Sends a greeting to multiple people
  rpc SayHelloGroup (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      post: "/helloworld/group"
      body: "*"
    };
  }
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1 [(validate.rules).string.min_len = 1];
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
  repeated string data = 2;
}

这个定义包含:

  • 一个Greeter服务,提供两个方法:SayHello和SayHelloGroup
  • 输入消息HelloRequest,包含一个name字段,并添加了验证规则
  • 输出消息HelloReply,包含message和data字段

生成Go代码

使用以下命令生成Go代码:

kratos proto client api/helloworld/helloworld.proto
kratos proto server api/helloworld/helloworld.proto -t internal/service

这会生成:

  • 客户端代码:api/helloworld/v1/helloworld_grpc.pb.go
  • HTTP处理代码:api/helloworld/v1/helloworld_http.pb.go
  • 服务端接口代码:internal/service/greeter.go

实现业务逻辑

编辑服务实现

打开internal/service/greeter.go文件,实现业务逻辑:

package service

import (
	"context"
	
	"github.com/go-kratos/kratos/v2/log"
	
	pb "helloworld/api/helloworld/v1"
)

type GreeterService struct {
	pb.UnimplementedGreeterServer
	
	log *log.Helper
}

func NewGreeterService(logger log.Logger) *GreeterService {
	return &GreeterService{
		log: log.NewHelper(logger),
	}
}

func (s *GreeterService) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
	s.log.Infof("Received SayHello request: %v", req)
	return &pb.HelloReply{Message: "Hello " + req.Name}, nil
}

func (s *GreeterService) SayHelloGroup(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
	s.log.Infof("Received SayHelloGroup request: %v", req)
	return &pb.HelloReply{
		Message: "Hello " + req.Name,
		Data:    []string{"Hello", req.Name, "from", "Kratos"},
	}, nil
}

依赖注入

Kratos使用Wire进行依赖注入,编辑internal/server/wire.go文件:

//+build wireinject

package server

import (
	"github.com/google/wire"
	
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/go-kratos/kratos/v2/transport/http"
	
	"helloworld/internal/conf"
	"helloworld/internal/service"
)

// NewWireServer creates a new server.
func NewWireServer(conf *conf.Server, greeter *service.GreeterService, logger log.Logger) (*kratos.App, func(), error) {
	panic(wire.Build(
		NewHTTPServer,
		NewGRPCServer,
		wire.Struct(new(kratos.App), "Servers"),
	))
}

// NewHTTPServer creates a HTTP server.
func NewHTTPServer(c *conf.Server, s *service.GreeterService, logger log.Logger) *http.Server {
	var opts = []http.ServerOption{
		http.Address(c.Http.Addr),
	}
	srv := http.NewServer(opts...)
	pb.RegisterGreeterHTTPServer(srv, s)
	return srv
}

// NewGRPCServer creates a gRPC server.
func NewGRPCServer(c *conf.Server, s *service.GreeterService, logger log.Logger) *grpc.Server {
	var opts = []grpc.ServerOption{
		grpc.Address(c.Grpc.Addr),
	}
	srv := grpc.NewServer(opts...)
	pb.RegisterGreeterServer(srv, s)
	return srv
}

配置服务

编辑配置文件

打开configs/config.yaml文件,配置服务端口:

server:
  http:
    addr: 0.0.0.0:8000
    timeout: 1s
  grpc:
    addr: 0.0.0.0:9000
    timeout: 1s

集成中间件

Kratos提供了丰富的中间件,用于实现服务治理功能。下面我们添加几个常用的中间件:

编辑主程序文件

打开cmd/server/main.go文件,添加中间件配置:

package main

import (
	"context"
	"flag"
	"os"
	
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/config"
	"github.com/go-kratos/kratos/v2/config/file"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/logging"
	"github.com/go-kratos/kratos/v2/middleware/metrics"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/go-kratos/kratos/v2/transport/http"
	
	_ "go.uber.org/automaxprocs"
	
	"helloworld/internal/conf"
	"helloworld/internal/server"
	"helloworld/internal/service"
)

var (
	// Name is the service name.
	Name = "helloworld"
	// Version is the service version.
	Version = "latest"
	// flagconf is the config flag.
	flagconf string
)

func init() {
	flag.StringVar(&flagconf, "conf", "configs", "config path, eg: -conf configs")
}

func newApp(logger log.Logger, hs *http.Server, gs *grpc.Server) *kratos.App {
	return kratos.New(
		kratos.Name(Name),
		kratos.Version(Version),
		kratos.Metadata(map[string]string{}),
		kratos.Logger(logger),
		kratos.Server(
			hs,
			gs,
		),
	)
}

func main() {
	flag.Parse()
	
	logger := log.With(log.NewStdLogger(os.Stdout),
		"service.name", Name,
		"service.version", Version,
		"ts", log.DefaultTimestamp,
		"caller", log.DefaultCaller,
	)
	
	c := config.New(
		config.WithSource(
			file.NewSource(flagconf),
		),
	)
	defer c.Close()
	
	if err := c.Load(); err != nil {
		panic(err)
	}
	
	var bc conf.Bootstrap
	if err := c.Scan(&bc); err != nil {
		panic(err)
	}
	
	app, cleanup, err := wireApp(bc.Server, bc.Data, logger)
	if err != nil {
		panic(err)
	}
	defer cleanup()
	
	// Start the application.
	if err := app.Run(); err != nil {
		panic(err)
	}
}

func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
	greeter := service.NewGreeterService(logger)
	
	// HTTP server
	httpSrv := http.NewServer(
		http.Address(confServer.Http.Addr),
		http.Middleware(
			recovery.Recovery(),
			logging.Server(logger),
			metrics.Server(),
			tracing.Server(),
		),
	)
	
	// gRPC server
	grpcSrv := grpc.NewServer(
		grpc.Address(confServer.Grpc.Addr),
		grpc.Middleware(
			recovery.Recovery(),
			logging.Server(logger),
			metrics.Server(),
			tracing.Server(),
		),
	)
	
	pb.RegisterGreeterHTTPServer(httpSrv, greeter)
	pb.RegisterGreeterServer(grpcSrv, greeter)
	
	app := newApp(logger, httpSrv, grpcSrv)
	return app, func() {
		// Cleanup resources here
	}, nil
}

我们添加了四个常用中间件:

  • recovery.Recovery(): 异常恢复,防止服务崩溃
  • logging.Server(logger): 访问日志记录
  • metrics.Server(): 性能指标收集
  • tracing.Server(): 分布式链路追踪

构建和运行服务

生成代码

go generate ./...

这个命令会生成Wire依赖注入代码和其他必要的代码文件。

运行服务

kratos run

如果一切正常,你会看到类似以下输出:

INFO[0000] starting server...                            module=helloworld
INFO[0000] http server started on [::]:8000              module=helloworld
INFO[0000] grpc server started on [::]:9000              module=helloworld

测试服务

测试HTTP接口

使用curl测试HTTP接口:

curl http://localhost:8000/helloworld/Kratos

预期输出:

{"message":"Hello Kratos"}

测试POST接口:

curl -X POST http://localhost:8000/helloworld/group -d '{"name":"Kratos"}'

预期输出:

{"message":"Hello Kratos","data":["Hello","Kratos","from","Kratos"]}

测试gRPC接口

创建一个gRPC客户端测试文件client/main.go

package main

import (
	"context"
	"log"
	
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	
	pb "helloworld/api/helloworld/v1"
)

func main() {
	conn, err := grpc.Dial("localhost:9000", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	
	c := pb.NewGreeterClient(conn)
	
	r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "Kratos"})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.Message)
}

运行客户端:

go run client/main.go

预期输出:

Greeting: Hello Kratos

服务部署

构建可执行文件

make build

这个命令会在bin/目录下生成可执行文件。

创建Docker镜像

创建Dockerfile

FROM golang:1.19-alpine AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o helloworld ./cmd/server

FROM alpine:3.16

WORKDIR /app

COPY --from=builder /app/helloworld .
COPY --from=builder /app/configs ./configs

EXPOSE 8000 9000

ENTRYPOINT ["./helloworld"]

构建Docker镜像:

docker build -t helloworld:latest .

运行Docker容器:

docker run -p 8000:8000 -p 9000:9000 helloworld:latest

微服务扩展

服务注册与发现

Kratos支持多种服务注册中心,以etcd为例:

  1. 安装etcd依赖:
go get github.com/go-kratos/kratos/contrib/registry/etcd/v2
  1. 配置etcd注册中心:
import (
	"github.com/go-kratos/kratos/contrib/registry/etcd/v2"
	clientv3 "go.etcd.io/etcd/client/v3"
)

func main() {
	// ...
	
	// 配置etcd客户端
	client, err := clientv3.New(clientv3.Config{
		Endpoints: []string{"127.0.0.1:2379"},
	})
	if err != nil {
		panic(err)
	}
	
	// 创建etcd注册中心
	reg := etcd.NewRegistry(etcd.WithClient(client))
	
	// 在HTTP和gRPC服务器中使用注册中心
	httpSrv := http.NewServer(
		http.Address(confServer.Http.Addr),
		http.Middleware(...),
		http.Registry(reg),
	)
	
	grpcSrv := grpc.NewServer(
		grpc.Address(confServer.Grpc.Addr),
		grpc.Middleware(...),
		grpc.Registry(reg),
	)
	
	// ...
}

配置中心集成

Kratos支持多种配置中心,以Apollo为例:

  1. 安装Apollo依赖:
go get github.com/go-kratos/kratos/contrib/config/apollo/v2
  1. 配置Apollo:
import (
	"github.com/go-kratos/kratos/contrib/config/apollo/v2"
)

func main() {
	// ...
	
	// 创建Apollo配置源
	apolloSource, err := apollo.NewSource(
		apollo.WithAppID("helloworld"),
		apollo.WithCluster("default"),
		apollo.WithEndpoint("http://127.0.0.1:8080"),
		apollo.WithNamespaces("application"),
		apollo.WithSecret(""),
	)
	if err != nil {
		panic(err)
	}
	
	// 使用Apollo配置源
	c := config.New(
		config.WithSource(
			apolloSource,
		),
	)
	
	// ...
}

总结与展望

通过本文的介绍,你已经掌握了使用Kratos框架快速搭建微服务应用的基本流程。我们从环境准备开始,逐步完成了项目创建、接口定义、业务实现、服务配置、中间件集成、测试和部署等各个环节。

Kratos框架提供了丰富的微服务开发组件和工具,大大简化了微服务应用的开发难度。它遵循简单、通用、高效、稳定的设计原则,帮助开发者快速构建可靠的微服务系统。

未来,你可以进一步探索Kratos的高级特性,如:

  • 分布式事务处理
  • 服务熔断与限流
  • 更完善的监控和可观测性
  • 服务网格集成

希望本文能够帮助你快速上手Kratos框架,开发出高质量的微服务应用!

附录:常用命令速查表

命令功能描述
kratos new <project>创建新项目
kratos proto add <proto-file>创建Protobuf文件
kratos proto client <proto-file>生成客户端代码
kratos proto server <proto-file> -t <target-dir>生成服务端代码
go generate ./...生成所有代码
kratos run运行服务
make build构建可执行文件
make docker构建Docker镜像

【免费下载链接】kratos Your ultimate Go microservices framework for the cloud-native era. 【免费下载链接】kratos 项目地址: https://gitcode.com/gh_mirrors/krato/kratos

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值