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

发布时间:2024年01月14日


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服务端程序(详细实现步骤在此忽略,网上很多例子)


  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前缀,如下图所示

dns

部分源码:

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个实例

2

3.3.2 通过headless服务将服务端服务暴露出来

headless

3.3.3 客户端部署一个实例

c

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

code

3.3.4 进入客户端容器命令行进行测试

在这里插入图片描述

3.3.5 分别查看两个客户端接受到的请求流量

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

在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/wcwmsj/article/details/135574264
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。