thrift - C#(CSharp)客户端连接池(ConnectionPool)
var tran = ThriftPool.Instance().BorrowInstance();
TProtocol protocol = new TBinaryProtocol(tran);
var client = new xxxx(protocol); //xxxx为生成的thrift代理类的Client对象
var ret = client.TestMethod(parameters); //TestMethod为业务方法名称
ThriftPool.Instance().ReturnInstance(tran);
return ret;
internal class ThriftConfig
{
#region 单例入口 private static ThriftConfig instance = null;
private static object objLock = new object();
public static ThriftConfig Instance()
{
if (instance == null)
{
lock (objLock)
{
if (instance == null)
{
instance = new ThriftConfig();
}
}
}
return instance;
} #endregion #region 私有构造函数 private ThriftConfig()
{
Host = ConfigHelper.GetAppSettingValue("ESHost");
Port = ConfigHelper.GetAppSettingInt32Value("ESPort");
Encode = Encoding.UTF8;
Timeout = 3000;
MaxActive = ConfigHelper.GetAppSettingInt32Value("ESMaxActiveConnectionCount");
MaxIdle = ConfigHelper.GetAppSettingInt32Value("ESMaxIdleConnectionCount");
MinIdle = ConfigHelper.GetAppSettingInt32Value("ESMinIdleConnectionCount");
MaxWait = 5;
} #endregion #region 配置属性定义 public string Host { get; set; } public int Port { get; set; } public Encoding Encode { get; set; } public bool Zipped { get; set; } public int Timeout { get; set; } public int MaxActive { get; set; } public int MaxIdle { get; set; } public int MinIdle { get; set; } public int MaxWait { get; set; }
#endregion }
internal class ThriftPool
{
#region 属性 private ThriftConfig config; /// 对象缓存池
private static Stack<TTransport> objectPool { get; set; }
/// 同步对象
private static AutoResetEvent resetEvent; /// 空闲对象数
private static volatile int idleCount = 0; private static volatile int activeCount = 0; /// 同步对象锁
private static object locker = new object(); #endregion #region 单例入口 private static long testcount = 0;
private static ThriftPool instance = null;
private static object objLock = new object();
public static ThriftPool Instance()
{
if (instance == null)
{
lock (objLock)
{
if (instance == null)
{
instance = new ThriftPool();
}
}
}
return instance;
} #endregion #region 构造函数 private ThriftPool()
{
config = ThriftConfig.Instance();
CreateResetEvent();
CreateThriftPool();
} #endregion #region 公有操作方法 /// 从对象池取出一个对象
public TTransport BorrowInstance()
{
lock (locker)
{
//Zkx.Infrastruction.Logger.Log.DebugFormat("借前对象池个数:{0},空闲个数:{1}", objectPool.Count(), idleCount);
TTransport transport;
//对象池无空闲对象 if (idleCount == 0)
{
//对象池已已创建对象数达上限
if (activeCount >= config.MaxActive)
{
//Console.WriteLine("waiting..." + activeCount);
resetEvent.WaitOne();
}
else
{
PushObject(CreateInstance());
}
}
transport = objectPool.Pop();
//Console.WriteLine("Pop 对象..." + transport.IsOpen); //空闲对象数小于最小空闲数,添加一个对象到对象池(已创建数不能超标)
if (--idleCount < config.MinIdle && activeCount < config.MaxActive)
{
PushObject(CreateInstance());
} ValidateInstance(transport);
//Console.WriteLine("借出......对象池个数:{0},空闲个数:{1}," + testcount, objectPool.Count(), idleCount);
return transport;
}
} /// 归还一个对象
/// <param name="instance"></param>
public void ReturnInstance(TTransport instance)
{
lock (locker)
{
// Console.WriteLine("Push 对象..." + instance.IsOpen); //空闲对象数达到上限,不再返回线程池,直接销毁
if (idleCount == config.MaxIdle)
{
DestoryInstance(instance);
}
else
{
ValidateInstance(instance);
PushObject(instance);
//发通知信号,有对象归还到对象池
resetEvent.Set();
//Console.WriteLine("归还...");
}
}
}
#endregion #region 私有方法 /// 创建线程同步对象
private void CreateResetEvent()
{
lock (locker)
{
if (resetEvent == null)
{
resetEvent = new AutoResetEvent(false);
}
}
} /// 创建对象池
private void CreateThriftPool()
{
lock (locker)
{
if (objectPool == null)
{
objectPool = new Stack<TTransport>();
}
}
} /// 添加对象到对象池
private void PushObject(TTransport transport)
{
objectPool.Push(transport);
idleCount++;
} /// 创建一个对象
private TTransport CreateInstance()
{
activeCount++;
var objsocket = new TSocket(config.Host, config.Port);
objsocket.Timeout = 5000;
TTransport transport = objsocket; transport.Open();
//Console.WriteLine("创建对象..." + activeCount);
return transport;
} /// 校验对象
private void ValidateInstance(TTransport instance)
{
if (!instance.IsOpen)
{
//Console.WriteLine("校验_重新打开...");
instance.Open();
}
} /// 销毁对象
private void DestoryInstance(TTransport instance)
{
if (instance.IsOpen)
{
instance.Close();
}
//instance.Flush();
instance.Dispose();
activeCount--;
//Console.WriteLine("销毁...");
} #endregion
}
thrift - C#(CSharp)客户端连接池(ConnectionPool)的更多相关文章
- 由浅入深了解Thrift之客户端连接池化续
前文<由浅入深了解Thrift之客户端连接池化>中我们已经实现了服务调用端 连接的池化,实现的过于简陋,离实际的项目运用还很遥远.本文将在进一步改造,主要是两方面:1.服务端如何注册多个服 ...
- Redis客户端连接池
使用场景 对于一些大对象,或者初始化过程较长的可复用的对象,我们如果每次都new对象出来,那么意味着会耗费大量的时间. 我们可以将这些对象缓存起来,当接口调用完毕后,不是销毁对象,当下次使用的时候,直 ...
- 由浅入深了解Thrift之客户端连接池化
一.问题描述 在上一篇<由浅入深了解Thrift之服务模型和序列化机制>文章中,我们已经了解了thrift的基本架构和网络服务模型的优缺点.如今的互联网圈中,RPC服务化的思想如火如荼.我 ...
- Swoole2.0协程客户端连接池的实现
Swoole2.0官方默认的实例是短连接的,在请求处理完毕后就会切断redis或mysql的连接.实际项目可以使用连接池实现复用. 实现原理也很简单,使用SplQueue,在请求到来时判断资源队列中是 ...
- redis客户端连接异常
本文参考:http://mdba.cn/2015/04/02/redistwemproxy-%e5%ae%a2%e6%88%b7%e7%ab%af%e8%bf%9e%e6%8e%a5%e5%bc%82 ...
- [20171106]配置客户端连接注意.txt
[20171106]配置客户端连接注意.txt --//在配置客户端连接时一般建议使用Net Manager工具,windows下调用执行Net Manager.--//linux下执行 netmgr ...
- QTcpServer实现多客户端连接
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QTcpServer实现多客户端连接 本文地址:https://www.techiel ...
- 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式
Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...
- 高版本->低版本迁移,低版本客户端连接高版本数据库EXP导出报错EXP-00008,ORA-01455,EXP-00000
生产环境: 源数据库:RHEL + Oracle 11.2.0.3 目标数据库:HP-UX + Oracle 10.2.0.4 需求:迁移部分表 11.2.0.3-->10.2.0.4,若 ...
随机推荐
- jQuery访问json文件(一个例子)
保存网址 打开时 点开一个类型 当点开一个类型,其他类型隐藏 回到所有类型 没有错,左下角有个这是什么样子的图标 做到了什么: 1.从json文件中取得网址,并根据访问次数排列,放到前面: 2.就是1 ...
- IIS访问php页面问题,报告404错误
IIS访问php页面出现问题,所有php页面找不到,显示404页面,html页面可以正常访问. 搜索结果: 方案1: 打开WEB服务扩展,把“所有未知ISAPI扩展”设为允许! 方案2: PHP没有完 ...
- matlab学习创建变量定义函数
定义变量a,b,c,计算输出d >> a=-3;b=2;c=5;>> d=(a^2+b)/c;>> d=(a^2+b)/c d = 2.2000 系统默认变量 a ...
- vc++元文件的保存,保存图形,重绘图形
1, CMateFileDC 可以用来多次打开自己的画布,这个元文件包含许多接口的命令 当绘制好之后可以用来播放元文件 首先,创建一个CMateFileDC的元文件对象 然后调用Create原函数,创 ...
- JavaScript 数字字符串比较大小
JavaScript中常用数字字符串比较 1.数字与数字之间直接比较 比较方式依据数学运算,没什么好说的. 2.数字与字符串数字之间直接比较 例如 数字5 与字符串数字'123',这种比较先将数字字符 ...
- HDU 5279 YJC plays Minecraft (分治NTT优化DP)
题目传送门 题目大意:有$n$个小岛,每个小岛上有$a_{i}$个城市,同一个小岛上的城市互相连接形成一个完全图,第$i$个小岛的第$a_{i}$个城市和第$i+1$个小岛的第$1$个城市连接,特别地 ...
- [网络流24题] 太空飞行计划问题 (最大流->最大权闭合图)
洛谷传送门 LOJ传送门 做这道题之前建议先看这篇论文,虽然论文里很多地方用了很多术语,但hbt神犇讲得很明白 这篇题解更加偏向于感性理解 把问题放到二分图上,左侧一列点是实验,权值为$p[i]$,右 ...
- 提高生产力:Web开发基础平台WebCommon的设计和实现
Web开发中,存在着各种各样的重复性的工作.为了提高开发效率,不在当码农,我在思考和实践如何搭建一个Web开发的基础平台. Web开发基础平台的目标和功能 1.提供一套基础的开发环境,整合了常用的框架 ...
- 做支付遇到的HttpClient大坑
前言 HTTPClient大家应该都很熟悉,一个很好的抓网页,刷投票或者刷浏览量的工具.但是还有一项非常重要的功能就是外部接口调用,比如说发起微信支付,支付宝退款接口调用等:最近我们在这个工具上栽了一 ...
- BA-传感器
01.室内温度传感器 壁装,西门子,QAA2061D 1.默认范围:温度0-50℃,湿度0-100% 2.供电方式:24vac 3.穿线方式:4芯屏蔽线 02.风管温度传感器 西门子,QAM2120. ...