GO 微服务GO-Micro(13)-串联我们的整个微服务(前篇-环境和服务准备)

说明

从前面的流程看,我们似乎已经差不多把一个微服务的开发流程给实施了,一遍,当然真正的微服务开发中还会涉及自身业务处理,上面只是简单的一些请求示例的处理,而且复杂的微服务的开发等更多业务逻辑处理,而且还缺少对微服务的包含微服务组件网关、配置中心、熔断器以及具体服务如何融合起来。

基于上述的说明,我重头开始梳理一次我的开发过程,也方便自己后续回头看看。比较我是一个小白,容易忘事!

参考资料

参考:https://github.com/xbox1994/go-micro-example 此示例是micro是V1版本的,我是 改为了我现在使用的V2版本的。

环境准备

环境依赖

  • windows 10 + goland
  • docker 搭建我们的etcd注册中心
  • golang 1.14
  • protoc、protoc-gen-go、protoc-gen-micro

运行方式

因为仅仅只是开发阶段,所以运行我们也运行在Windows平台。直接的go run 即可!

整体架构

image.png

从图示流程看,我们的我们服务的流程是:

启动我们的服务,我们的相关的服务都注册到服务注册中心,且从Config Service 获取想的配置信息。启动好后等待浏览器外部请求访问。

1: 外部浏览器请求我们的以 greeter/hello ,进入到我们的Micro Api网关(Api网关启动后)
2:Micro Api网关解析请求,并进行相关的身份的验证,验证通过则把解析出来用户信息写到header中,且转向我们的RPC服务
3:网关通过验证后,在向我们的GreeterService(srv服务)发起请求访问,然后转向我们微服务内部的Greeter.Call方法中,然后处理微服务内部的逻辑,
4:然后我们的GreeterService(srv服务)此时回向我们的UserService(srv服务)进行请求,尝试用户的其他信息,header也转发过去
6:然后我们的UserService(srv服务)中根据header中得到的id查询数据库得到具体的用户信息并返回

根据架构搭建项目

image.png

可选 模块创建 命令

$ micro new --type srv --alias auth github.com/hb-go/micro/xxxxxx/srv
$ micro new --type api --alias account github.com/hb-go/micro/xxxxxx/api
$ micro new --type web --alias account github.com/hb-go/micro/xxxxxx/web

实践步骤

1):使用模板命令创建默认两个SRV微服务

D:\code\go\micro-greeter\service>micro new --gopath=false user
D:\code\go\micro-greeter\service>micro new --gopath=false greeter
image.png

image.png

2):改造我们的user.proto 和 greeter.proto

  • 2.1)修改user.proto 源文件:
syntax = "proto3";

package go.micro.service.user;

service User {
    rpc Call(Request) returns (Response) {}
    rpc Stream(StreamingRequest) returns (stream StreamingResponse) {}
    rpc PingPong(stream Ping) returns (stream Pong) {}
}

message Message {
    string say = 1;
}

message Request {
    string name = 1;
}

message Response {
    string msg = 1;
}

message StreamingRequest {
    int64 count = 1;
}

message StreamingResponse {
    int64 count = 1;
}

message Ping {
    int64 stroke = 1;
}

message Pong {
    int64 stroke = 1;
}

修改为:

syntax = "proto3";

package go.micro.service.user;

service User {
    rpc Login (Request) returns (Response) {}
    rpc GetUserInfo (Empty) returns (UserInfo) {}

}

message Empty {
}

message UserInfo {
    string id = 1;
    string username = 2;
    string password = 3;
}

message Token {
    string token = 1;
    bool valid = 2;
}

message Message {
    string say = 1;
}

message Request {
    string name = 1;
}

message Response {
    string msg = 1;
}


然后生成我们的服务模板

D:\code\go\micro-greeter\service>cd user

D:\code\go\micro-greeter\service\user>protoc --proto_path=. --micro_out=. --go_out=. proto/user/user.proto
2021/01/27 16:28:46 WARNING: Missing 'go_package' option in "proto/user/user.proto",
please specify it with the full Go package path as
a future release of protoc-gen-go will require this be specified.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.


D:\code\go\micro-greeter\service\user>

修改我们的handle下的user,go:

package handler

import (
    "context"

    log "github.com/micro/go-micro/v2/logger"

    user "user/proto/user"
)

type User struct{}

