Based on the Triple protocol defined by Dubbo, you can easily write browser and gRPC compatible RPC services that run on both HTTP/1 and HTTP/2 simultaneously. The Dubbo Go SDK supports defining services using IDL or programming language-specific methods and provides a lightweight API for publishing or invoking these services.
This example demonstrates the RPC communication pattern based on the Triple protocol. The example uses Protocol Buffer to define the RPC service and demonstrates the processes of code generation, service publishing, and service access.
Since we are using Protocol Buffer, we first need to install the relevant code generation tools, including protoc
, protoc-gen-go
, and protoc-gen-go-triple
.
Install protoc
Install protoc
plugins
Next, we install the plugins protoc-gen-go
and protoc-gen-go-triple
.
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install dubbo.apache.org/dubbo-go/v3/cmd/protoc-gen-go-triple@v3.0.1
Make sure protoc-gen-go
and protoc-gen-go-triple
are in your PATH
. You can verify this with which protoc-gen-go
. If that command does not work, please execute the following commands:
[ -n "$(go env GOBIN)" ] && export PATH="$(go env GOBIN):${PATH}"
[ -n "$(go env GOPATH)" ] && export PATH="$(go env GOPATH)/bin:${PATH}"
We maintain a series of dubbo-go usage examples in the apache/dubbo-go-samples repository to help users quickly learn how to use dubbo-go.
You can download the example zip file and unzip it, or clone the repository:
$ git clone --depth 1 https://github.com/apache/dubbo-go-samples
Switch to the quick start example directory:
$ cd dubbo-go-samples/helloworld
In the go-server/cmd
directory:
Run the following command to start the server:
$ go run server.go
Use cURL
to verify that the server has been started correctly:
$ curl \
--header "Content-Type: application/json" \
--data '{"name": "Dubbo"}' \
http://localhost:20000/greet.GreetService/Greet
Greeting: Hello world
Open a new terminal and run the following command in the go-client/cmd
directory to start the client:
$ go run client.go
Greeting: Hello world
This is a complete development process of a dubbo-go RPC communication service.
Next, we will explain the source code of the dubbo-go-samples/helloworld
example.
The example uses Protocol Buffer (IDL) to define the Dubbo service.
syntax = "proto3";
package greet;
option go_package = "github.com/apache/dubbo-go-samples/helloworld/proto;greet";
message GreetRequest {
string name = 1;
}
message GreetResponse {
string greeting = 1;
}
service GreetService {
rpc Greet(GreetRequest) returns (GreetResponse) {}
}
This file declares a service called GreetService
, defining the Greet method along with its request parameter GreetRequest and return value GreetResponse.
Before running the server or client, we need to generate the relevant code using protoc-gen-go
and protoc-gen-go-triple
.
protoc --go_out=. --go_opt=paths=source_relative \
--go-triple_out=. --go-triple_opt=paths=source_relative \
./greet.proto
After running the above command, you will see the following generated files in the target directory:
proto
├── greet.pb.go
├── greet.proto
└── greet.triple.go
In the proto/greet/v1 package, there are two parts:
greet.pb.go
is generated by Google’s standard protoc-gen-go
, which contains the structures of GreetRequest
, GreetResponse
, and the encoding/decoding rules.greet.triple.go
is produced by the custom Dubbo plugin protoc-gen-go-triple
and includes key information, including the generated interface GreetService
, constructors, and more.Next, we need to add business logic by implementing the greet.GreetService
interface.
type GreetTripleServer struct {
}
func (srv *GreetTripleServer) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) {
resp := &greet.GreetResponse{Greeting: req.Name}
return resp, nil
}
Create a new Server, register the GreetTripleServer
we implemented earlier, and then initialize and start the Server, which will listen for requests on the specified port.
func main() {
srv, err := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(20000),
protocol.WithTriple(),
),
)
if err != nil {
panic(err)
}
if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); err != nil {
panic(err)
}
if err := srv.Serve(); err != nil {
logger.Error(err)
}
}
The simplest way is to use an HTTP/1.1 POST request to access the service, passing the parameters as standard JSON format in the HTTP payload. Here is an example using a cURL command:
curl \
--header "Content-Type: application/json" \
--data '{"name": "Dubbo"}' \
http://localhost:20000/greet.GreetService/Greet
You can also use a Dubbo client to request the service. First, obtain the service proxy from the generated code in the greet
package, specify the server address, and initialize it. Then you can initiate an RPC call.
func main() {
cli, err := client.NewClient(
client.WithClientURL("127.0.0.1:20000"),
)
if err != nil {
panic(err)
}
svc, err := greet.NewGreetService(cli)
if err != nil {
panic(err)
}
resp, err := svc.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"})
if err != nil {
logger.Error(err)
}
logger.Infof("Greet response: %s", resp.Greeting)
}
This is the basic working principle of dubbo-go RPC!
Learn about Streaming communication models, configuring timeout durations, passing headers, and more framework configurations.
Learn how to use dubbo-go to develop microservices, incorporating service discovery, observability, traffic control, and more service governance capabilities.