前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go微服务系列之一

go微服务系列之一

作者头像
李海彬
发布2019-05-08 10:40:31
7510
发布2019-05-08 10:40:31
举报

作者:稀饭下雪 链接:https://www.jianshu.com/p/9cb474dd451d 来源:简书

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文件,定义函数等 具体实现:

 1syntax = "proto3";
 2
 3package pb;
 4
 5
 6service UserService {
 7    //增
 8    rpc InsertUser (InsertUserReq) returns (InsertUserRep){}
 9    //删
10    rpc DeletetUser (DeletetUserReq) returns (DeletetUserRep){}
11    //查
12    rpc SelectUser(SelectUserReq)returns (SelectUserRep){}
13    //改
14    rpc ModifyUser(ModifyUserReq)returns (ModifyUserRep){}
15}
16
17message User{
18    int32 id = 1 ;
19    string name = 2;
20    string Address = 3;
21    string Phone = 4;
22}
23
24message ModifyUserReq {
25    int32 id = 1 ;
26    string name = 2;
27    string Address = 3;
28    string Phone = 4;
29}
30
31message ModifyUserRep {
32}
33
34message SelectUserReq {
35    int32 id = 1 ;
36}
37
38message SelectUserRep {
39    User users = 1;
40}
41
42message DeletetUserReq {
43    int32 id = 1 ;
44}
45
46message DeletetUserRep {
47}
48
49message InsertUserReq {
50    int32 id = 1 ;
51    string name = 2;
52    string Address = 3;
53    string Phone = 4;
54}
55
56message InsertUserRep {
57    int32 id = 1 ;
58    string name = 2;
59    string Address = 3;
60    string Phone = 4;
61}

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

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

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

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

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

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

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

 1package handler
 2
 3import(
 4    "mewe_job/GoMicroDemo/src/share/pb"
 5    "golang.org/x/net/context"
 6)
 7
 8type UserHandler struct {
 9
10}
11
12// new一个UserHandler
13func NewUserHandler() *UserHandler{
14    return &UserHandler{}
15}
16
17// 增
18func (c *UserHandler) InsertUser(ctx context.Context, req * pb.InsertUserReq,rsp *pb.InsertUserRep)error {
19
20    return nil
21}
22
23// 删
24func (c *UserHandler) DeletetUser(ctx context.Context, req * pb.DeletetUserReq,rsp *pb.DeletetUserRep)error {
25
26    return nil
27}
28
29// 查
30func (c *UserHandler) SelectUser(ctx context.Context, req * pb.SelectUserReq,rsp *pb.SelectUserRep)error {
31
32    return nil
33}
34
35//改
36func (c *UserHandler) ModifyUser(ctx context.Context, req * pb.ModifyUserReq,rsp *pb.ModifyUserRep)error {
37
38    return nil
39}

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

 1package main
 2
 3import (
 4    "github.com/micro/cli"
 5    "mewe_job/GoMicroDemo/src/share/pb"
 6    "github.com/micro/go-micro/server"
 7    "mewe_job/GoMicroDemo/src/user-srv/handler"
 8    "github.com/micro/go-micro"
 9    "log"
10    "mewe_job/GoMicroDemo/src/user-srv/db"
11    "mewe_job/GoMicroDemo/src/share/config"
12)
13
14func main() {
15
16
17    // 创建Service,并定义一些参数
18    service := micro.NewService(
19        micro.Name("go.micro.srv.user"),
20        micro.Version("latest"),
21    )
22
23    // 定义Service动作操作
24    service.Init(
25        micro.Action(func(c *cli.Context) {
26            log.Println("micro.Action test ...")
27            // 先注册db
28            db.Init(config.MysqlDSN)
29            pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
30        }),
31        micro.AfterStop(func() error {
32            log.Println("micro.AfterStop test ...")
33            return nil
34        }),
35        micro.AfterStart(func() error {
36            log.Println("micro.AfterStart test ...")
37            return nil
38        }),
39    )
40
41    log.Println("启动user-srv服务 ...")
42
43    //启动service
44    if err := service.Run(); err != nil {
45        log.Panic("user-srv服务启动失败 ...")
46    }
47}

这段代码主要的点有:

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

1  // 创建Service,并定义一些参数
2  service := micro.NewService(
3      micro.Name("go.micro.srv.user"),
4      micro.Version("latest"),
5  )

注册db连接和给go.micro.srv.user这个微服务绑定handler,虽然目前我还没有在db中定义db层的操作

1db.Init(config.MysqlDSN)
2            pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))

启动service,通过Run开启

1if err := service.Run(); err != nil {
2        log.Panic("user-srv服务启动失败 ...")
3    }

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

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

 1func main() {
 2
 3/*  方案一:
 4    mux := http.NewServeMux()
 5    mux.HandleFunc("/", handleRPC)
 6    log.Println("Listen on :8082")
 7    http.ListenAndServe(":8082", mux)*/
 8/*  方案二  */
 9    service := web.NewService(
10        web.Name(config.ServicePrefix+".web"),
11    )
12
13    service.HandleFunc("/", handleRPC)
14
15    if err := service.Init(); err != nil {
16        log.Fatal(err)
17    }
18
19    if err := service.Run(); err != nil {
20        log.Fatal(err)
21    }
22}

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

7、开启web服务

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

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

1http://127.0.0.1:36859/user/selectUser

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档