kafka 基础知识笔记

Kakfa 起初是由 LinkedIn 公司开发的一个分布式的消息系统,后成为 Apache 的一部分,它使用 Scala 编写,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如 Cloudera、Apache Storm、Spark 等都支持与 Kafka 集成。

体系架构

生产者使用 push 向 broker 发送消息,消费者使用 pull 模式拉取并消费消息

  • producer 可能是服务器日志,业务数据
  • broker 消息中间件节点,支持水平扩展,一般 broker 数量越多,集群吞吐率越高
  • consumer
  • zookeeper 集群, Kafka 依赖 zookeeper 管理

存储策略

Kafka 中消息是以 topic 进行分类的,生产者通过 topic 向 Kafka broker 发送消息,消费者通过 topic 读取数据。topic 在物理层面以 partition 为分组,partition 还可以细分为 segment。

假设 Kafka 消息文件存储目录

log.dirs=/tmp/kafka-logs

假设 partition 数量为 4

/bin/kafka-topics.sh –create –zookeeper localhost:2181 –partitions 4 –topic mytopic –replication-factor 4

然后就能在 /tmp/kafka-logs 目录中看到 4 个目录。

在 Kafka 文件存储中,同一个 topic 下有多个不同的 partition,每个 partiton 为一个目录,partition 的名称规则为:topic 名称 + 有序序号,第一个序号从 0 开始计,partition 是实际物理上的概念,而 topic 是逻辑上的概念。

每个 partition(目录)相当于一个巨型文件被平均分配到多个大小相等的 segment(段)数据文件中(每个 segment 文件中消息数量不一定相等)这种特性也方便 old segment 的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个 partition 只需要支持顺序读写就行,segment 的文件生命周期由服务端配置参数(log.segment.bytes,log.roll.{ms,hours}等若干参数)决定。

segment 文件由两部分组成,分别为.index文件和.log文件,分别表示为 segment 索引文件和数据文件。这两个文件的命令规则为:partition 全局的第一个 segment 从 0 开始,后续每个 segment 文件名为上一个 segment 文件最后一条消息的 offset 值,数值大小为 64 位,20 位数字字符长度,没有数字用 0 填充。.index 索引文件存储大量的元数据,.log 数据文件存储大量的消息,索引文件中的元数据指向对应数据文件中 message 的物理偏移地址。

每条消息都具有固定的物理结构,包括:offset(8 Bytes)、消息体的大小(4 Bytes)、crc32(4 Bytes)、magic(1 Byte)、attributes(1 Byte)、key length(4 Bytes)、key(K Bytes)、payload(N Bytes) 等等字段,

topic vs partition

一类 topic 可以认为一类消息,每个 topic 会被分成多个 partition,每个 partition 使用 append log 文件存储。

在创建 topic 时可以在 $KAFKA_HOME/config/server.properties 中指定 partition 的数量,也可以在 topic 创建之后去修改 partition 的数量。

# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=4

broker 重要配置

Kafka 有非常多的参数可以控制其工作和运行,大部分情况下默认值就可以,但是要用到生产上,就需要自定义一些参数来适应不同的环境。broker 中有一些非常重要的参数,这里列举一些,关于 broker 所有其他的参数可以参考 Kafka 的官方文档。

broker.id

每个 kafka broker 都需要有一个整型的唯一标识,这个标识通过 broker.id 来设置。默认的情况下,这个数字是 0, 但是它可以设置成任何值。需要注意的是,需要保证集群中这个 id 是唯一的。这个值是可以任意填写的,并且可以在必要的时候从 broker 集群中删除。比较好的做法是使用主机名相关的标识来做为 id, 比如,你的主机名当中有数字相关的信息,如 hosts1.example.com,host2.example.com, 那么这个数字就可以用来作为 broker.id 的值。

port

默认启动 kafka 时,监听的是 TCP 的 9092 端口,端口号可以被任意修改。如果端口号设置为小于 1024, 那么 kafka 需要以 root 身份启动。但是并不推荐以 root 身份启动。

zookeeper.connect

