micro / go-micro

A Go microservices framework
https://go-micro.dev
Apache License 2.0
21.86k stars 2.35k forks source link

gRPC as default client/server #2331

Closed asim closed 2 months ago

asim commented 2 years ago

Anyone interested in gRPC becoming the default client/server? It seems like most people adopt it and potentially makes sense to be the default.

asim commented 2 years ago

@xpunch thoughts?

xpunch commented 2 years ago

grpc seams to be the most popular rpc framework in go, but move the default server & client to grpc will make a breaking change. The simplest way is move grpc plugins into go-micro, then set the default server and client to grpc like go-micro v2. The implementation of grpc server/client plugins using custom codec/transport/pool instead of other go-micro plugins, which I think is kind of breaking some designs in go-micro. In my understanding, http/grpc should be transport protocols in go-micro, but they are implemented as server&client, and may have different behavior in subscriber. Service discovery, synchronous/asynchronous communication, configuration, tracing, monitoring, circuit breaker are become basic parts of micro service system, but currently some of them are supported as wrappers in go-micro. Should we use redesign server/client? Caller/Handler used to provide synchronous communication, Publisher/Subscriber used to provide asynchronous communication. Using grpc as default handler, try eliminat the protoc-gen-micro, and using default grpc protobuf tool.

asim commented 2 years ago

You're sort of arguing points I've argued before but I found gRPC became the sort of defacto standard wire format for RPC and if thats what go-micro is maybe it should support that. The v2 implementation with defaults was a bit clunky.

I think gRPC not honouring the transport is fine, but its also a design construct of go-micro v0 and it should be ok to evolve and let go of things if it makes sense. Being truly transport agnostic is nice but only if the design supports proper scalability and I guess maybe multi-transport support.

There is the potential for redesign of the client/server to strip and separate PubSub from it. We're separately having a discussion in another issue about moving beyond protobuf and gRPC but it might be a v5 or beyond thing.

I'm mostly just interested to see that we're serving the needs of people using go-micro. If the majority are in favour of gRPC then we should pursue it, if not and they prefer a transport agnostic system then we go in that direction. Go Micro has the potential to be completely agnostic of these things and more powerful in the long term. HTTP => gRPC => Web3????

xpunch commented 2 years ago

Currently go-micro works fine in my projects, the architecture is flexible enough to support all my needs. Some of my services is running under go-micro v2 and v3, and I'm going to upgrade new services into v4. The reason why I'm willing to upgrade with go-micro is the communication between services is compatible. So it'll be fine to have breaking changes or evolution if it can still works with my old services(just my personal option). But sometimes it also need to try some tricks, if it was not supported by go micro officially. So if we can collect some pain points from community, maybe it'll be more clear about the new direction of go micro. From my side, those issues hurt me:

  1. the way go micro load configurations, make its hard to create cli tools based on go micro
  2. plugins cannot read configurations of go micro, like the service name, its really hard to locate the error when you got an error from go.micro.server/go.micro.client.
  3. there is always a default broker even the service do not need it.
  4. protoc-go-micro makes it hard to maintain services based on different go micro versions.
joeblew99 commented 2 years ago

I have only used go-micro a little, but used GRPC quite a bit with golang and other languages.

I dont like grpc because grpc-web is too restrictive.

GPRC has this create schema evolution story, so that old clients can do IO with newer severs. But its not transport agnostic.

GRPC does have async but its not that nice.

Protobufs and flatbuffers are just the serialisation without the transport and so gives you the best of both worlds.

JsonSchema is basically what openAPI3.2. In other works openapi is a extension of jsonschema. The neat thing with this is that you get validation. sure you can get that grpc using hints etc but its pretty opaque. I also like how i dont need to compile. You can use reflection. But its slow.

You can do sync and asyn with openapi, jsonschema. checkout this ! https://github.com/swaggest/go-asyncapi https://github.com/swaggest/jsonschema-go


like all technical opinions it depends what you want the platform for !!

I quite like the general design thrust of the examples and the events system. Events uses gorilla web sockets which is a shame cause i cant compile to my go-micro golang clients to wasm, where as with https://pkg.go.dev/nhooyr.io/websocket its easy.

Also nats now has websockets and full cache and bucket store. Definitely replaces redis and etcd. Not quite postresql, but there is always genji.

another way is to use NATS as the transport, because its got load balancing, fault tolerance, built in security, clustering, leaf nodes and hence shards, and can use tcp or websockets. Then for the schema i would pick JSONSchema as a base, move it over the NATS protocol. Bridging the two via code generators is something i have not seen done by anyone yet.

asim commented 2 years ago

https://github.com/google/tarpc

tarpc differentiates itself from other RPC frameworks by defining the schema in code, rather than in a 
separate language such as .proto. This means there's no separate compilation process, and no 
context switching between different languages.

I found that really interesting

seaguest commented 2 years ago

In my use case, I use grpc as replacement of REST API in mobile development, and default transport for micro service on server side. And I did a stress test of empty echo service on my machine (8C16G), with grpc it can reach 9.6K/s, while the default MUCP only has 5.5K/s. in terms of popularity and community maturity, I prefer grpc.

gedw99 commented 2 years ago

https://github.com/google/tarpc

tarpc differentiates itself from other RPC frameworks by defining the schema in code, rather than in a 
separate language such as .proto. This means there's no separate compilation process, and no 
context switching between different languages.

I found that really interesting

No compilation. I like it. But its rust not golang.

there are ways to hook up golang to rust apparently. Also to cross compile to wasm maybe too.

asim commented 2 years ago

Its not about using tarpc, its about taking the idea of having something defined without the use of proto

gedw99 commented 2 years ago

@asim https://github.com/smallnest/rpcx is pure golang and the schema is the go code.

the team writing tarpc,compare it rpcx here: https://github.com/google/tarpc/issues/224

I have not had a chance to try either yet though.

rpcx supports QUIC though :)

gedw99 commented 2 years ago

tooling seems ok too...

https://github.com/rpcxio/rpcx-examples

https://github.com/smallnest/rpcx-ui

gedw99 commented 2 years ago

Its not about using tarpc, its about taking the idea of having something defined without the use of proto

Ok now i get it...

asim commented 2 years ago

We need to make a decision on this. @xpunch I'm thinking we strip Publish from Client and Subscribe from Server. Rip out the mucp implementation and transport package. Default to gRPC. Call it a v4.5.0 despite the breakage. Maybe even think about making the service routing dns based if that makes more sense for new environments aka kubernetes.

xpunch commented 2 years ago

If we are going to make breaking changes, then it should be v5. Usually, X.Y.Z means Major.Minor.Patch, v4 users should be OK to upgrade to latest v4 smoothly. Maybe we can create v5 experimental branch, develop and testing new features in that branch.