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,若 ...
随机推荐
- 函数反抖 debounce
debounce :如果在一段延时内又触发了事件,则重新开始延时.即每次触发事件,只触发最近一次的事件. const debounce = (fn, duration) => { let tim ...
- oracle 删除表空间及数据文件方法
oracle 11g版本,创建数据库表空间,默认单个数据文件最大为32G,如果数据文件大于32G,可以增加数据文件. --删除空的表空间,但是不包含物理文件 drop tablespace table ...
- centos7编译安装mysql5.6
先安装如下依赖包: $ yum -y install make gcc-c++ cmake bison-devel ncurses-devel 下载MySQL5.6.14安装包,https://pa ...
- C语言提高 (7) 第七天 回调函数 预处理函数DEBUG 动态链接库
链表就是一个结构体 指针指向自身结构体类型 双向链表插入的时候 先改变自身 再改变两边 双向链表删除的时候 先改变两边 再改变自己 逆序一个单向链表 回调函数 指向函数的指针 4链表的遍历回调用法 / ...
- UVA1585 - Score(紫书习题3.1)
如何计算你们的得分呢?,如"OOXXOXXOOO". "O"表示问题的正确答案,"X"表示错误的答案.那么它得分是由它自己和它刚刚以前连续的 ...
- 判断n是否为质数
#include <iostream> #include <vector> #include <stdio.h> using namespace std; int ...
- 2019-03-28 git github SSH配置,上传下载操作
1.通过git获取scrapy源码,并安装到系统里面 https://git-scm.com/download/win 下载无脑安装啊(C:\Program Files\Git),进入git bash ...
- String与StringBuffer与StringBuilder
package test; public class Test { public static void main(String[] args) { StringBuffer sb = new Str ...
- @Autowired @Resource @Inject 自动注入
一.@AutoWired ( spring 的注解 )自动注入 /** * @Autowired: * 默认按照 Student 类型去容器中找对应的组件:applicationContext.get ...
- linux下sort对中文排序
http://blog.csdn.net/luoleicn/article/details/6162358 设置: export LC_ALL=C;