Message.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #ifndef __TARS_MESSAGE_H_
  17. #define __TARS_MESSAGE_H_
  18. #include <util/tc_network_buffer.h>
  19. #include "util/tc_autoptr.h"
  20. #include "util/tc_monitor.h"
  21. #include "util/tc_loop_queue.h"
  22. #include "servant/Global.h"
  23. namespace tars
  24. {
  25. /**
  26. * 超时一定比率后进行切换
  27. * 设置超时检查参数
  28. * 计算到某台服务器的超时率, 如果连续超时次数或者超时比例超过阀值
  29. * 默认60s内, 超时调用次数>=2, 超时比率0.5或者连续超时次数>5,
  30. * 则失效
  31. * 服务失效后, 请求将尽可能的切换到其他可能的服务器, 并每隔tryTimeInterval尝试一次, 如果成功则认为恢复
  32. * 如果其他服务器都失效, 则随机选择一台尝试
  33. * 如果是灰度状态的服务, 服务失效后如果请求切换, 也只会转发到相同灰度状态的服务
  34. * @uint16_t minTimeoutInvoke, 计算的最小的超时次数, 默认2次(在checkTimeoutInterval时间内超过了minTimeoutInvoke, 才计算超时)
  35. * @uint32_t frequenceFailInvoke, 连续失败次数
  36. * @uint32_t checkTimeoutInterval, 统计时间间隔, (默认60s, 不能小于30s)
  37. * @float radio, 超时比例 > 该值则认为超时了 ( 0.1<=radio<=1.0 )
  38. * @uint32_t tryTimeInterval, 重试时间间隔
  39. */
  40. struct CheckTimeoutInfo
  41. {
  42. /*
  43. * 构造函数
  44. */
  45. CheckTimeoutInfo()
  46. : minTimeoutInvoke(2)
  47. , checkTimeoutInterval(60)
  48. , frequenceFailInvoke(2)
  49. , minFrequenceFailTime(5)
  50. , radio(0.5)
  51. , tryTimeInterval(10)
  52. , maxConnectExc(1)
  53. {
  54. }
  55. /*
  56. * 判断超时屏蔽时,计算的最小的超时次数
  57. */
  58. uint16_t minTimeoutInvoke;
  59. /*
  60. * 判断超时屏蔽时,时间间隔
  61. */
  62. uint32_t checkTimeoutInterval;
  63. /*
  64. * 判断因连续失败而进行屏蔽时,连续失败的次数
  65. */
  66. uint32_t frequenceFailInvoke;
  67. /*
  68. * 判断因连续失败而进行屏蔽时,最小的时间间隔
  69. */
  70. uint32_t minFrequenceFailTime;
  71. /*
  72. * 超时的比率
  73. */
  74. float radio;
  75. /*
  76. * 重试间隔
  77. */
  78. uint32_t tryTimeInterval;
  79. /*
  80. * 最大连接异常次数
  81. */
  82. uint32_t maxConnectExc;
  83. };
  84. #define IS_MSG_TYPE(m, t) ((m & t) != 0)
  85. #define SET_MSG_TYPE(m, t) do { (m |= t); } while (0);
  86. #define CLR_MSG_TYPE(m, t) do { (m &=~t); } while (0);
  87. struct ThreadPrivateData
  88. {
  89. /**
  90. * hash属性,客户端每次调用都进行设置
  91. */
  92. bool _hash = false; //是否普通取模hash
  93. bool _conHash = false; //是否一致性hash
  94. int64_t _hashCode = -1; //hash值
  95. /**
  96. * 染色信息
  97. */
  98. bool _dyeing = false; //标识当前线程是否需要染色
  99. string _dyeingKey; //染色的key值
  100. /**
  101. * 允许客户端设置接口级别的超时时间,包括同步和异步、单向
  102. */
  103. int _timeout = 0; //超时时间
  104. /**
  105. * 保存调用后端服务的地址信息
  106. */
  107. string _szHost; //调用对端地址
  108. /**
  109. * cookie
  110. */
  111. map<string, string> _cookie; // cookie内容
  112. };
  113. struct ReqMonitor;
  114. struct ReqMessage : public TC_HandleBase
  115. {
  116. //调用类型
  117. enum CallType
  118. {
  119. SYNC_CALL = 1, //同步
  120. ASYNC_CALL, //异步
  121. ONE_WAY, //单向
  122. // THREAD_EXIT //线程退出的标识
  123. };
  124. //请求状态
  125. enum ReqStatus
  126. {
  127. REQ_REQ = 0, //状态正常,正在请求中
  128. REQ_RSP, //请求已经发出去
  129. REQ_TIME, //请求超时
  130. REQ_EXC //客户端请求异常
  131. };
  132. /*
  133. * 构造函数
  134. */
  135. ReqMessage()
  136. : eStatus(ReqMessage::REQ_REQ)
  137. , eType(SYNC_CALL)
  138. , bFromRpc(false)
  139. , callback(NULL)
  140. , proxy(NULL)
  141. , pObjectProxy(NULL)
  142. , adapter(NULL)
  143. , pMonitor(NULL)
  144. , iBeginTime(TNOWMS)
  145. , iEndTime(0)
  146. , bPush(false)
  147. , sched(NULL)
  148. , iCoroId(0)
  149. {
  150. }
  151. /*
  152. * 析构函数
  153. */
  154. ~ReqMessage();
  155. /*
  156. * 初始化
  157. */
  158. void init(CallType eCallType, ServantProxy *proxy);
  159. ReqStatus eStatus; //调用的状态
  160. CallType eType; //调用类型
  161. bool bFromRpc = false; //是否是第三方协议的rcp_call,缺省为false
  162. RequestPacket request; //请求消息体
  163. shared_ptr<ResponsePacket> response; //响应消息体
  164. shared_ptr<TC_NetWorkBuffer::Buffer> sReqData; //请求消息体
  165. ServantProxyCallbackPtr callback; //异步调用时的回调对象
  166. ServantProxy *proxy = NULL;
  167. ObjectProxy *pObjectProxy = NULL; //调用端的proxy对象
  168. AdapterProxy *adapter = NULL; //调用的adapter
  169. ReqMonitor *pMonitor = NULL; //用于同步的monitor
  170. int64_t iBeginTime = 0; //请求时间
  171. int64_t iEndTime = 0; //完成时间
  172. bool bPush = false; //push back 消息
  173. bool bTraceCall; // 是否需要调用链追踪
  174. string sTraceKey; // 调用链key
  175. shared_ptr<TC_CoroutineScheduler> sched;
  176. int iCoroId = 0;
  177. std::function<void()> deconstructor; //析构时调用
  178. ThreadPrivateData data; //线程数据
  179. };
  180. /**
  181. * 用于同步调用时的条件变量
  182. */
  183. struct ReqMonitor
  184. {
  185. ReqMessage *msg = NULL;
  186. std::mutex mutex;
  187. std::condition_variable cond;
  188. bool bMonitorFin = false; //同步请求timewait是否结束
  189. ReqMonitor(ReqMessage *m) : msg(m) {}
  190. void wait();
  191. void notify();
  192. };
  193. typedef TC_AutoPtr<ReqMessage> ReqMessagePtr;
  194. typedef TC_LoopQueue<ReqMessage *> ReqInfoQueue;
  195. ////////////////////////////////////////////////////////////////////////////////////////////////////
  196. }
  197. #endif