@
目錄
- 寫在前面
- 1. 需求
- 1. 起另外的服務埠
- 2. 一個埠監聽
- 3. 同一個埠相同方法監聽
- 參考資料
基礎/標準庫/第三方庫
golang 導航
程式設計規範
演算法|面試
專案
寫在前面
- 相關博文
- 個人部落格首頁
- 免責宣告:僅供學習交流使用!開源框架可能存在的風險和相關後果將完全由使用者自行承擔,本人不承擔任何法律責任。
1. 需求
當 rpc 的服務啟用時,為了更好對外提供服務(測試、監控、心跳等);我們需要多協議支援
-
- 起另外一個埠服務
-
- 同一個埠監聽
-
- 同一個埠相同方法監聽
1. 起另外的服務埠
package main
import (
"context"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
go handleHttp("8088")
handleRpc("8080")
}
func handleHttp(port string) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
m.Handle("/", mux)
m.Serve()
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
svc.Serve()
}
2. 一個埠監聽
package main
import (
"context"
"github.com/soheilhy/cmux"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
//go handleHttp("8088")
//handleRpc("8080")
//l, err := net.Listen("tcp", "localhost:"+port)
//if err != nil {
// log.Fatalf("Run TCP Server err: %v", err)
//}
m := cmux.New(l)
grpcL := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldPrefixSendSettings("content-type", "application/grpc"))
httpL := m.Match(cmux.HTTP1Fast())
grpcS := handleRpc()
httpS := handleHttp(port)
go grpcS.Serve(grpcL)
go httpS.Serve(httpL)
//
err = m.Serve()
if err != nil {
log.Fatalf("Run Serve err: %v", err)
}
}
func handleHttp(port string) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() *grpc.Server {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
//res, err := tag.TagList()
//if err != nil {
// return
//}
//fmt.Printf("%s,%s", res.String(), err)
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
return svc
}
func handleGrpcGateway(port string) *runtime.ServeMux {
endpoint := "0.0.0.0:" + port
g := runtime.NewServeMux()
dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
_ = proto.RegisterTagSvcHandlerFromEndpoint(context.Background(), g, endpoint, dopts)
return g
}
3. 同一個埠相同方法監聽
# 1. 下載 Google API Proto 檔案
git clone https://github.com/googleapis/googleapis.git
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
protoc -I . -I $GOPATH\github.com\googleapis --grpc-gateway_out=logtostderr=true:. --go_out=. --go-grpc_out . rpc/proto/*.proto
service TagSvc {
// protoc -I . -I $GOPATH\github.com\googleapis --grpc-gateway_out=logtostderr=true:. --go_out=. --go-grpc_out . rpc/proto/*.proto
rpc TagList(TagRequest) returns (MessageResponse){
option (google.api.http) = {
get: "/api/v1/tag"
};
}
}
package main
import (
"context"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
grpcS := handleRpc()
grpcG := handleGrpcGateway(port)
httpS := handleHttp(port, grpcG)
err := http.ListenAndServe(":"+port, grpcHandlerFunc(grpcS, httpS))
if err != nil {
log.Fatalf("Run Serve err: %v", err)
}
}
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
}), &http2.Server{})
}
func handleHttp(port string, mux *runtime.ServeMux) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
m.Handle("/", mux)
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() *grpc.Server {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
//res, err := tag.TagList()
//if err != nil {
// return
//}
//fmt.Printf("%s,%s", res.String(), err)
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
return svc
}
func handleGrpcGateway(port string) *runtime.ServeMux {
endpoint := "0.0.0.0:" + port
g := runtime.NewServeMux()
dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
_ = proto.RegisterTagSvcHandlerFromEndpoint(context.Background(), g, endpoint, dopts)
return g
}
參考資料
基礎/標準庫/第三方庫
- 地鼠文件:比較多資料
- topgoer
- go awesome
- golang 文件學習
- golang 標準庫
- go 檔案常用操作
golang 導航
- golang 收集
- go-guide
- golang 導航
- go-concurrency-guide
- go-advice
- golang 知識路線
程式設計規範
- golang 程式設計規範
- golang 規範示例
演算法|面試
- cs 面試
- 面試網站
- Golang後端研發崗位相關面試題和簡歷
- 路人張的面試筆記
- golang 演算法
專案
- golang 專案推薦
- 7天系列
- go專案推薦
- go高效能程式設計