Go三件套使用 2| 青训营笔记

97 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天

Kitex安装

使用wsl2安装kitex,指令如下:

go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest

定义IDL,使用IDL定义服务于接口,通过IDL来约定RPC的协议,包括对方的接口,参数和返回值等

Kitex基本使用

服务器默认监听8888端口:

package main

import(
	"context"
	"example/kitex_gen/api"
)

type EchoImpl struct{}

func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error){
    return
}

创建Client:

import "example/kitex_gen/api/echo"
import "github.com/cloudwego/kitex/client"
...
c, err:= echo.NewClient("example",client.WithHostPorts("0.0.0.0:8888"))
if err!=nil{
	log.Fatal(err)
}

发起请求:

import "example/kiten_gen/api"
...
req:=&api.Request{Message:"my request"}
resp, err:= c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))
if err!=nil{
	log.Fatal(err)
}
log.Println(resp)

kitex服务与注册

目前Kitex的服务注册与发现已经对接了主流服务注册与发现中心,比如ETCD,Nacos等。

type HelloImpl struct{}

func (h *HelloImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error){
	resp = &api.Response{
		Message:req.Message
	}
	return
}

func main(){
	r, err := etcd. NewEtchRegistry([]string{"127.0.0.1:2379"})
	if err != nil{
		log.Fatal(err)
	}
	server:=hello.NewServer(new((HellooImpl), server.WithRegistry(r), server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{
		ServiceName:"hello"
	}))
	err =server.Run()
	if err!=nil{
		log.Fatal(err)
	}
}
func main() {
	rm err := etch.NewEtcdResolver([]string{"227.0.0.1:2379"})
    if err != nil{
        log.Fatal(err)
    }
    client := hello.MustNewClient("Hello", client.WithResolver(r))
    for {
        ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
        resp, err:=client.Echo(ctx, &api.Request{Message:"Hello"}
        cancel()
       if err != nil {
           log.Fatal(err)
       }
       log.Printlin(resp)
       time.Sleep(time.Second)
    }
}

Kitex生态

XDS 扩展 github.com/kitex-contr…

opentelemetry扩展 github.com/kitex-contr…

ETCD 服务注册与发现扩展 github.com/kitex-contr…

Nacos服务注册与发现扩展 github.com/kitex-contr…

Zookeeper 服务注册与发现扩展 github.com/kitex-contr…

polaris 扩展 github.com/kitex-contr…

示例代码与业务Demo github.com/cloudwego/k…

Hertz基本使用

Hertz实现在服务端监听8080端口并注册了GET方法的路由函数

package main
import(
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main() {
    h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
    h.GET( "/ping", func(c context.Context,ctx *app.RequestContext) {
        ctx.JSON(consts.StatusOK, utils.H{"ping" : "pong"})
    })
    h. Spin()
}

Hertz路由

  • Hertz提供了GET POST PUT DELETE ANY等方法用于注册路由
  • 提供路由组的能力,用于支持路由分组的功能
  • 提供参数路由和通配路由,路由的优先级为静态路由>命名路由>通配路由

Hertz 参数绑定

Hertz提供了Bind,Validate,BindAndValidate 函数用于进行参数绑定和校验

type Args struct {
    Query string `query:"query" `
    Queryslice []string `query :"q"`
    Path string `path : "path"`
    Header string`header: header"`
    Form string `form : "form"`
    Json string`json : "json"`
    vd int `query : "vd" vd : "$==0||$==1"`
 }
func main() {
	h := server.Default(server.WithHostPorts( hp: "127.0.0.1:8080"))
    h.POST( relativePath:"v:path/bind",,func(ctx context.Context,c *app.RequestContext){
        var arg Args
        err := c.BindAndValidate(&arg)
        if err != nil {
            panic(err) 
        }
        fmt.Println(arg)
	})
	h.Spin()
}

Hertz中间件

其中间件主要分为客户端和服务端中间件,终止中间件调用链的执行方法:

c.Abort, c.AbortWithMsg, c.AbortWithStats

func MyMiddleware() app.HandlerFunc {
	return func(ctx context.Context,c *app.RequestContext) {
	// pre-handle
		fmt.Printin(a...: "pre-handle")l
		c.Next(ctx) // call the next middleware ( handler)
		// post-handle
        fmt.Println( a...: "post-handle " )
	}
}

func main() {
	h := server.Default(server.WithHostPorts( hp: "127.0.0.1:8080") )
	h.Use(MyMiddleware())
	h.GET( relativePath: " /middleware" , func(ctx context.Context,c *app.RequestContext) {
	c.String(consts.StatusOk,format: "Hello hertz ! ")
	})
    h. spin()
}

Hertz Client

Hertz提供了HTTP Client用于帮助用户发送了HTTP请求

c, err := client.NewClient()
if err != nil {
	return
}
// send http get request
status, body,_ := c.Get(context.Background(),dst: nil,url: "http://www.example.com" )
fmt.Printf( format: "status=%v body=%v\n" , status,string(body))
// send http post request
var postArgs protocol.Args
postArgs.set( key: "arg" ,value: "a" ) // set post args
status, body,_ = c.Post(context.Background(),dst:nil,url: " http://www.example.com",&postArgs)
fmt.Printf( format: "status=%v body=%v\n", status, string(body))

代码工具

代码工具Hz,通过定义IDL文件生成对应的基础服务代码

namespace go hello.example
struct HelloReq {
1: string Name (api.query= " name " );
}
struct HelloResp {
1: string RespBody;
}
service HelloService {
	HelloResp HelloMethod(1: HelloReq request) (api.get="/hello" );
}

生成文件:

import (
    "context"
    "github.com/ cloudwego/hertz/pkg/app"
    "hertz-examples/hz/thrift/biz/model/hello/example"//HelloMethod 
//@router /hello[GET]
func HelloMethod(ctx context.Context, c *app.RequestContext) {
    var err error
    var req example.HelloReq
    err = c.BindAndValidate(&req)
    if err != nil {
        c.String( code: 400,err.Error())
        return
    }
    resp := new(example.HelloResp)
    c.JSON( code:200, resp)
}

Hertz生态

HTTP2扩展 github.com/hertz-contr…

opentelemetry扩展 github.com/hertz-contr…

国际化扩展 github.com/hertz-contr…

反向代理扩展 github.com/hertz-contr…

JWT鉴权扩展 github.com/hertz-contr…

Websocket扩展 github.com/hertz-contr…

丰富的示例代码Demo github.com/cloudwego/h…