这个世界既不是有钱人的世界,也不是有权人的世界,它是有心人的世界。


一些有用的命令

1.列出主题:kafka-topics.bat --list  --zookeeper localhost:2181

2.描述主题:kafka-topics.bat --describe --zookeeper localhost:2181 --topic [Topic Name]

3.从头读取消息:kafka-console-consumer.bat --zookeeper localhost:2181 --topic [Topic Name] --from-beginning

4.删除主题:E:\WorkSoftWare\kafka2.11\bin\windows>kafka-run-class.bat kafka.admin.TopicCommand --delete --topic test2016 --zookeeper localhost:2181

实体类:

KafkaProducerMessage.cs代码:

  [Table("KafkaProducerMessage")]
public partial class KafkaProducerMessage
{
public int KafkaProducerMessageID { get; set; } [Required]
[StringLength(1000)]
public string Topic { get; set; } [Required]
public string MessageContent { get; set; } public DateTime CreatedAt { get; set; }
}

KafkaConsumerMessage.cs代码:


[Table("KafkaConsumerMessage")]
public partial class KafkaConsumerMessage
{
public int KafkaConsumerMessageID { get; set; } [Required]
[StringLength(1000)]
public string Topic { get; set; } public int Partition { get; set; } public long Offset { get; set; } [Required]
public string MessageContent { get; set; } public DateTime CreatedAt { get; set; }
}

KafkaProducerMessageArchive.cs代码:


[Table("KafkaProducerMessageArchive")]
public partial class KafkaProducerMessageArchive
{
public int KafkaProducerMessageArchiveID { get; set; } public int KafkaProducerMessageID { get; set; } [Required]
[StringLength(1000)]
public string Topic { get; set; } [Required]
public string MessageContent { get; set; } public DateTime CreatedAt { get; set; } public DateTime ArchivedAt { get; set; }
}

vwMaxOffsetByPartitionAndTopic.cs代码:

    [Table("vwMaxOffsetByPartitionAndTopic")]
public partial class vwMaxOffsetByPartitionAndTopic
{
[Key]
[Column(Order = 0)]
[StringLength(1000)]
public string Topic { get; set; } [Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Partition { get; set; } public long? MaxOffset { get; set; }
}

KafkaConsumerRepository.cs代码:

    public class KafkaConsumerRepository
{
private KafkaModel context; public KafkaConsumerRepository ()
{
this.context = new KafkaModel();
} public List<KafkaConsumerMessage> GetKafkaConsumerMessages()
{
return context.KafkaConsumerMessage.ToList();
} public KafkaConsumerMessage GetKafkaConsumerMessageByID(int MessageID)
{
return context.KafkaConsumerMessage.Find(MessageID);
} public List<KafkaConsumerMessage> GetKafkaConsumerMessageByTopic(string TopicName)
{
return context.KafkaConsumerMessage
.Where(a => a.Topic == TopicName)
.ToList();
} public List<vwMaxOffsetByPartitionAndTopic> GetOffsetPositionByTopic(string TopicName)
{
return context.vwMaxOffsetByPartitionAndTopic
.Where(a => a.Topic == TopicName)
.ToList();
} public void InsertKafkaConsumerMessage(KafkaConsumerMessage Message)
{
Console.WriteLine(String.Format("Insert {0}: {1}", Message.KafkaConsumerMessageID.ToString(), Message.MessageContent));
context.KafkaConsumerMessage.Add(Message);
context.SaveChanges(); Console.WriteLine(String.Format("Saved {0}: {1}", Message.KafkaConsumerMessageID.ToString(), Message.MessageContent));
} public void Save()
{
context.SaveChanges();
} public void Dispose()
{
context.Dispose();
}
}

KafkaProducerRepository.cs代码:

