diff --git a/TseerAgent/TseerAgent.conf b/TseerAgent/TseerAgent.conf index 079943b..d4f4b0d 100644 --- a/TseerAgent/TseerAgent.conf +++ b/TseerAgent/TseerAgent.conf @@ -3,8 +3,8 @@ installpath=/usr/local #路由服务中心地址,必填 locator=Tseer.TseerServer.QueryObj@tcp -h 127.0.0.1 -p 9903 - #方便云端路由中心管理的地址,必须是非127.0.0.1 - localip=127.0.0.1 + #方便云端路由中心管理的地址,必须是非127.0.0.1,自动获取,如自动获取失败,手动填写可生效 + #localip=127.0.0.1 #提供给api查询的地址,默认是127.0.0.1 #routerip=127.0.0.1 diff --git a/TseerAgent/src/TseerAgentServer.cpp b/TseerAgent/src/TseerAgentServer.cpp index e017973..f5cd8c0 100644 --- a/TseerAgent/src/TseerAgentServer.cpp +++ b/TseerAgent/src/TseerAgentServer.cpp @@ -343,18 +343,22 @@ int parseConfig(int argc, char *argv[]) } string configFile = ""; - if (Op.hasParam("config")) - { + if (Op.hasParam("config")) { configFile = Op.getValue("config"); - } - else - { + } else { usage(); } + //获取本机配置的 ip (IPV4) + char iface[8]; + char ip[INET_ADDRSTRLEN]; + if (!get_default_if(iface, 8) || !get_ip(iface, ip, INET_ADDRSTRLEN)) { + cerr << FILE_FUN << " get default ip via /proc/net/route failed, using default value instead" << endl; + memset(ip, 0, INET_ADDRSTRLEN); + } + //读取配置文件 - if(!TC_File::isFileExistEx(configFile)) - { + if(!TC_File::isFileExistEx(configFile)) { cerr <", ""); - if(sInstallpatch.empty()) - { + if(sInstallpatch.empty()) { sInstallpatch = g_app.g_installPath; } - else - { - //记录安装路径 - g_app.g_installPath = sInstallpatch; - } + //解析主控地址列表 std::string locator = paramConf.get("/server", ""); - - //主要是要注册到路由中心方便云端管理,所以这里必须是内网ip - std::string innerIp = paramConf.get("/server", ""); - - //默认是绑定本地127.0.0.1,提供给api访问 - std::string routerIp = paramConf.get("/server", "127.0.0.1"); - if (locator.empty()) - { + if (locator.empty()) { cerr<<"you should provide locator"< ipPortlist = TC_Common::sepstr(locator,"|;"); - for (size_t i = 0; i < ipPortlist.size(); i++) - { + for (size_t i = 0; i < ipPortlist.size(); i++) { vector ipPort = TC_Common::sepstr(ipPortlist[i],":"); - if(ipPort.size() < 2) - { + if(ipPort.size() < 2) { cerr<", ip); + + //默认是绑定本地127.0.0.1,提供给api访问 + std::string routerIp = paramConf.get("/server", "127.0.0.1"); + if(routerIp.empty()) { //监听127.0.0.1 routerIp = "127.0.0.1"; } @@ -436,53 +423,54 @@ int parseConfig(int argc, char *argv[]) } } - g_app.g_configFile = confPath + "/."+TSEERAGENT_SERVERNAME + ".conf"; - g_app.g_innerIp = innerIp; - + g_app.g_installPath = sInstallpatch; + g_app.g_configFile = confPath + "/."+TSEERAGENT_SERVERNAME + ".conf"; + g_app.g_innerIp = innerIp; TC_Config newConf; map m; - //server config - m["app"]= TSEERAGENT_APPNAME; - m["server"]= TSEERAGENT_SERVERNAME; string sModuleName = TSEERAGENT_APPNAME + "." + TSEERAGENT_SERVERNAME; - m["localip"]= innerIp; + + //server config + m["app"] = TSEERAGENT_APPNAME; + m["server"] = TSEERAGENT_SERVERNAME; + m["localip"] = innerIp; // #服务的可执行文件 - m["basepath"]= TC_File::simplifyDirectory(sInstallpatch + "/"+TSEERAGENT_APPNAME+ "/" + TSEERAGENT_SERVERNAME+"/bin/"); + m["basepath"] = TC_File::simplifyDirectory(sInstallpatch + "/"+TSEERAGENT_APPNAME+ "/" + TSEERAGENT_SERVERNAME+"/bin/"); //服务的数据目录 - m["datapath"]= TC_File::simplifyDirectory(sInstallpatch + "/" + TSEERAGENT_APPNAME + "/" + TSEERAGENT_SERVERNAME+"/data"); - m["logpath"]= TC_File::simplifyDirectory(sInstallpatch + "/" + TSEERAGENT_APPNAME + "/" + TSEERAGENT_SERVERNAME +"/app_log"); - m["logLevel"]= "DEBUG"; + m["datapath"] = TC_File::simplifyDirectory(sInstallpatch + "/" + TSEERAGENT_APPNAME + "/" + TSEERAGENT_SERVERNAME+"/data"); + m["logpath"] = TC_File::simplifyDirectory(sInstallpatch + "/" + TSEERAGENT_APPNAME + "/" + TSEERAGENT_SERVERNAME +"/app_log"); + m["logLevel"] = paramConf.get("/server", "DEBUG"); //滚动日志大小和个数 - m["logsize"]= TC_Common::tostr(1024*1024*15); + m["logsize"] = TC_Common::tostr(1024*1024*15); m["closecout"] = "1"; newConf.insertDomainParam( "/tars/application/server", m, true); //servant config m.clear(); - m["endpoint"]= "udp -h " + routerIp +" -p 8865 -t 60000"; - m["maxconns"]= "10000"; - m["threads"]= "8"; - m["queuecap"]= "10000"; + m["endpoint"] = "udp -h " + routerIp +" -p 8865 -t 60000"; + m["maxconns"] = "10000"; + m["threads"] = "8"; + m["queuecap"] = "10000"; m["protocol"] = "tars"; m["queuetimeout"] = "60000"; - m["servant"] = sModuleName + ".RouterObj"; - m["allow"] = ""; + m["servant"] = sModuleName + ".RouterObj"; + m["allow"] = ""; m["handlegroup"] = "RouterObjAdapter"; newConf.insertDomainParam( "/tars/application/server/RouterObjAdapter", m, true); if(!g_app.g_innerIp.empty()) { m.clear(); - m["endpoint"]= "tcp -h " + g_app.g_innerIp +" -p 9765 -t 60000"; - m["maxconns"]= "10000"; - m["threads"]= "5"; - m["queuecap"]= "10000"; + m["endpoint"] = "tcp -h " + g_app.g_innerIp +" -p 9765 -t 60000"; + m["maxconns"] = "10000"; + m["threads"] = "5"; + m["queuecap"] = "10000"; m["protocol"] = "tars"; m["queuetimeout"] = "60000"; - m["servant"] = sModuleName + ".UpdateObj"; - m["allow"] = ""; + m["servant"] = sModuleName + ".UpdateObj"; + m["allow"] = ""; m["handlegroup"] = "UpdateObjAdapter"; newConf.insertDomainParam( "/tars/application/server/UpdateObjAdapter", m, true); } diff --git a/TseerAgent/src/util.h b/TseerAgent/src/util.h index ca87f32..a69dabb 100644 --- a/TseerAgent/src/util.h +++ b/TseerAgent/src/util.h @@ -1,25 +1,29 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + #ifndef _UTIL_H #define _UTIL_H +#include +#include +#include #include "util/tc_common.h" #include "RollLogger.h" + inline bool popen_sendMsg(const string& sCommand) { FILE *fp; @@ -47,5 +51,46 @@ inline string display(const T& t) t.displaySimple(stream); return(stream.str()); } -#endif +// get default network interface +inline bool get_default_if(char *iface, int size) { + if (size < 8) return false; + memset(iface, 0, size); + + FILE *f = fopen("/proc/net/route", "r"); + if (!f) return false; + + char dest[64] = {0, }; + while (!feof(f)) { + if (fscanf(f, "%s %s %*[^\r\n]%*c", iface, dest) != 2) continue; + if (strcmp(dest, "00000000") == 0) { + break; + } + } + + return strlen(iface) ? true : false; +} + +// get eth0's ipv4 address +inline bool get_ip(const char *iface, char* ip, int size) { + if (size < INET_ADDRSTRLEN) return false; + memset(ip, 0, size); + + struct ifaddrs * ifAddrStruct = NULL; + struct ifaddrs * ifa = NULL; + void * tmpAddrPtr = NULL; + + getifaddrs(&ifAddrStruct); + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if ((ifa->ifa_addr->sa_family == AF_INET) && (strcmp(ifa->ifa_name,iface) == 0)) { + tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + inet_ntop(AF_INET, tmpAddrPtr, ip, INET_ADDRSTRLEN); + } + } + + if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); + + return strlen(ip) ? true : false; +} + +#endif \ No newline at end of file diff --git a/TseerServer/TseerServer.conf b/TseerServer/TseerServer.conf index bcede65..f3b8414 100644 --- a/TseerServer/TseerServer.conf +++ b/TseerServer/TseerServer.conf @@ -1,8 +1,8 @@ #服务安装路径,默认是/usr/local,必填 installpath=/home/louishuang/onlineseer/seer/mytest - #服务绑定本机地址,必填 - localip=127.0.0.1 + #服务绑定本机地址,自动获取,如失败,手动填写可生效 + #localip=127.0.0.1 #服务日志等级,默认是DEBUG logLevel=DEBUG #服务默认的存储方式可选:etcd/mysql,默认是etcd diff --git a/TseerServer/src/TSeerServer.cpp b/TseerServer/src/TSeerServer.cpp index fb41b75..7385c97 100644 --- a/TseerServer/src/TSeerServer.cpp +++ b/TseerServer/src/TSeerServer.cpp @@ -264,6 +264,14 @@ int parseConfig(int argc, char *argv[]) useAge(); } + //获取本机配置的 ip (IPV4) + char iface[8]; + char ip[INET_ADDRSTRLEN]; + if (!get_default_if(iface, 8) || !get_ip(iface, ip, INET_ADDRSTRLEN)) { + cerr << FILE_FUN << " get default ip via /proc/net/route failed, using 127.0.0.1 instead" << endl; + strcpy(ip, "127.0.0.1"); + } + //读取配置文件 if(!TC_File::isFileExistEx(configFile)) { @@ -297,7 +305,7 @@ int parseConfig(int argc, char *argv[]) #endif } - string sInnerIp = conf.get("/server", "127.0.0.1"); + string sInnerIp = conf.get("/server", ip); string regPort = conf.get("/server", "9902"); string queryPort = conf.get("/server", "9903"); string apiPort = conf.get("/server", "9904"); diff --git a/TseerServer/src/util.h b/TseerServer/src/util.h index 078a9b6..df655ab 100644 --- a/TseerServer/src/util.h +++ b/TseerServer/src/util.h @@ -2,13 +2,13 @@ * Tencent is pleased to support the open source community by making Tseer available. * * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * + * * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at - * + * * https://opensource.org/licenses/BSD-3-Clause * - * Unless required by applicable law or agreed to in writing, software distributed + * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include "util/tc_common.h" #include "servant/TarsLogger.h" #include "reg_roll_logger.h" @@ -70,7 +73,7 @@ using namespace Tseer; url += key;\ url += "=";\ url += value;\ -}while(0) +}while(0) #define CHECK_SETVALUE(key) if (jData.HasMember(#key) && jData[#key].IsString())\ {\ @@ -82,7 +85,7 @@ using namespace Tseer; ret = API_INVALID_PARAM;\ break;\ } - + #define CHECK_SETKEYVALUE(key, value) if (jData.HasMember(key) && jData[key].IsString())\ {\ value = jData[key].GetString();\ @@ -93,7 +96,7 @@ using namespace Tseer; ret = API_INVALID_PARAM;\ break;\ } - + //用于遍历数据Json #define EXIST_GETVALUE_A(rvalue,key) do{\ @@ -181,7 +184,7 @@ namespace tars { return(TC_Common::tostr(t.begin(), t.end(), ",")); } - + template <> inline string TC_Common::tostr(const set&t) { @@ -243,21 +246,21 @@ inline bool needUpdate(const string& oldVer, const string& newVer,Compare f) */ vector oldVerList = TC_Common::sepstr(oldVer, "."); vector newVerList = TC_Common::sepstr(newVer, "."); - + if(oldVerList.size() != 2 || newVerList.size() != 2) { return false; } - + string masterOldVer = oldVerList[0].substr(1, oldVerList[0].length() - 1); string masterNewVer = newVerList[0].substr(1, newVerList[0].length() - 1); - + if(!TC_Common::isdigit(masterOldVer) || !TC_Common::isdigit(oldVerList[1]) || !TC_Common::isdigit(masterNewVer) || !TC_Common::isdigit(newVerList[1])) { return false; } - + int masterOldV = TC_Common::strto(masterOldVer); int masterNewV = TC_Common::strto(masterNewVer); if(masterOldV == masterNewV) @@ -282,5 +285,45 @@ inline bool needUpdate(const string& oldVer, const string& newVer,Compare f) } -#endif +// get default network interface +inline bool get_default_if(char *iface, int size) { + if (size < 8) return false; + memset(iface, 0, size); + + FILE *f = fopen("/proc/net/route", "r"); + if (!f) return false; + + char dest[64] = {0, }; + while (!feof(f)) { + if (fscanf(f, "%s %s %*[^\r\n]%*c", iface, dest) != 2) continue; + if (strcmp(dest, "00000000") == 0) { + break; + } + } + + return strlen(iface) ? true : false; +} + +// get eth0's ipv4 address +inline bool get_ip(const char *iface, char* ip, int size) { + if (size < INET_ADDRSTRLEN) return false; + memset(ip, 0, size); + + struct ifaddrs * ifAddrStruct = NULL; + struct ifaddrs * ifa = NULL; + void * tmpAddrPtr = NULL; + + getifaddrs(&ifAddrStruct); + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if ((ifa->ifa_addr->sa_family == AF_INET) && (strcmp(ifa->ifa_name,iface) == 0)) { + tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + inet_ntop(AF_INET, tmpAddrPtr, ip, INET_ADDRSTRLEN); + } + } + + if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); + + return strlen(ip) ? true : false; +} +#endif \ No newline at end of file diff --git a/api/cplus/demo/main_get_instance.cpp b/api/cplus/demo/main_get_instance.cpp new file mode 100644 index 0000000..de313ce --- /dev/null +++ b/api/cplus/demo/main_get_instance.cpp @@ -0,0 +1,107 @@ +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +#include +#include +#include +#include +#include "include/Tseer_api.h" +#include "include/Tseer_comm.h" + +using namespace std; +using namespace Tseerapi; + +int main(int argc, char *argv[]) { + const char* service_name = NULL; + int option = 0x001; + + int opt; + opterr = 0; + while ((opt = getopt(argc, argv, "iptah")) != -1) { + switch(opt) { + case 'a': + option |= 0x111; + break; + case 'i': + option |= 0x001; + break; + case 'p': + option |= 0x010; + break; + case 't': + option |= 0x100; + break; + case 'h': + printf("Usage: %s [OPTION] service_name\n", argv[0]); + printf(" -a\tprint all fileds\n"); + printf(" -i\tprint ip\n"); + printf(" -p\tprint port\n"); + printf(" -t\tprint tag\n"); + printf(" -h\tprint help message\n"); + exit(0); + default: + break; + } + } + + if (optind >= argc) { + fprintf(stderr, "Error: no service name, use -h for help\n"); + exit(1); + } + + service_name = argv[optind]; + string sErr; + + InitAgentApiParams initParams; + if (ApiSetAgentIpInfo(initParams, sErr) != 0) { + fprintf(stderr, "Error: init agent error\n"); + exit(2); + } + + RoutersRequest reqs; + reqs.obj = service_name; + reqs.lbGetType = LB_GET_ALL; + if (ApiGetRoutes(reqs, sErr) == 0) { + vector::iterator vIter; + for (vIter = reqs.nodeInfoVec.begin(); vIter != reqs.nodeInfoVec.end(); ++vIter) { + bool need_tab = false; + if (option & 0x001) { + if (need_tab) printf("\t"); + printf("%s", vIter->ip.c_str()); + need_tab = true; + } + + if (option & 0x010) { + if (need_tab) printf("\t"); + printf("%d", vIter->port); + need_tab = true; + } + + if (option & 0x100) { + if (need_tab) printf("\t"); + printf("%s", vIter->slaveSet.empty() ? "-" : vIter->slaveSet.c_str()); + need_tab = true; + } + + if (need_tab) printf("\n"); + } + } else { + fprintf(stderr, "Error: get service [%s] info failed\n", service_name); + exit(3); + } + + return 0; +} \ No newline at end of file diff --git a/api/cplus/src/Tseer_api.cpp b/api/cplus/src/Tseer_api.cpp index b4f8308..e64879e 100644 --- a/api/cplus/src/Tseer_api.cpp +++ b/api/cplus/src/Tseer_api.cpp @@ -217,7 +217,7 @@ static int initAgentRouter(std::string &errMsg) return -1; } - remoteProvider->init("./routersCache/"); + remoteProvider->init(ROUTERSCACHE_PATH); //初始化本地的路由信息提供者 CacheProvider *cacheProvider = new(std::nothrow) CacheProvider; if (!cacheProvider) @@ -242,7 +242,7 @@ static int initAgentRouter(std::string &errMsg) remoteProvider = NULL; return -1; } - cacheProvider->setCacheDir("./routersCache/"); + cacheProvider->setCacheDir(ROUTERSCACHE_PATH); agent_router->setProvider(remoteProvider, cacheProvider); return 0; @@ -318,7 +318,7 @@ static int initRegistryRouter(std::string &errMsg) return -1; } - remoteProvider->init("./routersCache/", registry_ep_mgr); + remoteProvider->init(ROUTERSCACHE_PATH, registry_ep_mgr); //初始化本地路由信息提供者 CacheProvider *cacheProvider = new(std::nothrow) CacheProvider; @@ -334,7 +334,7 @@ static int initRegistryRouter(std::string &errMsg) //不需要清理registry_ep_mgr return -1; } - cacheProvider->setCacheDir("./routersCache/"); + cacheProvider->setCacheDir(ROUTERSCACHE_PATH); registry_router->setProvider(remoteProvider, cacheProvider); return 0; diff --git a/api/cplus/src/cache_manager.cpp b/api/cplus/src/cache_manager.cpp index b52399f..a2ea2b4 100644 --- a/api/cplus/src/cache_manager.cpp +++ b/api/cplus/src/cache_manager.cpp @@ -1,19 +1,19 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + #include "cache_manager.h" #include @@ -53,7 +53,9 @@ CacheManager::~CacheManager() void CacheManager::init(const string &cacheDir) { _cacheDir = cacheDir; - Tseerapi::TC_File::makeDirRecursive(cacheDir); + mode_t old_mask = umask(0); + Tseerapi::TC_File::makeDirRecursive(cacheDir, 0777); + umask(old_mask); } void CacheManager::updateAllCache(const string &obj, const vector &activeEp, const vector &inactiveEp) @@ -238,14 +240,15 @@ void CacheManager::updateCache(const string &obj, const string &subdomain, const writeToDisk(obj, oldConf); } - int CacheManager::writeToDisk(const string &obj, Tseerapi::TC_Config *conf) { //用linux的系统调用write来执行,保证原子性 string content = conf->tostr(); string filePath = _cacheDir + obj; + mode_t old_mask = umask(0); int fileFd = open(filePath.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); + umask(old_mask); if (fileFd != -1) { write(fileFd, content.c_str(), content.size()); @@ -258,8 +261,10 @@ int CacheManager::writeToDisk(const string &obj, Tseerapi::TC_Config *conf) int CacheManager::writeUniCache(const std::string fileName, Tseerapi::TC_Config *conf) { string content = conf->tostr(); - string filePath = "routersCache/" + fileName; + string filePath = ROUTERSCACHE_PATH + fileName; + mode_t old_mask = umask(0); int fileFd = open(filePath.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); + umask(old_mask); if (fileFd != -1) { write(fileFd, content.c_str(), content.size()); diff --git a/api/cplus/src/global.h b/api/cplus/src/global.h index 3b88a8f..98a705a 100644 --- a/api/cplus/src/global.h +++ b/api/cplus/src/global.h @@ -1,19 +1,19 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + #ifndef __TSEER_API_GLOBAL_H_ #define __TSEER_API_GLOBAL_H_ @@ -132,10 +132,14 @@ std::string getUnkeyFromReq(const InnerRouterRequest &req); //合并错误信息,currErr本层错误信息,subErr上层的错误信息 std::string mergeErrMsg(const std::string &currErr, const std::string &subErr); +//定义缓存文件的路径 +#ifndef ROUTERSCACHE_PATH +#define ROUTERSCACHE_PATH "/tmp/.routersCache/" +#endif + #ifndef FILE_FUN #define FILE_FUN __FILE__<<":"<<__FUNCTION__<<":"<<__LINE__<<"|" #endif - } #endif diff --git a/api/cplus/src/route_info_provider.cpp b/api/cplus/src/route_info_provider.cpp index b521b88..f4d57eb 100644 --- a/api/cplus/src/route_info_provider.cpp +++ b/api/cplus/src/route_info_provider.cpp @@ -1,21 +1,20 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#include "route_info_provider.h" +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +#include "route_info_provider.h" #include #include #include @@ -96,7 +95,8 @@ int RegistryProvider::getRouteInfo(const InnerRouterRequest &req, Tseer::AgentRo vector activeEpF; vector inactiveEpF; TarsUniPacket<> packet; - packet.setRequestId(__sync_fetch_and_add(®istry_seq, 1)); + __asm__ __volatile__ ("lock; incl %0\n\t" : "+m" (registry_seq) :: "memory"); + packet.setRequestId(registry_seq); packet.setVersion(3); packet.setServantName(g_registry_obj); packet.put("id", req.obj); @@ -277,7 +277,7 @@ void RegistryProvider::setAvailable() {} const int AgentProvider::AGENT_FAIL_THRESHOLD = 3; -AgentProvider::AgentProvider() :_available(true), _failedNum(0) +AgentProvider::AgentProvider() :_failedNum(0), _revive_time(0) { _tid = syscall(SYS_gettid); } @@ -337,7 +337,8 @@ int AgentProvider::getRouteInfo(const InnerRouterRequest &req, Tseer::AgentRoute //编码到TUP TarsUniPacket<> packet; - packet.setRequestId(__sync_fetch_and_add(&agent_seq, 1)); + __asm__ __volatile__ ("lock; incl %0\n\t" : "+m" (agent_seq) :: "memory"); + packet.setRequestId(agent_seq); packet.setVersion(3); packet.setServantName(g_agent_router_obj); packet.setFuncName(g_agent_router_func); @@ -449,7 +450,7 @@ int AgentProvider::getRouteInfo(const InnerRouterRequest &req, Tseer::AgentRoute bool AgentProvider::isAvailable() const { - return _available; + return time(NULL) >= _revive_time; } bool AgentProvider::addFailedNumAndCheckAvailable() @@ -457,16 +458,17 @@ bool AgentProvider::addFailedNumAndCheckAvailable() ++_failedNum; if (_failedNum >= AGENT_FAIL_THRESHOLD) { - _available = false; + _revive_time = time(NULL) + AGENT_FAIL_THRESHOLD * g_node_normal_expire_interval; _failedNum = 0; + return false; } - return _available; + return true; } void AgentProvider::setAvailable() { - _failedNum = 0; - _available = true; + _failedNum = 0; + _revive_time = 0; } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/api/cplus/src/route_info_provider.h b/api/cplus/src/route_info_provider.h index 4f8b842..de3f02e 100644 --- a/api/cplus/src/route_info_provider.h +++ b/api/cplus/src/route_info_provider.h @@ -1,19 +1,19 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + #ifndef __TSEER_API_ROUTE_INFO_SOURCE_H_ #define __TSEER_API_ROUTE_INFO_SOURCE_H_ @@ -125,9 +125,9 @@ class AgentProvider : public RouteInfoProvider //线程ID unsigned _tid; - bool _available; - - int _failedNum; + //可用性判断 + int _failedNum; + time_t _revive_time; }; /******************************************************** diff --git a/api/cplus/src/router_manager.cpp b/api/cplus/src/router_manager.cpp index 2436112..d9d5352 100644 --- a/api/cplus/src/router_manager.cpp +++ b/api/cplus/src/router_manager.cpp @@ -1,21 +1,22 @@ -/** - * Tencent is pleased to support the open source community by making Tseer available. - * - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - +/** + * Tencent is pleased to support the open source community by making Tseer available. + * + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + #include "router_manager.h" +#include #include #include #include @@ -344,16 +345,10 @@ int RouterManager::getRouterSingle(InnerRouterRequest &req, string &errMsg, bool Tseer::AgentRouterResponse rsp; string fileName = req.obj + req.slaveSet + TC_Common::tostr(req.lbGetType) + TC_Common::tostr(req.type); - if (_remoteProvider->isAvailable()) - { + if (_remoteProvider->isAvailable()) { ret = _remoteProvider->getRouteInfo(req, rsp, errMsg); - if (ret == 0) - { + if (ret == 0 && rsp.resultList.size() == 1) { //填充返给客户的信息 - if (rsp.resultList.size() == 0 || rsp.resultList.size() > 1) { - //远端返回内容不合法 - goto cache; - } nodeInfo.ip = rsp.resultList[0].ip; nodeInfo.port = rsp.resultList[0].port; nodeInfo.isTcp = rsp.resultList[0].isTcp; @@ -368,34 +363,25 @@ int RouterManager::getRouterSingle(InnerRouterRequest &req, string &errMsg, bool UniRamCacheIter uniIter = _uniRamCache.find(tableKey); //更新内存信息 - if (isHash) - { - if (hashIter == _hashRamCache.end()) - { + if (isHash) { + if (hashIter == _hashRamCache.end()) { //首次访问,内存缓存map并不存在 std::map tmpMap; tmpMap.insert(std::make_pair(req.hashKey, nodeInfo)); _hashRamCache.insert(std::make_pair(tableKey, tmpMap)); - } - else - { + } else { hashIter->second[req.hashKey] = nodeInfo; } //更新文件缓存 _cacheMgr.updateHashCache(tableKey, fileName, _hashRamCache[tableKey]); - } - else - { - if (uniIter == _uniRamCache.end()) - { + } else { + if (uniIter == _uniRamCache.end()) { //首次访问,内存缓存set并不存在 std::set tmpSet; tmpSet.insert(nodeInfo); _uniRamCache.insert(std::make_pair(tableKey, tmpSet)); - } - else - { + } else { uniIter->second.insert(nodeInfo); } @@ -410,79 +396,60 @@ int RouterManager::getRouterSingle(InnerRouterRequest &req, string &errMsg, bool _uniCacheIndex.insert(std::make_pair(tableKey, indexIter)); } indexIter = _uniCacheIndex.find(tableKey)->second; - if (indexIter == _uniRamCache[tableKey].end()) - { + if (indexIter == _uniRamCache[tableKey].end()) { _uniCacheIndex.find(tableKey)->second = _uniRamCache[tableKey].begin(); - } - else - { + } else { _uniCacheIndex.find(tableKey)->second++; } } return 0; - - }//if (ret == 0) - else - { - goto cache; - } - }//if (_remoteProvider->isAvailable()) - else - { - cache: - ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); - if (ret == 0) - { - return 0; } - - std::string subErr; - if (isHash) - { - std::map newNodeMap; - ret = _cacheProvider->getRouteInfo(req, rsp, newNodeMap, subErr); - if (ret == 0) - { - _hashRamCache.insert(std::make_pair(tableKey, newNodeMap)); - //再次在内存中查找 - ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); - if (ret == -1) - { - //远程错误,本地也找不到节点 - return -2; - } - - return 0; - } - else - { + + //远端获取失败后对可用性状态进行检查, 走缓存逻辑 + _remoteProvider->addFailedNumAndCheckAvailable(); + } + + //remoteProvider不可用或者请求失败,从缓存中获取数据 + ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); + if (ret == 0) { + return 0; + } + + std::string subErr; + if (isHash) { + std::map newNodeMap; + ret = _cacheProvider->getRouteInfo(req, rsp, newNodeMap, subErr); + if (ret == 0) { + _hashRamCache.insert(std::make_pair(tableKey, newNodeMap)); + //再次在内存中查找 + ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); + if (ret == -1) { //远程错误,本地也找不到节点 return -2; } + + return 0; + } else { + //远程错误,本地也找不到节点 + return -2; } - else - { - std::set newNodeSet; - ret = _cacheProvider->getRouteInfo(req, rsp, newNodeSet, subErr); - if (ret == 0) - { - _uniRamCache.insert(std::make_pair(tableKey, newNodeSet)); - //再次在内存中查找 - ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); - if (ret == -1) - { - //远程错误,本地也找不到节点 - return -2; - } - - return 0; - } - else - { + } else { + std::set newNodeSet; + ret = _cacheProvider->getRouteInfo(req, rsp, newNodeSet, subErr); + if (ret == 0) { + _uniRamCache.insert(std::make_pair(tableKey, newNodeSet)); + //再次在内存中查找 + ret = getRouterFromUniRam(errMsg, req, nodeInfo, isHash); + if (ret == -1) { //远程错误,本地也找不到节点 return -2; } + + return 0; + } else { + //远程错误,本地也找不到节点 + return -2; } } return 0; @@ -776,5 +743,4 @@ int RouterManager::updateStat(const InnerRouterRequest &req, int ret, int timeCo } } - } diff --git a/build/cmake/mon_TseerAgent.sh b/build/cmake/mon_TseerAgent.sh index ce584c5..8cc512a 100755 --- a/build/cmake/mon_TseerAgent.sh +++ b/build/cmake/mon_TseerAgent.sh @@ -1,6 +1,6 @@ #!/bin/bash -IP=`ip a s |awk '/inet/ { if (($2 !~ /127.0.0.1/) && ($2 !~ /::1/)) { print $2} }'| cut -d / -f 1` +IP=`/sbin/ip a s |awk '/inet/ { if (($2 !~ /127.0.0.1/) && ($2 !~ /::1/)) { print $2} }'| cut -d / -f 1 | head -n 1` PORT=9765 BASE_DIR=/usr/local/ @@ -29,7 +29,7 @@ start_server() sleep 5 ps -ef |grep "${BASE_DIR}/Tseer/TseerAgent/bin/TseerAgent"|grep -v grep >/dev/null 2>&1 if [ "$?" -ne "0" ]; then - return 1 + return 1 fi return 0 } @@ -47,8 +47,7 @@ mon_process() mon_port() { - result1=`echo quit|telnet $IP $PORT 2>/dev/null` - echo $result1 |grep -q "Escape character" + netstat -tnl | grep "$IP:$PORT" >/dev/null 2>&1 if test $? = 0; then echo "`date +"%Y-%m-%d %H:%M:%S"` the port $PORT is good" return 0 @@ -58,19 +57,23 @@ mon_port() fi } -mon_process -flag_process=$? -if test $flag_process = 1; then - stop_server - start_server -else - mon_port - flag_port=$? - if test $flag_port = 1;then +for i in {1..11} +do + mon_process + flag_process=$? + if test $flag_process = 1; then stop_server start_server else - echo "TseerAgent process and port state is good" + mon_port + flag_port=$? + if test $flag_port = 1;then + stop_server + start_server + else + echo "TseerAgent process and port state is good" + fi fi -fi -exit 0 + sleep 5 +done +exit 0 \ No newline at end of file diff --git a/build/cmake/resolve_dependency.sh b/build/cmake/resolve_dependency.sh index 71714e3..cee0006 100755 --- a/build/cmake/resolve_dependency.sh +++ b/build/cmake/resolve_dependency.sh @@ -2,12 +2,16 @@ TIMESTAMP=`date "+%F %T"` -echo "[INFO] $TIMESTAMP resolve depedency rapidjson..." -git clone https://github.com/Tencent/rapidjson.git >/dev/null +if [ -e "./rapidjson" ]; then + echo "[INFO] $TIMESTAMP rapidjson already downloaded." +else + echo "[INFO] $TIMESTAMP resolve depedency rapidjson..." + git clone https://github.com/Tencent/rapidjson.git >/dev/null -if [ "$?" -ne "0" ]; then - echo "[ERROR] $TIMESTAMP Download rapidjson failed." - exit 3 + if [ "$?" -ne "0" ]; then + echo "[ERROR] $TIMESTAMP Download rapidjson failed." + exit 3 + fi fi mkdir -p ../thirdparty/ diff --git a/docs/cplus-api-quickstart.md b/docs/cplus-api-quickstart.md index 3bc5813..4cc8955 100644 --- a/docs/cplus-api-quickstart.md +++ b/docs/cplus-api-quickstart.md @@ -280,7 +280,6 @@ int main() req.obj = "tencent.tencentServer.HelloService"; req.lbGetType = LB_GET_SET; req.setInfo = "sz.a.b"; - req.type = LB_TYPE_ALL; iRet = ApiGetRoutes(req, errMsg); if (iRet == 0) {