简要:开发中,常常因为需要我们要认为修改消费者实例对kafka某个主题消费的偏移量。具体如何修改?为什么可行?其实很容易,有时候只要我们换一种方式思考,如果我自己实现kafka消费者,我该如何让我们的消费者代码如何控制对某一个主题消费,以及我们该如何实现不同消费者组可以消费同一个主题的同一条消息,一个消费组下不同消费者消费同一个主题的不同消息。如果让你实现该框架该如何实现?

  这里我演示实验storm的kafkaspout来进行消费,kafkaspout里面使用的低级api,所以他在zookeeper中存储数据的结构和我们使用kafka的java客户端的高级api在zookeeper中的存储结构是有所不同的。关于kafka的java客户端的高级api在zookeeper中的存储结构的构造可以看这篇文章:apache kafka系列之在zookeeper中存储结构

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/6212913.html

可接网站开发,java开发。

新浪微博:intsmaze刘洋洋哥

微信:intsmaze

 

  创建一个kafka主题名为intsmazX,指定分区数为3.

  使用kafkaspout创建该主题的消费者实例(指定元数据存放zookeeper中的路径为/kafka-offset,指定实例id为onetest),启动storm可以观察到如下信息:

INFO storm.kafka.ZkCoordinator - Task [1/1] Refreshing partition manager connections
INFO storm.kafka.DynamicBrokersReader - Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
INFO storm.kafka.KafkaUtils - Task [1/1] assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
INFO storm.kafka.ZkCoordinator - Task [1/1] Deleted partition managers: []
INFO storm.kafka.ZkCoordinator - Task [1/1] New partition managers: [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
INFO storm.kafka.PartitionManager - Read partition information from: /kafka-offset/onetest/partition_0 --> null //这个地方会到zookeeper中该目录下读取,看是否存储有对该分区的消费信息
INFO storm.kafka.PartitionManager - No partition information found, using configuration to determine offset//没有分区信息,这个时候就会直接到kafka的broker中得到该分区的最大偏移量
INFO storm.kafka.PartitionManager - Last commit offset from zookeeper: 0
INFO storm.kafka.PartitionManager - Commit offset 0 is more than 9223372036854775807 behind, resetting to startOffsetTime=-2
INFO storm.kafka.PartitionManager - Starting Kafka hadoop002.icccuat.com:0 from offset 0
INFO storm.kafka.PartitionManager - Read partition information from: /kafka-offset/onetest/partition_1 --> null
INFO storm.kafka.PartitionManager - No partition information found, using configuration to determine offset
INFO storm.kafka.PartitionManager - Last commit offset from zookeeper: 0
INFO storm.kafka.PartitionManager - Commit offset 0 is more than 9223372036854775807 behind, resetting to startOffsetTime=-2
INFO storm.kafka.PartitionManager - Starting Kafka hadoop003.icccuat.com:1 from offset 0
INFO storm.kafka.PartitionManager - Read partition information from: /kafka-offset/onetest/partition_2 --> null
INFO storm.kafka.PartitionManager - No partition information found, using configuration to determine offset
INFO storm.kafka.PartitionManager - Last commit offset from zookeeper: 0
INFO storm.kafka.PartitionManager - Commit offset 0 is more than 9223372036854775807 behind, resetting to startOffsetTime=-2
INFO storm.kafka.PartitionManager - Starting Kafka hadoop001.icccuat.com:2 from offset 0
这个时候在zookeeper的/kafka-offset下没有生成名为onetest的目录,这是因为对应的intsmazeX还没有数据产生。
我们使用kafka消费者生产3条数据,然后去查看zookeeper中对应目录下的信息:

{"topology":{"id":"34e94ae4-a0a0-41e9-a360-d0ab648fe196","name":"intsmaze-20161222-143121"},"offset":1,"partition":1,"broker":{"host":"hadoop003.icccuat.com","port":6667},"topic":"intsmazeX"}
{"topology":{"id":"34e94ae4-a0a0-41e9-a360-d0ab648fe196","name":"intsmaze-20161222-143121"},"offset":1,"partition":2,"broker":{"host":"hadoop001.icccuat.com","port":6667},"topic":"intsmazeX"}
{"topology":{"id":"34e94ae4-a0a0-41e9-a360-d0ab648fe196","name":"intsmaze-20161222-143121"},"offset":1,"partition":0,"broker":{"host":"hadoop002.icccuat.com","port":6667},"topic":"intsmazeX"}

30秒(kafkaspout中设置提交zookeeper消费偏移量时间为30秒)之后,可以看到,会记录该实例对每一个分区消费的偏移量为1.

杀掉该拓扑,这个时候我们再向intsmazeX主题生产6条数据,这个时候,broker中该主题每个分区的最大偏移量为3了。

然后我们修改/kafka-offset/onttest/下每一个分区的offset为3.

这个时候,我们再次部署该拓扑,可以发现拓扑没有消费刚刚产生的6条消息。再发送3条消息,拓扑就会立马消费这三条消息。

杀掉该拓扑,这个时候该拓扑消费者实例对每个分区的消费偏移量就是4了,然后我们把offset修改为6,然后启动拓扑,这个时候broker中该主题每个分区的最大偏移量为4并不是6,让我们看看,消费分区的偏移量大于主题分区当前偏移量会有什么样的情况出现。

WARN storm.kafka.KafkaUtils - Got fetch request with offset out of range: [6]; retrying with default start offset time from configuration. configured start offset time: [-2]
WARN storm.kafka.PartitionManager - Using new offset: 4
WARN storm.kafka.KafkaUtils - Got fetch request with offset out of range: [6]; retrying with default start offset time from configuration. configured start offset time: [-2]
WARN storm.kafka.PartitionManager - Using new offset: 4
WARN storm.kafka.KafkaUtils - Got fetch request with offset out of range: [6]; retrying with default start offset time from configuration. configured start offset time: [-2]
WARN storm.kafka.PartitionManager - Using new offset: 4
这个时候我们看到,消费者的分区偏移量的记录将会自动同步为每一个分区当前最大的偏移量了,kafkaspout会先用偏移量6去拉去,发现拉去不到,就到broker中获取该主题对应分区的最大偏移量。。
{"topology":{"id":"818ab9cc-d56f-454f-88b2-06dd830d54c1","name":"intsmaze-20161222-150006"},"offset":4,"partition":0,"broker":{"host":"hadoop002.icccuat.com","port":6667},"topic":"intsmazeX"}
....
把offset的偏移量设置为7000,一样在拓扑启动后,会更新为每个分区的最大偏移量。
    重新部署一个拓扑消费该主题,设置该拓扑的id为twotest,这个时候启动拓扑,我们发现,并没有启动拓扑前的消息数据,这是因为,拓扑启动后,要获得偏移量,而这个偏移量只能是当前主题每个分区的最大偏移量(因为分区的偏移量是递增,且
分区的数据会定时删除的,所以无法知道当前分区当前最开始的偏移量。)
Refreshing partition manager connections
Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Deleted partition managers: []
New partition managers: [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Read partition information from: /kafka-offset/twotest/partition_0 --> null
No partition information found, using configuration to determine offset
Starting Kafka hadoop002.icccuat.com:0 from offset 7
Read partition information from: /kafka-offset/twotest/partition_1 --> null
No partition information found, using configuration to determine offset
Starting Kafka hadoop003.icccuat.com:1 from offset 7
Read partition information from: /kafka-offset/twotest/partition_2 --> null
No partition information found, using configuration to determine offset
Starting Kafka hadoop001.icccuat.com:2 from offset 7
Finished refreshing
Refreshing partition manager connections
Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Deleted partition managers: []
New partition managers: []
Finished refreshing
Refreshing partition manager connections
Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Deleted partition managers: []
New partition managers: []
Finished refreshing
Refreshing partition manager connections
Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Deleted partition managers: []
New partition managers: []
Finished refreshing
Refreshing partition manager connections
Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop003.icccuat.com:6667, partition=1}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
Deleted partition managers: []
New partition managers: []
发送三条信息,查看该实例目录如下。
{"topology":{"id":"3d6a5f80-357f-4591-8e5c-b3d4d2403dfe","name":"demo-20161222-152236"},"offset":8,"partition":0,"broker":{"host":"hadoop002.icccuat.com","port":6667},"topic":"intsmazeX"}
再启动一个拓扑,实例为twotest不变:
[INFO] Task [1/2] Refreshing partition manager connections
[INFO] Task [2/2] Refreshing partition manager connections
[INFO] Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
[INFO] Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
[INFO] Task [1/2] assigned [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
[INFO] Task [2/2] assigned [Partition{host=hadoop003.icccuat.com:6667, partition=1}]
[INFO] Task [1/2] Deleted partition managers: []
[INFO] Task [2/2] Deleted partition managers: []
[INFO] Task [1/2] New partition managers: [Partition{host=hadoop002.icccuat.com:6667, partition=0}, Partition{host=hadoop001.icccuat.com:6667, partition=2}]
[INFO] Task [2/2] New partition managers: [Partition{host=hadoop003.icccuat.com:6667, partition=1}]
[INFO] Read partition information from: /kafka-offset/twotest/partition_0 --> {"topic":"intsmazeX","partition":0,"topology":{"id":"3d6a5f80-357f-4591-8e5c-b3d4d2403dfe","name":"demo-20161222-152236"},"broker":{"port":6667,"host":"hadoop002.icccuat.com"},"offset":8}
[INFO] Read partition information from: /kafka-offset/twotest/partition_1 --> {"topic":"intsmazeX","partition":1,"topology":{"id":"3d6a5f80-357f-4591-8e5c-b3d4d2403dfe","name":"demo-20161222-152236"},"broker":{"port":6667,"host":"hadoop003.icccuat.com"},"offset":8}
[INFO] Read last commit offset from zookeeper: 8; old topology_id: 3d6a5f80-357f-4591-8e5c-b3d4d2403dfe - new topology_id: 348af8da-994a-4cdb-a629-e4bf107348af
[INFO] Read last commit offset from zookeeper: 8; old topology_id: 3d6a5f80-357f-4591-8e5c-b3d4d2403dfe - new topology_id: 348af8da-994a-4cdb-a629-e4bf107348af
[INFO] Starting Kafka hadoop002.icccuat.com:0 from offset 8
[INFO] Starting Kafka hadoop003.icccuat.com:1 from offset 8
[INFO] Task [2/2] Finished refreshing
[INFO] Read partition information from: /kafka-offset/twotest/partition_2 --> {"topic":"intsmazeX","partition":2,"topology":{"id":"3d6a5f80-357f-4591-8e5c-b3d4d2403dfe","name":"demo-20161222-152236"},"broker":{"port":6667,"host":"hadoop001.icccuat.com"},"offset":8}
[INFO] Read last commit offset from zookeeper: 8; old topology_id: 3d6a5f80-357f-4591-8e5c-b3d4d2403dfe - new topology_id: 348af8da-994a-4cdb-a629-e4bf107348af
[INFO] Starting Kafka hadoop001.icccuat.com:2 from offset 8
[INFO] Task [1/2] Finished refreshing
[INFO] Task [2/2] Refreshing partition manager connections
[INFO] Read partition info from zookeeper: GlobalPartitionInformation{partitionMap={0=hadoop002.icccuat.com:6667, 1=hadoop003.icccuat.com:6667, 2=hadoop001.icccuat.com:6667}}
[INFO] Task [2/2] assigned [Partition{host=hadoop003.icccuat.com:6667, partition=1}]
[INFO] Task [1/2] Refreshing partition manager connections
[INFO] Task [2/2] Deleted partition managers: []
[INFO] Task [2/2] New partition managers: []
{"topology":{"id":"3d6a5f80-357f-4591-8e5c-b3d4d2403dfe","name":"demo-20161222-152236"},"offset":8,"partition":1,"broker":{"host":"hadoop003.icccuat.com","port":6667},"topic":"intsmazeX"}
然后发送消息,我们可以看到两个拓扑都会运行的,因为两个拓扑共用一个元数据信息。
这个过程有些坑要注意:
1:在使用kafka-spout的时候,我们要指定该kafka消费者在zookeeper中存储偏移量的地址,这里是/kafka-offset。同时指定该kafka对应的实例id这里是onetest.kafkapout和kafka客户端代码不一样,它没有消费组的概念,也不能这样说吧,只能说数据的存放不一样,不同的实例代表
不同的消费组。
2:修改某一个kafkaspout实例的时候,我们一定要把该id的拓扑关闭掉,我们在项目中遇到一个大坑,就是不熟一样的kafkaspout它的id是相同的,也就是共用同一个目录,那么如果我们没有下线这些拓扑任务,而只是把
这些拓扑任务设置为不活跃状态,那么我们修改zookeeper中偏移量后,再把拓扑设置为活跃状态后,会发现修改无效,offset还是变为以前的offset了,这是因为拓扑没有杀掉,它的运行程序中也会保存当前消费的偏移量,会定时更新的。
3:我们在杀拓扑时,要设置时间,因为拓扑默认30秒向zookeeper提交一下偏移量信息。
修改偏移量有两种,一种就是在部署拓扑前,先修改zookeeper中的偏移量,或者直接删除zookeeper中的对应实例的目录。这样从新部署都会从最新的偏移量开始运行。
 
  下面的是我当初自己学习kafka时,思考自己写kafka时,该如何解决kafka的消费者和消费组之间对数据消费时的判断。虽然框架极大简化了我们的生产力,但是作为一个有
思想的程序员,我们应该换一个角度去思考一个框架,而不应该再是这个框架有什么功能,我们用这个框架的这个功能,这样下去,我们就会一直认为这个框架好厉害,却不明白其内部实现方式。 如果自己要实现kafka功能:
第一,一个消费组创建后,这个消费组的创建是客户端完成的,它把消费组名会存到zookeeper中。
第二,消费者被创建以后,会把自己的名字存到zookeeper中所属消费组名的文件夹下面。
第三,消费者被创建了,我们当然要指定他可以消费主体的那一条消息,这个时候应该是kafka的broker进行控制了,它应该会不断监听zookeeper中所有消费组下的消费者的变得,当发现有消费者增加或删除就知道要进行重新分配,这个时候,它应该计算分配好一会在每一个消费者文件中写上他可以消费的分区号和该分区的偏移量。
第四,broker怎么知道每一个主题的分区情况,其实broker创建一条主题的时候指定了分区和副本数量,这个时候会在zookeeper中生成一个主题文件夹,文件夹下每一个文件代表一个分区,且每一个文件的内容就是这个分区的位置和副本位置等信息,关于该分区消费偏移量应该不会记录在里面,因为每一个消费组中消费者消费该分区偏移量是不同的。
第五,这个时候我可以猜想到,应该是消费者文件中记录着它已经消费的偏移量,当消费者对消费分区进行重新分配时,偏移量也要进行转移,不然重新分配后,又要消费之前已经消费过的数据。但是这也有问题:因为消费者被删除它消费的偏移量就删掉了,它之前消费的分区分给其他人,其他人也不知道从哪里开始消费。
 
看kafkazookeeper存储结构我们可以发现:
消费者(群)文件夹,这个文件夹夹下面是各个消费组文件夹,每一个文件夹代表一个消费组信息。
消费组文件夹下面有三个文件夹,一个是存储该消费组中的每一个消费者,每一消费者就是一个文件,另一个文件夹存储的这个消费组可以消费的主题的文件夹,每一个文件夹代表他可以消费哪些主题。每一个主题文件夹下面就是该主题的分区,每一个分区文件就记录被该消费组消费的偏移量。
这样就可以保证,当消费者增加或删除后,它所消费分区的偏移量还在,我们进行重新分配时,可以保证分配好的分区,消费者不会重新消费,而直到该分区被消费的位置。
但是我们怎么知道哪一个消费者消费哪一个分区,把分区好存储到消费者文件中,这样貌似也可以,因为消费者删除后,它消费的分区会丢失也没有关系,broker监听消费者数量变化,一变化就对他们进行重新分配。(我现在能想到的好处就是,如果现有系统中存在消费者没有消费数据,那么我们删掉该消费者,但是我们只是监听到了消费者变化,并不知道是否有分区随着消费者的删掉而被停止消费,仍然会进行重新消费,其实这种情况是没有必要的),那么我们换一个方法吧。上面的猜想错了,一个消费组中的消费者只能消费一个主题的一条消息,其实就是一个主题的分区只能对应一个消费组中的一个消费者,换过来想,一个消费组可以消费多条主题,应该是可以的,那么一个消费组中的消费者就可以消费多条主题的中的一个分区。
 
或者是一个消费组可以消费多个主题,还是是一个消费者只能消费一个主题的一个分区。
经过我测试发现,一个消费者消费多个主题是可以实现的。
一个消费者消费多条主题的一个分区如何实现?
还有最后一个文件,该文件下面也是多个主题的文件夹,每个文件夹下面就是该文件的一个一个分区,分区我应该让他记录消费它的消费者的名称。
 

kafka主题offset各种需求修改方法的更多相关文章

  1. 使用Java API创建(create),查看(describe),列举(list),删除(delete)Kafka主题(Topic)

    使用Kafka的同学都知道,我们每次创建Kafka主题(Topic)的时候可以指定分区数和副本数等信息,如果将这些属性配置到server.properties文件中,以后调用Java API生成的主题 ...

  2. IDE-IntelliJ IDEA 主题、字体、编辑区主题、文件编码修改、乱码问题

    主题修改 上图标注 1 所示为 IntelliJ IDEA 修改主题的地方,可以通过打开左上角的File -> Setting.在 Windows 系统上 IntelliJ IDEA 默认提供的 ...

  3. Kafka提交offset机制

    在kafka的消费者中,有一个非常关键的机制,那就是offset机制.它使得Kafka在消费的过程中即使挂了或者引发再均衡问题重新分配Partation,当下次重新恢复消费时仍然可以知道从哪里开始消费 ...

  4. IntelliJ IDEA 主题、字体、编辑区主题、文件编码修改

    主题修改 上图标注 1 所示为 IntelliJ IDEA 修改主题的地方,在 Windows 系统上 IntelliJ IDEA 默认提供的主题有四套:Darcula.IntelliJ.Window ...

  5. kafka 主题管理

    对于 kafka 主题(topic)的管理(增删改查),使用最多的便是kafka自带的脚本. 创建主题 kafka提供了自带的 kafka-topics 脚本,用来帮助用户创建主题(topic). b ...

  6. BluetoothChat用于蓝牙串口通信的修改方法

    本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这 ...

  7. linux 的终端字体色和背景色的修改方法(一)

    更改Linux系统终端的颜色主题 随着Linux系统在服务器端的崛起,Linux也在慢慢进军个人桌面系统领域.如果在使用Linux系统的终端时,对其颜色主题不是很满意,该怎么修改颜色的主题呢?今天笔者 ...

  8. 迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法

    迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法 详情了解:http://topeetboard.com 更多了解:https://arm-board.taobao.com/ 用户在开发板上运 ...

  9. kafka主题管理

    若代理设置了 auto.create.topics.enable=true,这样还未创建topic就往kafka发送消息时, 会自动创建一个 ${num.partitions}个分区和{default ...

随机推荐

  1. SQLServer2005创建定时作业任务

    SQLServer定时作业任务:即数据库自动按照定时执行的作业任务,具有周期性不需要人工干预的特点 创建步骤:(使用最高权限的账户登录--sa) 一.启动SQL Server代理(SQL Server ...

  2. maven常见异常以及解决方法

    本文写的是我在整合ssm框架时遇到的一些问题,我估计很多人也会遇到,所以,这里作为一个总结,希望能够帮助大家解决问题 一,加入shiro组件时抛出的异常 加入步骤(略) 问题 1,保存后,无法导入sh ...

  3. "用户增长"--快速身份认证实现用户增长的技术和产品方案

    "用户增长"--快速身份认证实现用户增长的技术和产品方案 1   引言 作为一个互联网产品,用户量的增长是一个非常重要的衡量指标. 这是一个集合了销售,市场,运营,技术的综合能力. ...

  4. Spring Boot -- Start Up

    做Java Web的同学,都知道项目启动需要放到servlet容器里面运行,无论是使用哪一款IDE,都是非常麻烦的一件事情.在很早之前,一个servlet容器下可以放下很多的项目,并一起运行,而到现在 ...

  5. ABP(现代ASP.NET样板开发框架)系列之2、ABP入门教程

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之2.ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  6. MySQL基础之视图

    关于视图 视图是虚表,其中并不存在数据,只是多个表的组成 使用视图的优势 视图可以代替复杂的查询SQL语句,可以事先将不同表的多个数据组织起来 提高权限控制管理,能够将权限限制为行级管理,更具有安全性 ...

  7. Failure to find xxx in xxx was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced @ xxx

    问题: 在linux服务器上使用maven编译war时报错: 16:41:35 [FATAL] Non-resolvable parent POM for ***: Failure to find * ...

  8. php 查询

    <h1>租房信息</h1> <?php $db = ","asdadads"); $tj = "1=1"; $tj1 = ...

  9. Python初学者之网络爬虫

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途. 本文将介绍我最近在学习Python过程中写的一个爬虫程序,将力争做到不需要有任何Python基础的程序员都能读懂.读者也可以先跳到 ...

  10. Logstash时区、时间转换,message重组

    适用场景 获取日志本身时间 日志时间转Unix时间 重组message 示例日志: hellow@,@world@,@2011-11-01 18:46:43 logstash 配置文件: input{ ...