go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用)


warden direct

本文是学习kratos warden第一节,kratos warden的直连方式client调用,我直接用demo项目做示例

demo-server

先创建一个用作grpc-server

kratos new grpc-server

在创建一个调用grpc-server接口的call-server

kratos new call-server

现在该目录下有两个服务

[I:\VSProject\kratos-note\warden\direct]$ tree
卷 办公 的文件夹 PATH 列表
卷序列号为 00650064 0007:32FD
I:.
├─call-server
│ ├─api
│ ├─cmd
│ ├─configs
│ ├─internal
│ │ ├─dao
│ │ ├─di
│ │ ├─model
│ │ ├─server
│ │ │ ├─grpc
│ │ │ └─http
│ │ └─service
│ └─test
└─grpc-server
├─api
├─cmd
├─configs
├─internal
│ ├─dao
│ ├─di
│ ├─model
│ ├─server
│ │ ├─grpc
│ │ └─http
│ └─service
└─test

我们后面用call-server直连 grpc-server 调用grpc接口。

grpc.toml

配置里面修改下端口,同时call-server里面添加grpc-server的地址,我这是9003.

[Server]
addr = "0.0.0.0:9004"
timeout = "1s" [Client]
addr = "0.0.0.0:9003"
timeout = "1s"

服务注册

grpc-server的internal/server/grpc目录打开server.go文件,可以看到以下代码,替换注释内容就可以启动一个gRPC、我们就是demo项目不需要替换。

package grpc

import (
pb "grpc-server/api" "github.com/bilibili/kratos/pkg/conf/paladin"
"github.com/bilibili/kratos/pkg/net/rpc/warden"
) // New new a grpc server.
func New(svc pb.DemoServer) (ws *warden.Server, err error) {
var (
cfg warden.ServerConfig
ct paladin.TOML
)
if err = paladin.Get("grpc.toml").Unmarshal(&ct); err != nil {
return
}
if err = ct.Get("Server").UnmarshalTOML(&cfg); err != nil {
return
}
ws = warden.NewServer(&cfg)
// 注意替换这里:
// RegisterDemoServer方法是在"api"目录下代码生成的
// 对应proto文件内自定义的service名字,请使用正确方法名替换
pb.RegisterDemoServer(ws.Server(), svc)
ws, err = ws.Start()
return
}

接着直接启动grpc-server

kratos run
I:/VSProject/go/pkg/mod/github.com/bilibili/kratos@v0.3.2-0.20191224125553-6e1180f53a8e/pkg/net/rpc/warden/server.go:329 warden: start grpc listen addr: [::]:9003

服务发现

client端要调用grpc的接口必须有它生成的protobuf文件

一般是下面两种方式:

1、拷贝proto文件到自己项目下并且执行代码生成

2、直接import服务端的api package

这里因为demo服务api一模一样,我就不做import了,直接取api里面的pb.go文件

internal/dao 里面直接修改dao文件并添加一个direct_client.go

direct_client.go

其中,target为gRPC用于服务发现的目标,使用标准url资源格式提供给resolver用于服务发现。warden默认使用direct直连方式,直接与server端进行连接。其他服务发现方式下回见。

package dao

import (
"context" "github.com/bilibili/kratos/pkg/net/rpc/warden" "google.golang.org/grpc"
) // target server addrs.
const target = "direct://default/127.0.0.1:9003" // NOTE: example // NewClient new member grpc client
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (DemoClient, error) {
client := warden.NewClient(cfg, opts...)
conn, err := client.Dial(context.Background(), target)
if err != nil {
return nil, err
}
// 注意替换这里:
// NewDemoClient方法是在"api"目录下代码生成的
// 对应proto文件内自定义的service名字,请使用正确方法名替换
return NewDemoClient(conn), nil
}

client direct 调用

dao.go 改成如下。

添加一个dao里面直接demoClient,newDao里面做democlient的初始化、并添加一个SayHello接口。

package dao

