.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分为五个区域:堆.虚拟机栈.本地方法栈.方法区(元空间).程序计数 ...
随机推荐
- prefetch 和 preload 及 webpack 的相关处理
使用预取和预加载是网站性能和用户体验提升的一个很好的途径,本文介绍了使用 prefetch 和 prefetch 进行预取和预加载的方法,并使用 webpack 进行实现 Link 的链接类型 < ...
- 学习web前端的免费12个学习网站,等你来撩
我相信很多人刚喜欢web前端或者刚刚接触web前端的时候,都不愿意去花钱去培训或者买资料去学习,因为不知道自己会不会学好,或者只是一时脑热,所以就选择免费的去学习基础.编程学习 很多人包括一些企业家, ...
- DFS(单词方阵)
思路: 先把地图二维字符数组存进去之后,遍历寻找到一个‘y’,然后我们可以设置一个八个方向的方向数组,让‘y’的坐标,遍历加上方向坐标,找到’i‘然后沿着这个方向,dfs下去,每次寻找到正确的,然后建 ...
- [Inno Setup] 开机自启动
[icons] Name: "{userstartup}\My Program"; Filename: "{app}\MyProg.exe"; Tasks:St ...
- 本周ASP.NET英文技术文章推荐[02/03 - 02/16]:MVC、Visual Studio 2008、安全性、性能、LINQ to JavaScript、jQuery...
摘要 继续坚持,继续推荐.本期共有9篇文章: 最新的ASP.NET MVC框架开发计划 Visual Studio 2008 Web开发相关的Hotfix发布 ASP.NET安全性教程系列 ASP.N ...
- SQL语句学习(一)
这篇文章用来记录再学习SQL语句的过程. 首先,我们从简单的创建表开始.创建表的语法是CREATE TABLE 表名(列1的名字 列1的属性,列2的名字 列2的属性...); 如果希望将某一列作为 ...
- 解决layui动态追加的点击事件不起作用问题
2019独角兽企业重金招聘Python工程师标准>>> //不起作用 $('#demo').on('click', function() { layer.msg('响应点击事件'); ...
- 替换input单选框的样式
实现效果:. css的input单选框的样式很丑,有时候不想使用原生的样式,如上照片,可以使用下面的方法. 思路是,给inpu加visibility:hidden隐藏,然后使用不同的图片绝对定位覆盖在 ...
- HTML(表格标签)
<table> 标签 表格由 <table> 标签来定义.每个表格均有若干行(由 <tr> 标签定义),每行被分割为若干单元格(由 <td> 标签定义) ...
- Jenkins 邮件收发(qq 邮箱)
一.配置 Jenkins 邮箱的全局配置 检查是否已安装插件 Email Extension Plugin 获取 qq 邮箱 授权码 进入 qq 邮箱 ---> 设置 ---> 账户 配置 ...