posted in 后端技术 

  1. Install this module
pm2 install pm2-logrotate
  1. Config this module

The following is an example of configuring pm2-logrotate. Other configuration items are similar to being configured. Please check current configuration or pm2 official documentation for detailed configuration items.

pm2 set pm2-logrotate:max_size 100M
  1. Check whether this module is active
pm2 list

If this module is working you should be able to see its status in the "Module" section.

  1. Check current configuration of this module
pm2 conf pm2-logrotate

  1. Check logs of pm2-logrotate
pm2 logs pm2-logrotate
  1. Reload pm2-logrotate
pm2 reload pm2-logrotate
posted in 后端技术 

当一个请求到达时,nginx通过如下算法确定最终用哪一个block来serve这次请求。

  1. listen匹配,nginx会先把所有server的ip:port用默认值补全,然后和目标请求的ip:port匹配,匹配优先级如下
    1. 唯一完全匹配——直接选中server
    2. 最高匹配度的一批server——比较server_name
  2. server_name匹配
    1. 完全匹配——直接选中server
    2. 尝试把请求host的第前一级域名变成*号到配置中去匹配——选中server
    3. 尝试把请求host的最后一级域名变成*号到配置中去匹配——选中server
    4. 尝试把请求host与配置中正则表达式的server_name去匹配——选中server
    5. 选中default server
  3. location匹配
    1. 带有 = 修饰符,能完全匹配的location——直接选中
    2. 寻找最长的前缀匹配结果,如存在,且带有 ^~ 修饰符,直接选中,若不带修饰符,暂存,然后看正则表达式location匹配结果
    3. 如果前缀匹配location的暂存结果中,有能匹配到的正则表达式location,则那个location优先级置顶,最终优先级最高的location被选中
    4. 如果没有正则表达式location被选中,之前暂存的前缀location被选中
posted in 后端技术 

  • Uses yarn
  • Organize code structure with Clean Architecturef
  • Demonstrates the twelve-factor methodology
  • ES2017 latest features like Async/Await
  • Watch code changes and restart for development using nodemon
    • yarn add nodemon --dev
  • Load environment variables from .env files with dotenv
  • Web framework using Express with middlewares as follows
    • yarn add express
    • Support CORS with express middleware cors
    • Gzip compression with express middleware compression
    • Parsing cookies with express middleware cookie-parser
      • yarn add cookie-parser
    • Customize request logs with express middleware morgan, which can be integrated with Winston.
    • Set some HTTP headers for security with helmet
      • yarn add helmet
      • import helmet from 'helmet';
      • const app = express();
      • app.use(helmet());
  • Request validation with joi
  • Authentication and Authorization with Passport
    • yarn add passport
  • MongoDB Modeling Lib with Mongoose
    • yarn add mongoose
  • Support pagination with Mongoose-aggregate-paginate-v2
    • yarn add mongoose-aggregate-paginate-v2
  • Deal with Date Object with Day.js
  • Git hooks with husky
  • Linting with ESLint
  • Format with Prettier
  • Consistent coding styles with EditorConfig
  • Tests with mocha, chai and sinon
  • Code coverage with Istanbul and coveralls
  • Continuous integration support with Travis CI
  • Docker support
  • Monitoring with pm2
  • Logging system using Winston
    • yarn add winston
    • With Winston, you can have multiple transports configured at different levels.
  • API documentation generation with apidoc
  • Image uploading with AWS S3 Client
  • Email sending by using SendGrid and AWS SES
  • SMS sending by using Twilio
  • Multilanguage Support using i18n
posted in 后端技术 

Kafka名字来源

Kafka作者之一Jay Kreps曾经谈及过命名的原因:

因为 Kafka 系统的写性能很强,所以找了个作家的名字来命名似乎是一个好主意。大学期间我上了很多文学课,非常喜欢 Franz Kafka 这个作家,另外为开源软件起这个名字听上去很酷。

Kafka的定位

Kafka 是 LinkedIn 公司内部孵化的项目。

Kafka 在设计之初就旨在提供三个方面的特性:

  • 提供一套 API 实现生产者和消费者;
  • 降低网络传输和磁盘存储开销;
  • 实现高伸缩性架构。