这个参数指定了 Zookeeper 所在的地址,它存储了 broker 的元信息。在前一章节的例子中,Zookeeper 是运行在本机的 2181 端口上,因此这个值被设置成 localhost:2181。这个值可以通过分号设置多个值,每个值的格式都是 hostname:port/path, 其中每个部分的含义如下:

  • hostname 是 zookeeper 服务器的主机名或者 ip 地址
  • port 是服务器监听连接的端口号
  • /path 是 kafka 在 zookeeper 上的根目录。如果缺省,会使用根目录

log.dirs

这个参数用于配置 Kafka 保存数据的位置,Kafka 中所有的消息都会存在这个目录下。可以通过逗号来指定多个目录,kafka 会根据最少被使用的原则选择目录分配新的 parition。注意 kafka 在分配 parition 的时候选择的规则不是按照磁盘的空间大小来定的,而是分配的 parition 的个数多小。

num.recovery.thread.per.data.dir

kafka 可以配置一个线程池,线程池的使用场景如下:

  • 当正常启动的时候,开启每个 parition 的文档块 segment
  • 当失败后重启时,检查 parition 的文档块
  • 当关闭 kafka 的时候,清除关闭文档块

默认,每个目录只有一个线程。最好是设置多个线程数,这样在服务器启动或者关闭的时候,都可以并行的进行操作。尤其是当非正常停机后,重启时,如果有大量的分区数,那么启动 broker 将会花费大量的时间。注意,这个参数是针对每个目录的。比如,num.recovery.threads.per.data.dir 设置为 8, 如果有 3 个 log.dirs 路径,那么一共会有 24 个线程。

auto.create.topics.enable

在下面场景中,按照默认的配置,如果还没有创建 topic,kafka 会在 broker 上自动创建 topic:

  • 当 producer 向一个 topic 中写入消息时
  • 当 cosumer 开始从某个 topic 中读取数据时
  • 当任何的客户端请求某个 topic 的信息时

在很多场景下,这都会引发莫名其妙的问题。尤其是没有什么办法判断某个 topic 是否存在,因为任何请求都会创建该 topic。如果你想严格的控制 topic 的创建,那么可以设置 auto.create.topics.enable 为 false。

num.partitions

这个参数用于配置新创建的 topic 有多少个分区,默认是 1 个。注意 partition 的个数只可以被增加,不能被减少。这就意味着如果想要减少主题的分区数,那么就需要重新创建 topic。

Kafka 通过分区来对 topic 进行扩展,因此需要使用分区的个数来做负载均衡,如果新增了 broker, 那么就会引发重新负载分配。这并不意味着所有的主题的分区数都需要大于 broker 的数量,因为 kafka 是支持多个主题的,其他的主题会使用其余的 broker。需要注意的是,如果消息的吞吐量很高,那么可以通过设置一个比较大的分区数,来分摊压力。

log.retention.ms

用于配置 kafka 中消息保存的时间,也可以使用 log.retention.hours, 默认这个参数是 168 个小时,即一周。另外,还支持 log.retention.minutes 和 log.retention.ms。这三个参数都会控制删除过期数据的时间,推荐还是使用 log.retention.ms。如果多个同时设置,那么会选择最小的那个。

过期时间是通过每个 log 文件的最后修改时间来定的。在正常的集群操作中,这个时间其实就是 log 段文件关闭的时间,它代表了最后一条消息进入这个文件的时间。然而,如果通过管理员工具,在 brokers 之间移动了分区,那么这个时候会被刷新,就不准确了。这就会导致本该过期删除的文件,被继续保留了。

log.retention.bytes

这个参数也是用来配置消息过期的,它会应用到每个分区,比如,你有一个主题,有 8 个分区,并且设置了 log.retention.bytes 为 1G, 那么这个主题总共可以保留 8G 的数据。注意,所有的过期配置都会应用到 patition 粒度,而不是主题粒度。这也意味着,如果增加了主题的分区数,那么主题所能保留的数据也就随之增加。

log.segment.bytes

用来控制 log 段文件的大小,而不是消息的大小。在 kafka 中,所有的消息都会进入 broker, 然后以追加的方式追加到分区当前最新的 segment 段文件中。一旦这个段文件到达了 log.segment.bytes 设置的大小,比如默认的 1G, 这个段文件就会被关闭,然后创建一个新的。一旦这个文件被关闭,就可以理 解成这个文件已经过期了。这个参数设置的越小,那么关闭文件创建文件的操作就会越频繁,这样也会造成大量的磁盘读写的开销。