  public class KafkaProducerRepository
{
private KafkaModel context;
public KafkaProducerRepository()
{
this.context = new KafkaModel();
} public List<KafkaProducerMessage> GetKafkaProducerMessages()
{
return context.KafkaProducerMessage.ToList();
} public List<string> GetDistinctTopics()
{
return context.KafkaProducerMessage.Select(a => a.Topic)
.Distinct()
.ToList();
} public KafkaProducerMessage GetKafkaProducerMessageByMessageID(int MessageID)
{
return context.KafkaProducerMessage.Find(MessageID);
} public List<KafkaProducerMessage> GetKafkaProducerMessageByTopic(string TopicName)
{
return context.KafkaProducerMessage
.Where(a => a.Topic == TopicName)
.OrderBy(a => a.KafkaProducerMessageID)
.ToList<KafkaProducerMessage>();
} public void InsertKafkaProducerMessage(KafkaProducerMessage Message)
{
context.KafkaProducerMessage.Add(Message);
context.SaveChanges();
} public void ArchiveKafkaProducerMessage(int MessageID)
{
KafkaProducerMessage m = context.KafkaProducerMessage.Find(MessageID);
KafkaProducerMessageArchive archivedMessage = KafkaProducerMessageToKafkaProducerMessageArchive(m); using (var dbContextTransaction = context.Database.BeginTransaction())
{
try
{
context.KafkaProducerMessageArchive.Add(archivedMessage);
context.KafkaProducerMessage.Remove(m);
dbContextTransaction.Commit();
context.SaveChanges();
}
catch (Exception)
{
dbContextTransaction.Rollback();
context.SaveChanges();
}
}
} public void ArchiveKafkaProducerMessageList(List<KafkaProducerMessage> Messages)
{
foreach (KafkaProducerMessage Message in Messages)
{
ArchiveKafkaProducerMessage(Message.KafkaProducerMessageID);
}
} public static KafkaProducerMessageArchive KafkaProducerMessageToKafkaProducerMessageArchive(KafkaProducerMessage Message)
{
return new KafkaProducerMessageArchive
{
KafkaProducerMessageID = Message.KafkaProducerMessageID,
MessageContent = Message.MessageContent,
Topic = Message.Topic,
CreatedAt = Message.CreatedAt,
ArchivedAt = DateTime.UtcNow
};
} public void Save()
{
context.SaveChanges();
} public void Dispose()
{
context.Dispose();
}
}

数据库上下文KafkaModel.cs代码:

