Application.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  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. #include <sstream>
  17. #include "util/tc_option.h"
  18. #include "util/tc_common.h"
  19. #include "servant/KeepAliveNodeF.h"
  20. #include "servant/Application.h"
  21. #include "servant/AppProtocol.h"
  22. #include "servant/AdminServant.h"
  23. #include "servant/ServantHandle.h"
  24. #include "servant/BaseF.h"
  25. #include "servant/AppCache.h"
  26. #include "servant/NotifyObserver.h"
  27. #include "servant/AuthLogic.h"
  28. #include "servant/CommunicatorFactory.h"
  29. #include <signal.h>
  30. #if TARGET_PLATFORM_LINUX
  31. #include <sys/resource.h>
  32. #endif
  33. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  34. #include <fcntl.h>
  35. #endif
  36. #if TARS_SSL
  37. #include "util/tc_openssl.h"
  38. #endif
  39. static TC_RollLogger __out__;
  40. #define NOTIFY_AND_WAIT(msg) { \
  41. RemoteNotify::getInstance()->report(msg); \
  42. std::this_thread::sleep_for(std::chrono::milliseconds(20)); \
  43. }
  44. namespace tars
  45. {
  46. std::string ServerConfig::TarsPath; //服务路径
  47. std::string ServerConfig::Application; //应用名称
  48. std::string ServerConfig::ServerName; //服务名称,一个服务名称含一个或多个服务标识
  49. std::string ServerConfig::LocalIp; //本机IP
  50. std::string ServerConfig::BasePath; //应用程序路径,用于保存远程系统配置的本地目录
  51. std::string ServerConfig::DataPath; //应用程序路径,用于本地数据
  52. std::string ServerConfig::Local; //本地套接字
  53. std::string ServerConfig::Node; //本机node地址
  54. std::string ServerConfig::Log; //日志中心地址
  55. std::string ServerConfig::Config; //配置中心地址
  56. std::string ServerConfig::Notify; //信息通知中心
  57. std::string ServerConfig::LogPath; //logpath
  58. int ServerConfig::LogSize; //log大小(字节)
  59. int ServerConfig::LogNum; //log个数()
  60. std::string ServerConfig::LogLevel; //log日志级别
  61. std::string ServerConfig::ConfigFile; //框架配置文件路径
  62. int ServerConfig::ReportFlow = 1; //是否服务端上报所有接口stat流量 0不上报 1上报 (用于非tars协议服务流量统计)
  63. int ServerConfig::IsCheckSet = 1; //是否对按照set规则调用进行合法性检查 0,不检查,1检查
  64. int ServerConfig::OpenCoroutine = 0; //是否启用协程处理方式
  65. size_t ServerConfig::CoroutineMemSize; //协程占用内存空间的最大大小
  66. uint32_t ServerConfig::CoroutineStackSize; //每个协程的栈大小(默认128k)
  67. bool ServerConfig::ManualListen = false; //手工启动监听端口
  68. //bool ServerConfig::MergeNetImp = false; //合并网络和处理线程
  69. int ServerConfig::NetThread = 1; //servernet thread
  70. bool ServerConfig::CloseCout = true;
  71. int ServerConfig::BackPacketLimit = 0;
  72. int ServerConfig::BackPacketMin = 1024;
  73. //int ServerConfig::Pattern = 0;
  74. #if TARS_SSL
  75. std::string ServerConfig::CA;
  76. std::string ServerConfig::Cert;
  77. std::string ServerConfig::Key;
  78. bool ServerConfig::VerifyClient = false;
  79. std::string ServerConfig::Ciphers;
  80. #endif
  81. map<string, string> ServerConfig::Context;
  82. ///////////////////////////////////////////////////////////////////////////////////////////
  83. //TC_Config Application::_conf;
  84. //TC_EpollServerPtr Application::_epollServer = NULL;
  85. CommunicatorPtr Application::_communicator = NULL;
  86. PropertyReportPtr g_pReportRspQueue;
  87. /**上报服务端发送队列大小的间隔时间**/
  88. #define REPORT_SEND_QUEUE_INTERVAL 10
  89. ///////////////////////////////////////////////////////////////////////////////////////////
  90. Application::Application()
  91. {
  92. _servantHelper = std::make_shared<ServantHelperManager>();
  93. _notifyObserver = std::make_shared<NotifyObserver>();
  94. setNotifyObserver(_notifyObserver);
  95. #if TARGET_PLATFORM_WINDOWS
  96. WSADATA wsadata;
  97. WSAStartup(MAKEWORD(2, 2), &wsadata);
  98. #endif
  99. }
  100. Application::~Application()
  101. {
  102. if(_epollServer)
  103. {
  104. _epollServer->terminate();
  105. _epollServer = NULL;
  106. }
  107. #if TARGET_PLATFORM_WINDOWS
  108. WSACleanup();
  109. #endif
  110. }
  111. string Application::getTarsVersion()
  112. {
  113. return TARS_VERSION;
  114. }
  115. CommunicatorPtr& Application::getCommunicator()
  116. {
  117. return _communicator;
  118. }
  119. void reportRspQueue(TC_EpollServer *epollServer)
  120. {
  121. if (!g_pReportRspQueue)
  122. return;
  123. static time_t iLastCheckTime = TNOW;
  124. time_t iNow = TNOW;
  125. if (iNow - iLastCheckTime > REPORT_SEND_QUEUE_INTERVAL)
  126. {
  127. iLastCheckTime = iNow;
  128. const vector<TC_EpollServer::BindAdapterPtr> &adapters = epollServer->getBindAdapters();
  129. size_t n = 0;
  130. for (size_t i = 0; i < adapters.size(); ++i)
  131. {
  132. n = n + adapters[i]->getSendBufferSize();
  133. }
  134. g_pReportRspQueue->report((int)n);
  135. }
  136. }
  137. void heartBeatFunc(const string& adapterName)
  138. {
  139. TARS_KEEPALIVE(adapterName);
  140. }
  141. void Application::manualListen()
  142. {
  143. vector<TC_EpollServer::BindAdapterPtr> v = getEpollServer()->getBindAdapters();
  144. for(auto &b : v)
  145. {
  146. b->manualListen();
  147. }
  148. }
  149. void Application::waitForShutdown()
  150. {
  151. assert(_epollServer);
  152. _epollServer->setCallbackFunctor(reportRspQueue);
  153. _epollServer->setHeartBeatFunctor(heartBeatFunc);
  154. _epollServer->setDestroyAppFunctor([&](TC_EpollServer *epollServer){
  155. this->destroyApp();
  156. NOTIFY_AND_WAIT("stop");
  157. });
  158. _epollServer->waitForShutdown();
  159. TC_Port::unregisterCtrlC(_ctrlCId);
  160. TC_Port::unregisterTerm(_termId);
  161. _epollServer = NULL;
  162. }
  163. void Application::waitForReady()
  164. {
  165. if(_epollServer)
  166. {
  167. _epollServer->waitForReady();
  168. }
  169. }
  170. void Application::terminate()
  171. {
  172. if (_epollServer && !_epollServer->isTerminate())
  173. {
  174. std::this_thread::sleep_for(std::chrono::milliseconds(100)); //稍微休息一下, 让当前处理包能够回复
  175. _epollServer->terminate();
  176. }
  177. }
  178. bool Application::cmdViewStatus(const string& command, const string& params, string& result)
  179. {
  180. TLOGTARS("Application::cmdViewStatus:" << command << " " << params << endl);
  181. ostringstream os;
  182. os << OUT_LINE_LONG << endl;
  183. os << TC_Common::outfill("[proxy config]:") << endl;
  184. outClient(os);
  185. os << OUT_LINE << "\n" << TC_Common::outfill("[server config]:") << endl;
  186. outServer(os);
  187. os << OUT_LINE << endl;
  188. outAllAdapter(os);
  189. result = os.str();
  190. return true;
  191. }
  192. bool Application::cmdCloseCoreDump(const string& command, const string& params, string& result)
  193. {
  194. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  195. struct rlimit tlimit;
  196. int ret = 0;
  197. ostringstream os;
  198. ret = getrlimit(RLIMIT_CORE, &tlimit);
  199. if (ret != 0)
  200. {
  201. TLOGERROR("error: "<<strerror(errno)<<endl);
  202. return false;
  203. }
  204. TLOGDEBUG("before :cur:" << tlimit.rlim_cur << ";max: " << tlimit.rlim_max << endl);
  205. os << (ServerConfig::Application + "." + ServerConfig::ServerName);
  206. os << "|before set:cur:" << tlimit.rlim_cur << ";max: " << tlimit.rlim_max;
  207. string param = TC_Common::lower(TC_Common::trim(params));
  208. bool bClose = (param == "yes") ? true : false;
  209. if (bClose)
  210. {
  211. tlimit.rlim_cur = 0;
  212. }
  213. else
  214. {
  215. tlimit.rlim_cur = tlimit.rlim_max;
  216. }
  217. ret = setrlimit(RLIMIT_CORE, &tlimit);
  218. if (ret != 0)
  219. {
  220. TLOGERROR("error: "<<strerror(errno)<<endl);
  221. return false;
  222. }
  223. ret = getrlimit(RLIMIT_CORE, &tlimit);
  224. if (ret != 0)
  225. {
  226. TLOGERROR("error: "<<strerror(errno)<<endl);
  227. return false;
  228. }
  229. TLOGDEBUG("after cur:" << tlimit.rlim_cur << ";max: " << tlimit.rlim_max << endl);
  230. os << "|after set cur:" << tlimit.rlim_cur << ";max: " << tlimit.rlim_max << endl;
  231. result = os.str();
  232. #else
  233. TLOGDEBUG("windows not support!");
  234. #endif
  235. return true;
  236. }
  237. bool Application::cmdSetLogLevel(const string& command, const string& params, string& result)
  238. {
  239. TLOGTARS("Application::cmdSetLogLevel:" << command << " " << params << endl);
  240. string level = TC_Common::trim(params);
  241. int ret = LocalRollLogger::getInstance()->logger()->setLogLevel(level);
  242. if (ret == 0)
  243. {
  244. ServerConfig::LogLevel = TC_Common::upper(level);
  245. result = "set log level [" + level + "] ok";
  246. AppCache::getInstance()->set("logLevel", level);
  247. }
  248. else
  249. {
  250. result = "set log level [" + level + "] error";
  251. }
  252. return true;
  253. }
  254. bool Application::cmdEnableDayLog(const string& command, const string& params, string& result)
  255. {
  256. TLOGTARS("Application::cmdEnableDayLog:" << command << " " << params << endl);
  257. vector<string> vParams = TC_Common::sepstr<string>(TC_Common::trim(params), "|");
  258. size_t nNum = vParams.size();
  259. if (!(nNum == 2 || nNum == 3))
  260. {
  261. result = "usage: tars.enabledaylog {remote|local}|[logname]|{true|false}";
  262. return false;
  263. }
  264. if((vParams[0] != "local" && vParams[0] != "remote"))
  265. {
  266. result = "usage: tars.enabledaylog {remote|local}|[logname]|{true|false}";
  267. return false;
  268. }
  269. if(nNum == 2 && (vParams[1] != "true" && vParams[1] != "false"))
  270. {
  271. result = "usage: tars.enabledaylog {remote|local}|[logname]|{true|false}";
  272. return false;
  273. }
  274. if(nNum == 3 && (vParams[2] != "true" && vParams[2] != "false"))
  275. {
  276. result = "usage: tars.enabledaylog {remote|local}|[logname]|{true|false}";
  277. return false;
  278. }
  279. bool bEnable = true;
  280. string sFile;
  281. if (nNum == 2)
  282. {
  283. bEnable = (vParams[1] == "true") ? true : false;
  284. sFile = "";
  285. result = "set " + vParams[0] + " " + vParams[1] + " ok";
  286. }
  287. else if (nNum == 3)
  288. {
  289. bEnable = (vParams[2] == "true") ? true : false;
  290. sFile = vParams[1];
  291. result = "set " + vParams[0] + " " + vParams[1] + " " + vParams[2] + " ok";
  292. }
  293. if (vParams[0] == "local")
  294. {
  295. RemoteTimeLogger::getInstance()->enableLocal(sFile, bEnable);
  296. return true;
  297. }
  298. if (vParams[0] == "remote")
  299. {
  300. RemoteTimeLogger::getInstance()->enableRemote(sFile, bEnable);
  301. return true;
  302. }
  303. result = "usage: tars.enabledaylog {remote|local}|[logname]|{true|false}";
  304. return false;
  305. }
  306. bool Application::cmdLoadConfig(const string& command, const string& params, string& result)
  307. {
  308. TLOGTARS("Application::cmdLoadConfig:" << command << " " << params << endl);
  309. string filename = TC_Common::trim(params);
  310. if (RemoteConfig::getInstance()->addConfig(filename, result, false))
  311. {
  312. RemoteNotify::getInstance()->report(result);
  313. return true;
  314. }
  315. RemoteNotify::getInstance()->report(result);
  316. return true;
  317. }
  318. bool Application::cmdConnections(const string& command, const string& params, string& result)
  319. {
  320. TLOGTARS("Application::cmdConnections:" << command << " " << params << endl);
  321. ostringstream os;
  322. os << OUT_LINE_LONG << endl;
  323. auto m = _epollServer->getListenSocketInfo();
  324. for (auto it = m.begin(); it != m.end(); ++it)
  325. {
  326. vector<TC_EpollServer::ConnStatus> v = it->second->getConnStatus();
  327. os << OUT_LINE << "\n" << TC_Common::outfill("[adapter:" + it->second->getName() + "] [connections:" + TC_Common::tostr(v.size()) + "]") << endl;
  328. os << TC_Common::outfill("conn-uid", ' ', 15)
  329. << TC_Common::outfill("ip:port", ' ', 25)
  330. << TC_Common::outfill("last-time", ' ', 25)
  331. << TC_Common::outfill("timeout", ' ', 10)
  332. << TC_Common::outfill("recvBufferSize", ' ', 30)
  333. << TC_Common::outfill("sendBufferSize", ' ', 30)
  334. << endl;
  335. for (size_t i = 0; i < v.size(); i++)
  336. {
  337. os << TC_Common::outfill(TC_Common::tostr<uint32_t>(v[i].uid), ' ', 15)
  338. << TC_Common::outfill(v[i].ip + ":" + TC_Common::tostr(v[i].port), ' ', 25)
  339. << TC_Common::outfill(TC_Common::tm2str(v[i].iLastRefreshTime, "%Y-%m-%d %H:%M:%S"), ' ', 25)
  340. << TC_Common::outfill(TC_Common::tostr(v[i].timeout), ' ', 10)
  341. << TC_Common::outfill(TC_Common::tostr(v[i].recvBufferSize), ' ', 30)
  342. << TC_Common::outfill(TC_Common::tostr(v[i].sendBufferSize), ' ', 30)
  343. << endl;
  344. }
  345. }
  346. os << OUT_LINE_LONG << endl;
  347. result = os.str();
  348. return true;
  349. }
  350. bool Application::cmdViewVersion(const string& command, const string& params, string& result)
  351. {
  352. result = "$" + string(TARS_VERSION) + "$";
  353. return true;
  354. }
  355. bool Application::cmdViewBuildID(const string& command, const string& params, string& result)
  356. {
  357. #define YEARSUF ((__DATE__ [9] - '0') * 10 + (__DATE__ [10] - '0'))
  358. #define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) \
  359. : __DATE__ [2] == 'b' ? 1 \
  360. : __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) \
  361. : __DATE__ [2] == 'y' ? 4 \
  362. : __DATE__ [2] == 'l' ? 6 \
  363. : __DATE__ [2] == 'g' ? 7 \
  364. : __DATE__ [2] == 'p' ? 8 \
  365. : __DATE__ [2] == 't' ? 9 \
  366. : __DATE__ [2] == 'v' ? 10 : 11)
  367. #define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
  368. + (__DATE__ [5] - '0'))
  369. #define TIMEINT ((((((__TIME__[0] - '0') * 10 + (__TIME__[1] - '0')) * 10 \
  370. + (__TIME__[3] - '0')) * 10 + (__TIME__[4] - '0')) * 10 \
  371. + (__TIME__[6] - '0')) * 10 + (__TIME__[7] - '0'))
  372. char buildTime[50] = {0};
  373. sprintf(buildTime, "%d.%02d%02d.%06d", YEARSUF, MONTH + 1, DAY, TIMEINT);
  374. result = "$" + ServerConfig::Application + "." + ServerConfig::ServerName + "-" + string(buildTime) + "$";
  375. return true;
  376. }
  377. bool Application::cmdLoadProperty(const string& command, const string& params, string& result)
  378. {
  379. try
  380. {
  381. TLOGTARS("Application::cmdLoadProperty:" << command << " " << params << endl);
  382. //重新解析配置文件
  383. _conf.parseFile(ServerConfig::ConfigFile);
  384. string sResult = "";
  385. //加载通讯器属性
  386. _communicator->setProperty(_conf);
  387. _communicator->reloadProperty(sResult);
  388. //加载远程对象
  389. ServerConfig::Log = _conf.get("/tars/application/server<log>");
  390. RemoteTimeLogger::getInstance()->setLogInfo(_communicator, ServerConfig::Log, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath,setDivision());
  391. ServerConfig::Config = _conf.get("/tars/application/server<config>");
  392. RemoteConfig::getInstance()->setConfigInfo(_communicator, ServerConfig::Config, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::BasePath,setDivision(), 5);
  393. ServerConfig::Notify = _conf.get("/tars/application/server<notify>");
  394. RemoteNotify::getInstance()->setNotifyInfo(_communicator, ServerConfig::Notify, ServerConfig::Application, ServerConfig::ServerName, setDivision(), ServerConfig::LocalIp);
  395. result = "loaded config items:\r\n" + sResult +
  396. "log=" + ServerConfig::Log + "\r\n" +
  397. "config=" + ServerConfig::Config + "\r\n" +
  398. "notify=" + ServerConfig::Notify + "\r\n";
  399. }
  400. catch (TC_Config_Exception & ex)
  401. {
  402. result = "load config " + ServerConfig::ConfigFile + " error:" + ex.what();
  403. }
  404. catch (exception &ex)
  405. {
  406. result = ex.what();
  407. }
  408. return true;
  409. }
  410. bool Application::cmdViewAdminCommands(const string& command, const string& params, string& result)
  411. {
  412. TLOGTARS("Application::cmdViewAdminCommands:" << command << " " << params << endl);
  413. result = result + _notifyObserver->viewRegisterCommand();
  414. return true;
  415. }
  416. bool Application::cmdSetDyeing(const string& command, const string& params, string& result)
  417. {
  418. vector<string> vDyeingParams = TC_Common::sepstr<string>(params, " ");
  419. if (vDyeingParams.size() == 2 || vDyeingParams.size() == 3)
  420. {
  421. _servantHelper->setDyeing(vDyeingParams[0], vDyeingParams[1], vDyeingParams.size() == 3 ? vDyeingParams[2] : "");
  422. result = "DyeingKey=" + vDyeingParams[0] + "\r\n" +
  423. "DyeingServant=" + vDyeingParams[1] + "\r\n" +
  424. "DyeingInterface=" + (vDyeingParams.size() == 3 ? vDyeingParams[2] : "") + "\r\n";
  425. }
  426. else
  427. {
  428. result = "Invalid parameters.Should be: dyeingKey dyeingServant [dyeingInterface]";
  429. }
  430. return true;
  431. }
  432. bool Application::cmdCloseCout(const string& command, const string& params, string& result)
  433. {
  434. TLOGTARS("Application::cmdCloseCout:" << command << " " << params << endl);
  435. string s = TC_Common::lower(TC_Common::trim(params));
  436. if (s == "yes")
  437. {
  438. AppCache::getInstance()->set("closeCout", "1");
  439. }
  440. else
  441. {
  442. AppCache::getInstance()->set("closeCout", "0");
  443. }
  444. result = "set closeCout [" + s + "] ok";
  445. return true;
  446. }
  447. bool Application::cmdReloadLocator(const string& command, const string& params, string& result)
  448. {
  449. TLOGDEBUG("Application::cmdReloadLocator:" << command << " " << params << endl);
  450. string sPara = TC_Common::lower(TC_Common::trim(params));
  451. bool bSucc(true);
  452. if (sPara == "reload")
  453. {
  454. TLOGDEBUG(__FUNCTION__ << "|" << __LINE__ << "|conf file:" << ServerConfig::ConfigFile << endl);
  455. TC_Config reloadConf;
  456. reloadConf.parseFile(ServerConfig::ConfigFile);
  457. string sLocator = reloadConf.get("/tars/application/client/<locator>", "");
  458. TLOGDEBUG(__FUNCTION__ << "|" << __LINE__ << "|conf file:" << ServerConfig::ConfigFile << "\n"
  459. << "|sLocator:" << sLocator << endl);
  460. if (sLocator.empty())
  461. {
  462. bSucc = false;
  463. result = "locator info is null.";
  464. }
  465. else
  466. {
  467. _communicator->setProperty("locator", sLocator);
  468. _communicator->reloadLocator();
  469. result = sLocator + " set succ.";
  470. }
  471. }
  472. else
  473. {
  474. result = "please input right paras.";
  475. bSucc = false;
  476. }
  477. return bSucc;
  478. }
  479. bool Application::cmdViewResource(const string& command, const string& params, string& result)
  480. {
  481. TLOGDEBUG("Application::cmdViewResource:" << command << " " << params << endl);
  482. ostringstream os;
  483. os << _communicator->getResourcesInfo() << endl;
  484. os << OUT_LINE << endl;
  485. vector<TC_EpollServer::BindAdapterPtr> adapters = _epollServer->getBindAdapters();
  486. for(auto adapter : adapters)
  487. {
  488. outAdapter(os, _servantHelper->getAdapterServant(adapter->getName()), adapter);
  489. os << TC_Common::outfill("recv-buffer-count") << adapter->getRecvBufferSize() << endl;
  490. os << TC_Common::outfill("send-buffer-count") << adapter->getSendBufferSize() << endl;
  491. }
  492. result += os.str();
  493. TLOGDEBUG("Application::cmdViewResource result:" << result << endl);
  494. return true;
  495. }
  496. void Application::outAllAdapter(ostream &os)
  497. {
  498. auto m = _epollServer->getListenSocketInfo();
  499. for (auto it = m.begin(); it != m.end(); ++it)
  500. {
  501. outAdapter(os, _servantHelper->getAdapterServant(it->second->getName()), it->second);
  502. os << OUT_LINE << endl;
  503. }
  504. }
  505. bool Application::addConfig(const string &filename)
  506. {
  507. string result;
  508. if (RemoteConfig::getInstance()->addConfig(filename, result, false))
  509. {
  510. RemoteNotify::getInstance()->report(result);
  511. return true;
  512. }
  513. RemoteNotify::getInstance()->report(result);
  514. return true;
  515. }
  516. bool Application::addAppConfig(const string &filename)
  517. {
  518. string result = "";
  519. // true-只获取应用级别配置
  520. if (RemoteConfig::getInstance()->addConfig(filename, result, true))
  521. {
  522. RemoteNotify::getInstance()->report(result);
  523. return true;
  524. }
  525. RemoteNotify::getInstance()->report(result);
  526. return true;
  527. }
  528. void Application::main(int argc, char *argv[])
  529. {
  530. TC_Option op;
  531. op.decode(argc, argv);
  532. main(op);
  533. }
  534. void Application::main(const TC_Option &option)
  535. {
  536. __out__.modFlag(0xfffff, false);
  537. //直接输出编译的TAF版本
  538. if (option.hasParam("version"))
  539. {
  540. __out__.debug() << "TARS:" << TARS_VERSION << endl;
  541. exit(0);
  542. }
  543. //加载配置文件
  544. ServerConfig::ConfigFile = option.getValue("config");
  545. if (ServerConfig::ConfigFile == "")
  546. {
  547. cerr << "start server with config, for example: exe --config=config.conf" << endl;
  548. exit(-1);
  549. }
  550. string config = TC_File::load2str(ServerConfig::ConfigFile);
  551. __out__.debug() << "config:" << ServerConfig::ConfigFile << endl;
  552. __out__.debug() << "config:" << config << endl;
  553. main(config);
  554. }
  555. void Application::main(const string &config)
  556. {
  557. try
  558. {
  559. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  560. TC_Common::ignorePipe();
  561. #endif
  562. __out__.modFlag(0xFFFF, false);
  563. //解析配置文件
  564. parseConfig(config);
  565. //初始化Proxy部分
  566. initializeClient();
  567. //初始化Server部分
  568. initializeServer();
  569. vector <TC_EpollServer::BindAdapterPtr> adapters;
  570. //绑定对象和端口
  571. bindAdapter(adapters);
  572. stringstream os;
  573. //输出所有adapter
  574. outAllAdapter(os);
  575. __out__.info() << os.str();
  576. __out__.info() << "\n" << TC_Common::outfill("[initialize server] ", '.') << " [Done]" << endl;
  577. __out__.info() << OUT_LINE_LONG << endl;
  578. {
  579. bool initing = true;
  580. std::mutex mtx;
  581. std::condition_variable cond;
  582. std::thread keepActiving([&]
  583. {
  584. do
  585. {
  586. //发送心跳给node, 表示正在启动
  587. TARS_KEEPACTIVING;
  588. //等待initialize初始化完毕
  589. std::unique_lock<std::mutex> lock(mtx);
  590. cond.wait_for(lock, std::chrono::seconds(5), [&](){
  591. return !initing;
  592. });
  593. }while(initing);
  594. });
  595. try
  596. {
  597. //业务应用的初始化
  598. initialize();
  599. {
  600. std::unique_lock<std::mutex> lock(mtx);
  601. initing = false;
  602. cond.notify_all();
  603. }
  604. keepActiving.join();
  605. }
  606. catch (exception & ex)
  607. {
  608. keepActiving.detach();
  609. NOTIFY_AND_WAIT("exit: " + string(ex.what()));
  610. __out__.error() << "[init exception]:" << ex.what() << endl;
  611. exit(-1);
  612. }
  613. }
  614. //动态加载配置文件
  615. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_LOAD_CONFIG, Application::cmdLoadConfig);
  616. //动态设置滚动日志等级
  617. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_SET_LOG_LEVEL, Application::cmdSetLogLevel);
  618. //动态设置按天日志等级
  619. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_SET_DAYLOG_LEVEL, Application::cmdEnableDayLog);
  620. //查看服务状态
  621. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_VIEW_STATUS, Application::cmdViewStatus);
  622. //查看当前链接状态
  623. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CONNECTIONS, Application::cmdConnections);
  624. //查看编译的TARS版本
  625. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_VIEW_VERSION, Application::cmdViewVersion);
  626. //查看服务buildid(编译时间)
  627. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_VIEW_BID, Application::cmdViewBuildID);
  628. //加载配置文件中的属性信息
  629. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_LOAD_PROPERTY, Application::cmdLoadProperty);
  630. //查看服务支持的管理命令
  631. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_VIEW_ADMIN_COMMANDS, Application::cmdViewAdminCommands);
  632. //设置染色信息
  633. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_SET_DYEING, Application::cmdSetDyeing);
  634. //设置服务的core limit
  635. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CLOSE_CORE, Application::cmdCloseCoreDump);
  636. //设置是否标准输出
  637. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CLOSE_COUT, Application::cmdCloseCout);
  638. //设置是否标准输出
  639. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_RELOAD_LOCATOR, Application::cmdReloadLocator);
  640. //设置是否标准输出
  641. TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_RESOURCE, Application::cmdViewResource);
  642. //上报版本
  643. TARS_REPORTVERSION(TARS_VERSION);
  644. //发送心跳给node, 表示启动了
  645. TARS_KEEPALIVE("");
  646. //发送给notify表示服务启动了
  647. RemoteNotify::getInstance()->report("restart");
  648. //ctrl + c能够完美结束服务
  649. _ctrlCId = TC_Port::registerCtrlC([=]{
  650. this->terminate();
  651. #if TARGET_PLATFORM_WINDOWS
  652. ExitProcess(0);
  653. #endif
  654. });
  655. _termId = TC_Port::registerTerm([=]{
  656. this->terminate();
  657. #if TARGET_PLATFORM_WINDOWS
  658. ExitProcess(0);
  659. #endif
  660. });
  661. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  662. if(_conf.get("/tars/application/server<closecout>",AppCache::getInstance()->get("closeCout")) != "0")
  663. {
  664. // 重定向stdin、stdout、stderr
  665. int fd = open("/dev/null", O_RDWR );
  666. if (fd != -1)
  667. {
  668. dup2(fd, 0);
  669. dup2(fd, 1);
  670. dup2(fd, 2);
  671. }
  672. else
  673. {
  674. close(0);
  675. close(1);
  676. close(2);
  677. }
  678. }
  679. #endif
  680. }
  681. catch (exception &ex)
  682. {
  683. __out__.error() << "[Application]:" << ex.what() << endl;
  684. terminate();
  685. NOTIFY_AND_WAIT("exit: " + string(ex.what()));
  686. exit(-1);
  687. }
  688. //初始化完毕后, 日志再修改为异步
  689. LocalRollLogger::getInstance()->sync(false);
  690. }
  691. void Application::parseConfig(const string &config)
  692. {
  693. _conf.parseString(config);
  694. __out__.setLogLevel(_conf.get("/tars/application/server<start_output>", "DEBUG"));
  695. onParseConfig(_conf);
  696. }
  697. TC_EpollServer::BindAdapter::EOrder Application::parseOrder(const string &s)
  698. {
  699. vector<string> vtOrder = TC_Common::sepstr<string>(s, ";, \t", false);
  700. if (vtOrder.size() != 2)
  701. {
  702. cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'." << endl;
  703. exit(0);
  704. }
  705. if ((TC_Common::lower(vtOrder[0]) == "allow") && (TC_Common::lower(vtOrder[1]) == "deny"))
  706. {
  707. return TC_EpollServer::BindAdapter::ALLOW_DENY;
  708. }
  709. if ((TC_Common::lower(vtOrder[0]) == "deny") && (TC_Common::lower(vtOrder[1]) == "allow"))
  710. {
  711. return TC_EpollServer::BindAdapter::DENY_ALLOW;
  712. }
  713. cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'." << endl;
  714. exit(0);
  715. }
  716. void Application::initializeClient()
  717. {
  718. __out__.info() << "\n" << OUT_LINE_LONG << endl;
  719. //初始化通信器
  720. _communicator = CommunicatorFactory::getInstance()->getCommunicator(_conf);
  721. __out__.info() << TC_Common::outfill("[proxy config]:") << endl;
  722. //输出
  723. stringstream os;
  724. outClient(os);
  725. __out__.info() << os.str();
  726. }
  727. void Application::outClient(ostream &os)
  728. {
  729. os << OUT_LINE << "\n" << TC_Common::outfill("[load client]:") << endl;
  730. os << TC_Common::outfill("locator") << _communicator->getProperty("locator") << endl;
  731. os << TC_Common::outfill("sync-invoke-timeout") << _communicator->getProperty("sync-invoke-timeout") << endl;
  732. os << TC_Common::outfill("async-invoke-timeout") << _communicator->getProperty("async-invoke-timeout") << endl;
  733. os << TC_Common::outfill("refresh-endpoint-interval") << _communicator->getProperty("refresh-endpoint-interval") << endl;
  734. os << TC_Common::outfill("stat") << _communicator->getProperty("stat") << endl;
  735. os << TC_Common::outfill("property") << _communicator->getProperty("property") << endl;
  736. os << TC_Common::outfill("report-interval") << _communicator->getProperty("report-interval") << endl;
  737. os << TC_Common::outfill("keep-alive-interval") << _communicator->getProperty("keep-alive-interval") << endl;
  738. // os << TC_Common::outfill("sample-rate") << _communicator->getProperty("sample-rate") << endl;
  739. // os << TC_Common::outfill("max-sample-count") << _communicator->getProperty("max-sample-count") << endl;
  740. os << TC_Common::outfill("netthread") << _communicator->getProperty("netthread") << endl;
  741. os << TC_Common::outfill("asyncthread") << _communicator->getProperty("asyncthread") << endl;
  742. os << TC_Common::outfill("modulename") << _communicator->getProperty("modulename") << endl;
  743. os << TC_Common::outfill("enableset") << _communicator->getProperty("enableset") << endl;
  744. os << TC_Common::outfill("setdivision") << _communicator->getProperty("setdivision") << endl;
  745. }
  746. string Application::toDefault(const string &s, const string &sDefault)
  747. {
  748. if (s.empty())
  749. {
  750. return sDefault;
  751. }
  752. return s;
  753. }
  754. string Application::setDivision()
  755. {
  756. bool bEnableSet = TC_Common::lower(_conf.get("/tars/application<enableset>", "n"))=="y"?true:false;;
  757. string sSetDevision = bEnableSet?_conf.get("/tars/application<setdivision>", ""):"";
  758. return sSetDevision;
  759. }
  760. void Application::addServantProtocol(const string& servant, const TC_NetWorkBuffer::protocol_functor& protocol)
  761. {
  762. string adapterName = _servantHelper->getServantAdapter(servant);
  763. if (adapterName == "")
  764. {
  765. throw runtime_error("addServantProtocol fail, no found adapter for servant:" + servant);
  766. }
  767. getEpollServer()->getBindAdapter(adapterName)->setProtocol(protocol);
  768. }
  769. void Application::addAcceptCallback(const TC_EpollServer::accept_callback_functor& cb)
  770. {
  771. _acceptFuncs.push_back(cb);
  772. }
  773. void Application::onAccept(TC_EpollServer::Connection* cPtr)
  774. {
  775. for (size_t i = 0; i < _acceptFuncs.size(); ++i)
  776. {
  777. _acceptFuncs[i](cPtr);
  778. }
  779. }
  780. //void Application::addServantOnClose(const string& servant, const TC_EpollServer::close_functor& cf)
  781. //{
  782. // string adapterName = _servantHelper->getServantAdapter(servant);
  783. //
  784. // if (adapterName.empty())
  785. // {
  786. // throw runtime_error("setServantOnClose fail, no found adapter for servant:" + servant);
  787. // }
  788. //
  789. // getEpollServer()->getBindAdapter(adapterName)->setOnClose(cf);
  790. //}
  791. void Application::outServer(ostream &os)
  792. {
  793. os << TC_Common::outfill("Application(app)") << ServerConfig::Application << endl;
  794. os << TC_Common::outfill("ServerName(server)") << ServerConfig::ServerName << endl;
  795. os << TC_Common::outfill("BasePath(basepath)") << ServerConfig::BasePath << endl;
  796. os << TC_Common::outfill("DataPath(datapath)") << ServerConfig::DataPath << endl;
  797. os << TC_Common::outfill("LocalIp(localip)") << ServerConfig::LocalIp << endl;
  798. os << TC_Common::outfill("Local(local)") << ServerConfig::Local << endl;
  799. os << TC_Common::outfill("LogPath(logpath)") << ServerConfig::LogPath << endl;
  800. os << TC_Common::outfill("LogSize(logsize)") << ServerConfig::LogSize << endl;
  801. os << TC_Common::outfill("LogNum(lognum)") << ServerConfig::LogNum << endl;
  802. os << TC_Common::outfill("LogLevel(loglevel)") << ServerConfig::LogLevel << endl;
  803. os << TC_Common::outfill("Log(log)") << ServerConfig::Log << endl;
  804. os << TC_Common::outfill("Node(node)") << ServerConfig::Node << endl;
  805. os << TC_Common::outfill("Config(config)") << ServerConfig::Config << endl;
  806. os << TC_Common::outfill("Notify(notify)") << ServerConfig::Notify << endl;
  807. os << TC_Common::outfill("OpenCoroutine(opencoroutine)") << ServerConfig::OpenCoroutine << endl;
  808. os << TC_Common::outfill("CoroutineMemSize(coroutinememsize)") << ServerConfig::CoroutineMemSize << endl;
  809. os << TC_Common::outfill("CoroutineStackSize(coroutinestack)") << ServerConfig::CoroutineStackSize << endl;
  810. os << TC_Common::outfill("CloseCout(closecout)") << ServerConfig::CloseCout << endl;
  811. os << TC_Common::outfill("NetThread(netthread)") << ServerConfig::NetThread << endl;
  812. os << TC_Common::outfill("ManualListen(manuallisten)") << ServerConfig::ManualListen << endl;
  813. // os << TC_Common::outfill("MergeNetImp(mergenetimp)") << ServerConfig::MergeNetImp << endl;
  814. os << TC_Common::outfill("ReportFlow(reportflow)") << ServerConfig::ReportFlow<< endl;
  815. os << TC_Common::outfill("BackPacketLimit(backpacketlimit)") << ServerConfig::BackPacketLimit<< endl;
  816. os << TC_Common::outfill("BackPacketMin(backpacketmin)") << ServerConfig::BackPacketMin<< endl;
  817. #if TARS_SSL
  818. os << TC_Common::outfill("Ca(ca)") << ServerConfig::CA << endl;
  819. os << TC_Common::outfill("Cert(cert)") << ServerConfig::Cert << endl;
  820. os << TC_Common::outfill("Key(key)") << ServerConfig::Key << endl;
  821. os << TC_Common::outfill("VerifyClient(verifyclient)") << ServerConfig::VerifyClient << endl;
  822. os << TC_Common::outfill("Ciphers(ciphers)") << ServerConfig::Ciphers << endl;
  823. #endif
  824. }
  825. void Application::initializeServer()
  826. {
  827. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[server config]:") << endl;
  828. ServerConfig::Application = toDefault(_conf.get("/tars/application/server<app>"), "UNKNOWN");
  829. //缺省采用进程名称
  830. string exe = "";
  831. try
  832. {
  833. exe = TC_File::extractFileName(TC_File::getExePath());
  834. }
  835. catch (TC_File_Exception & ex)
  836. {
  837. //取失败则使用ip代替进程名
  838. exe = _conf.get("/tars/application/server<localip>");
  839. }
  840. ServerConfig::ServerName = toDefault(_conf.get("/tars/application/server<server>"), exe);
  841. #if TARGET_PLATFORM_WINDOWS
  842. ServerConfig::BasePath = TC_File::simplifyDirectory(_conf.get("/tars/application/server<basepath.win>")) + FILE_SEP;
  843. if (ServerConfig::BasePath == FILE_SEP)
  844. {
  845. ServerConfig::BasePath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<basepath>"), ".")) + FILE_SEP;
  846. }
  847. ServerConfig::DataPath = TC_File::simplifyDirectory(_conf.get("/tars/application/server<datapath.win>")) + FILE_SEP;
  848. if(ServerConfig::DataPath == FILE_SEP)
  849. {
  850. ServerConfig::DataPath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<datapath>"), ".")) + FILE_SEP;
  851. }
  852. ServerConfig::LogPath = TC_File::simplifyDirectory(_conf.get("/tars/application/server<logpath.win>")) + FILE_SEP;
  853. if(ServerConfig::LogPath == FILE_SEP)
  854. {
  855. ServerConfig::LogPath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<logpath>"), ".")) + FILE_SEP;
  856. }
  857. #else
  858. ServerConfig::BasePath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<basepath>"), ".")) + FILE_SEP;
  859. ServerConfig::DataPath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<datapath>"), ".")) + FILE_SEP;
  860. ServerConfig::LogPath = TC_File::simplifyDirectory(toDefault(_conf.get("/tars/application/server<logpath>"), ".")) + FILE_SEP;
  861. #endif
  862. ServerConfig::TarsPath = TC_File::simplifyDirectory(ServerConfig::LogPath + FILE_SEP + ".." + FILE_SEP) + FILE_SEP;
  863. ServerConfig::LogSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server<logsize>"), "52428800"), 52428800);
  864. ServerConfig::LogNum = TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<lognum>"), "10"));
  865. ServerConfig::LocalIp = _conf.get("/tars/application/server<localip>");
  866. ServerConfig::Local = _conf.get("/tars/application/server<local>");
  867. ServerConfig::Node = _conf.get("/tars/application/server<node>");
  868. ServerConfig::Log = _conf.get("/tars/application/server<log>");
  869. ServerConfig::Config = _conf.get("/tars/application/server<config>");
  870. ServerConfig::Notify = _conf.get("/tars/application/server<notify>");
  871. ServerConfig::ReportFlow = _conf.get("/tars/application/server<reportflow>")=="0"?0:1;
  872. ServerConfig::IsCheckSet = _conf.get("/tars/application/server<checkset>","1")=="0"?0:1;
  873. ServerConfig::OpenCoroutine = TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<opencoroutine>"), "0"));
  874. ServerConfig::CoroutineMemSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server<coroutinememsize>"), "1G"), 1024*1024*1024);
  875. ServerConfig::CoroutineStackSize= (uint32_t)TC_Common::toSize(toDefault(_conf.get("/tars/application/server<coroutinestack>"), "128K"), 1024*128);
  876. ServerConfig::ManualListen = _conf.get("/tars/application/server<manuallisten>", "0") == "0" ? false : true;
  877. // ServerConfig::MergeNetImp = _conf.get("/tars/application/server<mergenetimp>", "0") == "0" ? false : true;
  878. ServerConfig::NetThread = TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<netthread>"), "1"));
  879. ServerConfig::CloseCout = _conf.get("/tars/application/server<closecout>","1")=="0"?0:1;
  880. ServerConfig::BackPacketLimit = TC_Common::strto<int>(_conf.get("/tars/application/server<backpacketlimit>", TC_Common::tostr(100*1024*1024)));
  881. ServerConfig::BackPacketMin = TC_Common::strto<int>(_conf.get("/tars/application/server<backpacketmin>", "1024"));
  882. ServerConfig::Context["node_name"] = ServerConfig::LocalIp;
  883. #if TARS_SSL
  884. ServerConfig::CA = _conf.get("/tars/application/server<ca>");
  885. ServerConfig::Cert = _conf.get("/tars/application/server<cert>");
  886. ServerConfig::Key = _conf.get("/tars/application/server<key>");
  887. ServerConfig::VerifyClient = _conf.get("/tars/application/server<verifyclient>","0")=="0"?false:true;
  888. ServerConfig::Ciphers = _conf.get("/tars/application/server<ciphers>");
  889. if(!ServerConfig::Cert.empty()) {
  890. _ctx = TC_OpenSSL::newCtx(ServerConfig::CA, ServerConfig::Cert, ServerConfig::Key, ServerConfig::VerifyClient, ServerConfig::Ciphers);
  891. if (!_ctx) {
  892. TLOGERROR("[load server ssl error, ca:" << ServerConfig::CA << endl);
  893. exit(-1);
  894. }
  895. }
  896. #endif
  897. if (ServerConfig::LocalIp.empty())
  898. {
  899. // ServerConfig::LocalIp = "127.0.0.1";
  900. vector<string> v = TC_Socket::getLocalHosts();
  901. ServerConfig::LocalIp = "127.0.0.1";
  902. //获取第一个非127.0.0.1的IP
  903. for(size_t i = 0; i < v.size(); i++)
  904. {
  905. if(v[i] != "127.0.0.1")
  906. {
  907. ServerConfig::LocalIp = v[i];
  908. break;
  909. }
  910. }
  911. }
  912. onServerConfig();
  913. ostringstream os;
  914. //输出信息
  915. outServer(os);
  916. __out__.info() << os.str();
  917. if (ServerConfig::NetThread < 1)
  918. {
  919. ServerConfig::NetThread = 1;
  920. __out__.info() << OUT_LINE << "\nwarning:netThreadNum < 1." << endl;
  921. }
  922. //网络线程的配置数目不能15个
  923. if (ServerConfig::NetThread > 15)
  924. {
  925. ServerConfig::NetThread = 15;
  926. __out__.info() << OUT_LINE << "\nwarning:netThreadNum > 15." << endl;
  927. }
  928. if(ServerConfig::CoroutineMemSize/ServerConfig::CoroutineStackSize <= 0)
  929. {
  930. __out__.error() << OUT_LINE << "\nerror:coroutine paramter error: coroutinememsize/coroutinestack <= 0!." << endl;
  931. exit(-1);
  932. }
  933. _epollServer = new TC_EpollServer();
  934. _epollServer->setThreadNum(ServerConfig::NetThread);
  935. _epollServer->setOpenCoroutine((TC_EpollServer::SERVER_OPEN_COROUTINE)ServerConfig::OpenCoroutine);
  936. _epollServer->setCoroutineStack(ServerConfig::CoroutineMemSize/ServerConfig::CoroutineStackSize, ServerConfig::CoroutineStackSize);
  937. _epollServer->setOnAccept(std::bind(&Application::onAccept, this, std::placeholders::_1));
  938. //初始化服务是否对空链接进行超时检查
  939. // bool bEnable = (_conf.get("/tars/application/server<emptyconcheck>","0")=="1")?true:false;
  940. // _epollServer->enAntiEmptyConnAttack(bEnable);
  941. _epollServer->setEmptyConnTimeout(TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<emptyconntimeout>"), "0")));
  942. ///////////////////////////////////////////////////////////////////////////////////////////////////
  943. //初始化本地文件cache
  944. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set file cache ]") << "OK" << endl;
  945. AppCache::getInstance()->setCacheInfo(ServerConfig::DataPath + ServerConfig::ServerName + ".tarsdat", 0);
  946. ///////////////////////////////////////////////////////////////////////////////////////////////////
  947. //初始化本地Log
  948. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set roll logger] ") << "OK" << endl;
  949. LocalRollLogger::getInstance()->setLogInfo(ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath, ServerConfig::LogSize, ServerConfig::LogNum, _communicator, ServerConfig::Log);
  950. _epollServer->setLocalLogger(LocalRollLogger::getInstance()->logger());
  951. //初始化是日志为同步
  952. LocalRollLogger::getInstance()->sync(true);
  953. //设置日志级别
  954. string level = AppCache::getInstance()->get("logLevel");
  955. if(level.empty())
  956. {
  957. level = _conf.get("/tars/application/server<logLevel>","DEBUG");
  958. }
  959. ServerConfig::LogLevel = TC_Common::upper(level);
  960. LocalRollLogger::getInstance()->logger()->setLogLevel(ServerConfig::LogLevel);
  961. ///////////////////////////////////////////////////////////////////////////////////////////////////
  962. //初始化到LogServer代理
  963. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set time logger] ") << "OK" << endl;
  964. bool bLogStatReport = (_conf.get("/tars/application/server<logstatreport>", "0") == "1") ? true : false;
  965. RemoteTimeLogger::getInstance()->setLogInfo(_communicator, ServerConfig::Log, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath, setDivision(), bLogStatReport);
  966. ///////////////////////////////////////////////////////////////////////////////////////////////////
  967. //初始化到配置中心代理
  968. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set remote config] ") << "OK" << endl;
  969. RemoteConfig::getInstance()->setConfigInfo(_communicator, ServerConfig::Config, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::BasePath,setDivision());
  970. ///////////////////////////////////////////////////////////////////////////////////////////////////
  971. //初始化到信息中心代理
  972. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set remote notify] ") << "OK" << endl;
  973. RemoteNotify::getInstance()->setNotifyInfo(_communicator, ServerConfig::Notify, ServerConfig::Application, ServerConfig::ServerName, setDivision(), ServerConfig::LocalIp);
  974. ///////////////////////////////////////////////////////////////////////////////////////////////////
  975. //初始化到Node的代理
  976. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set node proxy]") << "OK" << endl;
  977. KeepAliveNodeFHelper::getInstance()->setNodeInfo(_communicator, ServerConfig::Node, ServerConfig::Application, ServerConfig::ServerName);
  978. ///////////////////////////////////////////////////////////////////////////////////////////////////
  979. //初始化管理对象
  980. __out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set admin adapter]") << "OK" << endl;
  981. if (!ServerConfig::Local.empty())
  982. {
  983. _servantHelper->addServant<AdminServant>("AdminObj", this);
  984. string adminAdapter = "AdminAdapter";
  985. _servantHelper->setAdapterServant(adminAdapter, "AdminObj");
  986. TC_EpollServer::BindAdapterPtr lsPtr = _epollServer->createBindAdapter<ServantHandle>(adminAdapter, ServerConfig::Local, 1, this);
  987. setAdapter(lsPtr, adminAdapter);
  988. lsPtr->setMaxConns(TC_EpollServer::BindAdapter::DEFAULT_MAX_CONN);
  989. lsPtr->setQueueCapacity(TC_EpollServer::BindAdapter::DEFAULT_QUEUE_CAP);
  990. lsPtr->setQueueTimeout(TC_EpollServer::BindAdapter::DEFAULT_QUEUE_TIMEOUT);
  991. lsPtr->setProtocolName("tars");
  992. lsPtr->setProtocol(AppProtocol::parse);
  993. _epollServer->bind(lsPtr);
  994. }
  995. //队列取平均值
  996. if(!_communicator->getProperty("property").empty())
  997. {
  998. string sRspQueue("");
  999. sRspQueue += ServerConfig::Application;
  1000. sRspQueue += ".";
  1001. sRspQueue += ServerConfig::ServerName;
  1002. sRspQueue += ".sendrspqueue";
  1003. g_pReportRspQueue = _communicator->getStatReport()->createPropertyReport(sRspQueue, PropertyReport::avg());
  1004. }
  1005. TarsTimeLogger::getInstance()->enableLocal(TRACE_LOG_FILENAME, false);
  1006. }
  1007. void Application::setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name)
  1008. {
  1009. // 设置该obj的鉴权账号密码,只要一组就够了
  1010. {
  1011. std::string accKey = _conf.get("/tars/application/server/" + name + "<accesskey>");
  1012. std::string secretKey = _conf.get("/tars/application/server/" + name + "<secretkey>");
  1013. //注意这里必须用weak, 否则adapter最终释放不了!
  1014. weak_ptr<TC_EpollServer::BindAdapter> a = adapter;
  1015. adapter->setAkSkCallback(accKey, secretKey, std::bind(&tars::serverVerifyAuthCallback, std::placeholders::_1, std::placeholders::_2, a, _servantHelper->getAdapterServant(name)));
  1016. }
  1017. #if TARS_SSL
  1018. string cert = _conf.get("/tars/application/server/" + name + "<cert>");
  1019. if (!cert.empty())
  1020. {
  1021. string ca = _conf.get("/tars/application/server/" + name + "<ca>");
  1022. string key = _conf.get("/tars/application/server/" + name + "<key>");
  1023. bool verifyClient =
  1024. _conf.get("/tars/application/server/" + name + "<verifyclient>", "0") == "0" ? false : true;
  1025. string ciphers = _conf.get("/tars/application/server/" + name + "<ciphers>");
  1026. shared_ptr<TC_OpenSSL::CTX> ctx = TC_OpenSSL::newCtx(ca, cert, key, verifyClient, ciphers);
  1027. if (!ctx) {
  1028. TLOGERROR("load server ssl error, cert:" << cert << endl);
  1029. exit(-1);
  1030. }
  1031. adapter->setSSLCtx(ctx);
  1032. }
  1033. else
  1034. {
  1035. adapter->setSSLCtx(_ctx);
  1036. }
  1037. #endif
  1038. }
  1039. void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
  1040. {
  1041. string sPrefix = ServerConfig::Application + "." + ServerConfig::ServerName + ".";
  1042. vector<string> adapterName;
  1043. map<string, ServantHandle*> servantHandles;
  1044. if (_conf.getDomainVector("/tars/application/server", adapterName))
  1045. {
  1046. for (size_t i = 0; i < adapterName.size(); i++)
  1047. {
  1048. string servant = _conf.get("/tars/application/server/" + adapterName[i] + "<servant>");
  1049. checkServantNameValid(servant, sPrefix);
  1050. _servantHelper->setAdapterServant(adapterName[i], servant);
  1051. string sLastPath = "/tars/application/server/" + adapterName[i];
  1052. TC_Endpoint ep;
  1053. ep.parse(_conf[sLastPath + "<endpoint>"]);
  1054. if (ep.getHost() == "localip")
  1055. {
  1056. ep.setHost(ServerConfig::LocalIp);
  1057. }
  1058. TC_EpollServer::BindAdapterPtr bindAdapter = _epollServer->createBindAdapter<ServantHandle>(adapterName[i], _conf[sLastPath + "<endpoint>"], TC_Common::strto<int>(_conf.get(sLastPath + "<threads>", "1")), this);
  1059. //init auth & ssl
  1060. setAdapter(bindAdapter, adapterName[i]);
  1061. bindAdapter->setMaxConns(TC_Common::strto<int>(_conf.get(sLastPath + "<maxconns>", "128")));
  1062. bindAdapter->setOrder(parseOrder(_conf.get(sLastPath + "<order>", "allow,deny")));
  1063. bindAdapter->setAllow(TC_Common::sepstr<string>(_conf[sLastPath + "<allow>"], ";,", false));
  1064. bindAdapter->setDeny(TC_Common::sepstr<string>(_conf.get(sLastPath + "<deny>", ""), ";,", false));
  1065. bindAdapter->setQueueCapacity(TC_Common::strto<int>(_conf.get(sLastPath + "<queuecap>", "1024")));
  1066. bindAdapter->setQueueTimeout(TC_Common::strto<int>(_conf.get(sLastPath + "<queuetimeout>", "10000")));
  1067. bindAdapter->setProtocolName(_conf.get(sLastPath + "<protocol>", "tars"));
  1068. bindAdapter->setBackPacketBuffLimit(ServerConfig::BackPacketLimit);
  1069. bindAdapter->setBackPacketBuffMin(ServerConfig::BackPacketMin);
  1070. if (bindAdapter->isTarsProtocol())
  1071. {
  1072. bindAdapter->setProtocol(AppProtocol::parse);
  1073. }
  1074. //校验ssl正常初始化
  1075. #if TARS_SSL
  1076. if (bindAdapter->getEndpoint().isSSL() && (!(bindAdapter->getSSLCtx())))
  1077. {
  1078. __out__.error() << "load server ssl error, no cert config!" << bindAdapter->getEndpoint().toString() << endl;
  1079. exit(-1);
  1080. }
  1081. #endif
  1082. if(ServerConfig::ManualListen) {
  1083. //手工监听
  1084. bindAdapter->enableManualListen();
  1085. }
  1086. _epollServer->bind(bindAdapter);
  1087. adapters.push_back(bindAdapter);
  1088. //队列取平均值
  1089. if(!_communicator->getProperty("property").empty())
  1090. {
  1091. PropertyReportPtr p;
  1092. p = _communicator->getStatReport()->createPropertyReport(bindAdapter->getName() + ".queue", PropertyReport::avg());
  1093. bindAdapter->_pReportQueue = p.get();
  1094. p = _communicator->getStatReport()->createPropertyReport(bindAdapter->getName() + ".connectRate", PropertyReport::avg());
  1095. bindAdapter->_pReportConRate = p.get();
  1096. p = _communicator->getStatReport()->createPropertyReport(bindAdapter->getName() + ".timeoutNum", PropertyReport::sum());
  1097. bindAdapter->_pReportTimeoutNum = p.get();
  1098. }
  1099. }
  1100. }
  1101. }
  1102. void Application::checkServantNameValid(const string& servant, const string& sPrefix)
  1103. {
  1104. if ((servant.length() <= sPrefix.length()) || (servant.substr(0, sPrefix.length()) != sPrefix))
  1105. {
  1106. ostringstream os;
  1107. os << "Servant '" << servant << "' error: must be start with '" << sPrefix << "'";
  1108. NOTIFY_AND_WAIT("exit: " + string(os.str()));
  1109. __out__.error() << os.str() << endl;
  1110. exit(-1);
  1111. }
  1112. }
  1113. void Application::outAdapter(ostream &os, const string &v, TC_EpollServer::BindAdapterPtr lsPtr)
  1114. {
  1115. os << TC_Common::outfill("name") << lsPtr->getName() << endl;
  1116. os << TC_Common::outfill("servant") << v << endl;
  1117. os << TC_Common::outfill("endpoint") << lsPtr->getEndpoint().toString() << endl;
  1118. os << TC_Common::outfill("maxconns") << lsPtr->getMaxConns() << endl;
  1119. os << TC_Common::outfill("queuecap") << lsPtr->getQueueCapacity() << endl;
  1120. os << TC_Common::outfill("queuetimeout") << lsPtr->getQueueTimeout() << "ms" << endl;
  1121. os << TC_Common::outfill("order") << (lsPtr->getOrder() == TC_EpollServer::BindAdapter::ALLOW_DENY ? "allow,deny" : "deny,allow") << endl;
  1122. os << TC_Common::outfill("allow") << TC_Common::tostr(lsPtr->getAllow()) << endl;
  1123. os << TC_Common::outfill("deny") << TC_Common::tostr(lsPtr->getDeny()) << endl;
  1124. // os << outfill("queuesize") << lsPtr->getRecvBufferSize() << endl;
  1125. os << TC_Common::outfill("connections") << lsPtr->getNowConnection() << endl;
  1126. os << TC_Common::outfill("protocol") << lsPtr->getProtocolName() << endl;
  1127. os << TC_Common::outfill("handlethread") << lsPtr->getHandleNum() << endl;
  1128. }
  1129. //////////////////////////////////////////////////////////////////////////////////////////////////
  1130. }