• grpc实现跨语言(go与java)服务通信


    Golang微服务实战:使用gRPC实现跨语言通信!
    
    随着微服务架构的发展,越来越多的企业开始采用微服务架构来构建分布式系统。在微服务架构中,服务之间的通信是非常重要的。而gRPC作为一种高效、跨平台、跨语言的RPC框架,成为越来越多企业的首选。
    
    本篇文章将介绍如何使用gRPC实现跨语言通信。我们将实现一个用Golang编写的服务,与用Python编写的客户端通信,并探讨gRPC框架的一些核心技术点。
    

    简介

    多个服务在进行拆分后,我们往往要通过服务之间互相调用来实现某个业务功能,我们知道在java领域,有springCloud,Dubbo这些封装的很好的通信组件,但是如果服务之间是跨语言的,那么这些就不能解决了,今天有个需求,我想实现go服务和java服务之间的通信,于是就借鉴了一下google的一个轻量且高效的通讯框架-grpc来实现

    什么是grpc

    grpc官方文档

    项目需求

    实现一个简单的,用Go服务远程调用Java服务一个整数相加的接口

    服务端设计步骤

    • 服务端是maven工程,新建一个工程后,导入maven坐标
    • 在main目录下,java同级目录下建立proto文件夹,用来存放基于http2和protobuf的通信协议,新建justtest.proto
    1. syntax = "proto3"; //协议版本号
    2. option java_multiple_files = true;
    3. option java_package = "io.grpc.add";
    4. option java_outer_classname = "remote_add_service";
    5. package Test; // 包名
    6. //定义服务
    7. service Greeter {
    8. //注意:这里是returns 不是return
    9. rpc RemoteAdd (AddRequest) returns (AddResponse) {}
    10. }
    11. //定义消息类型
    12. message AddRequest {
    13. int32 num1 = 1;
    14. int32 num2 = 2;
    15. }
    16. message AddResponse {
    17. int32 answer = 1;
    18. }
    • 新建proto文件,写入文件协议规定的字段
    • 使用maven install生成由protoc反向解析出的一系列文件
    • 启动服务端

    客户端设计

    • 客户端的工程是golang工程,我们要事先安装好protobuf的包,网上有很多教程,大家可以去自行下载
    • 值得注意的是,go服务需要一些grpc的包,这些包…有些还真在github上找不到,所以大家可以去下载我的go所需要的库的仓库,我全部都打在了项目的govendor目录下,里头的包都是完整的,拿来就可以用
    • 将maven工程中的protoc文件拷贝到golang工程里面的proto包里,然后进入这个文件夹目录,使用下面的指令去生成一系列反向解析出来的go文件
    1. protoc --go-grpc_out=. 你的proto文件名.proto
    2. protoc --go_out=. 你的proto文件名.proto
    • 新建客户端服务,去监听一个端口,同时去调用这个远程接口服务

    演示实例

    服务端启动java服务

    在这里插入图片描述

    客户端启动golang服务
    client.go文件

    1. package main
    2. import (
    3. "fmt"
    4. "github.com/gin-gonic/gin"
    5. pb "go_grpc/pb"
    6. "google.golang.org/grpc"
    7. "log"
    8. "net/http"
    9. )
    10. func main() {
    11. // Set up a connection to the server.
    12. conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    13. if err != nil {
    14. log.Fatalf("did not connect: %v", err)
    15. }
    16. defer conn.Close()
    17. client := pb.NewGreeterClient(conn)
    18. r := gin.Default()
    19. r.GET("/", func(c *gin.Context) {
    20. //todo 远程调用整数相加
    21. req := &pb.AddRequest{Num1: 10,Num2: 10}
    22. res, err := client.RemoteAdd(c, req)
    23. if err != nil {
    24. c.JSON(http.StatusInternalServerError, gin.H{
    25. "error": err.Error(),
    26. })
    27. return
    28. }
    29. c.JSON(http.StatusOK, gin.H{
    30. "result": fmt.Sprint(res.Answer),
    31. })
    32. })
    33. // Run http server
    34. if err := r.Run(":8052"); err != nil {
    35. log.Fatalf("could not run server: %v", err)
    36. }
    37. }

    在这里插入图片描述

    文件代码地址

    文件代码在我的git上,测试可以通过,大家可以fetch下来使用,里头的不同分支是不同的服务
    https://github.com/zxhjames/grpc_demo

  • 相关阅读:
    MyBatis详解
    Java异步实现的N种方式
    Java学习笔记——字符串
    Keep-Alive中通过component多次加载同样的动态组件无法保持状态的解决办法
    设计模式与应用:组合模式
    iOS小技能:设置app语言(跟随系统和特定语言)
    深入浅出带你了解PHAR反序列化
    倍福使用AdsRemote组件实现和C#的ADS通讯
    沉睡者:你会的套路我都会,只是我不对你用而已。
    必看知识点:Redis 中的原子操作(1)-Redis 中命令的原子性
  • 原文地址:https://blog.csdn.net/waysoflife/article/details/133930409