.net core kafka 入门实例 一篇看懂
Kafka 是由 Apache软件基金会 开发的一个开源流处理平台,由 Scala 和 Java 编写。Kafka是一种高吞吐量的 分布式 ,支持分区(partition),多副本(replica)的 发布订阅消息系统 。与其他MQ最大不同是Topic 具有分区(Partition)的概念,消息出队的速度也比其他MQ快。
- 高吞吐量、低延迟
- 可扩展性:集群支持热扩展
- 持久性、可靠性
- 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
- 高并发:支持数千个客户端同时读写
- 日志收集
- 消息系统:生产者和消费者、缓存消息等。
- 用户活动跟踪:流网页、搜索、点击等活动
- 运营指标
- 工作流处理
- 对实时性要求不高的数据处理
![]()
Kafka 中可将消息分类,每一类的消息称为一个 Topic(主题),消费者可以对不同的 Topic 进行不同的处理。Topic相当于传统消息系统MQ中的一个队列queue,producer端发送的message必须指定是发送到哪个topic,但是不需要指定topic下的哪个partition,因为kafka会把收到的message进行load balance,均匀的分布在这个topic下的不同的partition上
每个 Broker(代理) 即一个 Kafka 服务实例,多个 Broker 构成一个 Kafka 集群,生产者发布的消息将保存在 Broker 中,消费者将从 Broker 中拉取消息进行消费。
生产者
消费者
分区,Kafka 中比较特色的部分,一个 Topic 可以分为多个 Partition,每个 Partition 是一个有序的队列,Partition 中的每条消息都存在一个有序的偏移量(Offest) ,同一个 Consumer Group 中,只有一个 Consumer 实例可消费某个 Partition 的消息。
Kafka会把消息持久化到本地文件系统中,每个 Topic 将消息分成多 Partition,每个 Partition 在存储层面是 append log 文件。任何发布到此 Partition 的消息都会被直接追加到 log 文件的尾部,每条消息在文件中的位置称为 Offest(偏移量),Partition 是以文件的形式存储在文件系统中,log 文件根据 Broker 中的配置保留一定时间后删除来释放磁盘空间。
由于message的写入持久化是顺序写入的,因此message在被消费的时候也是按顺序被消费的,保证partition的message是顺序消费的。
看到上面的一堆特性,巴拉巴拉,一顿吹,道理我都懂,怎么操作,还是没看到效果。
别急,接下来就上代码,这个是不能少的。保证你们拿去就能用