log.segment.ms

控制段文件关闭的时间,它定义了经过多长时间段文件会被关闭。

message.max.bytes

这个参数用于限制生产者消息的大小,默认是 1000000, 也就是 1M。生产者在发送消息给 broker 的时候,如果出错,会尝试重发;但是如果是因为大小的原因,那生产者是不会重发的。另外,broker 上的消息可以进行压缩,这个参数可以使压缩后的大小,这样能多存储很多消息。需要注意的是,允许发送更大的消息会对性能有很大影响。更大的消息,就意味着 broker 在处理网络连接的时候需要更长的时间,它也会增加磁盘的写操作压力,影响 IO 吞吐量。

Kafka 特点

  • kafka 也被设计为多个消费者去读取任意的单个消息流而不相互影响;同时多个 kafka 消费者也可以选择作为一个组的一部分,来分担一个消息流,确保这整个组,这个消息只被消费一次
  • 基于硬盘的消息保存,消息将按照持久化配置规则存储在硬盘上。这个可以根据每个 topic 进行设置,允许根据不同的消费者的需求不同设置不同消息流的保存时间不同,持久化保存意味着一旦消费者来不及消费或者突然出现流量高峰,而不会有丢失数据的风险。同样也意味着消息可以由 consumer 来负责管理,比如消费消息掉线了一段时间,不需要担心消息会在 producer 上累积或者消 息丢失,consumer 能够从上次停止的地方继续消费
  • 水平扩展能力强,扩展可以在集群正常运行的时候进行,对于整个系统的运作没有影响,集群如果要同时容忍更多的故障的话,可以配置更高的 replication factors
  • 高性能

Kafka 的使用场景

关于该部分,Kafka 官方的入门教程中有非常详细的介绍,包括从最早在 LinkedIn 中为记录用户访问数据设计该系统,到后面日志,消息处理,到流处理等等,Kafka 有着非常广阔的使用场景。

更多关于如何使用命令行启动 Kafka,还有一些基础内容可以参考翻译的 Kafka 中文文档

reference


2018-05-29 kafka , linkedin , message , broker

SSH 端口转发

SSH 全称 Secure Shell,是一种加密的网络传输协议,可以在不安全的网络中为网络服务提供安全的传输环境。

几个 ssh 命令的参数

  • C 压缩数据传输
  • -f 后台登录用户名密码,如果省去该参数 ssh 会一直等待
  • -g 允许打开的端口让远程主机访问
  • -N 不执行shell
  • -T 表示不为该连接分配TTY
  • -p 后接端口

本地端口转发

本地端口转发,就是将发送到本地端口的请求,转发到目标主机端口。

ssh -L 本地网络地址:本地端口:目标主机地址:目标端口 root@<主机地址>
ssh -L localhost:3000:localhost:80 root@<ip>  # 将发送到本地3000端口的请求,转发到远程主机80端口
ssh -L 3000:localhost:80 root@<ip>  # 将发送到本地3000端口的请求,转发到远程主机80端口,省略掉本地地址
ssh -p port -C -f -NT -g -L 3000:localhost:80 root@<ip>

远程端口转发

远程端口转发,就是将发送到远程端口的请求,转发到目标端口,一般用来将公网主机端口请求转发到局域网内机器端口以实现外网访问。

ssh -R 远程地址:远程端口:目标地址:目标端口 root@<主机地址>
ssh -R localhost:3000:localhost:80 root@<ip>  # 将远程主机 80 端口的请求转发到本地3000端口
ssh -p port -C -f -NT -g -R 3000:localhost:80 root@<ip>

动态端口转发

动态端口转发,则是绑定一个本地端口,目标地址,目标端口不固定,目标地址和目标端口由发起的请求决定。只有root才能转发特权,支持 Socks 5 本地。

ssh -D 本地地址:本地端口 root@<主机地址>
ssh -D localhost:5000 root@<ip>
ssh -D 5000 root@<ip>           # 省略 localhost,监听本地5000端口
ssh -p port -C -f -NT -g -D 8080 root@<ip>        # Sock监听本地 8080 端口,任何发给 8080 端口的内容都会被转发到远程主机

