暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Kafka集群与nginx结合使用指引

数据科学和工程 2020-06-08
7313

目录

  • 背景

  • 第一部分   使用Nginx
    实现Kafka集群代理

  • 第二部分   架构数据流说明

  • 第三部分  总结

  • 参考文献及资料

背景

我们在使用Kafka客户端连接到Kafka集群时,即使连接的节点只配置了一个集群的Broker地址,该Broker将返回给客户端集群所有节点的信息列表。然后客户端使用该列表信息(Topic的分区信息)再与集群进行数据交互。这里Kafka列表信息为服务配置文件service.properties
advertised.listeners
配置项中的信息。例如:

advertised.listeners=PLAINTEXT://192.168.1.1:9092

这样在通信中就存在一个网络连通性问题。如果Kafka位于内网环境,而客户端位于外网环境,即使内外网配置了IP地址映射(网络层面的NAT),由于返回给外网客户端的IP列表是内网地址,客户端和Broker第一次通讯获取集群元数据中包含是advertised.listeners
配置中的内网地址信息,由于内外网隔离,就会出现客户端和集群的通信无法通讯的报错。

通常对于这种情况的解决方案是Kafka集群的advertised.listeners
配置项使用主机名方式。例如:

advertised.listeners=PLAINTEXT://Kafka.node1:9092

在理解了客户端和集群通讯机制后,对于很多连接Kafka的通讯问题,就能定位问题。例如:文章:《致歉声明,Kafka 数据中转传输错误》,架构上计划在Kafka集群前面起一个Nginx
进行负载,客户端只与nginx
代理进行通信。事实上,客户端只有第一次和集群通讯的时候走了Nginx
来获取Broker信息,在进行实际数据通信的时候,则直接和Broker通信。这时候如果存在内外网环境或者火墙隔离,就会出现通讯报错。

在实际业务场景中,系统架构上确实存在需要使用Nginx
的场景,这时候就需要我们在架构设计上要符合Kafka的通讯机制。本文将介绍一种Kafka集群和Nginx
结合使用的架构设计,供大家参考。

第一部分 使用Nginx
实现Kafka集群代理

1.1 配置Kafka集群

为了介绍方便,启动测试Kafka集群,一共三个节点(均配置为域名模式):

84.10.228.44 psoc.kafka.node1
84.10.228.45 psoc.kafka.node2
84.10.228.52 psoc.kafka.node3

1.2 配置Nginx
实例

另外需要启动三个·启动对应三个Nginx
实例,设计配置有:

Nginx
所有实例需要配置好hosts(本地DNS
):

# kafka 集群主机名映射关系
84.10.228.44 psoc.kafka.node1
84.10.228.45 psoc.kafka.node2
84.10.228.52 psoc.kafka.node3

Nginx
实例应用分别配置为:

  • 节点1:

stream {
   #1
  server{
      listen 9092;
      proxy_pass node1;
  }
  upstream node1{
    server psoc.kafka.node1:9092 weight=1;
  }
}
  • 节点2:

stream {
   #2
  server{
      listen 9092;
      proxy_pass node2;
  }
  upstream node2{
    server psoc.kafka.node2:9092 weight=1;
  }
}
  • 节点3:

stream {
   #3
  server{
      listen 9092;
      proxy_pass node3;
  }
  upstream node3{
    server psoc.kafka.node3:9092 weight=1;
  }
}

需要注意的是,nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx支持四层负载均衡。默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream,使其支持stream代理。具体编译参考文章:《编译nginx平滑添加stream模块》。

1.4 Kafka客户端配置

对于客户端我们以Python
程序客户端为例子,在运行客户端程序的hosts文件中配置下面主机名映射:

# 客户端hosts配置:
76.10.237.73 psoc.kafka.node3
76.10.253.229 psoc.kafka.node2
76.10.253.230 psoc.kafka.node1

具体代码中Kafka
集群配置(分别是三台Nginx
服务的IP):

bootstrap_servers=['76.10.237.73:9092','76.10.253.229:9092','76.10.253.230:9092']

第二部分 架构数据流说明

2.1 架构图

2.2 数据流介绍

(1)客户端通过Nginx
代理获取到Kafka集群的元数据信息。

(2)元数据信息中包含的是集群的主机名信息,客户端获取到主机名后,在hosts文件中进行解析。例如:psoc.kafka.node1
映射为对应的Nginx
实例地址:76.10.253.230
。这样数据流就会再次Nginx
进行交互,相当于对Kafka客户端进行了"欺骗"。

第三部分 总结

使用Nginx
代理Kafka集群,架构并没有较少对外暴露服务的实例数量。架构上主要能实现内外网隔离安全。例如外网Kafka客户端不用开通到内网Kafka集群的直连火墙。只需要将Nginx
集群的地址暴露给外网客户端。

另外架构上可以将Kafka集群中三个节点的监听端口分别配置成不同端口,例如:

advertised.listeners=PLAINTEXT://psoc.kafka.node1:9092
advertised.listeners=PLAINTEXT://psoc.kafka.node2:9093
advertised.listeners=PLAINTEXT://psoc.kafka.node3:9094

这样可以在一台节点服务器上运行一个Nginx
,然后配置三个不同的server
分别监听不同的端口。下面nginx
配置信息:

stream {
   #1
  server{
      listen 9092;
      proxy_pass node1;
  }
  upstream node1{
    server psoc.kafka.node1:9092 weight=1;
  }
   #2
  server{
      listen 9093;
      proxy_pass node2;
  }
  upstream node2{
    server psoc.kafka.node2:9093 weight=1;
  }
   #3
  server{
      listen 9094;
      proxy_pass node3;
  }
  upstream node3{
    server psoc.kafka.node3:9094 weight=1;
  }
}

在资源上我们只需要部署一台对外暴露的Nginx
服务器IP和三个端口即可。

需要注意的是这时候客户端的hosts
文件需要配置如下:

192.168.1.1 psoc.kafka.node1
192.168.1.1 psoc.kafka.node2
192.168.1.1 psoc.kafka.node3

其中192.168.1.1
nginx
ip
。本质也是对kafka
进行了"欺骗"。这样客户端就避免和Kafka Broker
直连,而是通过nginx
进行了路由。

参考文献及资料

1、记一次数据通过中转后传输到Kafka集群的过程,链接:https://mp.weixin.qq.com/s?__biz=MzU1MTk1Nzk4Mw==&mid=2247483712&idx=1&sn=d9181b71f88684763c63e93f89211f5c&chksm=fb8825f0ccfface623f133837bfd3e291fb579e6a2a621dfbd26bb1ba37e4bd3d29b6e81b4fd&scene=21#wechat_redirect

2、致歉声明,Kafka 数据中转传输错误,链接:https://toutiao.io/posts/wsynxqp/preview

3、编译nginx
平滑添加stream模块,链接:https://www.cnblogs.com/crysmile/p/9565048.html

文章转载自数据科学和工程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论