Kafka既是消息引擎系统,也是一个分布式流处理平台。

Kafka作为流处理平台和其他主流计算框架相比的优势

  • 更容易实现端到端的正确性(精确一次处理语义)
  • Kafka Streams宣称自己是一个用于搭建流处理的客户端库,而非完整功能系统,有利于区别其他框架的目标市场(瞄准小公司)

Kafka术语

一张图说明Kafka术语

  • 消息(Record):消息引擎处理的主要对象
  • 主题(Topic):承载消息的逻辑容器,具体使用中用于区分业务
  • 分区(Partition):一个有序的消息队列,一个主题下可以有多个分区
  • 消息位移(Offset):表示分区中每条消息的位置,是一个单调递增不变的值
  • 副本(Replica):Kafka中一条消息可以被复制到多个地方实现数据冗余,这些地方就是副本。副本还分leader副本和follower副本。副本在分区的层级下,一个分区可以配置多个副本实现数据高可靠
  • 生产者(Producer):向主题发布新消息的应用程序
  • 消费者(Consumer):从主题订阅新消息的应用程序
  • 消费者位移(Consumer Offset):表征消费者的消费进度,每个消费者都有自己的消费者位移
  • 消费者组(Consumer Group):多个消费者实例共同构成一个组,同时消费多个分区实现高吞吐
  • 重平衡(Rebalance):消费者组内一个消费者实例挂掉后,其他消费者自动重新分配订阅主题分区的过程。Rebalance是Kafka实现消费者端高可用的手段

不能保持默认值的参数

Broker端参数

  • log.dirs:没有默认值,必须手动指定。CVS格式指定多个路径,且多个路径最好分布在不同磁盘上,提供读写性能和提高可用性
  • listeners:监听器,告诉外部连接者要用什么协议访问主机和端口开放的Kafka服务
  • advertised.listeners:这组监听器是Broker用于对外发布的
  • auto.create.topics.enable:配置为true时表示,当收到消息,发现所属主题不存在时则自动创建,建议生产配置false
  • unclean.leader.election.enable:是否允许unclean leader选举。是指落后最新消息的partition被选举为leader的许可。若配置为true,则有可能导致消息丢失
  • auto.leader.rebalance.enable:是否允许定期重新选举leader,没必要,且对生产环境影响非常大,建议配置false
  • log.retention.{hour|minutes|ms}:三个配置都是用来控制一条消息被保存多长时间,ms优先级最高,hour最低
  • log.retention.bytes:指Broker为消息保存的总磁盘容量大小,默认值-1,标识存多少都行
  • message.max.bytes:Broker能接收的最大消息大小

Topic级参数

  • retention.ms:规定了该topic消息被保存的时长,默认7天,优先级高于Broker配置
  • retention.bytes:规定了该topic预留多少磁盘空间
  • message.max.bytes:该topic下单条消息最大尺寸,可用于不同业务不同配置

Producer端参数

Consumer端参数

JVM参数

设置环境变量,提高JVM堆大小,业界公认最佳配置为6G,修改GC算法

  • KAFKA_HEAP_OPTS:堆大小
  • KAFKA_JVM_PERFORMANCE_OPTS:GC算法
$> export KAFKA_HEAP_OPTS=--Xms6g  --Xmx6g
$> export  KAFKA_JVM_PERFORMANCE_OPTS= -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true
$> bin/kafka-server-start.sh config/server.properties

操作系统参数

  • 文件描述符限制调大
  • 文件系统类型:根据官网的测试报告,XFS 的性能要强于 ext4,ZFS性能貌似更好
  • Swap修改成1:改成0容易导致内存溢出来不及处理
  • 文件刷盘时间间隔:消息写到页缓存上即算成功,减小刷盘间隔可以提高可用性,但是降低吞吐量

实现无消息丢失