   public partial class KafkaModel : DbContext
{
public KafkaModel()
: base("name=KafkaModel")
{
} public virtual DbSet<KafkaConsumerMessage> KafkaConsumerMessage { get; set; }
public virtual DbSet<KafkaProducerMessage> KafkaProducerMessage { get; set; }
public virtual DbSet<KafkaProducerMessageArchive> KafkaProducerMessageArchive { get; set; }
public virtual DbSet<vwMaxOffsetByPartitionAndTopic> vwMaxOffsetByPartitionAndTopic { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<KafkaConsumerMessage>()
.Property(e => e.Topic)
.IsUnicode(false); modelBuilder.Entity<KafkaProducerMessage>()
.Property(e => e.Topic)
.IsUnicode(false); modelBuilder.Entity<KafkaProducerMessageArchive>()
.Property(e => e.Topic)
.IsUnicode(false); modelBuilder.Entity<vwMaxOffsetByPartitionAndTopic>()
.Property(e => e.Topic)
.IsUnicode(false);
}
}

Program.cs代码:

class Program
{
private static string Topic;
static void Main(string[] args)
{
string invalidArgErrorMessage = "有效的args是:produce或consume"; if (args.Length < 1)
{
throw (new Exception(invalidArgErrorMessage));
} string intent = args[1]; Topic = ConfigurationManager.AppSettings["Topic"]; if (String.Equals(intent, "consume", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("开始消费者服务");
Consume();
}
else if (String.Equals(intent, "produce", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("开始生产者服务");
Produce();
}
else
{
throw (new Exception(invalidArgErrorMessage));
}
} private static BrokerRouter InitDefaultConfig()
{
List<Uri> ZKURIList = new List<Uri>(); foreach (string s in ConfigurationManager.AppSettings["BrokerList"].Split(','))
{
ZKURIList.Add(new Uri(s));
} var Options = new KafkaOptions(ZKURIList.ToArray());
var Router = new BrokerRouter(Options);
return Router;
} private static void Consume()
{
KafkaConsumerRepository KafkaRepo = new KafkaConsumerRepository();
bool FromBeginning = Boolean.Parse(ConfigurationManager.AppSettings["FromBeginning"]); var Router = InitDefaultConfig();
var Consumer = new Consumer(new ConsumerOptions(Topic, Router)); //如果我们不想从头开始,使用最新偏移量。
if (!FromBeginning)
{
var MaxOffsetByPartition = KafkaRepo.GetOffsetPositionByTopic(Topic);
//如果我们得到一个结果使用它,否则默认
if (MaxOffsetByPartition.Count != 0)
{
List<OffsetPosition> offsets = new List<OffsetPosition>();
foreach (var m in MaxOffsetByPartition)
{
OffsetPosition o = new OffsetPosition(m.Partition, (long)m.MaxOffset + 1);
offsets.Add(o);
}
Consumer.SetOffsetPosition(offsets.ToArray());
}
else
{
Consumer.SetOffsetPosition(new OffsetPosition());
}
} //消耗返回一个阻塞IEnumerable(ie:从没有结束流)
foreach (var message in Consumer.Consume())
{
string MessageContent = Encoding.UTF8.GetString(message.Value); Console.WriteLine(String.Format("处理带有内容的消息: {0}", MessageContent)); KafkaRepo = new KafkaConsumerRepository(); KafkaConsumerMessage ConsumerMessage = new KafkaConsumerMessage()
{
Topic = Topic,
Offset = (int)message.Meta.Offset,
Partition = message.Meta.PartitionId,
MessageContent = MessageContent,
CreatedAt = DateTime.UtcNow
}; KafkaRepo.InsertKafkaConsumerMessage(ConsumerMessage);
KafkaRepo.Dispose();
}
} private static void Produce()
{
KafkaProducerRepository KafkaRepo = new KafkaProducerRepository(); var Router = InitDefaultConfig();
var Client = new Producer(Router); List<Message> Messages = new List<Message>(); foreach (KafkaProducerMessage message in KafkaRepo.GetKafkaProducerMessageByTopic(Topic))
{
Messages.Add(new Message(message.MessageContent));
KafkaRepo.ArchiveKafkaProducerMessage(message.KafkaProducerMessageID);
} Client.SendMessageAsync(Topic, Messages).Wait(); KafkaRepo.Dispose();
}
}

App.config内容:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<appSettings>
<add key="BrokerList" value="http://localhost:9092"/>
<add key="Topic" value="test2017"/>
<add key="FromBeginning" value="true"/>
</appSettings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb"/>
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
</providers>
</entityFramework>
<connectionStrings>
<add name="KafkaModel" connectionString="Data Source=.;Initial Catalog=KafkaDemo;User ID=sa;Password=wu199010;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri=""/>
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400"/>
</providers>
</roleManager>
</system.web>
</configuration>

sql脚本:

IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = 'KafkaConsumerMessage')
BEGIN CREATE TABLE [dbo].[KafkaConsumerMessage](
[KafkaConsumerMessageID] [int] IDENTITY(1,1) NOT NULL,
[Topic] [varchar](1000) NOT NULL,
[Partition] [int] NOT NULL,
[Offset] [bigint] NOT NULL,
[MessageContent] [nvarchar](max) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
CONSTRAINT [PK_Kafka_Consumer_Message_KafkaConsumerMessageID] PRIMARY KEY CLUSTERED ([KafkaConsumerMessageID])
)
END GO IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = 'KafkaProducerMessage')
BEGIN
CREATE TABLE [dbo].[KafkaProducerMessage](
[KafkaProducerMessageID] [int] IDENTITY(1,1) NOT NULL,
[Topic] [varchar](1000) NOT NULL,
[MessageContent] [nvarchar](max) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
CONSTRAINT [PK_KafkaProducerMessage_KafkaProducerMessageID] PRIMARY KEY CLUSTERED ([KafkaProducerMessageID])
)
END GO IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = 'KafkaProducerMessageArchive')
BEGIN
CREATE TABLE [dbo].[KafkaProducerMessageArchive](
[KafkaProducerMessageArchiveID] [int] IDENTITY(1,1) NOT NULL,
[KafkaProducerMessageID] [int] NOT NULL,
[Topic] [varchar](1000) NOT NULL,
[MessageContent] [nvarchar](max) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
[ArchivedAt] [datetime] NOT NULL,
CONSTRAINT [PK_KafkaProducerMessageArchive_KafkaProducerMessageArchiveID] PRIMARY KEY CLUSTERED ([KafkaProducerMessageArchiveID])
)
END GO