// Call is a single request handler called via client.Call or the generated client code
func (e *User) Call(ctx context.Context, req *user.Request, rsp *user.Response) error {
    log.Info("Received User.Call request")
    rsp.Msg = "Hello " + req.Name
    return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (e *User) Stream(ctx context.Context, req *user.StreamingRequest, stream user.User_StreamStream) error {
    log.Infof("Received User.Stream request with count: %d", req.Count)

    for i := 0; i < int(req.Count); i++ {
        log.Infof("Responding: %d", i)
        if err := stream.Send(&user.StreamingResponse{
            Count: int64(i),
        }); err != nil {
            return err
        }
    }

    return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (e *User) PingPong(ctx context.Context, stream user.User_PingPongStream) error {
    for {
        req, err := stream.Recv()
        if err != nil {
            return err
        }
        log.Infof("Got ping %v", req.Stroke)
        if err := stream.Send(&user.Pong{Stroke: req.Stroke}); err != nil {
            return err
        }
    }
}

修改为:

PS: 这里可以快速的使用导入实现方法的形式实现我们的相关的对象的方法:
定义好我们的结构体后,选择它,然后右键-


image.png

image.png

image.png
package handler

import (
    "context"
    "github.com/prometheus/common/log"
    user "user/proto/user"
)

type User struct{}

func (u User) Login(ctx context.Context, request *user.Request, response *user.Response) error {
    //panic("implement me")
        log.Info("Received User.Call request")
        response.Msg = "Hello " + request.Name
        return nil
}

func (u User) GetUserInfo(ctx context.Context, empty *user.Empty, info *user.UserInfo) error {
    panic("implement me")
}



然后气启动一下我们的用户服务:

、D:\code\go\micro-greeter\service\user>go run main.go
2021-01-27 16:46:25  file=v2@v2.9.1/service.go:200 level=info Starting [service] go.micro.service.user
2021-01-27 16:46:25  file=grpc/grpc.go:864 level=info Server [grpc] Listening on [::]:57651
2021-01-27 16:46:25  file=grpc/grpc.go:881 level=info Broker [http] Connected to 127.0.0.1:57652
2021-01-27 16:46:25  file=grpc/grpc.go:697 level=info Registry [mdns] Registering node: go.micro.service.user-1985d4f5-d2c6-4b06-a628-27c62b1f1ef6
2021-01-27 16:46:25  file=grpc/grpc.go:730 level=info Subscribing to topic: go.micro.service.user

然后查看我们的服务信息:

D:\code\go\micro-greeter>micro get service go.micro.service.user
service  go.micro.service.user

version latest

ID      Address Metadata
go.micro.service.user-1985d4f5-d2c6-4b06-a628-27c62b1f1ef6      192.168.1.213:57651     transport=grpc,broker=http,protocol=grpc,registry=mdns,server=grpc

Endpoint: User.GetUserInfo

Request: {
        message_state MessageState {
                no_unkeyed_literals NoUnkeyedLiterals
                do_not_compare DoNotCompare
                do_not_copy DoNotCopy
                message_info MessageInfo
        }
        int32 int32
        unknown_fields []uint8
}

Response: {
        message_state MessageState {
                no_unkeyed_literals NoUnkeyedLiterals
                do_not_compare DoNotCompare
                do_not_copy DoNotCopy
                message_info MessageInfo
        }
        int32 int32
        unknown_fields []uint8
        id string
        username string
        password string
}


Endpoint: User.Login

Request: {
        message_state MessageState {
                no_unkeyed_literals NoUnkeyedLiterals
                do_not_compare DoNotCompare
                do_not_copy DoNotCopy
                message_info MessageInfo
        }
        int32 int32
        unknown_fields []uint8
        name string
}

Response: {
        message_state MessageState {
                no_unkeyed_literals NoUnkeyedLiterals
                do_not_compare DoNotCompare
                do_not_copy DoNotCopy
                message_info MessageInfo
        }
        int32 int32
        unknown_fields []uint8
        msg string
}


Endpoint: User.Handle

Metadata: subscriber=true,topic=go.micro.service.user

Request: {
        message_state MessageState {
                no_unkeyed_literals NoUnkeyedLiterals
                do_not_compare DoNotCompare
                do_not_copy DoNotCopy
                message_info MessageInfo
        }
        int32 int32
        unknown_fields []uint8
        say string
}

Response: {}


D:\code\go\micro-greeter>

同理修改我们的另一个greeter服务:

syntax = "proto3";

package go.micro.service.greeter;

service Greeter {
    rpc Call(Request) returns (Response) {}
    
}

message Request {
    string name = 1;
}

message Response {
    string msg = 1;
}

修改greeter服务的handler:

package handler

import (
    "context"
    log "github.com/micro/go-micro/v2/logger"

    greeter "greeter/proto/greeter"
)

type Greeter struct{}

func (g Greeter) Call(ctx context.Context, req *greeter.Request, rsp *greeter.Response) error {
    log.Info("Received Greeter.Call request")
    rsp.Msg = "Hello " + req.Name
    return nil
}



func (g Greeter) Stream(ctx context.Context, request *greeter.StreamingRequest, stream greeter.Greeter_StreamStream) error {
    panic("implement me")
}

func (g Greeter) PingPong(ctx context.Context, stream greeter.Greeter_PingPongStream) error {
    panic("implement me")
}




然后启动我们的服务:

D:\code\go\micro-greeter\service\greeter>go run main.go
2021-01-27 17:01:16  file=v2@v2.9.1/service.go:200 level=info Starting [service] go.micro.service.greeter
2021-01-27 17:01:16  file=grpc/grpc.go:864 level=info Server [grpc] Listening on [::]:60294
2021-01-27 17:01:16  file=grpc/grpc.go:697 level=info Registry [mdns] Registering node: go.micro.service.greeter-7dd028b3-dc0b-4442-a370-627674ca440c


查看启动的服务列表 信息:

D:\code\go\micro-greeter>micro cli
micro> list
go.micro.service.greeter
go.micro.service.user
micro.http.broker
micro>

2):修改我们的注册中心。把服务都注册到我们的ECTD上

D:\code\go\micro-greeter\service\greeter>go run main.go --registry=etcd --registry_address=192.168.219.130:2379

D:\code\go\micro-greeter\service\user>go run main.go --registry=etcd --registry_address=192.168.219.130:2379

查看我们的服务列表:(使用micro cli 进行查看)

D:\code\go\micro-greeter>micro  --registry etcd --registry_address 192.168.219.130:2379 cli
micro> list
go.micro.service.greeter
go.micro.service.user
micro>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容