reference


2018-05-28 ssh , port , forward , linux

每天学习一个命令:netcat 查看网络信息

nc 是 netcat 的简称,nc 工具是一个 TCP/IP 的瑞士军刀类型的工具,netcat 可以使用 TCP 或者 UDP 协议来进行网络连接的读写诊断,nc 命令可以用于 TCP,UDP,Unix 套接字相关的任何事情,是一个非常强大的网络工具。

端口是 Linux 机器上的应用、服务、进程与网络进行通信的端点。常用的 netstat 或者 nmap 等也能够列出本地机器上的开放端口。但是 nc 可以用来确定远程主机端口是否开放。

安装

sudo apt install netcat

使用实例

监听本地端口

nc -l -p 80   # 开启本机 80 端口 TCP 监听
nc -l -p 80 > /tmp/log

机器上运行该命令,端口 80 会被认为开放,可以用来欺骗扫描机

扫描端口

扫描端口

nc -zv host.example.com 22           # 扫描 22 端口是否开放
nc -zv host.example.com 22 80 443    # 扫描端口
nc -zv host.example.com 20-30        # 扫描一个范围
nc -zv -w 5 host.example.com 22-443  # -w 表示超时等待 5 秒

说明:

  • -z 设置 nc 只是扫描侦听守护进程,实际不发送任何数据
  • -v 开启 verbose,如果多加 -vv 会输出更多信息

上面的例子中,已经统计到了扫描一个端口,多个端口,或者指定端口范围。

作为简单的 Web Server

nc -l 8080 < index.html

客户端请求

curl localhost:8080

reference


2018-05-28 netcat , nc , linux , tcp , udp , command , netcat , port-scan , security

如何为视频配上合适的背景音乐

电影电视剧配乐一直都是一门学问,我一直很好奇韩剧或者韩综的配乐,如何能做到用音乐去推进故事,用音乐是暗示结局。但其实本文就是罗列了几个收集音乐的好地方,本不求达到那么专业的水平,只求在日常vlog或者短片中找到合适的BGM。

SoundCloud

SoundCloud 是一个在线音乐分享平台,上面有无数的音乐人作品,但是使用的时候请一定遵照版权。

几个账号

icons8

这是 icons8 推出的免费音乐计划,只有在使用的地方标注来源即可免费使用网站上的任何音乐素材。

YouTube

YouTube 是一个视频分享网站,YouTube 自身的版权做得非常健全,如果你使用了盗版的音乐素材极有可能直接被YouTube Content ID 扫描出来而直接屏蔽,所以谨慎使用版权素材,因此 YouTube 也提供了他的免费音乐库,上面也有非常多的选择。

另外作为数一数二的视频分享网站,YouTube 上面也有无数的音乐人,作曲家自己分享了很多作品,你可以在标明涞源的情况使用他们的音乐,这个就要依靠自己的发觉或者自身的喜好来决定收藏了。

bensound

Bensound 是一个免费的音乐素材网站,有丰富的免费音乐素材

artlist.io

该网站为收费网站, 199 刀 一年,还是很贵的


2018-05-28 music , youtube , soundcloud , sound , bgm , video

搬家整理之术收纳之术

最近要搬家,最初的需求就是快速打包搬走,想要找一些比较好用的搬家神器,搬家神器倒是没找到,不过找到了一些日常收纳整理之术。平时如果注重收纳整理,知道断舍离,其实搬家也远没有那么的痛苦。

可能提到搬家很多人会想到小推车,收纳箱等等用于收纳的物品,当然这些都是日常生活中必不可少的。即使不搬家,在家中使用收纳箱收拾平时不穿的鞋子,衣服等不仅能够防潮,也方便了快速分类整理。下面也不多废话,就直接把我整理过程中觉得比较有用的记录下来。

收纳

