天天看點

Micro基本示範

建立微服務指令說明

new #建立微服務

KaTeX parse error: Expected 'EOF', got '#' at position 8: GOPATH #̲建立 通過指定相對于GOPATH的目錄路徑,建立一個新的微服務。

USAGE:

#用法

micro new [command options][arguments…]

–namespace “go.micro” Namespace for the service e.g com.example

#服務的命名空間

–type “srv” Type of service e.g api, fnc, srv, web

#服務類型

–fqdn FQDN of service e.g com.example.srv.service (defaults to namespace.type.alias)

#服務的正式定義全面

–alias Alias is the short name used as part of combined name if specified

#别名是在指定時作為組合名的一部分使用的短名稱

建立2個服務

$micro new --type “srv” micro/rpc/srv

#“srv” 是表示目前建立的微服務類型

#micro是相對于go/src下的檔案夾名稱 可以根據項目進行設定

#srv是目前建立的微服務的檔案名

Creating service go.micro.srv.srv in /home/itcast/go/src/micro/rpc/srv

.

#主函數

├── main.go

#插件

├── plugin.go

#被調用函數

├── handler

│ └── example.go

#訂閱服務

├── subscriber

│ └── example.go

#proto協定

├── proto/example

│ └── example.proto

#docker生成檔案

├── Dockerfile

├── Makefile

└── README.md

download protobuf for micro:

brew install protobuf

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

go get -u github.com/micro/protoc-gen-micro

compile the proto file example.proto:

cd /home/itcast/go/src/micro/rpc/srv

protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto

#使用建立srv時給的protobuf指令保留用來将proto檔案進行編譯

micro new --type “web” micro/rpc/web

Creating service go.micro.web.web in /home/itcast/go/src/micro/rpc/web

.

#主函數

├── main.go

#插件檔案

├── plugin.go

#被調用處理函數

├── handler

│ └── handler.go

#前端頁面

├── html

│ └── index.html

#docker生成檔案

├── Dockerfile

├── Makefile

└── README.md

#編譯後将web端呼叫srv端的用戶端連接配接内容修改為srv的内容

#需要進行調通

啟動consul進行監管

consul agent -dev

對srv服務進行的操作

#根據提示将proto檔案生成為.go檔案

cd /home/itcast/go/src/micro/rpc/srv

protoc --proto_path=. --go_out=. --micro_out=. proto/example/example.proto

#如果報錯就按照提示将包進行下載下傳

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

go get -u github.com/micro/protoc-gen-micro

#如果還不行就把以前的包删掉從新下載下傳

對web服務進行的操作

main檔案:

package main

import (
    "github.com/micro/go-log"
	"net/http"
    "github.com/micro/go-web"
    "micro/rpc/web/handler"
)

func main() {
	// 建立1個web服務
        service := web.NewService(
           //注冊服務名
                web.Name("go.micro.web.web"),
            //服務的版本号
                web.Version("latest"),
                //!添加端口
                web.Address(":8080"),
        )

	//服務進行初始化
        if err := service.Init(); err != nil {
                log.Fatal(err)
        }

	//處理請求  / 的路由   //目前這個web微服務的 html檔案進行映射
	service.Handle("/", http.FileServer(http.Dir("html")))

	//處理請求 /example/call  的路由   這個相應函數 在目前項目下的handler
	service.HandleFunc("/example/call", handler.ExampleCall)

	//運作服務
        if err := service.Run(); err != nil {
                log.Fatal(err)
        }
}
           

handler檔案

package handler

import (
	"context"
	"encoding/json"
	"net/http"
	"time"

	"github.com/micro/go-micro/client"
    //将srv中的proto的檔案導入進來進行通信的使用
	example "micro/rpc/srv/proto/example"
)
//相應請求的業務函數
func ExampleCall(w http.ResponseWriter, r *http.Request) {
	// 将傳入的請求解碼為json
	var request map[string]interface{}
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	// 調用服務
    //替換掉原有的服務名
    //通過服務名和
	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
	}
}
           

更新成為grpc的版本

重新生成proto檔案

srv的main.go

package main

import (
	"github.com/micro/go-log"
	"github.com/micro/go-micro"
	"micro/grpc/srv/handler"
	"micro/grpc/srv/subscriber"
	example "micro/grpc/srv/proto/example"
	"github.com/micro/go-grpc"
)

func main() {
	// 建立新服務
	
	service := grpc.NewService(
        //目前微服務的注冊名
		micro.Name("go.micro.srv.srv"),
        //目前微服務的版本号
		micro.Version("latest"),
	)

	// 初始化服務
	service.Init()

	// Register Handler
    //通過protobuf的協定注冊我們的handler
	//參數1是我們建立好的服務傳回的句柄
	//參數2 使我們new的handler包中的類
	example.RegisterExampleHandler(service.Server(), new(handler.Example))

	// Register Struct as Subscriber
    //注冊結構體來自于Subscriber
	micro.RegisterSubscriber("go.micro.srv.srv", service.Server(), new(subscriber.Example))

	// Register Function as Subscriber
    // 注冊函數自于Subscriber
	micro.RegisterSubscriber("go.micro.srv.srv", service.Server(), subscriber.Handler)

	// Run service
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}
           

srv的example.go

package handler

import (
	"context"

	"github.com/micro/go-log"
	//更換了相關proto檔案
	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
}

// Stream is a server side stream handler called via client.Stream or the generated client code
//流資料的檢測操作
func (e *Example) Stream(ctx context.Context, req *example.StreamingRequest, stream example.Example_StreamStream) error {
	log.Logf("Received Example.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Logf("Responding: %d", i)
		if err := stream.Send(&example.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 *Example) PingPong(ctx context.Context, stream example.Example_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Logf("Got ping %v", req.Stroke)
		if err := stream.Send(&example.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}

           

修改web的main.go

package main
import (
        "github.com/micro/go-log"
	"net/http"

        "github.com/micro/go-web"
        "micro/grpc/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)
        }
}

           

修改web的handler.go

package handler

import (
	"context"
	"encoding/json"
	"net/http"
	"time"
	example "micro/grpc/srv/proto/example"
	"github.com/micro/go-grpc"
)

func ExampleCall(w http.ResponseWriter, r *http.Request) {

	server :=grpc.NewService()
	server.Init()

	// 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)
	//通過grpc的方法建立服務連接配接傳回1個句柄
	exampleClient := example.NewExampleService("go.micro.srv.srv", server.Client())
	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
	}
}
           

繼續閱讀