基于grpc-java开发的普通工程在k8s内部署多实例,如何实现客户端流量的负载均衡

文章目录

    • [1. 前言](#1. 前言)
    • 2.实现方案要点
    • 3.具体实现步骤
      • [3.1 编写一个grpc服务端程序(详细实现步骤在此忽略,网上很多例子)](#3.1 编写一个grpc服务端程序(详细实现步骤在此忽略,网上很多例子))
      • [3.2 编写grpc客户端程序,注意指定负载均衡策略和dns:///这个URI前缀,如下图所示](#3.2 编写grpc客户端程序,注意指定负载均衡策略和dns:///这个URI前缀,如下图所示)
      • [3.3 在k8s中部署服务端和客户端](#3.3 在k8s中部署服务端和客户端)
        • [3.3.1 服务端部署2个实例](#3.3.1 服务端部署2个实例)
        • [3.3.2 通过headless服务将服务端服务暴露出来](#3.3.2 通过headless服务将服务端服务暴露出来)
      • [3.3.3 客户端部署一个实例](#3.3.3 客户端部署一个实例)
        • [3.3.4 进入客户端容器命令行进行测试](#3.3.4 进入客户端容器命令行进行测试)
        • [3.3.5 分别查看两个客户端接受到的请求流量](#3.3.5 分别查看两个客户端接受到的请求流量)

1. 前言

本文主要讨论通过grpc-java开发的普通的java grpc工程,以多实例的方式部署在容器编排平台kubernetes(以下简称k8s)上,如何能够实现让同样部署在k8s

集群内的客户端请求流量均衡的分发到多个grpc应用部署实例上去。

2.实现方案要点

  • grpc服务端程序在k8s内部署的多个实例通过headless service暴露服务
  • grpc客户端程序显示指定负载均衡策略为round_robin
  • grpc客户端程序在创建channel时显示在service名称前加上dns:///(比如 dns:///service.ns)
  • grpc-java的版本要不低于1.38

3.具体实现步骤

3.1 编写一个grpc服务端程序(详细实现步骤在此忽略,网上很多例子)

text 复制代码
  package com.example.grpcserver;
  
  import io.grpc.Server;
  import io.grpc.ServerBuilder;
  import java.io.IOException;
  public class ProductInfoServer {
  Server server;
  
      public static void main(String[] args) {
          ProductInfoServer productInfoServer = new ProductInfoServer();
          productInfoServer.startServer();
          productInfoServer.blockUntilShutdown();
      }
  
      private void startServer(){
  
          int port = 50501;
          try {
              server = ServerBuilder.forPort(port).addService(new ProductInfoImpl()).build().start();
              Runtime.getRuntime().addShutdownHook(new Thread( ()-> {
                  ProductInfoServer.this.stop();
              }));
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
      }
  
      private void stop(){
          if(server != null){
              server.shutdown();
          }
      }
  
      private void blockUntilShutdown(){
          if (server != null){
              try {
                  System.out.println("begin =====server.awaitTermination();");
                  server.awaitTermination();
                  System.out.println("end =====server.awaitTermination();");
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }
          }
  
      }
  
  }

3.2 编写grpc客户端程序,注意指定负载均衡策略和dns:///这个URI前缀,如下图所示

部分源码:

text 复制代码
package com.example.grpccli;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.javaboy.grpc.demo.Product;
import org.javaboy.grpc.demo.ProductId;
import org.javaboy.grpc.demo.ProductInfoGrpc;

public class ProductClient {

    public static void main(String[] args) {
        // 请注意此处是要连接的service暴露的端口
        int port = 50501;
        String serverAddr = "grpc-server-headless-srv.platform";
        String dnsAddr = "dns:///"+serverAddr+":"+port;
        System.out.println("dnsAddr: " + dnsAddr);
        ManagedChannel managedChannel = ManagedChannelBuilder.forTarget("dns:///"+serverAddr+":"+port)
                .defaultLoadBalancingPolicy("round_robin").usePlaintext().build();
        ProductInfoGrpc.ProductInfoBlockingStub stub = ProductInfoGrpc.newBlockingStub(managedChannel);

        // 循环分别创建和查询100次产品
        for(int i=0; i<100; i++){
            Product product = Product.newBuilder().setId("" + i).
                    setName("TH项目-" + i).
                    setPrice(i).
                    setDescription("grpc实战项目-" + i).
                    build();

            // 添加产品
            ProductId id = stub.addProduct(product);
            System.out.println("我是增加产品: "+ id.getValue());

            // 查询产品
            Product prd = stub.getProduct(ProductId.newBuilder().setValue("" + i).build());
            System.out.println("我是查询产品:" + prd.toString());
        }


    }

}

3.3 在k8s中部署服务端和客户端

此处直接使用Kubesphere平台进行部署

3.3.1 服务端部署2个实例
3.3.2 通过headless服务将服务端服务暴露出来

3.3.3 客户端部署一个实例

注意客户端代码此处URI配置为(dns:///service:port)

3.3.4 进入客户端容器命令行进行测试
3.3.5 分别查看两个客户端接受到的请求流量

服务端实例1和服务端实例2各接收到客户端50%的请求流量


相关推荐
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
张忠琳6 小时前
【NVIDIA】 NVIDIA Container Toolkit v1.19.1 — OCI 模块超深度分析之三
云原生·容器·架构·kubernetes·nvidia
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19948 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
Elastic 中国社区官方博客8 小时前
将你的 Grafana Kubernetes 仪表板迁移到 Elastic Observability:相同的 PromQL,30 倍更快的查询
大数据·人工智能·elasticsearch·搜索引擎·容器·kubernetes·grafana
噢,我明白了8 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品9 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库