写点什么

「微服务的细节」—— 如何获取本地 IP?

作者:袁世超
  • 2022 年 4 月 25 日
  • 本文字数:1255 字

    阅读完需:约 4 分钟

计划写个系列文章,专注于微服务中的一些细节,不谈架构,也不谈治理。

问题

做为一个服务的实例,我需要把本地 IP 告诉注册中心,那么我如何获取本地 IP 呢?

当然我可以手工配置一下,如果上了 k8s,可以通过环境变量传入 status.podIP,那么有没有比较通用的方式呢?


通过 ifname

如果能确定要发布的网络接口,那么可以获取接口地址。

bool NetClient::GetIpByIf(const std::string& ifname, std::string* ip) {  if (ifname.empty() || ip == NULL) {    return false;  }  int fd, intrface;  struct ifreq buf[10];  struct ifconf ifc = {0, {0}};  memset(buf, 0, sizeof(buf));  struct in_addr addr;  char addr_buffer[32] = {0};
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if (!ioctl(fd, SIOCGIFCONF, &ifc)) { intrface = ifc.ifc_len / sizeof(struct ifreq); while (intrface-- > 0) { if (strcmp(buf[intrface].ifr_name, ifname.c_str()) == 0) { if (!(ioctl(fd, SIOCGIFADDR, &buf[intrface]))) { memset(addr_buffer, 0, sizeof(addr_buffer)); addr = ((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr; if (inet_ntop(AF_INET, static_cast<void*>(&addr), addr_buffer, sizeof(addr_buffer))) { ip->assign(addr_buffer); close(fd); return true; } } break; } } } close(fd); } return false;}
复制代码


通过连接

上面的方式还需要接口信息,还有一个更通用的方式:向注册中心建立连接,然后获取 socket 绑定的 IP。


bool NetClient::GetIpByConnect(std::string* ip) {  std::vector<SeedServer> default_servers;  SeedServerConfig::GetDefaultSeedServer(default_servers);  POLARIS_ASSERT(!default_servers.empty());  SeedServer& server = default_servers[time(NULL) % default_servers.size()];
int socket_fd = CreateTcpSocket(true); if (socket_fd < 0) { POLARIS_LOG(LOG_ERROR, "get local ip by connect to server[%s:%d] with create socket errno: %d", server.ip_.c_str(), server.port_, errno); return false; } ConnectWithTimeout(socket_fd, server.ip_, server.port_, 200); struct sockaddr_in addr; socklen_t len = sizeof(addr); if (getsockname(socket_fd, (struct sockaddr*)&addr, &len) < 0) { POLARIS_LOG(LOG_INFO, "get local ip by connect to server[%s:%d] with errno: %d", server.ip_.c_str(), server.port_, errno); CloseNoLinger(socket_fd); return false; } ip->assign(inet_ntoa(addr.sin_addr)); CloseNoLinger(socket_fd); return true;}
复制代码


示例代码来自 polaris-cpp

发布于: 刚刚阅读数: 5
用户头像

袁世超

关注

还未添加个人签名 2017.11.30 加入

还未添加个人简介

评论

发布
暂无评论
「微服务的细节」—— 如何获取本地IP?_微服务_袁世超_InfoQ写作社区