想要打包的时候加快速度,那就一定成都上依赖于平时的收纳,我自己平时本没有那么注意收纳,因此在打包时格外的零碎,各种文件,电器,工具分散在房间的各个地方,抽屉,架子,箱子中哪里都是。这可能是我第一要注意的事情,物品分类收纳是平时就需要养成的习惯。说到分类整理,对于我这样常年在外的人来说,收纳箱就必不可少了,虽然可能也有柜子书桌,但是一遇到搬家可能就要挪位置,还不如直接使用收纳箱来整理。

列清单

按照 不常用 - 常用 - 日常用 顺序打包,最后打包日常洗漱用品,杯子、碗筷、枕头、床铺之类

我是这么觉得,如果要出差一周需要打包的东西,比如洗漱用品,换洗衣服,以及必要的电子设备,这些可以放到最后打包,其他剩下的所有东西都可以提前打包好。最后留一个 20 几寸的行李箱装下所有日常装备就行。而其他平时不用的分类整理到收纳箱,或者纸箱中等待运输即可。易碎物品一定要贴上标签,特别注意。

日常用品基本上可以用一个行李箱搞定,剩下的就是平时也会用到的,比如台灯,衣架等等一个礼拜就要用上几次的物品,这类物品可以稍晚一些打包,预留一个比较充裕的纸箱,或者收纳箱,最后在搬家前将这类物品迅速的放到箱中,搬完之后也可以第一时间将这些物品拆出来。

而剩下的不常用的物品,按照物品品类分类打包:

  • 电器,日常大概率使用的电器,比如电磁炉,电饭锅,电水壶,显示器,音响等等可以提前打包好,稍微大一些的电器比如电饭锅等等如果有原包装带泡沫垫是最好的,否则也要做相应的防碰撞措施。
  • 小家电,最好有原包装,没有的话,没用的毛巾衣服就可以派上用场了,用它们或者其他软物报纸等包起来,避免在搬动时碰撞
  • 电源线,所有的家电电源线,能拿下来的,贴好标签装在一个袋子里,不能拿下来的,用胶布贴死在电器上。
  • 被褥,非当季的被褥衣服鞋子等等也可以装入收纳袋,纸箱封存起来,贴上相应的标签方便未来拆箱
  • 衣服,在所有东西里,衣服大概是最好打包的,可以按照存储的地方分类装袋或装箱
  • 鞋子,如果有盒子,可以直接把鞋装在盒子里,用胶布封好,然后用绳子或胶布粘成可以单手拎一次的大小;如果没有盒子,可以用绳子或胶布按双困在一起,放在箱子或袋子里
  • 贵重物品,一般都是要单独携带,以免丢失。数码产品类单反、单反镜头、笔记本电脑等… 证书类:毕业证书、学位证书、各种资格考试证书等等
  • 液体,卫生间和厨房各种洗洁精、洗发水、洗手液等开封的瓶瓶罐罐,扣紧,再用塑料袋封口,加胶带缠一圈,以免散出来
  • 粉状,各种没用完的调料、洗衣粉等开封的袋装物品,都用胶布封好,装箱。在箱子外面贴上”向上”“怕洒”
  • 书籍,等密度高的东西尽量使用小箱子装,或者将书分别放到多个箱底分散重量。放重物的箱子,底部要确实封牢
  • 其他各种不怕摔的零碎可以按照各种方法分类装箱,我习惯于按照平时存放的位置一袋一袋整理,比如抽屉里的东西,按顺序每个抽屉装一袋,拆包时可以就可以直接放回抽屉
  • 食材,一般在搬家前就要尽量减少采购食品原料,如果实在没用完,如米、面、蔬菜等,可以分类装箱,需要的写上“勿压”之类;如果是冰箱里的冷冻食品就只能请家庭成员单独携带了
  • 绿植,如果不太大,可以直接拎过去
  • 编号,打包好了最好编号,可以列个清单大致记一下每个箱子里都有什么,记住箱子和袋子,以免东西丢失而不自知,拆包时找东西也会比较快

对于我,大部分的电器我都留了原始的包装,其中的防碰撞泡沫可以完美的契合物品,除此之外各种零碎物品我都放到抗压的收纳箱中,衣服被褥则放到了收纳袋,然后装到纸箱中。

我个人使用了 50L 的收纳箱,然后有一下规格的收纳袋, 45 * 70 可以放下一个枕头,或者日常春秋外套, 56 * 80 放一些冬季棉衣、羽绒服,80 * 100 放被子等大件。