/// <summary>
/// 消费者
/// </summary>
public interface IKafkaConsumer : IDisposable
{
/// <summary>
/// 消费数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Consume<T>() where T : class;
} public interface IKafkaProducer : IDisposable
{
/// <summary>
/// 发布消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="data"></param>
/// <param name="operateType"></param>
/// <returns></returns>
bool Produce<T>(string key, T data, int operateType) where T : class;
}
实现方法
using Confluent.Kafka;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text; namespace Kafka
{
public class KafkaConsumer : IKafkaConsumer
{
private bool disposeHasBeenCalled = false;
private readonly object disposeHasBeenCalledLockObj = new object(); private readonly IConsumer<string, string> _consumer; /// <summary>
/// 构造函数,初始化配置
/// </summary>
/// <param name="config">配置参数</param>
/// <param name="topic">主题名称</param>
public KafkaConsumer(ConsumerConfig config, string topic)
{
_consumer = new ConsumerBuilder<string, string>(config).Build(); _consumer.Subscribe(topic);
} /// <summary>
/// 消费
/// </summary>
/// <returns></returns>
public T Consume<T>() where T : class
{
try
{
var result = _consumer.Consume(TimeSpan.FromSeconds(1));
if (result != null)
{
if (typeof(T) == typeof(string))
return (T)Convert.ChangeType(result.Value, typeof(T)); return JsonConvert.DeserializeObject<T>(result.Value);
}
}
catch (ConsumeException e)
{
Console.WriteLine($"consume error: {e.Error.Reason}");
}
catch (Exception e)
{
Console.WriteLine($"consume error: {e.Message}");
} return default;
} /// <summary>
/// 释放
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// Dispose
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
lock (disposeHasBeenCalledLockObj)
{
if (disposeHasBeenCalled) { return; }
disposeHasBeenCalled = true;
} if (disposing)
{
_consumer?.Close();
}
}
} }
public class KafkaProducer : IKafkaProducer
{
private bool disposeHasBeenCalled = false;
private readonly object disposeHasBeenCalledLockObj = new object(); private readonly IProducer<string, string> _producer;
private readonly string _topic; /// <summary>
/// 构造函数,初始化配置
/// </summary>
/// <param name="config">配置参数</param>
/// <param name="topic">主题名称</param>
public KafkaProducer(ProducerConfig config, string topic)
{
_producer = new ProducerBuilder<string, string>(config).Build();
_topic = topic;
} /// <summary>
/// 发布消息
/// </summary>
/// <typeparam name="T">数据实体</typeparam>
/// <param name="key">数据key,partition分区会根据key</param>
/// <param name="data">数据</param>
/// <param name="operateType">操作类型[增、删、改等不同类型]</param>
/// <returns></returns>
public bool Produce<T>(string key, T data, int operateType) where T : class
{
var obj = JsonConvert.SerializeObject(new
{
Type = operateType,
Data = data
}); try
{
var result = _producer.ProduceAsync(_topic, new Message<string, string>
{
Key = key,
Value = obj
}).ConfigureAwait(false).GetAwaiter().GetResult(); #if DEBUG Console.WriteLine($"Topic: {result.Topic} Partition: {result.Partition} Offset: {result.Offset}");
#endif
return true; }
catch (ProduceException<string, string> e)
{
Console.WriteLine($"Delivery failed: {e.Error.Reason}");
}
catch (Exception e)
{
Console.WriteLine($"Delivery failed: {e.Message}");
} return false;
} /// <summary>
/// 释放
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// Dispose
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
lock (disposeHasBeenCalledLockObj)
{
if (disposeHasBeenCalled) { return; }
disposeHasBeenCalled = true;
} if (disposing)
{
_producer?.Dispose();
}
}
}
static void Main(string[] args)
{
var config = new ProducerConfig
{
BootstrapServers = "localhost:9092",
Acks = Acks.All
};
//发送消息 using (var kafkaProducer = new KafkaProducer(config, "topic-d"))
{
var result = kafkaProducer.Produce<object>("a", new { name = "猪八戒3" }, 1); }
Console.WriteLine("消息发送成功");
} static void Main(string[] args)
{
var config = new ConsumerConfig
{
BootstrapServers = "localhost:9092",
GroupId = "test",
AutoOffsetReset = AutoOffsetReset.Earliest
}; string text;
Console.WriteLine("接受中......");
while ((text = Console.ReadLine()) != "q")
{
//接受消息
using (var kafkaProducer = new KafkaConsumer(config, "topic-d"))
{
var result = kafkaProducer.Consume<object>();
if (result != null)
{
Console.WriteLine(result.ToString());
} }
} }
上结果、