配置最佳实践

  1. 不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。
  2. 设置 acks = all。acks 是 Producer的一个参数,代表了你对“已提交”消息的定义。如果设置成 all,则表明所有副本 Broker 都要接收到消息,该消息才算是“已提交”。这是最高等级的“已提交”定义。
  3. 设置 retries 为一个较大的值。这里的 retries同样是 Producer 的参数,对应前面提到的 Producer 自动重试。当出现网络的瞬时抖动时,消息发送可能会失败,此时配置了 retries > 0 的 Producer 能够自动重试消息发送,避免消息丢失。
  4. 设置 unclean.leader.election.enable = false。这是 Broker 端的参数,它控制的是哪些 Broker 有资格竞选分区的 Leader。如果一个 Broker 落后原先的 Leader 太多,那么它一旦成为新的 Leader,必然会造成消息的丢失。故一般都要将该参数设置成 false,即不允许这种情况的发生。
  5. 设置 replication.factor >= 3。这也是Broker 端的参数。其实这里想表述的是,最好将消息多保存几份,毕竟目前防止消息丢失的主要机制就是冗余。
  6. 设置 min.insync.replicas > 1。这依然是 Broker 端参数,控制的是消息至少要被写入到多少个副本才算是“已提交”。设置成大于 1 可以提升消息持久性。在实际环境中千万不要使用默认值 1。
  7. 确保 replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。我们不仅要改善消息的持久性,防止数据丢失,还要在不降低可用性的基础上完成。推荐设置成 replication.factor = min.insync.replicas + 1。
  8. 确保消息消费完成再提交。Consumer 端有个参数 enable.auto.commit,最好把它设置成 false,并采用手动提交位移的方式。就像前面说的,这对于单 Consumer 多线程处理的场景而言是至关重要的。

常见丢消息案例

posted in 后端技术 

DNS域名规范

  • 域名中的标号由英文和数字组成,标号中除连字符“-”外不能使用其他的标点符号,不区分大小写字母
  • 每一个标号不超过63个字符
  • 级别最低的域名写在最左边,而级别最高的字符写在最右边
  • 由多个标号组成的完整域名总共不超过255个字符
  • DNS既不规定一个域名需要包含多少个下级域名,也不规定每一级域名代表什么意思。
  • 各级域名由其上一级的域名管理机构管理,而最高的顶级域名则由ICANN进行管理

域名管理

  • 顶级域名分三大类

    • 国家顶级域名nTLD:采用ISO3166的规定。如:cn代表中国,us代表美国,uk代表英国,等等。国家域名又常记为ccTLD(cc表示国家代码contry-code)
    • 通用顶级域名gTLD:最常见的通用顶级域名有7个,即:com(公司企业),net(网络服务机构),org(非营利组织),int(国际组织),gov(美国的政府部门),mil(美国的军事部门)
    • 基础结构域名(infrastructure domain):只有一个arpa,用于反向域名解析,因此成为反向域名

    xxx

域名服务器的分类

  • 根域名服务器:记录顶级域名服务器
  • 顶级域名服务器:管理在该顶级域名服务器注册的二级域名
  • 权威域名服务器(authoritative domain name system):负责一个zone的域名解析
  • 本地域名服务器:不在域名服务器树结构中,但是很重要,域名解析首先发给本地域名服务器

域名解析过程

  1. 请求本地域名服务器
  2. 本地域名服务器返回解析结果或想根域名服务器请求
  3. 根域名服务器返回顶级域名服务器的地址
  4. 本地域名服务器请求顶级域名服务器
  5. 顶级域名服务器返回权威域名服务器的地址
  6. 本地域名服务器请求权威域名服务器
  7. 权威域名服务器返回解析结果或报错
  8. 本地域名服务器返回解析结果或报错

DNS记录类型

  • A记录:将域名指向IPv4地址
  • AAAA:将域名指向IPv6地址(例如:ff06:0:0:0:0:0:0:c3)
  • CNAME:将域名指向另一个域名
  • TXT:在这里可以填写任何东西,长度限制255字符。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)
  • NS:授权其他域名服务器解析域名
  • MX:指向邮箱服务器
  • SOA:SOA叫做起始授权机构记录,表明负责一个zone的多台权威DNS服务器(由NS记录标记)之间的关系,SOA指向的DNS有修改权,其他DNS从SOA同步数据
  • SRV记录:记录提供特定服务的服务器,SRV记录了哪台计算机提供了哪个服务。格式为:服务的名字.协议的类型(例如:_example-server._tcp)
  • PTR记录:PTR记录是A记录的逆向记录,又称做IP反查记录或指针记录,负责将IP反向解析为域名