rpc中客户端的连接池的设计

为什么需要连接池?      
     连接池是一个创建和管理连接的缓冲池技术,我们知道,client 每次向 server 发起请求都会创建一个连接。一般一个 rpc 请求消耗的时间可能是几百毫秒到几秒,也就是说在一个比较短的时间内,这个连接就会被销毁。假设我们一秒钟需要处理 20w 个请求,假如不使用连接池的话,可能几万十几万的连接在短时间内都会被创建和销毁,这对 cpu 资源是一个很大的消耗,同时因为我们的端口数是 1~65535,除了一些端口被计算机内部占用,每次 client 创建连接都需要分配一个端口,假如并发量过大的话,可能会出现计算机端口不够用的情况。因此为了提高性能和避免端口不够用的情况,需要连接池

 

   客户端可能同时向多个下游调用,因此一个server地址对应一个子连接池,客户端net.dail时先判断poolManager中是否有该地址的子连接池,如果没有则创建一个子连接池pool,如果有则从该子连接池直接get一个链接。
1.整个pool的管理器结构用一个map存储所有的子连接池,key是address
type poolManager struct {
   opts  *Options
   conns *sync.Map
}

2.子连接池结构如下,子连接池管理了本子连接池中所有的连接,所有链接用channel管理

// 子链接池
type pool struct {
   net.Conn                  
   initialCap  int           // initial capacity 连接池中链接的数量
   maxCap      int           // max capacity
   maxIdle     int           // max idle conn number
   idleTimeout time.Duration // idle timeout
   dialTimeout time.Duration // dial timeout
   Dial        func(context.Context) (net.Conn, error)
   conns       chan *PoolConn
   mu          sync.RWMutex
}

3.每个链接的结构如下:

type PoolConn struct {
   net.Conn
   c           *channelPool 
   unusable    bool         // if unusable is true, the conn should be closed
   mu          sync.RWMutex
   t           time.Time     // connection idle time
   dialTimeout time.Duration // connection timeout duration
}

 连接池用于连接的复用,那么连接什么时候关闭?

  1.server关闭连接

   2.连接闲置太久

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以使用多种框架实现RPC客户端和服务端,以下是一些常用的框架: 1. Apache Dubbo:Apache Dubbo是一种高性能、轻量级的Java RPC框架,支持服务治理和多种协议,如Dubbo协议、REST协议等。 2. Spring Cloud:Spring Cloud是一个基于Spring Boot的微服务框架,提供了丰富的服务治理功能,包括服务注册、发现、路由、负载均衡等。 3. gRPC:gRPC是Google开源的高性能、跨语言的RPC框架,使用Protocol Buffers作为序列化协议,支持多种语言,包括Java。 以下是一个使用Java实现RPC客户端和服务端的基本步骤: 1. 定义RPC接口:在服务端和客户端都需要定义一个接口,用于描述RPC的服务。 2. 编写服务端实现:实现RPC接口,并将其注册到RPC框架,以便客户端能够调用。 3. 配置服务端:配置服务端的监听端口、协议等信息。 4. 编写客户端:创建一个RPC客户端对象,使用RPC框架提供的API来调用服务端的方法。 5. 配置客户端:配置客户端的连接信息,如服务端的IP地址、端口号、协议等。 6. 测试:启动服务端和客户端,测试RPC调用是否成功。 以下是一个简单的示例代码: 1. 定义RPC接口 ```java public interface HelloService { public String sayHello(String name); } ``` 2. 编写服务端实现 ```java public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello, " + name; } } ``` 3. 配置服务端 ```java public class Server { public static void main(String[] args) throws Exception { HelloService helloService = new HelloServiceImpl(); Server server = new NettyServer("localhost", 8888); server.registerService(helloService); server.start(); } } ``` 4. 编写客户端 ```java public class Client { public static void main(String[] args) throws Exception { Client client = new NettyClient("localhost", 8888); HelloService helloService = client.getProxy(HelloService.class); String result = helloService.sayHello("world"); System.out.println(result); } } ``` 5. 配置客户端 ```java public class NettyClient implements Client { private final String host; private final int port; private final EventLoopGroup group; public NettyClient(String host, int port) { this.host = host; this.port = port; this.group = new NioEventLoopGroup(); } @Override public <T> T getProxy(Class<T> clazz) { return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new RpcInvocationHandler(host, port, group)); } } ``` 6. 测试 启动服务端和客户端,运行Client的main方法,输出结果为:Hello, world。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值