总结

整理过程中,该丢的一定要丢掉,学会断舍离,然后平时一定要学会分类整理,把规划制定到平时。所以写到这里也就回答了我最初的问题,有没有搬家神器,有,只不过都在平时。


2018-05-26 thought , sort-out , moving , clean-up

rabbitmq

RabbitMQ 消息代理,能够接收并转发消息,可以把他看成邮局。

RabbitMQ is open source message broker software (sometimes called message-oriented middleware) that implements the Advanced Message Queuing Protocol (AMQP). The RabbitMQ server is written in the Erlang programming language and is built on the Open Telecom Platform framework for clustering and failover. Client libraries to interface with the broker are available for all major programming languages.

安装

各个平台的安装官网都非常详细: https://www.rabbitmq.com/download.html

各个语言的客户端:https://www.rabbitmq.com/devtools.html

apt install rabbitmq-server

Docker 安装

docker pull rabbitmq
docker run -d -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin --name rabbitmq --hostname=rabbitmq rabbitmq:latest  

rabbitmq 默认的 latest tag 是不带管理页面的如果是要管理页面需要使用 rabbitmq:3-management

docker run -d -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin --name rabbitmq --hostname=rabbitmq rabbitmq:3-management

启动之后访问 http://ip:15672 就能够访问管理后台

使用

列出当前 RabbitMQ 中的队列

sudo rabbitmqctl list_queues

列出 exchange

sudo rabbitmqctl list_exchanges

各个客户端的教程官方的教程非常详细可以直接参考。

reference


2018-05-25 rabbitmq , message , broker , queue

每天学习一个命令:ip 处理网络管理任务

linux中的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者。ifconfig是net-tools中已被废弃使用的一个命令。iproute2 套件里提供了许多增强功能的命令,ip命令即是其中之一。只需一个ip命令,就能很轻松地执行一些网络管理任务。

常见用法

给机器设置一个IP地址

sudo ip addr add 192.168.0.193/24 dev wlan0

列出路由表条目

ip route show

显示网络统计数据

ip -s link

2018-05-22 network , linux , command , ip , ifconfig

Flask 使用 Celery 避免循环引用

在 Flask 中使用 Celery 官方给出了一个非常详细的教程,可是这个教程中有一点没有讲清楚,就是关于引入了 Celery 之后如何在项目中划分模块以及模块之间的相互调用,我们知道 Flask 用于构建比较大的项目时可能会使用到 blueprints,而这个时候项目结构可能就比较复杂了。

而引入 Celery 直接面临的问题是如何初始化 Celery 实例,在创建 Flask app 的同时创建 Celery 实例,这时候就面临一个问题,通常我们都在 Views 中引用 celery 异步任务,不可避免的会导致,需要在 views 中 import celery 相关的 module,而 celery 相关的 module 会引入 Flask app 相关的内容,而 Flask app 初始化会引入 views 相关的内容,就变成了循环调用。

有一个比较简单的解法就是初始化两个 Flask App 实例,一个用来启动,一个用来给 Celery 创造上下文。

不要在 create_app() 中再创建 Celery 实例。比如新建 celery_worker.py 来初始化 celery 实例,而在另外的文件中初始化 Flask() 实例。

项目结构大致如下:

├── README.md
├── app
│   ├── __init__.py
│   ├── config.py
│   ├── forms
│   ├── models
│   ├── tasks
│   │   ├── __init__.py
│   │   └── email.py
│   └── views
│   │   ├── __init__.py
│   │   └── account.py
├── celery_worker.py
├── manage.py
└── wsgi.py

图中

  • manage.py 用来初始化 Flask instance
  • celery_worker.py 用来初始化 Celery 并且作为 Celery worker 的入口

app/__init__.py

from celery import Celery
from flask import Flask

from app.config import BaseConfig

celery = Celery(__name__, broker=BaseConfig.CELERY_BROKER_URL)


def create_app():
    app = Flask(__name__)
    # ....
    celery.conf.update(app.config)	# 更新 celery 的配置
    # ...
    return app

celery_worker.py

from app import create_app, celery

