本项目用于移动端的数据统计,项目地址: 。开源的数据统计countly做的很好,但是基础免费版的功能实在不够看,因此我就决定用go语言来写了这个项目,一来可以在实践中学习go语言,二来也可以开发功能完整的开源平台。该项目正在开发中,欢迎有兴趣的gopher一起参与。
成都创新互联公司是一家专注网站建设、网络营销策划、微信小程序开发、电子商务建设、网络推广、移动互联开发、研究、服务为一体的技术型公司。公司成立10年以来,已经为近千家生料搅拌车各业的企业公司提供互联网服务。现在,服务的近千家客户与我们一路同行,见证我们的成长;未来,我们一起分享成功的喜悦。
数据存储方面使用的是mongodb。由于数据统计业务几乎不涉及到事务以及严格的一致性场景,而且mongodb的自动分片功能可以支撑较大的数据量。使用大数据的存储组件的话就太过于重了。因此选用mongodb。
业务逻辑整体基于事件的发布订阅。当收到客户端请求, frontend 会对请求数据进行处理,然后发布响应的事件。 backend 收到事件后进行统计处理。
后台展示基于Vue-Admin-Template开发,本人前端能力基本就是依葫芦画瓢,希望有前端大神来开发后台页面,项目地址:
目前客户端API仅有2个。一个是上报 openApp 打开APP时间,一个是上报 usageTime 一次启动使用时长事件。SDK方面也需要移动端的大神开发,感兴趣的大佬可以一起开发。
下面放一点后台页面的效果图:
GoAnalytics是基于go实现的一个数据统计平台,用于统计移动端的数据指标,比如启动次数、用户增长、活跃用户、留存等指标分析。前端数据展示项目是 goanalytics-web 。目前正在积极开发中,欢迎提交新的需求和pull request。
Go版本需要支持module,本地开发测试
cmd/goanalytics_kafka 和 goanalytics_rmq 是分别基于 kafka 和 rocketmq 的发布订阅功能做的数据发布
和订阅处理,横向扩展能力比 local 高。另外由于 rocketmq 还没有原生基于 go 的客户端(原生客户端正在开发中
2.0.0 road map ),可能会存在问题。
项目结构
├── README.md
├── api
│ ├── authentication 用户认证、管理API
│ ├── middlewares GIN 中间件
│ └── router API route
├── cmd
│ ├── account 生成admin账号命令
│ ├── analytic_local 不依赖消息系统的goanalytics
│ ├── goanalytics_kafka 基于kafak的goanalytics
│ ├── goanalytics_rmq 基于rocketmq的goanalytics
│ └── test_data 生成测试数据命令
├── common
│ └── data.go
├── conf 配置
│ └── conf.go
├── event
│ ├── codec 数据编解码
│ └── pubsub 消息发布订阅
├── go.mod
├── go.sum
├── metric 所有的统计指标在这里实现
│ ├── init.go
│ └── user 用户相关指标的实现
├── schedule
│ └── schedule.go 定时任务调度
├── storage 存储模块
│ ├── counter.go 计数器接口
│ ├── data.go
│ └── mongodb 基于mongodb实现的存储及计数器
└── utils
├── date.go
├── date_test.go
├── errors.go
└── key.go
这10款工具如下:
AKHQ
Kowl
Kafdrop
UI for Apache Kafka
Lenses
CMAK
Confluent CC
Conduktor
LogiKM
kafka-console-ui
如果上面这个地址可以打开,可以直接去看介绍,下文也不再重复说明。
关于前8款的对比,可以看下面这张图片,图片也是于上面,我直接copy过来了(可能有好多同学打不开上面这个链接,就直接看这张图片了解了下吧)
关于这8款工具的介绍,人家说的很清晰了,这里就不再重复说明了,并且这些工具,大部分我也没用过,也没资格评价太多。
考虑到很多同学可能打开github太慢,我下面会把相关基本信息整理一下,供大家快速了解,方便选型。
概览
AKHQ (previously known as KafkaHQ)
开发语言:后端是java为主
Kowl - A Web UI for Apache Kafka
p.s. github上完整的动图这里上传失败,就只放一个静态的截图了,如果可以打开github,建议打开下面的地址直接看吧。
但是这个并不是所有功能都是免费,有部分功能是商业版才有:
开发语言:后端是go为主
Kafdrop – Kafka Web UI
开发语言:后端以java为主
要求jdk11或更高版本
UI for Apache Kafka – Free Web UI for Apache Kafka
开发语言:后端以java为主
要求jdk13或更高版本
Lenses.io
Apache Kafka 和 Kubernetes 的实时应用程序和数据操作 #DataOps 门户。
CMAK (Cluster Manager for Apache Kafka, previously known as Kafka Manager)
这个想必很多同学都知道,原来的名字就是kafka manager。
开发语言:后端以scala为主
Confluent Inc.
Apache
Conduktor
一个商业版本的桌面客户端
官网找到一个这样的图片,凑合看吧:
LogiKM
滴滴开源的一站式Apache Kafka集群指标监控与运维管控平台。
也是分社区版和商业版的。
这个建议直接看github说明吧,都是中文,内容清晰,相关的资料也都有。
我也简单的了解了下,有个逻辑集群的概念,对于规模比较大的kafka集群管理还是挺好的,不过,这里比较高端的特性都是不开源的,必须商业版才能用。
开发语言:后端以java为主
kafka-console-ui(kafka可视化管理平台)
一款轻量级的kafka可视化管理平台,安装配置快捷、简单易用。界面风格有点类似rocketmq-console。
这款权当是“王婆卖瓜,自卖自夸”吧,一个小工具,如果刚接触kafka的同学或者是中小型集群,想找个简单易用的,可以考虑一下。
开发语言:后端以java和scala为主
参考链接:
本文主要研究一下golang的zap的ZapKafkaWriter
WriteSyncer内嵌了io.Writer接口,定义了Sync方法;Sink接口内嵌了zapcore.WriteSyncer及io.Closer接口;ZapKafkaWriter实现Sink接口及zapcore.WriteSyncer接口,其Write方法直接将data通过kafka发送出去。
最近写了个kafka的接收消息的功能,需要使用回调处理收到的消息。
一个是基本的回调,一个是使用接口功能实现回调,对接口是个很好的学习。
1.正常回调
kafka的接收消息处。收到消息后,使用传入的Onmessage进行处理。
调用kafka接收消息的单元,并在调用方写好回调
在调用方实现回调需要执行的方法
感觉还是使用基本回调相对简单点,接口就当学习了。
另外跨包的接口的方法要大写!定位了好久发现个入门的问题。
1. 介绍
最近在研究一些消息中间件,常用的MQ如RabbitMQ,ActiveMQ,Kafka等。NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,由bitly公司开源出来的一款简单易用的消息中间件。
官方和第三方还为NSQ开发了众多客户端功能库,如官方提供的基于HTTP的nsqd、Go客户端go-nsq、Python客户端pynsq、基于Node.js的JavaScript客户端nsqjs、异步C客户端libnsq、Java客户端nsq-java以及基于各种语言的众多第三方客户端功能库。
1.1 Features
1). Distributed
NSQ提供了分布式的,去中心化,且没有单点故障的拓扑结构,稳定的消息传输发布保障,能够具有高容错和HA(高可用)特性。
2). Scalable易于扩展
NSQ支持水平扩展,没有中心化的brokers。内置的发现服务简化了在集群中增加节点。同时支持pub-sub和load-balanced 的消息分发。
3). Ops Friendly
NSQ非常容易配置和部署,生来就绑定了一个管理界面。二进制包没有运行时依赖。官方有Docker image。
4.Integrated高度集成
官方的 Go 和 Python库都有提供。而且为大多数语言提供了库。
1.2 组件
1.3 拓扑结构
NSQ推荐通过他们相应的nsqd实例使用协同定位发布者,这意味着即使面对网络分区,消息也会被保存在本地,直到它们被一个消费者读取。更重要的是,发布者不必去发现其他的nsqd节点,他们总是可以向本地实例发布消息。
NSQ
首先,一个发布者向它的本地nsqd发送消息,要做到这点,首先要先打开一个连接,然后发送一个包含topic和消息主体的发布命令,在这种情况下,我们将消息发布到事件topic上以分散到我们不同的worker中。
事件topic会复制这些消息并且在每一个连接topic的channel上进行排队,在我们的案例中,有三个channel,它们其中之一作为档案channel。消费者会获取这些消息并且上传到S3。
nsqd
每个channel的消息都会进行排队,直到一个worker把他们消费,如果此队列超出了内存限制,消息将会被写入到磁盘中。Nsqd节点首先会向nsqlookup广播他们的位置信息,一旦它们注册成功,worker将会从nsqlookup服务器节点上发现所有包含事件topic的nsqd节点。
nsqlookupd
2. Internals
2.1 消息传递担保
1)客户表示已经准备好接收消息
2)NSQ 发送一条消息,并暂时将数据存储在本地(在 re-queue 或 timeout)
3)客户端回复 FIN(结束)或 REQ(重新排队)分别指示成功或失败。如果客户端没有回复, NSQ 会在设定的时间超时,自动重新排队消息
这确保了消息丢失唯一可能的情况是不正常结束 nsqd 进程。在这种情况下,这是在内存中的任何信息(或任何缓冲未刷新到磁盘)都将丢失。
如何防止消息丢失是最重要的,即使是这个意外情况可以得到缓解。一种解决方案是构成冗余 nsqd对(在不同的主机上)接收消息的相同部分的副本。因为你实现的消费者是幂等的,以两倍时间处理这些消息不会对下游造成影响,并使得系统能够承受任何单一节点故障而不会丢失信息。
2.2 简化配置和管理
单个 nsqd 实例被设计成可以同时处理多个数据流。流被称为“话题”和话题有 1 个或多个“通道”。每个通道都接收到一个话题中所有消息的拷贝。在实践中,一个通道映射到下行服务消费一个话题。
在更底的层面,每个 nsqd 有一个与 nsqlookupd 的长期 TCP 连接,定期推动其状态。这个数据被 nsqlookupd 用于给消费者通知 nsqd 地址。对于消费者来说,一个暴露的 HTTP /lookup 接口用于轮询。为话题引入一个新的消费者,只需启动一个配置了 nsqlookup 实例地址的 NSQ 客户端。无需为添加任何新的消费者或生产者更改配置,大大降低了开销和复杂性。
2.3 消除单点故障
NSQ被设计以分布的方式被使用。nsqd 客户端(通过 TCP )连接到指定话题的所有生产者实例。没有中间人,没有消息代理,也没有单点故障。
这种拓扑结构消除单链,聚合,反馈。相反,你的消费者直接访问所有生产者。从技术上讲,哪个客户端连接到哪个 NSQ 不重要,只要有足够的消费者连接到所有生产者,以满足大量的消息,保证所有东西最终将被处理。对于 nsqlookupd,高可用性是通过运行多个实例来实现。他们不直接相互通信和数据被认为是最终一致。消费者轮询所有的配置的 nsqlookupd 实例和合并 response。失败的,无法访问的,或以其他方式故障的节点不会让系统陷于停顿。
2.4 效率
对于数据的协议,通过推送数据到客户端最大限度地提高性能和吞吐量的,而不是等待客户端拉数据。这个概念,称之为 RDY 状态,基本上是客户端流量控制的一种形式。
efficiency
2.5 心跳和超时
组合应用级别的心跳和 RDY 状态,避免头阻塞现象,也可能使心跳无用(即,如果消费者是在后面的处理消息流的接收缓冲区中,操作系统将被填满,堵心跳)为了保证进度,所有的网络 IO 时间上限势必与配置的心跳间隔相关联。这意味着,你可以从字面上拔掉之间的网络连接 nsqd 和消费者,它会检测并正确处理错误。当检测到一个致命错误,客户端连接被强制关闭。在传输中的消息会超时而重新排队等待传递到另一个消费者。最后,错误会被记录并累计到各种内部指标。
2.6 分布式
因为NSQ没有在守护程序之间共享信息,所以它从一开始就是为了分布式操作而生。个别的机器可以随便宕机随便启动而不会影响到系统的其余部分,消息发布者可以在本地发布,即使面对网络分区。
这种“分布式优先”的设计理念意味着NSQ基本上可以永远不断地扩展,需要更高的吞吐量?那就添加更多的nsqd吧。唯一的共享状态就是保存在lookup节点上,甚至它们不需要全局视图,配置某些nsqd注册到某些lookup节点上这是很简单的配置,唯一关键的地方就是消费者可以通过lookup节点获取所有完整的节点集。清晰的故障事件——NSQ在组件内建立了一套明确关于可能导致故障的的故障权衡机制,这对消息传递和恢复都有意义。虽然它们可能不像Kafka系统那样提供严格的保证级别,但NSQ简单的操作使故障情况非常明显。
2.7 no replication
不像其他的队列组件,NSQ并没有提供任何形式的复制和集群,也正是这点让它能够如此简单地运行,但它确实对于一些高保证性高可靠性的消息发布没有足够的保证。我们可以通过降低文件同步的时间来部分避免,只需通过一个标志配置,通过EBS支持我们的队列。但是这样仍然存在一个消息被发布后马上死亡,丢失了有效的写入的情况。
2.8 没有严格的顺序
虽然Kafka由一个有序的日志构成,但NSQ不是。消息可以在任何时间以任何顺序进入队列。在我们使用的案例中,这通常没有关系,因为所有的数据都被加上了时间戳,但它并不适合需要严格顺序的情况。
2.9 无数据重复删除功能
NSQ对于超时系统,它使用了心跳检测机制去测试消费者是否存活还是死亡。很多原因会导致我们的consumer无法完成心跳检测,所以在consumer中必须有一个单独的步骤确保幂等性。
3. 实践安装过程
本文将nsq集群具体的安装过程略去,大家可以自行参考官网,比较简单。这部分介绍下笔者实验的拓扑,以及nsqadmin的相关信息。
3.1 拓扑结构
topology
实验采用3台NSQD服务,2台LOOKUPD服务。
采用官方推荐的拓扑,消息发布的服务和NSQD在一台主机。一共5台机器。
NSQ基本没有配置文件,配置通过命令行指定参数。
主要命令如下:
LOOKUPD命令
NSQD命令
工具类,消费后存储到本地文件。
发布一条消息
3.2 nsqadmin
对Streams的详细信息进行查看,包括NSQD节点,具体的channel,队列中的消息数,连接数等信息。
nsqadmin
channel
列出所有的NSQD节点:
nodes
消息的统计:
msgs
lookup主机的列表:
hosts
4. 总结
NSQ基本核心就是简单性,是一个简单的队列,这意味着它很容易进行故障推理和很容易发现bug。消费者可以自行处理故障事件而不会影响系统剩下的其余部分。
事实上,简单性是我们决定使用NSQ的首要因素,这方便与我们的许多其他软件一起维护,通过引入队列使我们得到了堪称完美的表现,通过队列甚至让我们增加了几个数量级的吞吐量。越来越多的consumer需要一套严格可靠性和顺序性保障,这已经超过了NSQ提供的简单功能。
结合我们的业务系统来看,对于我们所需要传输的发票消息,相对比较敏感,无法容忍某个nsqd宕机,或者磁盘无法使用的情况,该节点堆积的消息无法找回。这是我们没有选择该消息中间件的主要原因。简单性和可靠性似乎并不能完全满足。相比Kafka,ops肩负起更多负责的运营。另一方面,它拥有一个可复制的、有序的日志可以提供给我们更好的服务。但对于其他适合NSQ的consumer,它为我们服务的相当好,我们期待着继续巩固它的坚实的基础。