这是我参与「第五届青训营 」伴学笔记创作活动的第 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…