app = create_app()
app.app_context().push()

这个文件有两个操作,一个为初始化 Flask 实例,也就初始化了 Celery 实例,然后第二个操作是使用 Flask 的 application context,celery 的所有操作都会在这个环境中执行。

然后就可以启动 Celery celery worker -A celery_worker.celery -l INFO

在 Flask 外部使用 Flask-SQLAlchemy

这里便引出了另外一个问题,如何在 Flask 外部使用 SQLAlchemy 中定义好的 model,当我们定义好和数据库相对应的 Object 之后,难免有些时候需要在 Flask 外部使用,比如清洗一些数据,或者单独跑一些数据时,这时没有 Flask Context 环境,那么这个时候需要借助 app_context() 函数:

from my_package import create_app

app = create_app(my_envrionment)

with app.app_context():
    # your code here

在 Context 上下文环境中就能够使用定义好的 model 了。另外一种方法是使用 @with_appcontext 装饰器:

from flask.cli import with_appcontext

@click.command(name='db-init-data')
@with_appcontext
def db_init_data():
    """Init db with some data"""
    admin = User(fname='John', lname='Smith', email='jsmith@google.com')
    db.session.add(admin)
    db.session.commit()

来自 stackoverflow

reference


2018-05-21 flask , celery , python , import

斐讯 k3 刷机教程

k3 的折腾记录

降级

我的固件版本 V21.6.12.66

只要两步,WEB 直刷,就能降级

  • 第一步,下载提供的 K3_V21.6.11.58P 固件,并在 WEB 管理页面手动升级处,选择这个固件刷机
  • 第二步, 选择欲降级到的固件 比如 K3_V21.5.37.246,在 WEB 管理页面手动升级处,选择这个固件刷机,就可以降级到 K3_V21.5.37.246

K3_V21.6.11.58P 下载地址 链接:https://pan.baidu.com/s/1rasSyjq 密码:ksxp

K3_V21.5.37.246 下载地址 链接:https://pan.baidu.com/s/1mjv2jaC 密码:xmrh

激活 Telnet

使用这个教程 激活 Telnet 端口

然后备份路由器

telnet 192.168.2.1

mount  # 查看当前挂载的 U 盘
cd /tmp/share/sda1/
mkdir backup
cd backup
cat /dev/mtdblock0 > mtdblock0.bin     # 备份 CFE
cat /dev/mtdblock5 > mtdblock5.bin     # 备份设备信息
cat /dev/mtdblock6 > mtdblock6.bin     # 备份固件,备份固件时间可能有些长 1min 左右

这个几个分区的作用

对于 K3 官方固件:

mtd0 boot
cfe 引导分区,建议备份,还包含了部分 nvram 参数和 MAC 等信息,不要刷入别人的,也不要随意刷写这个分区。
mtd1 nvram
设置分区,不用备份,保存了路由的所有设置信息,恢复出厂时会格式化然后从 cfe 和当前固件复制默认参数。
mtd2 nvram_back
从名字看像是 nvram 的备份,实际固件没有使用,全部空白,不用备份。
mtd3 res_info
没有使用,全部空白,不用备份。
mtd4 pro_info
只有 6 字节数据,00904C17F234,所有机器都一样,可选备份,就算没备份把这 6 字节复制过去就恢复了。
mtd5 dev_info
176 字节数据,好像是加密的固件的版本一些信息,刷写官方固件版本号发生变化时候这里的数据就变化,可选备份。
mtd6 linux
整个固件分区,平常刷写官方固件或者 LEDE 都是刷到这里,官方提供固件下载,只要 cfe 正常随便刷,不用备份。
mtd7 rootfs
动态的,包含在 linux 分区,mtd6 减去当前固件内核部分,是固件的后半部分,而固件是一个整体,当然不用备份。
mtd8 brcmnand
存储分区,日志文件、自己安装的软件保存再这里,固件版本信息变化时系统会格式化,不用备份,也不要恢复。

寻找固件刷入

这里我使用 abccba94 官改固件,在页面下载固件,现在最新的已经到了 k3_v16d ,解压,得到 k3_v16d.bin 文件,复制到 U 盘,如果 U 盘还连在路由器,可以使用 \192.168.2.1\ 然后远程将文件拷贝到 U 盘中。

