Application.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  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_APPLICATION_H
  17. #define __TARS_APPLICATION_H
  18. #include <iostream>
  19. #include <set>
  20. #include <signal.h>
  21. #include <vector>
  22. #include "util/tc_autoptr.h"
  23. #include "util/tc_config.h"
  24. #include "util/tc_option.h"
  25. #include "util/tc_epoll_server.h"
  26. #include "servant/BaseNotify.h"
  27. #include "servant/ServantHelper.h"
  28. #include "servant/ServantHandle.h"
  29. #include "servant/StatReport.h"
  30. #include "Communicator.h"
  31. #include "servant/RemoteLogger.h"
  32. #include "servant/RemoteConfig.h"
  33. #include "servant/RemoteNotify.h"
  34. #include "servant/NotifyObserver.h"
  35. #include "util/tc_openssl.h"
  36. namespace tars
  37. {
  38. #define OUT_LINE (TC_Common::outfill("", '-', 100))
  39. #define OUT_LINE_LONG (TC_Common::outfill("", '=', 100))
  40. #define OUT_LINE_TAB(x) (TC_Common::outfill("", '-', 100 - 4*x))
  41. /**
  42. * 以下定义配置框架支持的命令
  43. */
  44. #define TARS_CMD_LOAD_CONFIG "tars.loadconfig" //从配置中心, 拉取配置下来: tars.loadconfig filename
  45. #define TARS_CMD_SET_LOG_LEVEL "tars.setloglevel" //设置滚动日志的等级: tars.setloglevel [NONE, ERROR, WARN, DEBUG]
  46. #define TARS_CMD_VIEW_STATUS "tars.viewstatus" //查看服务状态
  47. #define TARS_CMD_VIEW_VERSION "tars.viewversion" //查看服务采用TARS的版本
  48. #define TARS_CMD_CONNECTIONS "tars.connection" //查看当前链接情况
  49. #define TARS_CMD_LOAD_PROPERTY "tars.loadproperty" //使配置文件的property信息生效
  50. #define TARS_CMD_VIEW_ADMIN_COMMANDS "tars.help" //帮助查看服务支持的管理命令
  51. #define TARS_CMD_SET_DYEING "tars.setdyeing" //设置染色信息: tars.setdyeing key servant [interface]
  52. #define TARS_CMD_CLOSE_COUT "tars.closecout" //设置是否启关闭cout\cin\cerr: tars.openthreadcontext yes/NO 服务重启才生效
  53. #define TARS_CMD_SET_DAYLOG_LEVEL "tars.enabledaylog" //设置按天日志是否输出: tars.enabledaylog [remote|local]|[logname]|[true|false]
  54. #define TARS_CMD_CLOSE_CORE "tars.closecore" //设置服务的core limit: tars.setlimit [yes|no]
  55. #define TARS_CMD_RELOAD_LOCATOR "tars.reloadlocator" //重新加载locator的配置信息
  56. #define TARS_CMD_RESOURCE "tars.resource" //get resource
  57. #define TARS_CMD_VIEW_BID "tars.bid" //查看服务编译时间,build id
  58. //////////////////////////////////////////////////////////////////////
  59. /**
  60. * 通知信息给notify服务, 展示在页面上
  61. */
  62. //上报普通信息
  63. #define TARS_NOTIFY_NORMAL(info) {RemoteNotify::getInstance()->notify(NOTIFYNORMAL, info);}
  64. //上报警告信息
  65. #define TARS_NOTIFY_WARN(info) {RemoteNotify::getInstance()->notify(NOTIFYWARN, info);}
  66. //上报错误信息
  67. #define TARS_NOTIFY_ERROR(info) {RemoteNotify::getInstance()->notify(NOTIFYERROR, info);}
  68. //发送心跳给node 多个adapter分别上报
  69. #define TARS_KEEPALIVE(adapter) {KeepAliveNodeFHelper::getInstance()->keepAlive(adapter);}
  70. //发送激活信息
  71. #define TARS_KEEPACTIVING {KeepAliveNodeFHelper::getInstance()->keepActiving();}
  72. //发送TARS版本给node
  73. #define TARS_REPORTVERSION(x) {KeepAliveNodeFHelper::getInstance()->reportVersion(TARS_VERSION);}
  74. //////////////////////////////////////////////////////////////////////
  75. /**
  76. * 添加前置的命令处理方法
  77. * 在所有Normal方法之前执行
  78. * 多个前置方法之间顺序不确定
  79. */
  80. #define TARS_ADD_ADMIN_CMD_PREFIX(c,f) \
  81. do { addAdminCommandPrefix(string(c), std::bind(&f, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } while (0);
  82. /**
  83. * 添加Normal命令处理方法
  84. * 在所有前置方法最后执行
  85. * 多个Normal方法之间顺序不确定
  86. */
  87. #define TARS_ADD_ADMIN_CMD_NORMAL(c,f) \
  88. do { addAdminCommandNormal(string(c), std::bind(&f, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } while (0);
  89. //////////////////////////////////////////////////////////////////////
  90. /**
  91. * 服务基本信息
  92. */
  93. struct SVT_DLL_API ServerConfig
  94. {
  95. static std::string TarsPath;
  96. static std::string Application; //应用名称
  97. static std::string ServerName; //服务名称,一个服务名称含一个或多个服务标识
  98. static std::string BasePath; //应用程序路径,用于保存远程系统配置的本地目录
  99. static std::string DataPath; //应用程序数据路径用于保存普通数据文件
  100. static std::string LocalIp; //本机IP
  101. static std::string LogPath; //log路径
  102. static int LogSize; //log大小(字节)
  103. static int LogNum; //log个数()
  104. static std::string LogLevel; //log日志级别
  105. static std::string Local; //本地套接字
  106. static std::string Node; //本机node地址
  107. static std::string Log; //日志中心地址
  108. static std::string Config; //配置中心地址
  109. static std::string Notify; //信息通知中心
  110. static std::string ConfigFile; //框架配置文件路径
  111. static bool CloseCout;
  112. static int ReportFlow; //是否服务端上报所有接口stat流量 0不上报 1上报(用于非tars协议服务流量统计)
  113. static int IsCheckSet; //是否对按照set规则调用进行合法性检查 0,不检查,1检查
  114. static int OpenCoroutine; //是否启用协程处理方式(0~3)
  115. static size_t CoroutineMemSize; //协程占用内存空间的最大大小
  116. static uint32_t CoroutineStackSize; //每个协程的栈大小(默认128k)
  117. static int NetThread; //servernet thread
  118. static bool ManualListen; //是否启用手工端口监听
  119. static int BackPacketLimit; //回包积压检查
  120. static int BackPacketMin; //回包速度检查
  121. static std::string CA;
  122. static std::string Cert;
  123. static std::string Key;
  124. static bool VerifyClient;
  125. static std::string Ciphers;
  126. static map<string, string> Context; //框架内部用, 传递节点名称(以域名形式部署时)
  127. };
  128. class PropertyReport;
  129. //////////////////////////////////////////////////////////////////////
  130. /**
  131. * 服务的基类
  132. */
  133. class Application: public BaseNotify
  134. {
  135. public:
  136. /**
  137. * 应用构造
  138. */
  139. Application();
  140. /**
  141. * 应用析构
  142. */
  143. virtual ~Application();
  144. /**
  145. * 初始化 --config=xxxx
  146. * @param argv
  147. */
  148. void main(int argc, char *argv[]);
  149. /**
  150. * init
  151. * @param option
  152. */
  153. void main(const TC_Option &option);
  154. /**
  155. * config , 实际配置文件的内容(而不是目录)
  156. * @param config
  157. */
  158. void main(const string &config);
  159. /**
  160. * 运行
  161. */
  162. void waitForShutdown();
  163. /**
  164. * 等待服务已经正常运行了
  165. */
  166. void waitForReady();
  167. public:
  168. /**
  169. * 获取配置文件
  170. *
  171. * @return TC_Config&
  172. */
  173. TC_Config &getConfig() { return _conf; }
  174. const TC_Config &getConfig() const { return _conf; }
  175. /**
  176. * 获取通信器
  177. *
  178. * @return CommunicatorPtr&
  179. */
  180. static CommunicatorPtr& getCommunicator();
  181. /**
  182. * 获取服务Server对象
  183. *
  184. * @return TC_EpollServerPtr&
  185. */
  186. TC_EpollServerPtr &getEpollServer() { return _epollServer; }
  187. const TC_EpollServerPtr &getEpollServer() const { return _epollServer; }
  188. /**
  189. * 中止应用
  190. */
  191. void terminate();
  192. /**
  193. * 获取框架的版本
  194. */
  195. static string getTarsVersion();
  196. /**
  197. * 添加Config
  198. * @param filename
  199. */
  200. bool addConfig(const string &filename);
  201. /**
  202. * 添加应用级的Config
  203. * @param filename
  204. */
  205. bool addAppConfig(const string &filename);
  206. /**
  207. * 手工监听所有端口(Admin的端口是提前就监听的)
  208. */
  209. void manualListen();
  210. /**
  211. * 添加Servant
  212. * @param T
  213. * @param id
  214. */
  215. template<typename T>
  216. void addServant(const string &id)
  217. {
  218. _servantHelper->addServant<T>(id, this, true);
  219. }
  220. /**
  221. * 添加Servant
  222. * @param T
  223. * @param id
  224. * @param p, p will pass to T, T must has constructor with p
  225. */
  226. template<typename T, typename P>
  227. void addServantWithParams(const string &id, const P &p)
  228. {
  229. _servantHelper->addServant<T>(id, this, p, true);
  230. }
  231. /**
  232. * get servant helper
  233. * @return
  234. */
  235. const shared_ptr<ServantHelperManager> &getServantHelper() { return _servantHelper; }
  236. /**
  237. * get notify observer
  238. * @return
  239. */
  240. shared_ptr<NotifyObserver> &getNotifyObserver() { return _notifyObserver; }
  241. /**
  242. * 非tars协议server,设置Servant的协议解析器
  243. * @param protocol
  244. * @param servant
  245. */
  246. void addServantProtocol(const string &servant, const TC_NetWorkBuffer::protocol_functor &protocol);
  247. /**
  248. * @desc 添加接收新链接的回调
  249. *
  250. * @param cb
  251. */
  252. void addAcceptCallback(const TC_EpollServer::accept_callback_functor& cb);
  253. protected:
  254. /**
  255. * 初始化, 只会进程调用一次
  256. */
  257. virtual void initialize() = 0;
  258. /**
  259. * 析够, 进程只会调用一次
  260. */
  261. virtual void destroyApp() {};
  262. /**
  263. * 解析服务的网络配置(业务可以在里面变更网络配置)
  264. */
  265. virtual void onParseConfig(TC_Config &conf){};
  266. /**
  267. * 初始化ServerConfig之后, 给app调整自定义配置值的机会
  268. */
  269. virtual void onServerConfig(){};
  270. /**
  271. * 处理加载配置的命令
  272. * 处理完成后继续通知Servant
  273. * @param filename
  274. */
  275. bool cmdLoadConfig(const string &command, const string &params, string &result);
  276. /**
  277. * 设置滚动日志等级
  278. * @param command
  279. * @param params
  280. * @param result
  281. *
  282. * @return bool
  283. */
  284. bool cmdSetLogLevel(const string &command, const string &params, string &result);
  285. /**
  286. * 设置服务的core limit
  287. * @param command
  288. * @param params
  289. * @param result
  290. *
  291. * @return bool
  292. */
  293. bool cmdCloseCoreDump(const string& command, const string& params, string& result);
  294. /**
  295. * 设置按天日志是否生效
  296. * @param command
  297. * @param params [remote|local]|[logname]|[true|false]
  298. * @param result
  299. *
  300. * @return bool
  301. */
  302. bool cmdEnableDayLog(const string &command, const string &params, string &result);
  303. /**
  304. * 查看服务状态
  305. * @param command
  306. * @param params
  307. * @param result
  308. *
  309. * @return bool
  310. */
  311. bool cmdViewStatus(const string &command, const string &params, string &result);
  312. /**
  313. * 查看链接状态
  314. * @param command
  315. * @param params
  316. * @param result
  317. *
  318. * @return bool
  319. */
  320. bool cmdConnections(const string &command, const string &params, string &result);
  321. /**
  322. * 查看编译的版本
  323. * @param command
  324. * @param params
  325. * @param result
  326. *
  327. * @return bool
  328. */
  329. bool cmdViewVersion(const string &command, const string &params, string &result);
  330. /**
  331. * 查看服务的buildid(编译时间)
  332. * @param command
  333. * @param params
  334. * @param result
  335. *
  336. * @return bool
  337. */
  338. bool cmdViewBuildID(const string &command, const string &params, string &result);
  339. /**
  340. * 使配置文件的property信息生效
  341. * @param command
  342. * @param params
  343. * @param result
  344. *
  345. * @return bool
  346. */
  347. bool cmdLoadProperty(const string &command, const string &params, string &result);
  348. /**
  349. *查看服务支持的管理命令
  350. * @param params
  351. * @param result
  352. *
  353. * @return bool
  354. */
  355. bool cmdViewAdminCommands(const string &command, const string &params, string &result);
  356. /**
  357. * 设置染色消息
  358. * @param command
  359. * @param params
  360. * @param result
  361. *
  362. * @return bool
  363. */
  364. bool cmdSetDyeing(const string &command, const string &params, string &result);
  365. /**
  366. * 设置是否关闭stdcout/stderr/stdin 服务重启能才生效
  367. * @param command
  368. * @param params
  369. * @param result
  370. *
  371. * @return bool
  372. */
  373. bool cmdCloseCout(const string& command, const string& params, string& result);
  374. /*
  375. *通过命令动态加载配置文件,获取最新的locator,以方便应对主控便更
  376. * @param command
  377. * @param params
  378. * @param result
  379. */
  380. bool cmdReloadLocator(const string& command, const string& params, string& result);
  381. /*
  382. * view server resource
  383. * @param command
  384. * @param params
  385. * @param result
  386. */
  387. bool cmdViewResource(const string& command, const string& params, string& result);
  388. protected:
  389. /**
  390. * @desc callback when accept new client
  391. *
  392. * @param cPtr
  393. */
  394. void onAccept(TC_EpollServer::Connection* cPtr);
  395. // /**
  396. // *
  397. // *
  398. // * @param command
  399. // * @param params
  400. // * @param result
  401. // *
  402. // * @return bool
  403. // */
  404. // void addServantOnClose(const string& servant, const TC_EpollServer::close_functor& f);
  405. protected:
  406. /**
  407. * 读取基本信息
  408. */
  409. void initializeClient();
  410. /**
  411. * 输出
  412. * @param os
  413. */
  414. void outClient(ostream &os);
  415. /**
  416. * 初始化servant
  417. */
  418. void initializeServer();
  419. /**
  420. * 输出
  421. * @param os
  422. */
  423. void outServer(ostream &os);
  424. /**
  425. * 输出所有的adapter
  426. * @param os
  427. */
  428. void outAllAdapter(ostream &os);
  429. /**
  430. * 输出
  431. * @param os
  432. */
  433. void outAdapter(ostream &os, const string &v, TC_EpollServer::BindAdapterPtr lsPtr);
  434. /**
  435. * 解析配置文件
  436. */
  437. void parseConfig(const string &config);
  438. /**
  439. * 解析ip权限allow deny 次序
  440. */
  441. TC_EpollServer::BindAdapter::EOrder parseOrder(const string &s);
  442. /**
  443. * bind server adapter
  444. */
  445. void bindAdapter(vector<TC_EpollServer::BindAdapterPtr> &adapters);
  446. /**
  447. * set adapter
  448. * @param adapter
  449. * @param name
  450. */
  451. void setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name);
  452. /**
  453. * @param servant
  454. * @param sPrefix
  455. */
  456. void checkServantNameValid(const string &servant, const string &sPrefix);
  457. /**
  458. * 换成缺省值
  459. * @param s
  460. *
  461. * @return string
  462. */
  463. string toDefault(const string &s, const string &sDefault);
  464. /**
  465. * 获取服务的set分组信息,setname.setarea.setgroup
  466. *
  467. * @return string 没有按set分组则返回空""
  468. */
  469. string setDivision(void);
  470. protected:
  471. /**
  472. * config
  473. */
  474. TC_Config _conf;
  475. /**
  476. * epoll server
  477. */
  478. TC_EpollServerPtr _epollServer;
  479. /**
  480. * communicator
  481. */
  482. static CommunicatorPtr _communicator;
  483. /**
  484. * accept
  485. */
  486. std::vector<TC_EpollServer::accept_callback_functor> _acceptFuncs;
  487. /**
  488. * servant helper
  489. */
  490. shared_ptr<ServantHelperManager> _servantHelper;
  491. /**
  492. * notify observer
  493. */
  494. shared_ptr<NotifyObserver> _notifyObserver;
  495. /**
  496. * ssl ctx
  497. */
  498. shared_ptr<TC_OpenSSL::CTX> _ctx = nullptr;
  499. size_t _ctrlCId = -1;
  500. size_t _termId = -1;
  501. PropertyReport * _pReportQueue;
  502. PropertyReport * _pReportConRate;
  503. PropertyReport * _pReportTimeoutNum;
  504. };
  505. ////////////////////////////////////////////////////////////////////
  506. }
  507. #endif