版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gzy11/article/details/78503015
干货---实现思路:RPC Thrift 服务端 注册服务端信息到zookeeper上。客户端从zookeeper获取服务端信息,并实现负载。
经验---注意事项。
如图:
Thrift 坑:
1)Thrift 二次封装的socket 使用 using (TBufferedTransport transport = new TBufferedTransport(GetTSocket())),会被活生生坑死。IDisposable中为实现close()..
所以必须使用如下代码, transport.Close();是重点
using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
{
try
{
transport.Open();
TProtocol protocol = new TBinaryProtocol(transport);
CityService.Client client = new CityService.Client(protocol);
return func(client);
//return "";
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
return "fales:" + e.Message;
}
finally
{
transport.Close();
}
}
经验:
1)当zookeeper服务器节点信息如有异常服务时,会自动轮询可用RPC Thrift服务。(指无法连接RPC Thrift服务端,代码层面报错不在此范围内。)
2)客户端实现注意去除异常服务器连接,如下代码实现。
/// <summary>
/// 记录error数
/// </summary>
private int errorCount = 0;
/// <summary>
/// 查询(包含保险公司是否可以投保)
/// </summary>
/// <param name="query"></param>
/// <param name="shortEName"></param>
/// <returns></returns>
public string GetQueryCitiesInfo(string query, string shortEName = null)
{
using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
{
try
{
transport.Open();
TProtocol protocol = new TBinaryProtocol(transport);
CityService.Client client = new CityService.Client(protocol);
return client.getQueryCitiesInfo(query, shortEName);
}
catch (Exception e)
{
errorCount++;
Console.WriteLine(e.StackTrace);
if (errorCount >= thriftClient._nodeChildren.Count())
{
Logs.WriteLogInfo("无可用服务!" + e.StackTrace);
errorCount = 0;
return null;
}
return GetQueryCitiesInfo(query, shortEName);
}
finally
{
transport.Close();
}
}
}
public class ClientShort
{
/// <summary>
/// 负载模式--枚举
/// </summary>
internal enum ConnectModel
{
/// <summary>
/// 随机
/// </summary>
Random,
/// <summary>
/// 轮询
/// </summary>
Loadbalance,
}
/// <summary>
/// 获取一个唯一类目的thriftClient(YiXin.BaoXian.Toolkits.Common.Thrift.Clien)
/// </summary>
private static YiXin.BaoXian.Toolkits.Common.Thrift.Client thriftClient = Toolkits.Common.Thrift.Client.GetSingleInstance("YinXin.BaoXian.RegionCityRPC");
/// <summary>
/// thrift TBufferedTransport()
/// </summary>
private static TBufferedTransport _TBufferedTransport;
/// <summary>
/// 记录error数
/// </summary>
private int errorCount = 0;
/// <summary>
/// thrift tsocket
/// </summary>
private static TSocket _tsocket = null;
/// <summary>
/// 短连接-构造函数
/// </summary>
public ClientShort()
{
thriftClient.Init();
}
#region 测试可删除代码
/// <summary>
/// 委托实验--可删除
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private string UsingTBufferedTransport(Func<CityService.Client, string> func)
{
using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
{
try
{
transport.Open();
TProtocol protocol = new TBinaryProtocol(transport);
CityService.Client client = new CityService.Client(protocol);
return func(client);
//return "";
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
return "fales:" + e.Message;
}
finally
{
transport.Close();
}
}
}
/// <summary>
/// 委托实验可删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
private string UsingTransport<T>(Func<T, string> func) where T : class
{
using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
{
try
{
transport.Open();
TProtocol protocol = new TBinaryProtocol(transport);
CityService.Client client = new CityService.Client(protocol);
T t = client as T;
return func(t);
//return "";
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
return "fales:" + e.Message;
}
finally
{
transport.Close();
}
}
}
/// <summary>
/// 委托实验调用时更简洁,性能会有影响。
/// </summary>
/// <param name="shortEName"></param>
/// <returns></returns>
public string GetCityInfoList1__Test(string shortEName = null)
{
return UsingTransport<CityService.Client>((client) =>
{
return client.getCityInfoList(shortEName);
});
}
/// <summary>
/// 选择负载模式
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private TBufferedTransport GetTBufferedTransport(ConnectModel model)
{
string servers = null;
switch (model)
{
case ConnectModel.Random:
servers = thriftClient.Random();
break;
case ConnectModel.Loadbalance:
servers = thriftClient.Loadbalance();
break;
default:
break;
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + servers);
TBufferedTransport transport = thriftClient.GetTSocket(servers);
try
{
if (!transport.IsOpen)
transport.Open();
}
catch (Exception e)
{
Console.Write("寻找可用客户端");
errorCount++;
if (errorCount >= thriftClient._nodeChildren.Count())
{
Logs.WriteLogInfo("寻找可用客户端" + e.StackTrace);
return null;
}
return GetTBufferedTransport(ConnectModel.Loadbalance);//轮询
}
_TBufferedTransport = transport;
errorCount = 0;
return _TBufferedTransport;
}
#endregion
/// <summary>
/// 查询
/// </summary>
/// <param name="query"></param>
/// <param name="shortEName"></param>
/// <returns></returns>
public string GetQueryCitiesInfo(string query, string shortEName = null)
{
using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
{
try
{
transport.Open();
TProtocol protocol = new TBinaryProtocol(transport);
CityService.Client client = new CityService.Client(protocol);
return client.getQueryCitiesInfo(query, shortEName);
}
catch (Exception e)
{
errorCount++;
Console.WriteLine(e.StackTrace);
if (errorCount >= thriftClient._nodeChildren.Count())
{
Logs.WriteLogInfo("无可用服务!" + e.StackTrace);
errorCount = 0;
return null;
}
return GetQueryCitiesInfo(query, shortEName);
}
finally
{
transport.Close();
}
}
}
}