然后在登录 telnet 192.168.2.1

cd /tmp/share/sda1/
cat k3_v16d.bin > /dev/mtdblock6 && reboot

将该目录下固件刷入,等待重启之后,做一次恢复出厂设置,长按 reset 键 5 秒。

固件大全

K3 的固件整理大全

  • 官改固件 by abccba94 http://www.right.com.cn/forum/thread-259012-1-1.html
  • 官改 By tianbaoha http://www.right.com.cn/forum/thread-212725-1-1.html
  • 梅林 By 63780223 http://www.right.com.cn/forum/thread-249788-1-1.html
  • 梅林 By laode1987 http://www.right.com.cn/forum/thread-251361-1-1.html
  • LEDE By stones http://koolshare.cn/thread-104733-1-1.html
  • LEDE By XiaoShan http://www.right.com.cn/forum/thread-215164-1-2.html
  • LEDE By ypjalt http://www.right.com.cn/forum/thread-215807-1-4.html
  • LEDE By Lean http://www.right.com.cn/forum/forum.php?mod=viewthread&tid=214087
  • LEDE By updateing http://koolshare.cn/thread-91998-1-1.html

entware 包管理

在管理后台软件中心安装 entware 之后,可以使用命令安装很多扩展。

entware 中的包列表:

http://pkg.entware.net/binaries/armv7/Packages.html

网页终端模拟器

安装 ttyd

opkg install ttyd

然后在 webshell 中设置开启网页管理,那么直接访问 http://ip:7681 ,输入用户名和密码就能够在网页中管理路由器。

ttyd 开源在 GitHub,使用 C 语言,websocket 通信。

更多有趣的包可以查看这里

手机移动端 SSH 工具:

IOSTermiusPrompt 2 AndroidJuiceSSHConnectBotTermius

常见问题

SSH 用户名和密码

K3 的 SSH 用户名是 admin,密码是网页管理密码。(网页管理密码和 SSH 密码是分开保存的,如果你开机后改过网页密码(比如执行恢复出厂设置相当于改成预置的 admin),ssh 密码不会立即同步,重启之后才会同步网页的管理密码)

reference


2018-05-19 『斐讯,phicomm, , k3, , 刷机,router, , ]

个人非常喜欢的几个 icon 主题

我一直用的是 Cinnamon 的桌面环境,使用 icon 主题也比较方便,这里就做个记录。

Papirus icon

地址:

安装

sudo add-apt-repository ppa:papirus/papirus
sudo apt-get update
sudo apt-get install papirus-icon-theme

Ultra flat icon

地址

安装

sudo add-apt-repository ppa:noobslab/icons
sudo apt-get update
sudo apt-get install ultra-flat-icons

更多的 ICON 主题可以看


2018-05-19 linux , icon-theme , unity , theme

电子书

最近文章

  • 使用命令行远程网络唤起主机 在 Linux 下可以通过 etherwake 命令来网络唤醒设备。
  • Cloud-init 初始化虚拟机配置 在安装 Proxmox 后在它的文档中了解到了 cloud-init。所以就来梳理一下。
  • BitTorrent 协议中的 BenCode 编码 在了解 BitTorrent 协议的时候,想着 .torrent 文件是如何生成的,所以就找了几个 CLI,比如 transmission-cli 和 mktorrent这两个开源的制作 torrent 文件的开源项目,发现他们就是按照一种约定的格式来生成文件。而这个约定的结构中就少不了现在要谈的 BenCode 编码。
  • Proxmox 设定直通硬盘 之前的文章讲了 Proxmox 的安装,以及在此基础上又安装了 OpenMediaVault,现在我的机器上一共三块硬盘,120 G SSD 安装了系统,并作为默认的 lvm,放一些 ISO,以及存放一些系统盘,另外的 1T 准备做 Proxmox 相关的数据盘,而剩下的一块 4T 盘想要直通给 OpenMediaVault 做数据盘。所以就产生了这样的一个需求。
  • OpenMediaVault 设置 OpenMediaVault,是一个开源的基于 Debian Linux 的下一代网络附加存储 (NAS) 解决方案。