引用.net kafka 组件:


启动zookeeper服务器,kafka服务器

打开一个DOS环境窗口

zkServer
  • 1

打开第二个DOS窗口

kafka-server-start D:xxxxxxxxx\config\server.properties
  • 1

结果如图:

手动添加生产者表三条记录:

 



消费者表


Kafka.net使用编程入门(三)的更多相关文章

  1. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  2. Minecraft Forge编程入门三 “初始化项目结构和逻辑”

    经过前面两个教程Minecraft Forge编程入门一 "环境搭建"和Minecraft Forge编程入门二 "工艺和食谱",我们大体知道了如何自定义合成配 ...

  3. Kafka.net使用编程入门(四)

    新建一个cmd窗口,zkServer命令启动zookeeper 打开另一个cmd窗口,输入: cd D:\Worksoftware\Apachekafka2.11\bin\windows kafka- ...

  4. Kafka.net使用编程入门(一)

    最近研究分布式消息队列,分享下! 首先zookeeper  和 kafka 压缩包 解压 并配置好! 我本机zookeeper环境配置如下: D:\Worksoftware\ApacheZookeep ...

  5. Kafka.net使用编程入门

    最近研究分布式消息队列,分享下! 首先zookeeper  和 kafka 压缩包 解压 并配置好! 我本机zookeeper环境配置如下: D:\Worksoftware\ApacheZookeep ...

  6. Kafka.net使用编程入门(二)

    1.首先创建一个Topic,命令如下: kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partit ...

  7. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  8. 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

    本文引用了“帅地”发表于公众号苦逼的码农的技术分享. 1.引言 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢 ...

  9. 脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

    本文引用了公众号纯洁的微笑作者奎哥的技术文章,感谢原作者的分享. 1.前言   老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天.实时音视频等)时,如果发现网络连接超时,第一时间想到的就是 ...

随机推荐

  1. 写给前端的Python依赖管理指北

    概述 在Python的项目中,我们可以通过pip来安装依赖包,但是不像npm install,pip默认安装的依赖包会挂在全局上,不利于项目工程协作. 这时候需要一款类似npm的工具记录我们的项目依赖 ...

  2. 力扣(LeetCode)461. 汉明距离

    两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意: 0 ≤ x, y < 231. 示例: 输入: x = 1, y ...

  3. 力扣(LeetCode) 509. 斐波那契数

    斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F(0) = 0, F(1) = 1 F(N) = F(N ...

  4. cmd中mvn命令,出现No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

    在cmd里执行mvn命令,出错 查看mvn -v 发现mvn运行在jre上,更改高级设置.我的电脑-->属性-->高级系统设置-->环境变量 更改完之后,再次查看 mvn -v 搞定 ...

  5. DP入门基本问题

    个人对简单的dp问题的理解:找是否有重叠问题,明确递推关系,怎么推的(顺序千万不要搞错),找到状态方程,循环时注意边界条件和方程式是否严格成立. 转自:https://www.cnblogs.com/ ...

  6. 学习笔记13—python DataFrame获取行数、列数、索引及第几行第几列的值

    1. df=DataFrame([{‘A’:’11’,’B’:’12’},{‘A’:’111’,’B’:’121’},{‘A’:’1111’,’B’:’1211’}]) print df.column ...

  7. POP3、SMTP和IMAP介绍和设置

    什么是POP3.SMTP和IMAP? 参照:http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html 用于 Outlook 的 POP 和 IMAP 电 ...

  8. every day a practice —— morning(6)

    "Nearly one in five job ads for China's 2018 national civil service called for 'men only' or 'm ...

  9. libavcodec是一款LGPL自由软件编解码库,用于视频和音频数据的编解码工作

    http://zh.wikipedia.org/zh-cn/Libavcodec http://baike.baidu.com/view/856526.htm libavcodec是一款LGPL自由软 ...

  10. 2018-02-16 GetSameTypeQuestion

    '目前存在的BUG '图片补丁存在多个URL Private Declare Function URLDownloadToFile Lib "urlmon" Alias " ...