import (
"context"
"time" demoapi "call-server/api"
"call-server/internal/model" "github.com/bilibili/kratos/pkg/cache/memcache"
"github.com/bilibili/kratos/pkg/cache/redis"
"github.com/bilibili/kratos/pkg/conf/paladin"
"github.com/bilibili/kratos/pkg/database/sql"
"github.com/bilibili/kratos/pkg/net/rpc/warden"
"github.com/bilibili/kratos/pkg/sync/pipeline/fanout"
xtime "github.com/bilibili/kratos/pkg/time"
grpcempty "github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors" "github.com/google/wire"
) var Provider = wire.NewSet(New, NewDB, NewRedis, NewMC) //go:generate kratos tool genbts
// Dao dao interface
type Dao interface {
Close()
Ping(ctx context.Context) (err error)
// bts: -nullcache=&model.Article{ID:-1} -check_null_code=$!=nil&&$.ID==-1
Article(c context.Context, id int64) (*model.Article, error)
SayHello(c context.Context, req *demoapi.HelloReq) (resp *grpcempty.Empty, err error)
} // dao dao.
type dao struct {
db *sql.DB
redis *redis.Redis
mc *memcache.Memcache
demoClient demoapi.DemoClient
cache *fanout.Fanout
demoExpire int32
} // New new a dao and return.
func New(r *redis.Redis, mc *memcache.Memcache, db *sql.DB) (d Dao, cf func(), err error) {
return newDao(r, mc, db)
} func newDao(r *redis.Redis, mc *memcache.Memcache, db *sql.DB) (d *dao, cf func(), err error) {
var cfg struct {
DemoExpire xtime.Duration
}
if err = paladin.Get("application.toml").UnmarshalTOML(&cfg); err != nil {
return
} grpccfg := &warden.ClientConfig{}
paladin.Get("grpc.toml").UnmarshalTOML(grpccfg)
var grpcClient demoapi.DemoClient
if grpcClient, err = NewClient(grpccfg); err != nil {
return
} d = &dao{
db: db,
redis: r,
mc: mc,
demoClient: grpcClient,
cache: fanout.New("cache"),
demoExpire: int32(time.Duration(cfg.DemoExpire) / time.Second),
}
cf = d.Close
return
} // Close close the resource.
func (d *dao) Close() {
d.cache.Close()
} // Ping ping the resource.
func (d *dao) Ping(ctx context.Context) (err error) {
return nil
} // SayHello say hello.
func (d *dao) SayHello(c context.Context, req *demoapi.HelloReq) (resp *grpcempty.Empty, err error) {
if resp, err = d.demoClient.SayHello(c, req); err != nil {
err = errors.Wrapf(err, "%v", req.Name)
}
return
}

service.go里面调用dao.SayHello()

// SayHello grpc demo func.
func (s *Service) SayHello(ctx context.Context, req *pb.HelloReq) (reply *empty.Empty, err error) {
reply = new(empty.Empty)
s.dao.SayHello(ctx, req)
fmt.Printf("hello %s", req.Name)
return
}

最后调用call-server的http接口测试:

从grpc-server的日志里面可以看到我们的调用是成功的, 本节完(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤。

本例子源代码 :https://github.com/ailumiyana/kratos-note

go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用)的更多相关文章

  1. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  2. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

  3. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  4. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  5. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

  6. 微服务框架surging学习之路——序列化 (转载https://www.cnblogs.com/alangur/p/10407727.html)

    微服务框架surging学习之路——序列化   1.对微服务的理解 之前看到在群里的朋友门都在讨论微服务,看到他们的讨论,我也有了一些自己的理解,所谓微服务就是系统里的每个服务都 可以自由组合.自由组 ...

  7. golang微服务框架go-micro 入门笔记2.4 go-micro service解读

    本章节阐述go-micro 服务发现原理 go-micro架构 下图来自go-micro官方 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go- ...

  8. golang微服务框架go-micro 入门笔记2.3 micro工具之消息接收和发布

    本章节阐述micro消息订阅和发布相关内容 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架go-mi ...

  9. golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

    micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go- ...

随机推荐

  1. 【t093】外星密码

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有了防护伞,并不能完全避免2012的灾难.地球防卫小队决定去求助外星种族的帮助.经过很长时间的努力,小 ...

  2. [android] eclipse里面的安卓模拟器起不来

    提示信息可能是: The connection to adb is down, and a severe error has occured. 网上看了下,常见原因有两个: 1,系统里面另外有个叫ad ...

  3. 2018百度之星初赛B - A,D,F

    总结:这一次的百度之星之行到这里也就结束了,充分的认识到了自己的不足啊...果然还是做的题太少,,见识的题型也还太少,对于STL的掌握还是不够到位啊!!(STL大法是真的好,建议大家认认真真的好好学学 ...

  4. ZR10.1青岛集训三地联考

    ZR10.1青岛集训三地联考 谢谢dijk和smy A 题目大意: 已知斐波那契数列\(f\) 设 \[ F_i = \sum_{i = 0}^nf_if_{n - i} \] 求 \[ \sum_{ ...

  5. ReactNative笔记

    Android studio 模拟器(Nexus_5_API_28.avd)无法联网可进入settings/Network&internet/Private DNS把默认的automatic改 ...

  6. [wireshark] ip filter

    查ip 时,使用 ip==10.224.37.18 发现无效 使用 ip.dst, 查到了 Match destination: ip.dst == x.x.x.x Match source: ip. ...

  7. pyinstaller打包py脚本Warning:lib not found等相关问题

    小爬从使用Pyinstaller打包py为exe文件以来,一直都会碰到Warning:lib not found等相关问题,诸如: 虽然大多数时候,您像我一样忽略这些warning,打包后的exe也能 ...

  8. Java第一次创建对象速度比之后慢的原因

    类的对象在第一次创建的时候,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载.如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入.一般某个类 ...

  9. java的package和import机制

    在说package.import机制前我们先来了解下java的CLASSPATH. CLASSPATH顾名思义就是class的路径,当我们在系统中运行某个java程序时,它就会告诉系统在这些地方寻找这 ...

  10. DEVOPS技术实践_23:判断文件下载成功作为执行条件

    在实际生产中,我们经常会需要通过判断一个结果作为一个条件去执行另一个内容,比如判断一个文件是否存在,判官一个命令是否执行成功等等 现在我们选择其中一个场景进行实验,当某个目录下存在,则执行操作 1. ...