日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gRPC学习记录(六)--客户端连接池

發布時間:2025/3/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gRPC学习记录(六)--客户端连接池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于客戶端來說建立一個channel是昂貴的,因為創建channel需要連接,但是建立一個stub是很簡單的,就像創建一個普通對象,因此Channel就需要復用,也就是說需要實現一個連接池應用.本文使用commons-pool2來實現連接池應用. 該案例可以當成連接池模板案例.

<!--客戶端連接池--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.4.2</version></dependency>

寫法的封裝類似我的另一篇博文: Redis學習記錄(二)--使用Jedis連接,模仿SpringJdbcTemplate模板類寫法.

首先定義一個回調接口.

public interface WorkCallBack<S> {void callback(S s); }

再者定義一個產生連接池的工廠,需要繼承自BasePooledObjectFactory,其用處是產生連接池中需要的客戶端.

public class HelloWorldFactory extends BasePooledObjectFactory<HelloWorldClientSingle> {private String host = "127.0.0.1";private int port = 50051;@Overridepublic HelloWorldClientSingle create() throws Exception {return new HelloWorldClientSingle(this.host,this.port);}@Overridepublic PooledObject<HelloWorldClientSingle> wrap(HelloWorldClientSingle helloWorldClientSingle) {return new DefaultPooledObject<>(helloWorldClientSingle);}@Overridepublic void destroyObject(PooledObject<HelloWorldClientSingle> p) throws Exception {p.getObject().shutdown();super.destroyObject(p);} }

實現相應的連接池,注意看execute()方法,該方法是一個模板方法,進行從池中獲取客戶端和歸還客戶端給連接池,其主要邏輯都定義在WorkCallBack接口中,也因此從服務端拿回的數據要在其里面處理完畢.

public class HelloWorldClientPool {private static GenericObjectPool<HelloWorldClientSingle> objectPool = null;static {// 連接池的配置GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();// 池中的最大連接數poolConfig.setMaxTotal(8);// 最少的空閑連接數poolConfig.setMinIdle(0);// 最多的空閑連接數poolConfig.setMaxIdle(8);// 當連接池資源耗盡時,調用者最大阻塞的時間,超時時拋出異常 單位:毫秒數poolConfig.setMaxWaitMillis(-1);// 連接池存放池化對象方式,true放在空閑隊列最前面,false放在空閑隊列最后poolConfig.setLifo(true);// 連接空閑的最小時間,達到此值后空閑連接可能會被移除,默認即為30分鐘poolConfig.setMinEvictableIdleTimeMillis(1000L * 60L * 30L);// 連接耗盡時是否阻塞,默認為truepoolConfig.setBlockWhenExhausted(true);// 連接池創建objectPool = new GenericObjectPool<>(new HelloWorldFactory(), poolConfig);}/*** 從連接池獲取對象*/private static HelloWorldClientSingle borrowObject(){try {HelloWorldClientSingle clientSingle = objectPool.borrowObject();System.out.println("總創建線程數"+objectPool.getCreatedCount());return clientSingle;} catch (Exception e) {e.printStackTrace();}//連接池失敗則主動創建return createClient();}/*** 當連接池異常,則主動創建對象*/private static HelloWorldClientSingle createClient(){return new HelloWorldClientSingle("127.0.0.1", 55001);}/*** 執行器* @param workCallBack 主要服務內容*/public static Runnable execute(WorkCallBack<HelloWorldClientSingle> workCallBack){return () -> {HelloWorldClientSingle client = borrowObject();try {workCallBack.callback(client);} finally {/** 將連接對象返回給連接池 */objectPool.returnObject(client);}};}}

對于客戶端來說,因為存根是不能共享的,所以存根要放在調用函數中實例化,不要擔心性能問題,這個操作就是創建一個對象.greeterBlockingStub = GreeterGrpc.newBlockingStub(channel).withCompression("gzip");該代碼從之前的構造函數中移位到了greet中.

public class HelloWorldClientSingle {private final ManagedChannel channel; //一個gRPC信道private GreeterGrpc.GreeterBlockingStub greeterBlockingStub;//阻塞/同步 存根//初始化信道和存根public HelloWorldClientSingle(String host,int port){channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();}public void shutdown() throws InterruptedException {channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);}//客戶端方法public void greet(String name){//需要用到存根時創建,不可復用greeterBlockingStub = GreeterGrpc.newBlockingStub(channel).withCompression("gzip");HelloRequest request = HelloRequest.newBuilder().setName(name).build();HelloReply response;try {response = greeterBlockingStub.sayHello(request);} catch (StatusRuntimeException e) {System.out.println("RPC調用失敗:"+e.getMessage());return;}System.out.println("服務器返回信息:"+response.getMessage());} }

寫一個簡單的測試類

public class HelloWorldClientTest {public static void main(String[] args) {for (int i = 0; i < 100; i++) {new Thread( HelloWorldClientPool.execute(clientSingle -> {clientSingle.greet("world");})).start();}} }

因為我限定的8個客戶端,所以最高也就8個channel再跑了.


Paste_Image.png

參考博文: http://zk-chs.iteye.com/blog/2308730

代碼地址:
https://github.com/nl101531/JavaWEB



作者:此博廢棄_更新在個人博客
鏈接:https://www.jianshu.com/p/267078010c68
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

總結

以上是生活随笔為你收集整理的gRPC学习记录(六)--客户端连接池的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。