可以看到,消息已经收到了。这个demo里,消费端要一直处于正常状态才行,才能消费生产者得信息
本文版权归作者和博客园共有,来源网址:欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
.net core kafka 入门实例 一篇看懂的更多相关文章
- springboot + kafka 入门实例 入门demo
springboot + kafka 入门实例 入门demo 版本说明 springboot版本:2.3.3.RELEASE kakfa服务端版本:kafka_2.12-2.6.0.tgz zooke ...
- pyhton pandas数据分析基础入门(一文看懂pandas)
//2019.07.17 pyhton中pandas数据分析基础入门(一文看懂pandas), 教你迅速入门pandas数据分析模块(后面附有入门完整代码,可以直接拷贝运行,含有详细的代码注释,可以轻 ...
- 《OD大数据实战》Kafka入门实例
官网: 参考文档: Kafka入门经典教程 Kafka工作原理详解 一.安装zookeeper 1. 下载zookeeper-3.4.5-cdh5.3.6.tar.gz 下载地址为: http://a ...
- ASP.NET Core 快速入门(环境篇)
[申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是让你精通Linux ... 的开机与关机.nginx安装与部署.Core的Hello World .. ...
- 【转】ASP.NET Core 快速入门(环境篇)
原文链接:http://www.cnblogs.com/zhaopei/p/netcore.html [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是 ...
- ASP.NET Core 快速入门(实战篇)
上篇讲了<asp.net core在linux上的环境部署>.今天我们将做几个小玩意实战一下.用到的技术和工具有mysql.websocket.AngleSharp(爬虫html解析).n ...
- java web 入门实例servlet篇(显示后台数据库列表,删除某一条记录并显示)
编写过程中需要注意的问题: 1.建立eclipse动态web工程时,需要改写编译后class文件的位置,通常情况下是这个位置:/WebContent/WEB-INF/classes 2.配置的页面链接 ...
- 一篇看懂Docker
松勤教育2020.4.20 我要分享 Docker 是什么? Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口.它是目前最流行的 Linux 容器解决方案. Dock ...
- 一篇看懂JVM底层详解,利用class反编译文件了解文件执行流程
JVM之内存结构详解 JVM内存结构 java虚拟机在执行程序的过程中会将内存划分为不同的区域,具体如图1-1所示. 五个区域 JVM分为五个区域:堆.虚拟机栈.本地方法栈.方法区(元空间).程序计数 ...
随机推荐
- PHP如何实现判断提交的是什么方式
function get_request_method() { // $_SERVER包含了诸多头信息.路径.以及脚本位置等等信息的数组,这个数组中的项目有web服务器创建. if (isset($_ ...
- Visual Studio 添加图标和版本
在Visual Studio中,如果你创建的是纯C语言的工程,那么给可执行程序添加图标就没有便捷的入口. 但也只是入口不好找了,添加步骤还是比较简单的,以下为具体操作方法: 1. 右键点击C工 ...
- 从GC的SuppressFinalize方法带你深刻认识Finalize底层运行机制
如果你经常看开源项目的源码,你会发现很多Dispose方法中都有这么一句代码: GC.SuppressFinalize(this); ,看过一两次可能无所谓,看多了就来了兴趣,这篇就跟大家聊一聊. 一 ...
- 【Linux常见命令】vimdiff命令
在类nuix平台,我们希望对文件之间的差异之间快速定位,希望能够很容易的进行文件合并……. 可以使用Vim提供的diff模式,通常称作vimdiff,就是这样一个能满足所有这些需求,甚至能够提供更多的 ...
- 《Java 开发从入门到精通》—— 2.3 使用IDE工具序
本节书摘来异步社区<Java 开发从入门到精通>一书中的第2章,第2.3节,作者: 扶松柏 , 陈小玉,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.3 使 ...
- Netflix:当你按下“播放”的时候发生了什么?
从用户端来看,使用Netflix是很简单的,按下播放键之后视频就像变魔术一样完美呈现了.看起来很容易是吧?然而实际不是这样的.了解过云计算的人可能会简单地以为,既然Netflix使用AWS来提供视频服 ...
- 如何在Vue项目中优雅的使用sass
开始之前,请先确保有一个基于webpack模板的项目(vue-cli脚手架一键安装~) 1.打开项目终端,安装sass的依赖包 npm install --save-dev sass-loader / ...
- Muduo网络库实战(一):安装和配置
1. 参考资料 <Muduo_网络库使用手册> 2. 实战记录 1) muduo依赖项安装 centos安装cmake命令:# yum install cmake centos安装libb ...
- CF思维联系–CodeForces -224C - Bracket Sequence
ACM思维题训练集合 A bracket sequence is a string, containing only characters "(", ")", ...
- Codeforce 1102 C. Doors Breaking and Repairing
Descirbe You are policeman and you are playing a game with Slavik. The game is turn-based and each t ...