go微服务系列之一

作者: Java面试官 | 来源:发表于2017-10-11 20:18 被阅读970次

    hey,好久没有发博客了,最近换了新东家有点忙(其实是忙着学习,不是工作,毕竟为了money放弃了较擅长的java投向了go),很多要学的;这是在新公司接触微服务框架(micro框架)后的总结,在未来,我将会较深入的研究go和微服务,之后也会陆陆续续的发布一些文章,如果想直接查阅源码或者通过demo学习的,可以访问ricoder_demo

    如何编写一个微服务?这里用的是go的微服务框架go micro,具体的情况可以查阅:http://btfak.com/%E5%BE%AE%E6%9C%8D%E5%8A%A1/2016/03/28/go-micro/

    这里给出的是开发一个微服务的步骤:

    1、书写proto文件,定义函数等
    具体实现:

    syntax = "proto3";
    
    package pb;
    
    
    service UserService {
        //增
        rpc InsertUser (InsertUserReq) returns (InsertUserRep){}
        //删
        rpc DeletetUser (DeletetUserReq) returns (DeletetUserRep){}
        //查
        rpc SelectUser(SelectUserReq)returns (SelectUserRep){}
        //改
        rpc ModifyUser(ModifyUserReq)returns (ModifyUserRep){}
    }
    
    message User{
        int32 id = 1 ;
        string name = 2;
        string Address = 3;
        string Phone = 4;
    }
    
    message ModifyUserReq {
        int32 id = 1 ;
        string name = 2;
        string Address = 3;
        string Phone = 4;
    }
    
    message ModifyUserRep {
    }
    
    message SelectUserReq {
        int32 id = 1 ;
    }
    
    message SelectUserRep {
        User users = 1;
    }
    
    message DeletetUserReq {
        int32 id = 1 ;
    }
    
    message DeletetUserRep {
    }
    
    message InsertUserReq {
        int32 id = 1 ;
        string name = 2;
        string Address = 3;
        string Phone = 4;
    }
    
    message InsertUserRep {
        int32 id = 1 ;
        string name = 2;
        string Address = 3;
        string Phone = 4;
    }
    

    2、采用代码生成工具生成user.pb.go文件,生成协议

    具体可以查看 https://github.com/micro/go-micro ,这里我自己写了个脚本文件 build_proto.sh ,自动将指定文件夹下的proto文件生成相应的协议,具体代码如下:

    #!/usr/bin/env bash
    protoc --proto_path=./proto --go_out=plugins=micro:./src/share/pb ./proto/*.proto
    
    

    可以对代码进行自定义修改 ... .... ...

    运行 build_proto.sh 文件后可以看到在指定文件夹下生成了相应的 user.pb.go 文件,在我这里如:

    Screenshot from 2017-10-11 17-09-09.png

    3、书写一个handler实现user.pb.go定义的接口

    具体实现:
    1)先创建一个user.go文件
    2)定义一个结构体,命名为UserHandler,实现user.proto文件所有定义的service,在这里要注意一点,即使是暂时没有实现好业务,也有给个空实现,代码如下:

    package handler
    
    import(
        "mewe_job/GoMicroDemo/src/share/pb"
        "golang.org/x/net/context"
    )
    
    type UserHandler struct {
    
    }
    
    // new一个UserHandler
    func NewUserHandler() *UserHandler{
        return &UserHandler{}
    }
    
    // 增
    func (c *UserHandler) InsertUser(ctx context.Context, req * pb.InsertUserReq,rsp *pb.InsertUserRep)error {
    
        return nil
    }
    
    // 删
    func (c *UserHandler) DeletetUser(ctx context.Context, req * pb.DeletetUserReq,rsp *pb.DeletetUserRep)error {
    
        return nil
    }
    
    // 查
    func (c *UserHandler) SelectUser(ctx context.Context, req * pb.SelectUserReq,rsp *pb.SelectUserRep)error {
    
        return nil
    }
    
    //改
    func (c *UserHandler) ModifyUser(ctx context.Context, req * pb.ModifyUserReq,rsp *pb.ModifyUserRep)error {
    
        return nil
    }
    
    

    4、将handler注册进微服务,这一步在main中实现
    具体实现:

    package main
    
    import (
        "github.com/micro/cli"
        "mewe_job/GoMicroDemo/src/share/pb"
        "github.com/micro/go-micro/server"
        "mewe_job/GoMicroDemo/src/user-srv/handler"
        "github.com/micro/go-micro"
        "log"
        "mewe_job/GoMicroDemo/src/user-srv/db"
        "mewe_job/GoMicroDemo/src/share/config"
    )
    
    func main() {
    
    
        // 创建Service,并定义一些参数
        service := micro.NewService(
            micro.Name("go.micro.srv.user"),
            micro.Version("latest"),
        )
    
        // 定义Service动作操作
        service.Init(
            micro.Action(func(c *cli.Context) {
                log.Println("micro.Action test ...")
                // 先注册db
                db.Init(config.MysqlDSN)
                pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
            }),
            micro.AfterStop(func() error {
                log.Println("micro.AfterStop test ...")
                return nil
            }),
            micro.AfterStart(func() error {
                log.Println("micro.AfterStart test ...")
                return nil
            }),
        )
    
        log.Println("启动user-srv服务 ...")
    
        //启动service
        if err := service.Run(); err != nil {
            log.Panic("user-srv服务启动失败 ...")
        }
    }
    

    这段代码主要的点有:

    • 创建service,通过以下代码可以初始化一个名叫 go.micro.srv.user 的微服务

        // 创建Service,并定义一些参数
        service := micro.NewService(
            micro.Name("go.micro.srv.user"),
            micro.Version("latest"),
        )
      
    • 注册db连接和给go.micro.srv.user这个微服务绑定handler,虽然目前我还没有在db中定义db层的操作
    db.Init(config.MysqlDSN)
                pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
    
    • 启动service,通过Run开启
    if err := service.Run(); err != nil {
            log.Panic("user-srv服务启动失败 ...")
        }
    

    5、现在就可以通过 go run main.go --registry=mdns 启动该服务了,之所以携带 --registry=mdns 是因为我本地ubuntu系统没有安装consul实现服务发现,所以就采用了gomicro官方推荐的方法。

    Screenshot from 2017-10-11 17-42-03.png

    6、到这一步客户端还无法访问到服务,需要做些处理,我这里是加了个web服务,再将客户端的请求进行转发,main函数实现如下:

    func main() {
    
    /*  方案一:
        mux := http.NewServeMux()
        mux.HandleFunc("/", handleRPC)
        log.Println("Listen on :8082")
        http.ListenAndServe(":8082", mux)*/
    /*  方案二  */
        service := web.NewService(
            web.Name(config.ServicePrefix+".web"),
        )
    
        service.HandleFunc("/", handleRPC)
    
        if err := service.Init(); err != nil {
            log.Fatal(err)
        }
    
        if err := service.Run(); err != nil {
            log.Fatal(err)
        }
    }
    
    

    这里主要的函数是handleRPC这个函数,由于代码量偏多,具体实现可以查看源码。这里如果使用consul实现了服务发现,也可以通过方案一进行实现,这样的话web服务的端口还是固定的。

    7、开启web服务

    $ go run web.go --registry=mdns
    Listening on [::]:36859
    

    8、到这一步客户端就可以通过web服务端口和接口以及参数访问user这个微服务了,访问链接:(这里安利postman,一个谷歌的插件,超级好用 ... )

    http://127.0.0.1:36859/user/selectUser
    

    tip:该项目的源码(包含数据库的增删查改的demo)可以查看 源代码

    有兴趣的可以关注我的个人公众号 ~

    qrcode_for_gh_04e57fbebd02_258.jpg

    相关文章

      网友评论

      • SharpChen:service ip 哪里指定啊
      • 莫少玲:hey
        莫少玲: @李锡钒 哈哈哈好玩
        Java面试官: @少玲007     ___
           /   ▲
        / ̄  ヽ ■■
        ●     ■■
        ヽ___  ■■
            )=|
           / ||
         ∩∩__とノ
         しし———┘

      本文标题:go微服务系列之一

      本文链接:https://www.haomeiwen.com/subject/zjkgyxtx.html