六.Micro
Micro是一个专注于简化分布式系统开发的微服务生态系统,是一个工具集合,其含义类似beego中的bee.
环境安装
下载micro
go get -u -v github.com/go-log/log
go get -u -v github.com/gorilla/handlers
go get -u -v github.com/gorilla/mux
go get -u -v github.com/gorilla/websocket
go get -u -v github.com/mitchellh/hashstructure
go get -u -v github.com/nlopes/slack
go get -u -v github.com/pborman/uuid
go get -u -v github.com/pkg/errors
go get -u -v github.com/serenize/snaker
# hashicorp_consul.zip包解压在github.com/hashicorp/consul
unzip hashicorp_consul.zip -d github.com/hashicorp/consul
# miekg_dns.zip 包解压在github.com/miekg/dns
unzip miekg_dns.zip -d github.com/miekg/dns
go get github.com/micro/micro
# 编译安装micro
cd $GOPATH/src/github.com/micro/micro
go build -o micro main.go
sudo cp micro /bin/
# 插件安装
go get -u -v github.com/golang/protobuf/{proto,protoc-gen-go}
go get -u -v github.com/micro/protoc-gen-micro
micro演示
micro 是默认使用rpc框架的
micro new [command optionts ]_[arguments…]
–namespace “go.micro” # 服务的命名空间 e.g com.example
–type “srv” # 服务类型,e.g api, fnc, srv, web
–fqdn # 服务的正式定义全面 e.g com.example.srv.service (默认为 namespace.type.alias)
–alias # 别名
- 创建服务端
micro new --type "srv" micro/rpc/srv #micro是相对于go/src下的文件夹名称
.
├── main.go
├── plugin.go # 插件
├── handler # 被调用函数
│ └── example.go
├── subscriber # 订阅服务
│ └── example.go
├── proto/example # proto协议
│ └── example.proto
├── Dockerfile # docker生成文件
├── Makefile
└── README.md
文件会生成在$GOPATH/src/micro/rpc/srv下
- 创建web
micro new --type "web" micro/rpc/web
.
├── main.go
├── plugin.go
├── handler
│ └── handler.go
├── html # 前端页面
│ └── index.html
├── Dockerfile
├── Makefile
└── README.md
文件会默认生成在$GOPATH/src/micro/rpc/web下
- 启动consul进行监管
consul agent -dev
- 对srv服务操作
cd /home/eric/go/src/micro/rpc/srv
protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto
# 这时进入 proto/example 查看多了 example.micro.go example.pb.go 两个文件
#如果报错就按照提示将包进行下载
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
go get -u github.com/micro/protoc-gen-micro
#如果还不行就把以前的包删掉从新下载
- 对web端main.go进行修改
只在17行添加了端口
package main
import (
"github.com/micro/go-log"
"net/http"
"github.com/micro/go-web"
"micro/rpc/web/handler"
)
func main() {
// create new web service
service := web.NewService(
web.Name("go.micro.web.web"),
web.Version("latest"),
//添加端口
web.Address(":8080"),
)
// initialise service
if err := service.Init(); err != nil {
log.Fatal(err)
}
// register html handler
service.Handle("/", http.FileServer(http.Dir("html")))
// register call handler
service.HandleFunc("/example/call", handler.ExampleCall)
// run service
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
-
将准备好的html文件替换掉原有的文件
-
运行consul, srv, web 3个程序,浏览器打开http://127.0.0.1:8080/ 显示如下:
此时进行提交没有反应
- 修改web中handler函数
- 修改了10行 导入的包应该是上面生成的文件的包
- 修改了22行 调用的micro名称应该为srv里main.go中micro.Name的值
package handler
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/micro/go-micro/client"
example "micro/rpc/srv/proto/example"
)
func ExampleCall(w http.ResponseWriter, r *http.Request) {
// decode the incoming request as json
var request map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
http.Error(w, err.Error(), 500)
return
}
// call the backend service
exampleClient := example.NewExampleService("go.micro.srv.srv", client.DefaultClient)
rsp, err := exampleClient.Call(context.TODO(), &example.Request{
Name: request["name"].(string),
})
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// we want to augment the response
response := map[string]interface{}{
"msg": rsp.Msg,
"ref": time.Now().UnixNano(),
}
// encode and write the response as json
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, err.Error(), 500)
return
}
}
重启3个程序,浏览器出现下面输出,说明调用成功
升级为grpc版本
复制rpc文件夹为grpc
- 修改srv文件中example.proto文件 -注释两行代码
- 重新生成文件
cd /home/eric/go/src/micro/rpc/srv
protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto
-
修改srv里main.go
注意导入包的正确性
注释掉2行代码
- 修改handler文件夹中example.go函数
package handler
import (
"context"
"github.com/micro/go-log"
example "micro/grpc/srv/proto/example"
)
type Example struct{}
// Call is a single request handler called via client.Call or the generated client code
func (e *Example) Call(ctx context.Context, req *example.Request, rsp *example.Response) error {
log.Log("Received Example.Call request")
rsp.Msg = "Hello " + req.Name
return nil
}
- web端修改main.go中包的名称
import (
"github.com/micro/go-log"
"net/http"
"github.com/micro/go-web"
"micro/grpc/web/handler"
)
- 修改handler文件夹中handler.go中包的名称
import (
"context"
"encoding/json"
"net/http"
"time"
example "micro/grpc/srv/proto/example"
"github.com/micro/go-grpc"
)
修改完毕
查看consul是否还在运行 ps aux | grep consul
若开启,启动srv和web的main函数,进入浏览器查看输出,若能通畅,说明更改成功!