在学习go语言之前,看了很多国内外大牛的博客,总结一下就是缺点是有的,但是他的优点也是不可忽视的,还发现一个问题,关于语言好坏的讨论是相当的火热,可是入门例子搜了半天还是那屈指可数的几个网页,而且例子或多或少都存在讲述不清楚的地方,近期公司策略讲go语言纳入到公司的知识体系里。抽了些时间将go语言和goMicro做了一个入门了解。(里面肯定有不成熟的地方,欢迎指正)废话不多说开始例子。
整个学习过程是在win10系统下进行的,docker+linux固然不错放到后面再写。
前期安装准备
1.JetBrains GoLand 2019.1 x64 这个工具比较好,支持很多主流的开发语言,开发习惯具有迁移性,奉上下载链接JetBrains
2.下载安装go的sdk,go1.12.2.windows-amd64.msi 有好些都是需要下载积分的,所有就把这个放到,www.dxnbr.com(萤火虫专卖网)域名下了这个是我自己的网站,没有木马。放心下载。这个安装的时候记得把go放到环境变量那个选项勾选上。主要配置两个环境变量。安装时勾选的只会自动配置好GOROOT。要重点注意的是GOPATH这个环境变量一定要配置,不然当你引用你写的go文件时会报错,找不到本地路径,截图如下。
GOROOT:Go的安装目录
GOPATH:用于存放Go语言Package的目录,这个目录不能在Go的安装目录中
3.安装etcd,etcd-v3.3.12-windows-amd64.zip etcd是一个开源的分布式键值对数据存储系统提供共享配置,这里我们使用它来做服务的注册和发现。当然也可以用其他的,本次已etcd为例。开发环境用单机版就可以了。解压后直接点击运行就好。
4.下载第三方的go包。好多文档都是使用 go get github.com/micro/go-micro。亲自测试由于不能科学上网。get不下来。
其中 -g这个参数加上才会下载到,GOPATH的src目录下,下面罗列的可能不是很全。如果有遗漏google,或者百度自行解决。
gopm get -g github.com/micro/go-plugins/registry/etcdv3
gopm get -g github.com/coreos/etcd/clientv3
gopm get -g github.com/micro/go-micro
gopm get -g github.com/go-sql-driver/mysql
gopm get -g github.com/jmoiron/sqlx
gopm get -g github.com/micro/micro
gopm get -g github.com/micro/protoc-gen-micro
gopm get -g code.google.com/p/goprotobuf/protoc-gen-go。
GOROOT/bin目录下会有这些exe,实际情况下并没有生成这么多,本人直接下载了exe放到的这里。
二.项目构建。
1.首先在GOPATH/src 创建一个文件夹,本人英文一般经常随意取名字,就叫GoMicroDemo吧。
proto文件中创建user.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;
}
在cmd中到该proto文件下,运行命令protoc --micro_out=. --go_out=. user.proto,运行无误的话会生成如下两个文件。
为了清晰布局,把这两个文件换个目录
user.micro.go具体内容如下,肯定会跟你生成的有点出入。我做了些人为更改。
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: user.proto
package pb
import (
fmt “fmt”
proto “github.com/golang/protobuf/proto”
math “math”
)
import (
context “context”
client “github.com/micro/go-micro/client”
server “github.com/micro/go-micro/server”
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ client.Option
var _ server.Option
// Client API for UserService service
type UserServiceClient interface {
// 增
InsertUser(ctx context.Context, in *InsertUserReq, opts …client.CallOption) (*InsertUserRep, error)
// 删
DeletetUser(ctx context.Context, in *DeletetUserReq, opts …client.CallOption) (*DeletetUserRep, error)
// 查
SelectUser(ctx context.Context, in *SelectUserReq, opts …client.CallOption) (*SelectUserReq, error)
// 改
ModifyUser(ctx context.Context, in *ModifyUserReq, opts …client.CallOption) (*ModifyUserRep, error)
}
type userServiceClient struct {
c client.Client
serviceName string
}
func NewUserServiceClient(serviceName string, c client.Client) UserServiceClient {
if c == nil {
c = client.NewClient()
}
if len(serviceName) == 0 {
serviceName = “pb”
}
return &userServiceClient{
c: c,
serviceName: serviceName,
}
}
func (c *userServiceClient) InsertUser(ctx context.Context, in *InsertUserReq, opts …client.CallOption) (*InsertUserRep, error) {
req := c.c.NewRequest(c.serviceName, “UserService.InsertUser”, in)
out := new(InsertUserRep)
err := c.c.Call(ctx, req, out, opts…)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userServiceClient) DeletetUser(ctx context.Context, in *DeletetUserReq, opts …client.CallOption) (*DeletetUserRep, error) {
req := c.c.NewRequest(c.serviceName, “UserService.DeletetUser”, in)
out := new(DeletetUserRep)
err := c.c.Call(ctx, req, out, opts…)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userServiceClient) SelectUser(ctx context.Context, in *SelectUserReq, opts …client.CallOption) (*Sele